はじめに
AtCoder さん、ありがとうございます。
結論
clone | |
---|---|
Ruby | 浅い (shallow) コピー |
crystal | 深い (deep) コピー |
E - SNS のログ
Ruby clone(WA)
n, m = gets.split.map(&:to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
s = gets.split.map(&:to_i)
case s[0]
when 1
a[s[1]][s[2]] = "Y"
when 2
(1..n).each do |i|
a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
end
when 3
b = a.clone
(1..n).each do |i|
if b[s[1]][i] == "Y"
(1..n).each do |j|
a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
end
end
end
end
end
(1..n).each do |i|
puts a[i][1..].join("")
end
WA
NYYYYY # NYYNYY
NNYNNN
NNNYNN
NNNNNN
NNNNNY
YNNNYN
下記のリファレンスマニュアルにある通り、cloneは浅い(shallow)コピー
であるため、配列の変更結果が反映されてしまします。
Ruby Marshal(AC)
n, m = gets.split.map(&:to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
s = gets.split.map(&:to_i)
case s[0]
when 1
a[s[1]][s[2]] = "Y"
when 2
(1..n).each do |i|
a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
end
when 3
- b = a.clone
+ b = Marshal.load(Marshal.dump(a))
(1..n).each do |i|
if b[s[1]][i] == "Y"
(1..n).each do |j|
a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
end
end
end
end
end
(1..n).each do |i|
puts a[i][1..].join("")
end
Rubyで深い (deep) コピー
といえばMarshal、頻繁に使用されます。
b = Marshal.load(Marshal.dump(a))
crystal clone (AC)
n, m = read_line.split.map(&.to_i)
a = Array.new(n + 1){ Array.new(n + 1, "N") }
m.times do
s = read_line.split.map(&.to_i)
case s[0]
when 1
a[s[1]][s[2]] = "Y"
when 2
(1..n).each do |i|
a[s[1]][i] = "Y" if a[i][s[1]] == "Y"
end
when 3
b = a.clone
(1..n).each do |i|
if b[s[1]][i] == "Y"
(1..n).each do |j|
a[s[1]][j] = "Y" if b[i][j] == "Y" && j != s[1]
end
end
end
end
end
(1..n).each do |i|
puts a[i][1..].join("")
end
crystalではcloneが深い (deep) コピー
なんですね。
まとめ
- crystalに詳しくなった
- 久々に更新しました