while, for, break;

남의 코드를 보는 것은 역시 사고를 넓혀주는 것 같다.
코드워스 문제를 풀이하다가 재미있는 문제가 있어서 가져와봤다. 이렇게 문제를 많이 풀어봐야 사람이 겸손해지는 것이다.🥲

일단 문제는 위 썸네일 사진과 같다. 해석 약간 하자면 숫자를 받아 로마문자로 출력해줘야한다. 규칙은 같은 로마문자를 세 개 연속 쓸 수 없다. (이 문장은 밑에 있어서 짤렸다) 이것을 가지고 생각해보면 단위마다 1000(M)의 경우는 900, 500(D)의 경우는 400 이런 단위들은 단위 왼쪽에 100(C)을 뺀다는 의미로 CM, CD 라고 써줘야한다. (600, 700, 800까지는 DC, DCC, DCCC 이렇게 됨) 즉 오른쪽으로 문자가 증가하는 것이 정규칙, 왼쪽으로 문자를 써주는 경우는 예외가 된다.

내가 낸 해답

function solution(number){
  let [M, D, C, L, X, V, I ] = [1000, 500, 100, 50, 10, 5, 1]
  let result = ''; 
  if (number >= 4000) {
    return 'cannot convert';
  }
  while (number >= 1000 && number < 4000) {
    number = number - M;
    result += 'M';
  }
  while (number >= 900) {
    number = number - 900;
    result += 'CM';
  }
  while (number >= 500) {
    number = number - D;
    result += 'D';
  }
  while (number >= 400) {
    number = number - 400;
    result += 'CD'
  }
  while (number >= 100) {
    number = number - C;
    result += 'C'
  }
  while (number >= 90) {
    number =  number - 90;
    result += 'XC';
  }
  while (number >= 50) {
    number = number - L;
    result += 'L';
  }
  while (number >= 40) {
    number = number - 40;
    result += 'XL'
  }
  while (number >= 10) {
    number = number - X;
    result += 'X';
  }
  while (number >= 9) {
    number = number - 9;
    result += 'IX';
  }
  while (number >= 5) {
    number = number - V;
    result += 'V';
  }
  while (number >= 4) {
    number = number - 4;
    result += 'IV';
  }
  while (number >= 1) {
    number = number - I;
    result += 'I'
  }
  return result
}

그렇다. 머리가 나쁘면 원래 손이 고생하는 것이다. 내가 쓰면서도 이건 아닌데... 더 나은 방법이 있을텐데 했는데, 어쨌든 테스트 통과해서, 리팩토링 하기 전에 타인의 잘 쓴 해답을 볼 수 있었다.

내가 보기에 잘 쓴 타인의 답


function solution(number){
    var  roman = {M:1000, CM:900, D:500, CD:400, C:100, XC:90, L:50, XL:40, X:10, IX:9, V:5, IV:4, I:1}

    var ans = '';
    while(number>0){
        for(a in roman){ 
            if(roman[a]<=number){ ans += a; number-=roman[a]; break;}

        }
    }
    return ans;
}

그래. 이런 방식으로 하고 싶었다. 잘썼네. ㅠ_ㅠ (난 왜..)
처음에 switch/case 구문을 쓸까 하다가 생각해보니, 이건 빼면서 해도 될 것 같아서, 이렇게 해봤다.

리팩토링 후 제출

function solution(number){
  let symbols = {M: 1000, CM: 900, D: 500, CD: 400, C: 100, XC: 90, L:50, 
                 XL: 40, X: 10, IX: 9, V: 5, IV: 4, I: 1}
  let result = ''; 
    
    while (number > 0) {
      for (symbol in symbols) {
        if (symbols[symbol] <= number) {
          result += symbol;
          number -= symbols[symbol];
           break
        }
      }
    }
   return result
  }

쓰고나서 보니 다 베꼈네. 원래 배열로 해보려고 했는데 문자와 함께 숫자를 저장하기에는 객체보다 더 나은 게 없다. 그냥 베끼려고 이렇게 된 것이 아닌 것이다. 객체로 데이터를 관리하는 것이 최적이었다.

break 없으면 계산이 맞질 않는다. 22를 'XIXIII' 이렇게 출력해버린다. (옳은 답은 'XXII')
break을 mdn에서 찾아보면 "break 문은 현재 반복문, switch 문, 또는 label 문을 종료하고, 그 다음 문으로 프로그램 제어를 넘깁니다."라고 되어있다. 즉 result에 symbol 키를 추가하고, number 에서 symbol 값을 빼주고 나서 다시 for문을 돌아야하는데 break이 없으면 if문을 또 돌게 되는 것이다.... 22 - 10 한 뒤 result에 X를 쓰고 또 12에서 9를 빼고 XIX를 쓴 것이다... 이러면 안 돼. 그래서 if문 한 번 돌았으면 다시 키를 순회해주도록 break을 써야만한다. 오류분석을 통해서 프로그램의 작동원리를 섬세히 익히는 것도 중요하겠다. (break을 공부하고도 언제 써야할 지 감이 없었는데 이 문제로 약간 알게된 듯)

친구들이 지금 1등은 800점대, 2등은 300점대를 달리고 있다. 나는 오늘 90점이네? ㅋㅋㅋㅋㅋ 한참 더 노력해야겠다. 더 많은 문제를 풀어서 혹시 내가 3등안에 들게되면 기쁨의 블로깅을 해야겠다. 현재는 꼴찌에서 두 번째이다.

좋은 웹페이지 즐겨찾기