LoginSignup
0
0

More than 3 years have passed since last update.

ビンゴカード作成問題を解いてみた

Posted at

問題はこちら

最初に書いたコード

class Bingo
    SIZE = 5

    def generate_card
        format_a_row = Proc.new do |array|
            array.map {|f| f.to_s.rjust(3)}.join(' |')
        end

        header = format_a_row("BINGO".chars)
        rows = (1..SIZE).map do |i|
            (1..SIZE).map {rand((i-1)*15+1..i*15)}
        end.transpose

        rows[(SIZE-1)/2][(SIZE-1)/2] = ""       
        rows.map! {|r| format_a_row(r)}

        puts [header, *rows].join("\n")
    end
end

Bingo.new.generate_card

出力結果は以下。

  B |  I |  N |  G |  O
  9 | 21 | 40 | 46 | 74
  9 | 29 | 45 | 59 | 67
  6 | 22 |    | 56 | 61
 12 | 18 | 34 | 51 | 66
  7 | 28 | 36 | 47 | 62

transposeすぐ発想できたのはよかった。

ん…?数字重複してるじゃん!これじゃだめだ。

修正したコード

解答例もみる。

あと考えたらheaderとbodyの整形まとめた方がいいな。

class Bingo
    SIZE = 5
    FORMAT = Array.new(5, '%3s').join(' |')

    def generate_card
        rows = (1..SIZE)
        .map {|i| [*((i-1)*15-1..i*15)].sample(5)}
        .transpose.tap {|t| t[(SIZE-1)/2][(SIZE-1)/2] = ""}

        puts rows.unshift("BINGO".chars).map {|r| FORMAT % r}.join("\n")
    end
end

Bingo.new.generate_card

tapってこうやってつかうんやな…すっきりやな…。

学んだこと

String#%(args)

sprintf的なフォーマットができる。リファレンス

> "--%s--" % "hoge"  # => "--hoge--"

# 引数に配列もわたせる
> "--%s--%s--" % ["hoge", "fuga"]  # => "--hoge--fuga--"

# 幅も指定できる(右寄せになる)
> "--%10s--" % "hoge"  # => "--      hoge--"

ランダムな値

をとるときには、重複を許容する/しないを意識すべし。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0