Half Sierpinski
Half Sierpinski 終了。結局、ゴルフ的最良解に到ることはできなかった。Top Player たちの答えを見てみると、ただの、AND だった。ちょっとおどろき。よく、こんなの思いつくなぁ。
ただ、答えが分かって Wikipedia の Sierpinski triangle を見直してみると、確かにそんな記述がある。Construction 項目の下のほうの説明に、
bitwise AND - The 2D AND function, z=AND(x,y) can also also produce a white on black right angled Sierpinski triangle if all pixels of which z=0 are white, and all other values of z are black.
とある。この項目は事前に見ていたが、『ぁあ?なんで AND が?』と、よく言わんとしていることが分からなかった。でも、答えが分かってみると、まさに AND 関数が Sierpinski Triangle を生成するということなんだね。
(0..15).each{x-> (0..15).each{y-> print x&y?' ':'#' } println'' }
とやると(上記は Groovy の例)
################ # # # # # # # # ## ## ## ## # # # # #### #### # # # # ## ## # # ######## # # # # ## ## # # #### # # ## #
↑こんな出力が得られる。うぁ、まんまだ。Wikipedia の記事はこういうことを言っていたんだ。(でも、Wikipedia の bitwise AND の次にある bitwise XOR の項目は何が言いたいんだかやっぱり分からない。)
AND がこんなパターンを生成するなんて面白いね。
さて、私が答えに使ったのは、
V(n)=V(n-1)^2*V(n-1)
という漸化式。要するに、ある項を 2 倍して XOR を取ると次の項が得られるというものだ。1 からはじめると、3, 5, 15, 17 ... という数列が得られ、各項の 2 進数表示が、やはり、Sierpinski Triangle のパターンを生成する。
それから、もうひとつ気づいたものとして、2^32-1 (つまり 2 進数で 1 が 32 個並んだ数)の約数を並べると、それらの約数の 2 進数表示がやはり Sierpinski Triangle になる。簡単のために bit 数の少ない、255 を例に取るとその約数は、
255: 11111111 (LSB <--> MSB) 85: 1010101 51: 110011 17: 10001 15: 1111 5: 101 3: 11 1: 1
↑となる。それから、以前の日記に書いた Pascal Triangle との関係。
- Sierpinski Triangle
- 2 次元 AND 関数
- V=V^2*V の漸化式の各項の 2 進数表示
- 2^32-1 の約数の集合の 2 進数表示
- Pascal Triangle の偶数を白、奇数を黒にしたもの
なんで、この一見関係ないようなものがみな同じ性質を示すんだろうね。面白いな。