せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】バイナリ、packなど。 プログラミング言語Ruby 学習感想文 ~1章 数独を解く


この本を読んでいます。

プログラミング言語 Ruby

プログラミング言語 Ruby

 
1章のコードがやば美しいので、
自分でも書いて理解します。

書いてる中で気付いたことなど。

 

後置ifでは変数宣言ができない

このコード後置ifで書いたらエラー

      if i = s.index(/[^123456789\.]/)
        raise Invalid , "wrong character #{s[i]} in pazzle" 
      end

 

文字列から数値配列への変換

"1821." ⇒[1,8,2,1,0]
 
普通ならこう書くのでは?

a = tmp.split("")
a.map! do |i|
  next 0 if i == '.'
  i.to_i
end

 

本ではこう!
ASCII = ".123456789"
BIN = "\000\001\002\003\004\005\006\007\010\011"
s.tr!(ASCII, BIN)
@grid = s.unpack('c*')

 
すごい。
unpack pack について学んだ


 

2進法・8進法・補数

\nnn
8 進数表記 (n は 0-7)

http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fliteral.html

なるほど。
\001 って書けば、これでもう8進法なんだ。
 
でも、

p BIN
⇒"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\a\b\t"

って「u」がついたり「a」になったりするのはなんでだろう。

色々調べたけれど、
そもそもpメソッド自体がバイナリをどう解釈してるか
による結果なわけだから、
きにしない。
puts BIN
って書いたら文字化けするし。
これはputsのバイナリ解釈によって、化けてしまっているわけで。

「8進法で9の数字までを入れている」ことが理解できたから良し。

 

\376".unpack("c*")  #<= -2

376(8) -> 254(10)
-> -128+64+32+16+8+4+1 = -2

 
このように16進数で書くことも出来る。

BIN = "\000\001\002\003\004\005\006\007\x8\x9"

ふむふむ

 

数独データ準備

こちらのサイトから数独の問題を頂きました。
ナンプレ20 - 無料で遊べる数独(ナンプレ)問題集
 
ただし、このままコピペすると
求める順番と違うので整形する必要がある。
 
f:id:sekaiya:20130928135851j:plain
 
図でいうと、1,4、7、2、5、・・・の順でデータを整形する
0始まりじゃなくてごめんね。。再キャプるの手間なので。。

データ整形コード

data = [
"1..",
"...",
"4..",
"42.",
"8..",
"..1",
"...",
"2..",
"..8",
"..4",
"..9",
"...",
"..3",
".4.",
"...",
".9.",
"...",
".1.",
".35",
"...",
"7.2",
"...",
".39",
".6.",
"...",
".6.",
".54",
]

result=[]
result0=[]
result1=[]
result2=[]
data.each_with_index do |d, i|
  result0 << d if i %3 == 0
  result1 << d if i %3 == 1
  result2 << d if i %3 == 2
end
0.step(9, 3) do |i|
  result << result0[i,3]
  result << result1[i,3]
  result << result2[i,3]
end
p result.flatten!

 
■実行結果

[1, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 2, 0, 0, 4, 0, 0, 0, 0, 1, 0, 0, 8, 0, 0, 4, 0, 0, 3, 0, 9, 0, 0, 0, 9, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 9, 0, 6, 0, 7, 0, 2, 0, 6, 0, 0, 5, 4]