古来より日本のプログラマの間には、「正月はフラクタル」という風習があります。
フラクタルについて、知識としては知っていても、実際にプログラムを書いたことはない人も結構いると思います。そんなフラクタルに、年に一度くらいは想いを馳せたり、手を動かしたりしてみよう、という風習です (去年の例: (1) (2)) 。
ちなみになぜ正月かと言うと、毎日と毎年が自己相似して末永く平穏に暮らせることを祈念するとか、もちに生えたカビがマンデルブロ集合に見えたとか、門松が L-system を想起させたとか、諸説ありますがわかっていません。
今年はコッホ曲線してみました。難読化などはしませんでした。
R3 = Math.sqrt(3) AA = " _,_ _,_..,_wypy _,_>qjgrq,gwamg _;_~ypyrrrLmmmy~~~g~qmgrmpgmmmm _,_\ ],_..,_4ZZy']/_4]j]/Z/Z44#g'_;_GGpyf{f{mm$$^^^gWN$$##\#$\#@$$```_`\\`_``,_\ kyLy```_N]}gPqPgwa#g`\\[_\\\\\\yFL[[kmmy^^^gNNNNPWP$W@$$'''_']]]'Z[[TZZZ']\ ']]]}]7Z7Z#Z#ZFF[[TS5SFF[[M$$$^^^MMNM$MMM$M@$$" def koch(x0, y0, x4, y4, scr) if Math.hypot(x0 - x4, y0 - y4) >= 1 x1, y1 = (x0 * 2 + x4) / 3, (y0 * 2 + y4) / 3 x3, y3 = (x0 + x4 * 2) / 3, (y0 + y4 * 2) / 3 vx, vy = (x4 - x0) / 3, (y4 - y0) / 3 x2, y2 = (vx + R3 * vy) / 2 + x1, (vy - R3 * vx) / 2 + y1 a = [[x0, y0], [x1, y1], [x2, y2], [x3, y3], [x4, y4]] a.each_cons(2) {|(x0, y0), (x1, y1)| koch(x0, y0, x1, y1, scr) } else x, y = (x0 + x4) / 2, (y0 + y4) / 2 scr[y][x] = "1" if (0...158) === x && y < 88 end end def asciiart(scr) (0...22).map do |y| (0...79).map do |x| AA[(0..3).map {|i| scr[y * 4 + i][x * 2, 2] }.join.to_i(2)] end.join.rstrip end end t = Time.now 55.times do |k| k = k - 55 scr = (0...88).map { "0" * 158 } koch(-k, (55 + k) * R3, 165.0 + k * 2, 0.0, scr) koch(165.0 + k * 2, 0.0, 165.0 + k * 2, (55 + k) * 2 * R3, scr) koch(165.0 + k * 2, (55 + k) * 2 * R3, -k, (55 + k) * R3, scr) puts "-- koch curve in ascii-art -- (c) Yusuke Endoh 2011", *asciiart(scr) s = (t += 0.125) - Time.now sleep s if s > 0 end loop do t = Time.now 110.times do |k| k = 109 - k scr = (0...88).map { "0" * 158 } koch(-k, (55 + k) * R3, 165.0 + k * 2, 0.0, scr) puts "-- koch curve in ascii-art -- (c) Yusuke Endoh 2011", *asciiart(scr) sleep (t += 0.125) - Time.now end end