Inverse FizzBuzzを解いた。
私の回りではイマイチ盛り上がってないInverse FizzBuzzですが、とりあえず解いてみたので公開しておきます。
逆FizzBuzz問題 (Inverse FizzBuzz)
@list = [] (1..15).each do |v| out = "" out += "fizz" if v % 3 == 0 out += "buzz" if v % 5 == 0 @list << {idx: v, value: out} if out != "" end def inverse(list) out = nil saved_diff = 999 @list.each_cons(list.size).each do |v| if list == v.map{|x| x[:value]} diff = v.last[:idx] - v.first[:idx] if saved_diff > diff out = v saved_diff = diff end end end unless out.nil? puts "#{list} => #{(out.first[:idx]..out.last[:idx]).to_a}" end end inverse(["fizz"]) inverse(["buzz"]) inverse(["fizz","buzz"]) inverse(["buzz","fizz"]) inverse(["fizz","buzz","fizz"]) inverse(["fizz","fizz"]) inverse(["fizz","fizz","buzz"])
ポイント
- FizzBuzzは15個しか作らない
15以降は繰り返しなので、15まででパターンマッチしなければ答えは存在しないということになる。
- 空白は気にしない
必要なのは条件にマッチする先頭とお尻の位置。答えを見ればわかるが先頭とお尻がわかれば後はそのrangeで表現できる。
- each_consは便利だね
まさしくこの問題のためにあるようなメソッドだ。これに出会わなければ解けなかったと思う。
間違い等ありましたらご指摘下さい。