アルゴリズム・パズルです。
問題。
IPアドレスは例えば 192.168.1.2 のように表せますね。これは2進数で32ビットの数字を、8ビットずつに区切ってさらに10進数で表した形式になっています。
ここで、0~9 のすべての数字が 1度ずつ現れたような IPアドレスで(数字の先頭の 0 は勘定に入れません)、32ビットの2進数でこれを表すと(これは先頭の 0 を含め、必ず32ビットの形で考えます)ビットの並びが左右対称になるようなものは、全部で何個あるでしょうか?
Ruby で解いてみます。
q41a.rb
def check(str) 10.times do |i| n = str.count(i.to_s) return false unless n == 1 end true end store = [] 0.upto(0b1111111111111111) do |i| bi = "%016b" % i bi += bi.reverse str = [bi[0, 8], bi[8, 8], bi[16, 8], bi[24, 8]].map {|x| ("0b" + x).to_i(0)}.join(".") store << str if check(str) end puts store.size p store
結果。
$ time ruby q41a.rb 8 ["34.179.205.68", "34.205.179.68", "68.179.205.34", "68.205.179.34", "179.34.68.205", "179.68.34.205", "205.34.68.179", "205.68.34.179"] real 0m0.432s user 0m0.428s sys 0m0.000s
最初は10進数で 0~9 の数字を並び替えて、それから 2進数に直して判定するという方法でやってみましたが、遅くて使い物になりませんでした。なので、逆にまず 2進数で左右対称になるものを作って、10進数で判定してやる方法でやりました。こちらの方が圧倒的に速いですね。
プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問
- 作者: 増井敏克
- 出版社/メーカー: 翔泳社
- 発売日: 2015/10/16
- メディア: Kindle版
- この商品を含むブログ (8件) を見る