Ansatzの備忘録

勉強したことあるいはふと思い立ったこと

シェルワンライナー160本ノック問題95

問題95 交番二進符号

後半の交番二進符号を10進数に直すところがよくわからなくて苦戦した。

解答例は

seq 0 8 | perl -nle 'printf("%08b\n", $_ ^ $_>>1)'

cat graycode | perl -nle '$n=unpack("C", pack("B*", $_));$m=$n;while($n>>=1){$m ^= $n} print $m'

となる。前半は何をしているか理解できた。後半はまず前半の出力をgraycodeに記録しておくことから始める。perlでまず$nにgraycodeのデータをオクテット(8ビット)として読み込む。そのあと$mに同じものを代入して、whileで$nをシフトしながらXORをとるらしいがここがよくわからない。($n>>=1)が条件式なのはわかるがこの中身がどういう意味なのか自信が持てない。多分$n=$n>>1の省略表現なのだと思うが。で、これの処理が終わった後の$nの値が0にならない限りループが繰り返される。ただの2進数を条件式に突っ込んでうまくループを回しているだけだと思う。あとは^=でXORの計算をして結果を$mに代入して出力する。$mは2進数のままのはずだがなぜか10進数に治っているのがよくわからなかったがperlのprintの仕様で、2進数などは原則10進数に直して出力するらしい。