# Algorithm

FizzBuzz 정복하기

잡담
FizzBuzz 정복하기

FizzBuzz

369랑 살짝 비슷한 게임입니다. 위키피디아엔 애기들 교육용 놀이라는데, 구글에 검색하면 관련 내용은 거의 온데간데없는 수준이고 코드만 난무합니다.

룰은 간단합니다. 1부터 시작해 3의 배수엔 Fizz를, 5의 배수엔 Buzz를 얘기하면 됩니다. 3과 5의 공배수인 15의 배수엔 FizzBuzz를 외쳐야 합니다.

도전과제

그냥 풀어만 보고 넘어간 문제였는데, 어쩌다 알게 된 코드 골프(최대한 짧은 코드로 결과를 구현하는 것) 사이트에 있길래 저 도전과제 하나만 보고 난생처음 보는 언어들로 풀어봤네요. 와중에 PHP랑 Javascript는 1등도 먹었습니다.

게임은 접어도 도전과제만 보면 깨고 싶은 욕구는 사라지질 않네요.

C

#include <stdio.h>
int main(void)
{
for (int i = 1; i < 101; i++)
{
if (i % 3 == 0 && i % 5 == 0)
{
printf("FizzBuzz\n");
}
else if (i % 3 == 0)
{
printf("Fizz\n");
}
else if (i % 5 == 0)
{
printf("Buzz\n");
}
else
{
printf("%d\n", i);
}
}
return 0;
}

굉장히 정석적이고 정상적인 FizzBuzz 구현 방법입니다. 사실 위 코드를 보시면 아시겠지만, 이제 막 공부를 시작한 사람이 아니고서야 딱히 흥미를 느끼기 어려운 코드입니다. 이래서 보통 이런 문제를 코드 골프에 쓰지 않나 싶네요. 짧게 줄이려고 갖은 꼼수 동원하다 보니 머리를 많이 굴려야 하더라고요.

Javascript

for (let i = 1; i < 101; i++) {
console.log(
i % 3 === 0 && i % 5 === 0
? "FizzBuzz"
: i % 3 === 0
? "Fizz"
: i % 5 === 0
? "Buzz"
: i
);
}

벌써 동업자가 있다면 몇 대 줘 터질 코드긴 하지만, 아직 더 줄여야 합니다.

보통 for 루프를 시작할 때, i = 1; i < 101; i++ 에서 i=0;++i<100; 같은 방식으로 글자를 줄이는 것으로 시작합니다.

게다가 자바스크립트처럼 좀 근본이 없는 언어는 a = 1처럼 변수를 선언해도 별문제가 없습니다.

for (i = 1; ++i < 101; ) {
console.log((i % 3 ? "" : "Fizz") + (i % 5 ? "" : "Buzz") || i);
}

천천히 보시면 이해가 될 겁니다.

%는 나머지를 구하는 것이고, 숫자는 0을 제외하면 참이니 i % 3이란 조건은 3으로 나누어떨어지면 false를, 아니면 true를 반환합니다. String을 더하면 두 문자열이 합쳐집니다. 조건에 텅 빈 문자열이 들어가면 false입니다.

많이 짧아지긴 했지만, i % 3, i % 5 두 가지 조건에 계속 ? "" : "String"이 들어가는 게 영 보기 거슬립니다.

for (초기문; 조건문; 증감문) {
실행 문장;
}

넘어가기 전에 짧게 for loop의 동작 방식을 살펴보겠습니다.

  1. 초기문 실행.
  2. 조건문 검사 (참이면 진행, 거짓이면 종결)
  3. 실행 문장 실행
  4. 증감문 실행

위 방법으로 for loop가 동작합니다.

for (i = 0; ++i < 101; console.log(i % 5 ? x || i : x + "Buzz"))
x = i % 3 ? "" : "Fizz";

위를 활용해 실행 문장에 변수를 하나 선언해두고 증감문에서 console.log를 실행하면 이런 기괴하고 짧은 코드가 탄생합니다.

for (i = 0; ++i < 101; console.log(i % 5 ? x || i : x + "Buzz"))
x = i % 3 ? "" : "Fizz";

이를 압축하면 62글자로 이루어진 짧은 FizzBuzz가 탄생합니다.

PHP

while($i++<100)echo[Fizz][$i%3].[Buzz][$i%5]?:$i,'
'

얘도 하나씩 뜯어보면 이해 가능하실 겁니다. Array에 없는 인덱스에 접근해도 아무런 오류도 없고, undefined가 뜨지도 않으니 위 코드처럼 기괴하게 작성해도 잘 작동합니다.

CSS

여담으로, for 루프 없이 HTML,CSS로도 가능합니다.

- var n = 0;
ol
while n < 100
li
- n++

ol>li*100을 다 적을 순 없으니 Pug로 대체합니다.

ol {
list-style: decimal inside;
}
li:nth-child(3n),
li:nth-child(5n) {
list-style-type: none;
}
li:nth-child(3n):before {
content: "Fizz";
}
li:nth-child(5n):after {
content: "Buzz";
}

실행 결과

잡담 카테고리 관련 글

위 글이 유용하셨다면, 아래 글도 읽어보세요!

2024 상반기 회고

2024 상반기 회고

벌써 2024년도 절반이 넘게 지나가 버렸습니다. 간만에 인생을 좀 돌아봐야겠다는 생각이 들어 회고를 작성해보았습니다.

간만에 한 장비 업데이트

간만에 한 장비 업데이트

약 3개월 정도에 걸쳐 조금씩 장비들을 구매했고, 이제 얼추 끝난 것 같아 정리하기 위해 글을 작성해봅니다. 제일 먼저 사진엔 없지만, 본체에선 CPU와 램이 바뀌었습니다.4년 전에 맞춘 1700에서 5600x로 시간을 달려왔습니다.1700 사고 얼마 안 돼서 2000번대 발표돼서 가슴 아파하던 게 벌써 4년이나 됐네요.바이오스 업데이트하다 보드 날려 먹어서 메인보드도 MSI b550m 박격포로 바꿨습니다. 쿨러는 Thermalright Assassin X

클린 코드 스터디, SSG 막코딩

클린 코드 스터디, SSG 막코딩

클린 코드 스터디 독자가 개발자와 컴퓨터라는 점을 제외하면 개발자도 작가와 꽤 비슷하지 않나 싶습니다. 표현하고자 하는 대상의 이름을 정확히 알고, 같은 표현을 여러 방식으로 할 줄 알아야 한단 점 등으로 미루어봤을 때요.글을 쓰고 퇴고하듯 매번 더 좋은 코드를 작성하기 위해 나름대로 노력해왔으나, 오픈 소스 코드를 여러개 까보며 보는 눈을 높여가고, 팀 프로젝트에서 남이 짠 코드를

SSG