みなさん、こんにちは。まどぎわです(・∀・)
RubyKaigiでCookpadさんのブースで出題されていたRuby Puzzleを、Ruby Kaigi中に楽しくやっていたので、
解答も下記で公開されたので、自分の解答をメモしておきます。
Day 1
Problem 1-1
# Hint: Use Ruby 2.6. puts "#{"Goodbye" .. "Hello"} world"
My Answer(2文字)
puts "#{"Goodbye" .. && "Hello"} world"
HintにあるようにRuby2.6から追加された終端なしRangeを使って、
"Hello"だけを返せればいいのかなと思ったので&&
を使ってみました。
Problem 1-2
puts&.then { # Hint: &. is a safe # navigation operator. "Hello world" }
My Answer(2文字)
puts 1&.then { # Hint: &. is a safe # navigation operator. "Hello world" }
これはputs
の返り値が、nil
になってしまってthen
以降が実行されなくなっていたので、
puts 1&.then
として、puts
の返り値を使用しないようにしてました。
Problem 1-3
include Math # Hint: the most beautiful equation Out, *, Count = $>, $<, E ** (2 * PI) Out.puts("Hello world" * Count.abs.round)
My Answer (2文字)
include Math # Hint: the most beautiful equation Out, *, Count = $>, $<, E ** (2 * PI*0) Out.puts("Hello world" * Count.abs.round)
Countが1に近い値になれば、"Hello world"が1回実行されるので、
E ** (2 * PI*0)
として、1に近い値を作りました。
Day 2
Problem 2-1
def say -> { "Hello world" } # Hint: You should call the Proc. yield end puts say { "Goodbye world" }
My Answer(1文字)
def say -> { "Hello world" }. # Hint: You should call the Proc. yield end puts say { "Goodbye world" }
これは.yield
は.call
と同じなので、それを使うようにしました。
Problem 2-2
e = Enumerator.new do |g| # Hint: Enumerator is # essentially Fiber. yield "Hello world" end puts e.next
My Answer(2文字)
e = Enumerator.new do |g| # Hint: Enumerator is # essentially Fiber. g.yield "Hello world" end puts e.next
g
はEnumerator::Yielder
が返却される。
そして検索してたら下記のようなページを発見し、g.yield
と書けそうなことがわかったのでそれを使いました。
Problem 2-3
$s = 0 def say(n = 0) $s = $s * 4 + n end i, j, k = 1, 2, 3 say i say j say k # Hint: Binary representation. $s != 35 or puts("Hello world")
My Answer(2文字)
$s = 0 def say(n = 0) $s = $s * 4 + n end i, j, k = 1, 2, 3 say i say j say k # Hint: Binary representation. $s+8 != 35 or puts("Hello world")
$s
が27を返すので、35となるように+8
しました。
Day 3
Problem 3-1
def say s="Hello", t:'world' "#{ s }#{ t } world" end # Hint: Arguments in Ruby are # difficult. puts say :p
My Answer(1文字)
def say s="Hello", t:'world' "#{ s }#{ t } world" end # Hint: Arguments in Ruby are # difficult. puts say t:p
p
の返り値はnil
なので、s="Hello", t:nil
となり、"Hello world"が出力されます。
Problem 3-2
def say s, t="Goodbye " # Hint: You can ignore a warning. s = "#{ s } #{ t }" t + "world" end puts say :Hello
My Answer(3文字)
def say s, t="Goodbye " # Hint: You can ignore a warning. st = "#{ s } "#{ t }" st + "world" end puts say :Hello
ここは最初say :Hello,p
のような形でいけるかと思ったのですが、
:Hello
はsymbolのため+
メソッドが使えないのです。。。
なので、st = "#{ s } "
とすることで、st
に"Hello"だけが入るようにして、
st + "world"
として"Hello world"となるようにしました。
Problem 3-3
def say "Hello world" if false && false # Hint: No hint! end puts say
My Answer(2文字)
def say "Hello world" if :false && :false # Hint: No hint! end puts say
これは単純で、false
がtrue
になるようにすればいいので、
!false
と思ったのですが、それだとあまりにもと思ったので:false
にしました。
Extra Stage
Ruby Kaigi後に出題されたExtra Stageについてもやってみたので、解答をメモしておきます✍
"Cookpad Daily Ruby Puzzles" in RubyKaigi 2019 - Extra Stage · GitHub
⚠️⚠️⚠️ここからは解答がまだ発表されていないので、ネタバレ注意です⚠️⚠️⚠️
Problem Extra-1
Hello = "Hello" # Hint: Stop the recursion. def Hello Hello() + " world" end puts Hello()
My Answer(2文字)
Hello = "Hello" # Hint: Stop the recursion. def Hello Hello+#() + " world" end puts Hello()
これはHintの通り、メソッド呼び出しを止めればいいので、Hello+#() +
として、変数側のHello
を参照するようにしました。
Problem Extra-2
s = "" # Hint: https://techlife.cookpad.com/entry/2018/12/25/110240 s == s.upcase or s == s.downcase or puts "Hello world"
My Answer(1文字)
s = "Dz" # Hint: https://techlife.cookpad.com/entry/2018/12/25/110240 s == s.upcase or s == s.downcase or puts "Hello world"
これはHintのURLを参考したら該当文字Dz
が載っていたので、それを使うようにしました。
Problem Extra-3
def say s = 'Small' t = 'world' puts "#{s} #{t}" end TracePoint.new(:line){|tp| tp.binding.local_variable_set(:s, 'Hello') tp.binding.local_variable_set(:t, 'Ruby') tp.disable }.enable(target: method(:say)) say
My Answer(2文字)
def say s = 'Small' t = 'world' puts "#{s} #{t}" end TracePoint.new(:line){|tp| tp.binding.local_variable_set(:s, 'Hello') #tp.binding.local_variable_set(:t, 'Ruby') #tp.disable }.enable(target: method(:say)) say
tp.disable
をコメントアウトしたところ"Hello Ruby"が返されるようになったので、
tp.binding.local_variable_set(:s, 'Hello')
だけが実行されるようにしました。
おわりに
Cookpadさんの問題が、面白すぎてセッションに集中出来なかった部分もありますが・・・笑
問題に取り組むなかで、マニュアルを読んだり、いろいろ調べたりするなかで、
rubyのイディオムやリテラル周りの知識が見について非常に勉強になりました🙌
来年のRuby Kaigiでは、もっといい感じの答えが出せるように頑張ろう💪