あなたは生まれてから何日が経ちましたか?20歳なら約7,300日、30歳なら約10,000日、40歳なら約14,600日だそうです。
ここまで数字が大きくなってくると、N進法(N=2〜32)にしたときに「何かそれっぽい数字」になってる可能性が高いとは思いませんか?つまり「毎日ゾロ目とか連番とか"それっぽい"数字になるなら毎日が記念日じゃん!」
ということでやってみましょう。
判定する関数たちの紹介
正直、このゾロ目判定関数や連番判定関数の紹介をしたいだけです。
const funs = { zorome: str => (/^([\s\S])\1*$/s).test(str), reverse: str => str === [...str].reverse().join(''), inc(str) { for (let i = 1, last = str.length; i < last; i++) if (Number(str.charAt(i - 1)) + 1 !== Number(str.charAt(i))) return false; return true; }, dec: str => funs.inc([...str].reverse().join('')), };
関数名がそのまま機能です。一応解説すると
- zoromeは与えられた文字列がゾロ目であるか判定します。「先頭の文字が1回以上続いている」という正規表現で判定しています。
- reverseは回文になっているか判定します。与えられた文字列を逆順にしても一致するかで判定しています。
- incは1ずつ増える増加列になっているか判定します(12345のような感じ)。
- decは1ずつ減る減少列になっているか判定します(54321のような感じ)。
試してみる
10,000日の前後20日で試してみます。
const funs = { zorome: str => (/^([\s\S])\1*$/s).test(str), reverse: str => str === [...str].reverse().join(''), inc(str) { for (let i = 1, last = str.length; i < last; i++) if (Number(str.charAt(i - 1)) + 1 !== Number(str.charAt(i))) return false; return true; }, dec: str => _funs.inc([...str].reverse().join('')), }; const funs = Object.keys(_funs).map(key => _funs[key]); for (let d = -20; d < 20; d++) { const diff = 10000 + d; for (let i = 2; i < 32; i++) { const str = diff.toString(i); if (funs.map(f => f(str)).some(val => val)) console.log(`${diff}は${i}進法で${str}になる`); } }
実行結果
9980は28進法でckcになる 9984は11進法で7557になる 9986は22進法でkdkになる 9987は29進法でbpbになる 9990は25進法でfofになる 9992は31進法でacaになる 9998は26進法でekeになる 9999は10進法で9999になる 10000は9進法で14641になる 10000は23進法でikiになる 10001は10進法で10001になる 10001は24進法でh8hになる 10001は30進法でb3bになる 10003は27進法でdjdになる 10007は7進法で41114になる 10008は5進法で310013になる 10008は22進法でkekになる 10008は28進法でclcになる 10010は8進法で23432になる 10016は25進法でg0gになる 10016は29進法でbqbになる
…28進法でckcになるとか、「だからなんだよ」感がヤバイですね。現場からは以上です。