全然書いた記憶はなかったんですが、昔の僕は逆FizzBuzz という問題に挑戦してました。 逆FizzBuzzを解いてみた - Panda Noir
この解答コードがもうちょいシンプルに書けたので載せておきます
おさらい: 逆FizzBuzzとは?
- [1,2,3,4,5,…] のように並んだ数列がある
- これを FizzBuzz で変換する([1,2,Fizz,4,Buzz,…])
- そこから数字を取り除く([Fizz,Buzz,…])
- そうして出来た文字列が入力として与えられる
- このとき元の数列を求めよ
- ただし、元の数列は複数ありうるため、数列の最初の数字が一番小さい数列を正解とする
以上が逆FizzBuzzです。
サンプルテストケース
- 入力が Fizz であれば [3] が正解
- 入力が Buzz Fizz Fizz Buzz Fizz なら [5, 6, 7, 8, 9, 10, 11, 12] が正解
Fizz に対して [6] と出力するのは、[3] のほうが数字が小さいため不正解。
コード
だいたいは元記事の方針に沿ってリファクタリングしました。
const range = (start, stop) => stop < start ? [] : [...Array(stop - start).keys()].map((x) => x + start); const solve = (arr) => { arr = arr.map((s) => s.replace(/[a-z]/g, '')); const index = arr.indexOf('FB'); if (index === -1) { // FB が含まれていない switch (arr.join('')) { case 'F': return range(3, 4); case 'B': return range(5, 6); case 'FB': return range(9, 11); case 'BF': return range(5, 7); case 'FF': return range(6, 10); case 'FBF': return range(3, 7); case 'BFF': return range(5, 10); case 'FFB': return range(6, 11); case 'FBFF': return range(3, 10); case 'BFFB': return range(5, 11); case 'FFBF': return range(6, 13); case 'FBFFB': return range(3, 11); case 'BFFBF': return range(5, 13); case 'FBFFBF': return range(3, 13); default: return null; } } const beforeFB = arr.slice(0, index); const afterFB = arr.slice(index + 1); // arr == [...beforeFB, 'FB', ...afterFB] // FB 以降が規則通りに並んでいるかチェックする if (!afterFB.every((s, i) => s === 'F B F F B F FB'.split(' ')[i % 7])) { return null; } const start = { '': 15, F: 12, BF: 10, FBF: 9, FFBF: 6, BFFBF: 5, FBFFBF: 3 }[ beforeFB.join('') ]; if (!start) { return null; } return range( start, (Math.floor(afterFB.length / 7) + 1) * 15 + [1, 4, 6, 7, 10, 11, 13][afterFB.length % 7] ); };
ちゃんとテストケースを確認したわけじゃないので間違ってるかも。一応以下のケースは満たしていることを確認済み。
検証に使ったテストケース
for (const [input, expect] of [ ['Fizz', [3]], ['Buzz', [5]], ['FizzBuzz', [15]], ['Fizz Fizz', [6, 7, 8, 9]], ['Fizz Buzz', [9, 10]], ['Buzz Fizz', [5, 6]], ['Fizz FizzBuzz', [12, 13, 14, 15]], ['FizzBuzz Fizz', [15, 16, 17, 18]], ['Fizz Fizz Buzz', [6, 7, 8, 9, 10]], ['Fizz Buzz Fizz', [3, 4, 5, 6]], ['Buzz Fizz Fizz', [5, 6, 7, 8, 9]], ['Buzz Fizz FizzBuzz', [10, 11, 12, 13, 14, 15]], ['Fizz Fizz Buzz Fizz', [6, 7, 8, 9, 10, 11, 12]], ['Fizz Buzz Fizz Fizz', [3, 4, 5, 6, 7, 8, 9]], ['Buzz Fizz Fizz Buzz', [5, 6, 7, 8, 9, 10]], ['Fizz Buzz Fizz FizzBuzz', [9, 10, 11, 12, 13, 14, 15]], ['Fizz Buzz Fizz Fizz Buzz', [3, 4, 5, 6, 7, 8, 9, 10]], ['Buzz Fizz Fizz Buzz Fizz', [5, 6, 7, 8, 9, 10, 11, 12]], ['Fizz Fizz Buzz Fizz FizzBuzz', [6, 7, 8, 9, 10, 11, 12, 13, 14, 15]], ['Fizz Buzz Fizz Fizz Buzz Fizz', [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]], [ 'Buzz Fizz Fizz Buzz Fizz FizzBuzz', [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], ], [ 'Fizz Buzz Fizz Fizz Buzz Fizz FizzBuzz', [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], ], ]) { console.log( JSON.stringify(solve(input.split(' '))) === JSON.stringify(expect) ); }