ココアコードテスト|さっきの歌


問題のショートカット
今日は一日中問題をつかんだ.解けましたが、力が抜けて説明を断念^^!

すくい取る


再生時間を間違えました.
13:30-14:40終了時の分数が開始時の分数よりも大きい場合を考えただけです.13:50-14:00のように終わる時間帯がもっと小さい場合も考えなければなりません.

自分で頑張るところ


与えられた入力を有意義な資料構造にするために,Mapを用いた.一度に1つの値を抽出するのが便利なので、Mapと書いてありますが、この問題では特に仕事ができないので、直接オブジェクトとして使えます.でもまだコードが熟練していないのは散らかっています資料構造を作るときも関数を作って書くべきでしたが、素晴らしいので勝手に書きました.😅

学識


このような入力を受け入れて利用可能なデータとして処理することがtokenizeであることを直接感じた.ココの授業で聞いたことのあるコンセプトですが、自分でやってみて意味が分かりました.ここで重要なのは、tokenごとに比較できるようにすることです.どういう意味ですか.問題の中でCは同じ字で、Cは同じ字で、Cは2つの字を加えています.['C', 'C#']のように並べたり、#を足した内容を問題で使わない他の文字(例えば小文字、'Cc')に変えたりするには、適切な処理が必要です.

デザイン





コード#コード#

function solution(m, musicinfos) {
  const getPlayTime = (start, end) => { // string type의 시간을 받아 재생 시간 리턴
    const startTime = start.split(':').map(str => Number(str));
    const endTime = end.split(':').map(str => Number(str));
    if(startTime[1] <= endTime[1]) {
      return (endTime[0] - startTime[0]) * 60 + endTime[1] - startTime[1];
    }
    if(startTime[1] > endTime[1]) {
      endTime[1] += 60;
      endTime[0] -= 1;
      return (endTime[0] - startTime[0]) * 60 + endTime[1] - startTime[1];
    }
  }

  const getUnitArr = (musicSheet) => {
    const splitMusicSheet = musicSheet.split('');
    for(let i = 1; i < splitMusicSheet.length; i++) {
      if(splitMusicSheet[i] === '#') {
        splitMusicSheet[i - 1] = splitMusicSheet[i - 1].toLowerCase();
      }
    }
    return splitMusicSheet.filter(scale => scale !== '#')
  }

  // string type의 악보 받아 한 곡이 몇 분인지 리턴
  const getMusicPlayTime = (musicSheet) => { 
    const unitArr = getUnitArr(musicSheet);
    const musicPlayTime = unitArr.length;
    return musicPlayTime
  }

  // 재생 시간에 맞게 노래 자르거나 이어붙이기 - 리턴값을 m과 비교할 것임
  const getEntireMusicSheet = (playTime, musicPlayTime, unitArr) => { 
    let entireMusicSheetArr = [];
    const repeat = Math.floor(playTime / musicPlayTime);
    const remain = playTime % musicPlayTime;
  
    if(playTime < musicPlayTime) {
      return unitArr.slice(0, playTime + 1).join('');
    }

    if(playTime >= musicPlayTime) {
      for(let i = 1; i <= repeat; i++) {
        entireMusicSheetArr.push(...unitArr);
      }
      entireMusicSheetArr.push(...unitArr.slice(0, remain));
    }
    return entireMusicSheetArr.join('');
  }

  const hasM = (entireMusicSheet, m) => {
    return (entireMusicSheet.includes(m) === true) ? true : false
  }

  // --------------------------------------- 실행부 ---------------------------------------

  const tokenizedM = getUnitArr(m).join('');
  const splitInfos = musicinfos.map(info => info.split(','));
  console.log(splitInfos)
  let data = [];
  for(let i = 0; i < splitInfos.length; i++) {
    const infoMap = new Map();
    const playTime = getPlayTime(splitInfos[i][0], splitInfos[i][1]);
    const musicPlayTime = getMusicPlayTime(splitInfos[i][3]);
    const unitArr = getUnitArr(splitInfos[i][3]);
    const entireMusicSheet = getEntireMusicSheet(playTime, musicPlayTime, unitArr)

    infoMap.set('순서', i);
    infoMap.set('제목', splitInfos[i][2]);
    infoMap.set('재생된시간', playTime);
    infoMap.set('재생된전체악보', entireMusicSheet);
    infoMap.set('m포함?', hasM(entireMusicSheet, tokenizedM));
    data.push(infoMap);
  }

  const musicsContainM = data.filter(musicInfo => musicInfo.get('m포함?') === true)
  
  if(musicsContainM.length === 0) return '(None)';
  if(musicsContainM.length === 1) return musicsContainM[0].get('제목');
  
  let comparedItem = musicsContainM[0]
  for(let i = 1; i < musicsContainM.length; i++) {
    const currItem = musicsContainM[i]
    if(comparedItem.get('재생된시간') < currItem.get('재생된시간')) {comparedItem = currItem}
    if(comparedItem.get('재생된시간') >= currItem.get('재생된시간')) continue;
  }
  return comparedItem.get('제목');
}