1 부터 9 까지의 숫자를 이용하여 100 만들기 [Matlab 코드]

written by jjycjn   2016. 9. 2. 15:59

1 부터 9 까지의 숫자를 "순서대로" 사용하고, "덧셈"과 "뺄셈"만을 이용하여 "100"을 만드는 문제를 풀어 보았다. 더 자세한 정보는 이곳에서 확인해 볼 수 있다. 어쨌든, 이러한 스타일의 문제는 필수적으로 컴퓨터를 이용한 작업이 수반되어야 하므로 역시 Matlab을 이용하여 해결해 보았다. 


주어진 문제를 코딩하는 알고리듬는 매우 간단하다.

  1. 처음 초기값은 1부터 시작한다.
  2. For 구문을 (1부터 3까지) 이용하여, 1인 경우 12로, 2인 경우 1+2로, 3인 경우 1-2로 초기값을 업데이트 한다.
  3. 다시 한번 For 구문을 (1부터 3까지) 이용하여, 1인 경우 [값]3, 2인 경우 [값]+3, 3인 경우 [값]-3으로 값을 업데이트 한다.
  4. 이러한 과정을 8번 반복한다...
  5. 최종 결과값의 계산 결과가 100이면 출력, 아니면 다시 (1)로 돌아간다.

알고리듬 자체는 매우 간단한데, 문제는 이 알고리듬을 구현하기 위해서 For 구문을 8번 반복해야 하므로, 코드가 매우 지저분해 지저분해 진다는 점이다. 하지만 어짜피 구문 반복의 총 횟수는 $3^8 = 6561$번 밖에는 안되기 때문에, 더 간단한 알고리듬을 고민하는 대신에 일단 지저분한대로 코드를 짜 보기로 했다.


코드를 작성할 때 가장 고민했던 부분은, 세개의 변수 1, +, 2를 하나로 합쳐서 하나의 변수로 만드는 것이었다. 여러개의 string 변수를 하나로 합칠 때에는 strcat 함수를 이용하면 되는데, 이 때 문제는 1과 2의 속성은 string이 아니라 number라는 점이었다. 하지만 num2str 함수를 이용하여 1과 2의 속성을 string으로 변환해 줄 수 있으므로, 이 문제는 간단히 해결할 수 있었다. 이제 1, +, 2를 하나로 합치기 위해 아래의 코드를 사용하였다.

>> strcat(num2str(1), '+', num2str(2))
    ans = 1+2

결과는 "1+2"로 잘 나오지만, 가독성이 좋지 않아 사이를 한칸씩 띄워 "1 + 2"와 같이 나오게 하고 싶었다. 그래서 코드를 약간 수정해 보았다.

>> strcat(num2str(1), '', '+', '', num2str(2))
    ans = 1+2
>> strcat(num2str(1), ' + ', num2str(2))
    ans = 1 +2

하지만 위의 두가지 경우 모두 원하는 결과가 나오지 않았다. 왜 그런가 싶어서 구글 검색을 해보니 strcat 함수는 whitespace를 무시해 버리기 때문이라고 한다. 또한 이 문제를 해결하기 위해서는 ' + ' 대신에 {' + '}를 사용하면 된다고 한다. 그 결과는

>> strcat(num2str(1), {' + '}, num2str(2))
    ans = '1 + 2'

거의 원하는 결과가 나왔지만, 이번에는 결과값의 속성이 string이 아닌 cell이 되어 버리는게 문제였다. (이게 결과값이 1 + 2가 아니라 "1 + 2"로 나오는 이유이다.) 마지막으로 이를 해결하기 위해서 char 함수를 이용하여

>> char(strcat(num2str(1), {' + '}, num2str(2)))
    ans = 1 + 2

결국 원하는 결과를 얻어낼 수 있었다. 나머지는 위의 코드의 단순한 반복으로 간단히 해결할 수 있었다. 


그렇게 해서 완성한 코드는 다음과 같다. 

allowfrontminus = 0;
for a1 = 1:3
    if a1 == 1
        sum1 = char(strcat(num2str(1), num2str(2)));
    elseif a1 == 2
        sum1 = char(strcat(num2str(1), {' + '}, num2str(2)));
    else
        sum1 = char(strcat(num2str(1), {' - '}, num2str(2)));
    end
for a2 = 1:3
    if a2 == 1
        sum2 = char(strcat(num2str(sum1), num2str(3)));
    elseif a2 == 2
        sum2 = char(strcat(num2str(sum1), {' + '}, num2str(3)));
    else
        sum2 = char(strcat(num2str(sum1), {' - '}, num2str(3)));
    end
for a3 = 1:3
    if a3 == 1
        sum3 = char(strcat(num2str(sum2), num2str(4)));
    elseif a3 == 2
        sum3 = char(strcat(num2str(sum2), {' + '}, num2str(4)));
    else
        sum3 = char(strcat(num2str(sum2), {' - '}, num2str(4)));
    end
for a4 = 1:3
    if a4 == 1
        sum4 = char(strcat(num2str(sum3), num2str(5)));
    elseif a4 == 2
        sum4 = char(strcat(num2str(sum3), {' + '}, num2str(5)));
    else
        sum4 = char(strcat(num2str(sum3), {' - '}, num2str(5)));
    end
for a5 = 1:3
    if a5 == 1
        sum5 = char(strcat(num2str(sum4), num2str(6)));
    elseif a5 == 2
        sum5 = char(strcat(num2str(sum4), {' + '}, num2str(6)));
    else
        sum5 = char(strcat(num2str(sum4), {' - '}, num2str(6)));
    end
for a6 = 1:3
    if a6 == 1
        sum6 = char(strcat(num2str(sum5), num2str(7)));
    elseif a6 == 2
        sum6 = char(strcat(num2str(sum5), {' + '}, num2str(7)));
    else
        sum6 = char(strcat(num2str(sum5), {' - '}, num2str(7)));
    end
for a7 = 1:3
    if a7 == 1
        sum7 = char(strcat(num2str(sum6), num2str(8)));
    elseif a7 == 2
        sum7 = char(strcat(num2str(sum6), {' + '}, num2str(8)));
    else
        sum7 = char(strcat(num2str(sum6), {' - '}, num2str(8)));
    end
for a8 = 1:3
    if a8 == 1
        sum8 = char(strcat(num2str(sum7), num2str(9)));
    elseif a8 == 2
        sum8 = char(strcat(num2str(sum7), {' + '}, num2str(9)));
    else
        sum8 = char(strcat(num2str(sum7), {' - '}, num2str(9)));
    end
    if allowfrontminus == 1
        sum9 = char(strcat({'- '}, num2str(sum8)));
    else
        sum9 = sum8;
    end
    if str2num(sum9) == 100;
        disp(char(strcat(sum9, {' = '}, num2str(str2num(sum9)))));
    end
end
end
end
end
end
end
end
end

코드의 앞부분에 있는 변수 allowfrontminus는 뺄셈 기호를 1 앞에도 허용하는 경우를 대비해서 넣어 두었다. 이 변수가 0인 경우는 1 앞에 뺼셈 기호가 붙지 않고, 1인 경우에는 뺄셈 기호가 붙는다.


이제 이 코드를 실행해 보면 아래의 결과를 얻는다.

>> make100with1to9
    123 + 45 - 67 + 8 - 9 = 100
    123 + 4 - 5 + 67 - 89 = 100
    123 - 45 - 67 + 89 = 100
    123 - 4 - 5 - 6 - 7 + 8 - 9 = 100
    12 + 3 + 4 + 5 - 6 - 7 + 89 = 100
    12 + 3 - 4 + 5 + 67 + 8 + 9 = 100
    12 - 3 - 4 + 5 - 6 + 7 + 89 = 100
    1 + 23 - 4 + 56 + 7 + 8 + 9 = 100
    1 + 23 - 4 + 5 + 6 + 78 - 9 = 100
    1 + 2 + 34 - 5 + 67 - 8 + 9 = 100
    1 + 2 + 3 - 4 + 5 + 6 + 78 + 9 = 100


1 앞에 뺄셈을 허용한 경우를 구하기 위해서 allowfrontminus 변수를 1로 설정하고 위 코드를 다시 한번 실행하면 아래의 결과를 얻는다.
>> make100with1to9
    - 1 + 2 - 3 + 4 + 5 + 6 + 78 + 9 = 100


  ::  
  • 공유하기  ::