那須ラボ7月

これまで、その時々でやりたいことをやっていたけれど、OSMOに会って、ようやく継続してやれることがみつかってきたようだ。以前もOSMO Tangramをやらせてもらって楽しめた時もあったけど、ちょっとその場限りな感じだった。しかし前々回から始めたCodingは面をクリアしていく楽しさもあるようだが、クリアした面を敢えて違うCodingで達成できる、という楽しさも知ったようだ。最初は1ブロックづつだったのが、昨日は一気に進められるよう、ブロック4段5段+ループ制御と複雑度があがっていた。ゲームチックにゴールが存在するようなので、とりあえずは飽きるまで進めばいいかな。

那須ラボ4月

マイクラでほぼ90分間、羊の毛刈りだけをしたり、ジェイソンに刺激されてScratchをやったりと、相変わらず的が定まっていない活動(?)をしているけど、それが楽しいと言ってくれているので親としても続けたいと考えている。

羊の毛刈りは本人もやり続けてはどうかと思っていたらしく、感想を聞いても照れ笑いをしていた。もう少し話を聞くと、本来は海や山のあるワールドを作りたかったらしい。イメージはあるようなので、フラットなワールドを用意してもらった後は、あまり口出しをせずに好きにやらせたいと考えている。

 

Project Euler 57を書いて思ったこと

またもやProject Eulerネタ。

Problem57にトライ。 

def root2_series
  (1..1000).inject( [3/2r] ) do |result, i|
    result << 1 + 1 / (result.last + 1)
  end
end

def bigger_numerators
  root2_series.select do |term|
    term.numerator.to_s.size > term.denominator.to_s.size
  end
end

p bigger_numerators.size

 3/2rはRationalのリテラルで、2.1から使えるようになったとのことだ。ちなみに複素数リテラルもできたみたいで、そういえば昔、3+2iって試して、できなかったことがあったのを思い出した。

それと今回は√2の級数を求めるのにinjectを使った。私はinjectは「前の値を使って1つの値を求める」しか頭になかった。しかしある人のコードで、「前の値」に配列を入れることで、まるでmapのように配列を作った例があったので、そのアイデアを使わせてもらった。injectを使うことで漸化式の各要素の入った配列を作ることができるなんて、自分だけではなかなか気づけないと思う。

そうなるとコードはシンプルになる。初項の3/2rが入った配列を初期値にしてやると、前イテレーションの計算結果がresult.lastで取り出せるので、最終的に1000個の項が入った配列になってくれる。

級数配列が完成すれば、Rationalの分母分子の桁数(.to_s.size)で比較すれば終わり、となる。

Rationalすごい?!

このコードをtoRubyで見せたところ、@you_ssk から、この級数の不思議な特徴を教えてもらった。ProjrctEulerにあるように、この級数は以下のように算出できる。

1 + 1/2 = 3/2 = 1.5
1 + 1/(2 + 1/2) = 7/5 = 1.4
1 + 1/(2 + 1/(2 + 1/2)) = 17/12 = 1.41666...
1 + 1/(2 + 1/(2 + 1/(2 + 1/2))) = 41/29 = 1.41379...

この各項を見てみると以下のような規則があるというのだ。


3/2
7/5 = (3+2*2)/(3+2)
17/12 = (7+2*5)/(7+5)
41/29 = (17+2*12)/(17+12)

つまり、
an/bn = (an-1 + 2 * bn-1)/(an-1 + bn-1)
なのである。これはすごいと、早速コードを書き直した。

def root2_series
  (1..1000).inject( [ [3,2] ] ) do |result, n|
    result << [result.last[0] + 2 * result.last[1], result.last[0] + result.last[1]]
  end
end

def bigger_numerators
  root2_series.select do |term|
    term[0].to_s.size > term[1].to_s.size
  end
end

p bigger_numerators.size

コード的にはほとんど変わらないのだけど、Rationalクラスを使わずに済んでいるのでなんとなく節約できた気になった。そこで処理時間を測ってみた。以下に結果を載せる。(100回動かした合計時間と100で割った平均時間)

                      user     system      total        real
Without Rational  3.323000   0.000000   3.323000 (  3.315948)
 Avg              0.033230   0.000000   0.033230 (  0.033159)

Rational     	  1.700000   0.000000   1.700000 (  1.697862)
 Avg          	  0.017000   0.000000   0.017000 (  0.016979)

 

Rational使った方が早い。。。これはどういうこと?

分数を使わずにできることをたまたま人から教わったからいいけど、自分で必死に思いついてたら、Rubyに「時間返せ」と言ってたかもしれない。かっこいいなぁ、Rational。

 

Project EulerをRubyで書いている

Project EulerRubyで解いているんだけど、Problem55で初めて自分としては良い出来のコードが書けたので自慢しようと思う。

 

class Integer
  def reverse
    self.to_s.reverse.to_i
  end

  def palindrome?
    self == self.reverse
  end

  def lychrel?
    myself = self

    (1..50).all? do |i|
      !(myself += myself.reverse).palindrome?
    end
  end
end

puts (1..9999).select { |i| i.lychrel? }.size

配列のall?やany?メソッドは、これまで書いていた方法と比べるとスキッと書けるから使っていて楽しい。人に「好きなメソッドは?」と聞かれたら、all?とany?と答えることにしよう!!
それとワンライナーではないけど、私はメソッドを数珠繋ぎにしがちだった。人のWebでのRubyコードが適切にメソッド分けしていたので真似したら、これまたスキッと書けたので驚いた。「returnが必要ない」の意味が少しつかめたかもしれない。

 

那須ラボ3/5

本音を言うと、子供のコンピュータのアプローチは時期尚早だったと感じ始めている。わかっていたけども、別にプログラミングでなくても学べることはあると通ってきていたが、マイクラでそれほど完成度を上げられないのはどうしたものかと考えていた。

この日、最後に先生から、「次回はViscuitをやってみましょう」となって、ありがたく思うと同時に、子供の楽しみの1つになってくれそうで、ちょっとほっとした。自宅に帰り、私は少し真面目にViscuitをいじってみた。おもしろい!! 子供も熱中してくれると嬉しいな。

この日はマイクラの黄昏ワールドをやり始めた。結構、集中していたのか1時間過ぎたあたりで疲れたようだった。お姉さん二人のワールドをみながら、色々と考えていたみたいだった。

実はあまり記憶になく、これは私のProblem。子供とふりかえりをやらなかったからだ。次回は簡単な予習というか、課題の設定と、終わってからのふりかえりをやりたい。

 

MinecraftPIのタイマー

少し前に作ってうまくいかなかったタイマーを手直しして、1.1分で0.2秒くらいのずれで実現できた。なにより描画がスムースになったのがよかった。悪かったのは気を利かせたつもりの描画スレッドだった。minecraft_pi_rubyを見てみるとTCPソケットでマイクラと交信していたので、余計なスレッドをなくしたらあっさり動いてくれた。

時間精度の方はLindaのRuby実装であるRindaをタイマースレッドで動かすようにしたことで安定した。お試し以外でRindaを使ったのは初めてだったけど、とっても簡単にできた。もしCPUが混んでもいいように、tapleには表示すべき時刻を秒単位で書くようにしたけど、tapleはdefaultの60秒は残るので、ダメダメ、タイムアウトを変えないと。

マイクラの画面は以下のコードでフラットにしちゃってる。

 mc.set_blocks(-100, 0,  -100, 100, 63, 100, Block::AIR)
 mc.set_blocks(-100, -1,  -100, 100, 1, 100, Block::GRASS)
 mc.set_blocks(-100, -63,  -100, 100, -2, 100, Block::STONE)

これだとあまりに殺風景なので、適当なワールドを作って、ブロックデータを取り出し、それを毎回適用するようにしようと考えている。またタイマーのフォントも気に入らないので、できるだけ綺麗にしたいな。

 

宇都宮toRuby (RaspberryPI勉強会、Rails勉強会)

今回、初参加な方が2名いらして、なんだか会として充実してきた感じだ。参加して思うのは楽しいということ。参加者が楽しんでいるのが伝搬してきたのかも。

 

ラズパイの方は、Lチカとして知られているLED点灯消灯をプログラム制御するところをやったり、ボタンのON/OFFを取り出す、ラズパイのHellow worldな日だった。もちろん動作した時の嬉しさはあるんだが、このTutorialが終わった後にどうするかが悩みどころだと思う。少し時間がかかる課題に取り組めるといいのだけど、そのネタがなぁ〜。すがぬまさんの夢をみんなで実現するのもいいかもしれないな。

 

Rails Tutorialは8章が終わり、Sign in/Sign outができるまできた。テストから作っているので色々とコードを書いてきたが、わずかなコードで実現できる手品みたいな部分は少し理解できてきたと思う。ただまだ自分でさっと書けるかというと難しいな。

初参加の方がいたので、Rails Tutorialの途中参加者への対応が難しいことがわかった。ただ、自分で発言したように、Rails Tutorialが終わるまでは継続するのがいいんじゃないかな。何度も戻ったりすると、最初からやってきたメンバーが辛くなるけど、継続している中での途中参加者は自分で追いつけると思うから。今の第二版を完遂して達成感を味わいたい。