美しい?IPアドレス(Ruby)

アルゴリズム・パズルです。

問題。

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進数で判定してやる方法でやりました。こちらの方が圧倒的に速いですね。