はじめに
Paizaの「もし次の常駐先が女子エンジニアばかりだったら」(もし女)を解いた時に
「同じ内容でもソースコードってこんなに変わるのか……」っていうのを実体験したので、その時の事をメモ代わりにおいて置きます。
問題文
緑川つばめを窮地から救え (Bランク問題)
https://paiza.jp/moshijo/challenge/moshijo_character_9
最初に書いた時のソースコード
n = gets.to_i
l = n.to_s.length
def ary(a)
a = []
end
ans = []
(l - 1).times do |h|
ans << ary(h)
end
ansl = ans.length
if l == 1
if n < 5
ans << n
else
ans << n.round(-1)
end
elsif l == 2
ans << n.round(-0)
ans << n.round(-1)
else
ansl.times do |m|
break if m + 1 == ansl
l.times do |i|
ans[m] << n #これを入れておかないと、100みたいな値を入れたときに表示が出ない
ans[m] << n.round(-i) if n.round(-i) > n# ifで改行するとendの数がずれて動かなくなる
ans[m].each do |j|
if j.round(-i) > n.round(-i) && j.round(-i) != n.round(-i)
ans[m + 1] << j.round(-i)
ans[m + 1].uniq!
end
end
end
end
end
m = ans.flatten.max
#以下のif文は、445を入れた時に500で止めずに1000まで行かせるため,何も考えずにroundさせると123とかが0になるのでifで場合分け
if m > m.round(-l)
puts m
else
puts m.round(-l)
end
もはや自分でも何がしたかったか良く分からないコードに(むしろこれでよくテストケース通ったな・・・・・・)
配列の中に配列を作って、その中に四捨五入した値を入れて、最終的にその中の最大値を取り出す的な事をしたかったらしい。
このソースコードを提出した次の日
ある配列操作のメソッドを知り、それを利用することで大幅に改善する事ができた。
改善後のソースコード
n =gets.to_i
l = n.to_s.length
ans = []
ans << n
(0..l).each do |i|
if ans[0] < ans[0].round(-i)
ans << ans[0].round(-i)
ans.shift
else
#何もしない
end
end
puts ans[0]
一体何があったのか分からないぐらいシンプルになる。
重要なメソッドは.shift
配列の最初の要素を消してくれるメソッドである。
これにより、配列の中身が常に最大の数になったため、場合分けが1回で済むようになった
動きも単純になり、
値を比較して、もし大きければ配列に格納、その後に先端の値を削除する。違ったら何もしない
という誰が見ても分かるようになった。
で、何が言いたいか
プログラミングってたのしー!
オマケ
他の問題のソースコードも置いておきます
御影百合絵からのお願い (Dランク問題)
a = gets.to_i
b = gets.to_i
c = gets.to_i
sum = a + b + c
puts sum
春日みちるからのSOS (Dランク問題)
a = gets.to_s
re =Regexp.new("help")
if re =~ a
puts "SOS"
else
puts a
end
園田冴絵からの応援要請 (Dランク問題)
a,b,c= gets.split
d = a.to_i+b.to_i
e = a.to_i-b.to_i
if c == '+' then
puts d
elsif
puts e
end
芦屋川雛乃からのヘルプ依頼 (Cランク問題)
a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 = gets.split.map(&:to_i)
s = gets.chop.to_s #chopで改行コードを消さないとifの時にマッチしないので注意
t = gets.chop.split('').map(&:to_i) # chopは改行コードを落すため、この状態で配列を作成すると最後に\nが入って、to_iで数値化した時に最終的に0になる
ary = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
# encode時の処理
if s == "encode"
x = []
t.each do |i|
x << ary[i]
end
puts x.join
else
# decode時の処理
y = []
t.each do |i|
y << ary.index(i)
end
puts y.join
end
桂乃梨子とピンチを乗り越えろ (Cランク問題)
n = gets.to_i
ary1 = gets.split.map(&:to_i)
ary2 = gets.split.map(&:to_i)
aryc = ary1.slice(0,n)
aryr = ary2.slice(0,n)
aryf = []
aryr.product(aryc) do |i,j|
aryf << i + j
end
arys = aryf.each_slice(n).to_a
arys.each do |n|
puts n.join(" ")
end
水無瀬朋の一大事 (Cランク問題)
n = gets.to_i
h = {}
n.times do |i|
h[i+1] = gets.split.map(&:to_i)
end
m = gets.to_i
ary = []
m.times do |j|
ary[j] = gets.split.map(&:to_i)
end
m.times do |k|
item = h[ary[k][0]]
op= item[0] * ary[k][1] #opはoriginal_priceから
dc = (ary[k][1] / item[1]) * item[2] #dcはdiscountから
price = op - dc
puts price
end
六村リオの緊急事態 (Bランク問題)
まだ解けてないです
(絶対パスは分かるけど、相対パスの位置関係が・・・・・・)
参考にしていただければ幸いです。