33.5 코드 단축하기

이번에는 코드를 매우 단축하여 FizzBuzz를 풀어보겠습니다.

fizzbuzz_code_golf.c

#include <stdio.h>

int main()
{
    for (int i = 0; ++i <= 100;)    // 조건식 안에서 변화식을 함께 작성
        printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);
        // 삼항 연산자를 세 번 사용하여 printf 안에서 처리

    return 0;
}

실행 결과

... (생략)
FizzBuzz
91
92
Fizz
94
Buzz
Fizz
97
98
Fizz
Buzz

이번 예제는 코드 골프 방식으로 작성해보았습니다. 코드 골프란 골프에서 따온 말인데, 실제 골프 경기는 더 적은 타수로 승부를 겨룹니다. 마찬가지로 코드 골프도 소스 코드의 문자 수를 최대한 줄여서 작성하는 놀이입니다(코드의 문자 수를 얼마나 줄일 수 있는지 겨루는 놀이일 뿐 실무에서 이런 방식으로 작성하면 나중에 작성자 본인을 포함해서 여러 사람이 고생하게 됩니다).

다음과 같이 for 반복문도 변화식 부분은 생략한 채 조건식에서 변화식을 모두 처리합니다. ++i <= 100은 증가 연산자의 특성을 이용한 코드인데 반복할 때마다 ++을 수행하여 1을 증가시킨 뒤 100보다 작거나 같은지 검사합니다.

for (int i = 0; ++i <= 100;)

삼항 연산자를 사용하여 각 조건을 모두 처리하면서 문자열만 printf로 출력하는 방식입니다. i % 3을 계산하여 0이 아니면(3의 배수가 아니면) i % 5로 갑니다. i % 50이 아니면 %di를 출력합니다.

printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);

i % 50이면 "Buzz"를 출력합니다.

printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);

i % 30이면 다시 i % 5를 계산합니다. 이때 0이 아닌 값이 나오면 3의 배수이므로 "Fizz"를 출력합니다.

printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);

이제 i % 30이고, i % 50이면 3과 5의 공배수이므로 "FizzBuzz"를 출력합니다.

printf(i % 3 ? i % 5 ? "%d\n" : "Buzz\n" : i % 5 ? "Fizz\n" : "FizzBuzz\n", i);

이처럼 C 언어에서 연산자의 특성을 활용하면 코드의 길이를 짧게 줄일 수 있습니다.

지금까지 반복문, 조건문, 논리 연산자, 나머지 연산자를 사용하여 FizzBuzz 문제를 풀어보았는데 간단하면서도 내용이 조금 까다로웠습니다. FizzBuzz 문제는 회사 면접 문제로 자주 사용되는데 의외로 경력이 꽤 되는 프로그래머가 문제를 틀립니다. 보통 "이런 간단한 문제를 내다니"하면서 쉽게 보다가 3과 5의 공배수 처리 부분에서 실수를 하게 됩니다. 사실 FizzBuzz 문제는 프로그래밍 실력을 보는 것이 아니라 이해력을 보는 문제이기 때문입니다. 프로그래밍 실력보다 중요한 것이 요구 사항에 대한 이해력이라는 점 잊지 마세요.