Easy_6
def div_ceil(x, y)
(x+y-1)//y
end
h, w = read_line.split.map(&.to_i)
puts div_ceil(x*y, 2)
間違いが2つある。
間違い1つめはsampleで発覚する。sample_3でCEになる。
Unhandled exception: Arithmetic overflow (OverflowError)
オーバーフローを指摘してくれるのはありがたい。
64ビット整数
Crystalの整数型はデフォルトでは符号付き32ビット(Int32)。
今回の制約だと最大で$10^{18}$くらいになるのでオーバーフローした。
64ビット整数Int64を利用する必要がある。標準入力から受け取った文字列を数値に変換するのにto_iでなくto_i64を使用すればよい。
コーナーケース、3項演算子
間違い2つめはコーナーケース。
$H=1$または$W=1$のときの場合分けが必要。
if文で十分だが、3項演算子を使用してみる。
cond ? A : Bで、condを評価して真ならA、偽ならBが値となる。
真か偽かを示すのにはbool型である必要はない。
false、nil、ヌルポインタの時が偽で、それ以外が真。
AC例
def div_ceil(x, y)
(x+y-1)//y
end
h, w = read_line.split.map(&.to_i64)
puts h == 1 || w == 1 ? 1 : div_ceil(h*w, 2)
Easy_7
ビンゴカードと出た数が与えられるので、ビンゴかどうかを答える。
「やるだけ」ではあるが、ビンゴが8通りあるので面倒。冗長にコーディングすれば何にしても出来るが、ミスのもと。
配列の構成
ビンゴカードの数字が3x3で与えられているが、面倒なので長さ9の配列として読みこむ。
Array + Arrayで2つの配列を結合することが出来る。便利そうだが、$O(1)$ではないだろう。
なお、Array << elemで、配列の最後に1つ要素を追加できる。これは多分$O(1)$だが、非常に長い配列を構成するときはリアロケーションで時間をロスするので、capacityを指定してコンストラクトするのが良いだろう。
a = Array(Int32).new # 要素が全てInt32の新規行列を長さ0で作成
a = [] of Int32 # 上と同じ意味
a = Array(Int32).new(initial_capacity: 100000) # 今は長さ0だが100000までは対応できるようにメモリを確保
a = Array.new(size: 5, value: 10) # => [10, 10, 10, 10, 10]
b = [1, 2, 3]; c = [4, 5, 6]
puts b+c # => [1, 2, 3, 4, 5, 6]
ビンゴカードに書かれている数字を長さ9の配列に格納したあと、ビンゴとなる数字の組み合わせを1つ1つ試す。必要な3つの数が全部あらわれている組み合わせが1つでもあればビンゴ、そうでなければビンゴでない。
タプル{a, b, c}をブロックで受け取るときは、|x, y, z|の形で受け取れる。
A && B && CはABC全て真の時に真、そうでなければ偽だが、Aが偽ならBCは評価しない。Aが真でもBが偽ならCは評価しない。論理式の評価法としては100%正しいが、副作用を伴う式を置く時は留意が必要。
x ||= yはxが偽(false, nil, ヌルポインタ)の時にはyを評価して返す。そうでなければxは真なのでxを返し、yは評価しない。
a = [] of Int32
3.times {a += read_line.split.map(&.to_i)}
n = read_line.to_i
b = Array.new(101, false)
n.times {b[read_line.to_i] = true}
bingo = [{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
{0, 3, 6}, {1, 4, 7}, {2, 5, 8},
{0, 4, 8}, {2, 4, 6}]
flag = false
bingo.each do |x, y, z|
flag ||= b[a[x]] && b[a[y]] && b[a[z]]
end
puts flag ? "Yes" : "No"