AOJ(問題集)4
AIZU ONLINE JUDGE: Programming Challenge
0031 Weight
def measure(object, weight, result = []) return result.join(" ") if weight.zero? result.unshift(weight) if (object / weight).nonzero? measure(object % weight, weight / 2, result) end $<.readlines.map(&:to_i).each {|ob| puts measure(ob, 512)}
0032 Plastic Board
rectangle = lozenge = 0 $<.readlines.map {|l| l.split(",").map(&:to_i)}.each do |a, b, c| rectangle += 1 if a * a + b * b == c * c lozenge += 1 if a == b end puts rectangle, lozenge
0033 Ball
def try(balls, b ,c) return 1 if balls.empty? nxt = balls.first bl = balls.drop(1) if nxt > b and nxt > c try(bl, nxt, c) + try(bl, b, nxt) elsif nxt > b try(bl, nxt, c) elsif nxt > c try(bl, b, nxt) else 0 end end $<.gets.to_i.times do balls = $<.gets.split.map(&:to_i) puts try(balls.drop(1), balls.first, 0).nonzero? ? "YES" : "NO" end
読み込みに readlines
を使ったらエラーが出る。gets
を使ったコードに替えたら正解になった。非本質的なところで延々と悩まされた。
0034 Railway Lines
$<.readlines.map {|l| l.split(",").map(&:to_i)}.each do |given| ls = given.first(10) v1, v2 = given.last(2) s = Rational(v1 * ls.sum, v1 + v2) l = 0 ls.each_with_index do |ln, i| next if s > (l += ln) puts i + 1 break end end
0035 Is it Convex?
$<.readlines.map {|l| l.split(",").map(&:to_r)}.each do |given| f = (given + given.first(4)).each_slice(2).each_cons(3).map do |a, b, c| (c[0] - a[0]) * (b[1] - a[1]) - (c[1] - a[1]) * (b[0] - a[0]) > 0 end puts((f.all? or f.none?) ? "YES" : "NO") end
0036 A Figure on Surface
L = 8 table = [["11", "11"], ["1", "1", "1", "1"], ["1111"], ["01", "11", "10"], ["110", "011"], ["10", "11", "01"], ["011", "110"]] table.map! {|pt| [pt.size, l = pt.first.length, pt.join("0" * (L - l))]} $<.readlines.chunk {|l| !!l.match(/^\d/) || nil} .map {|a| a.last.map(&:chomp).join}.each do |field| table.each_with_index do |ary, k| y, n, pt = ary (L + 1 - y).times do |i| (L + 1 - n).times do |j| puts "ABCDEFG"[k] if field[i * L + j, pt.length] == pt end end end end
0037 Path on a Grid
given = $<.readlines.map {|l| l.chomp.chars.map(&:to_i)} yoko = 0.step(8, 2).map {|i| given[i]} tate = 1.step(8, 2).map {|i| given[i]}.transpose dirs = "LRUD" go = nil route = "" f = false get_yoko = ->(x, y, dir) { if dir == 0 if tate[x][y] == 1 go.(x, y, 3) elsif x > 0 and yoko[y][x - 1] == 1 go.(x, y, 0) elsif y > 0 and tate[x][y - 1] == 1 go.(x, y, 2) else go.(x, y, 1) end else if y > 0 and tate[x][y - 1] == 1 go.(x, y, 2) elsif x <= 3 and yoko[y][x] == 1 go.(x, y, 1) elsif tate[x][y] == 1 go.(x, y, 3) else go.(x, y, 0) end end } get_tate = ->(x, y, dir) { if dir == 2 if x > 0 and yoko[y][x - 1] == 1 go.(x, y, 0) elsif y > 0 and tate[x][y - 1] == 1 go.(x, y, 2) elsif yoko[y][x] == 1 go.(x, y, 1) else go.(x, y, 3) end else if x <= 3 and yoko[y][x] == 1 go.(x, y, 1) elsif y <= 3 and tate[x][y] == 1 go.(x, y, 3) elsif x > 0 and yoko[y][x - 1] == 1 go.(x, y, 0) else go.(x, y, 2) end end } go = ->(x, y, dir) { return if x.zero? and y.zero? and f f = true route += dirs[dir] if dir <= 1 get_yoko.(x + dir * 2 - 1, y, dir) else get_tate.(x, y + dir * 2 - 5, dir) end } go.(0, 0, 1) puts route
何だか全然よくないコード。もっと考えたい。
0038 Poker Hand
def same_numbers(ary, result = []) return result.sort if ary.empty? a = ary.first co = ary.count(a) result << co if co > 1 same_numbers(ary - [a], result) end $<.readlines.map {|l| l.split(",").map(&:to_i)}.each do |hand| puts case same_numbers(hand) when [4] then "four card" when [2, 3] then "full house" when [3] then "three card" when [2, 2] then "two pair" when [2] then "one pair" else hand.sort! if hand.sum == (hand.first + 2) * 5 or hand == [1, 10, 11, 12, 13] "straight" else "null" end end end
0039 Roman Figure
table = {I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000, nil => 0} count = ->(roman, number = 0) { return number if roman.empty? a, b = table[roman.first], table[roman[1]] number += if a >= b r = roman.drop(1) a else r = roman.drop(2) b - a end count.(r, number) } $<.readlines.map(&:chomp).each {|roman| puts count.(roman.chars.map(&:to_sym))}
0040 Affine Cipher
def decode(word, a, b) g = (0..25).map {|i| [[*"a".."z"][(a * i + b) % 26], i]}.to_h word.chars.map {|st| (g[st] + 97).chr}.join end e = Enumerator.new do |y| generate = ->(n) { a, b = n, 0 n.times do y << [a, b] a -= 1 b += 1 end generate.(n + 1) } generate.(1) end $<.readlines.drop(1).map {|a| a.split}.each do |sentence| loop do a, b = e.next dsr = (1..a).select {|i| (a % i).zero?} next if dsr.include?(2) or dsr.include?(13) or dsr.include?(26) f = sentence.select {|w| w.length == 4}.map do |word| st = decode(word, a, b) st == "that" or st == "this" end.any? next unless f puts sentence.map {|word| decode(word, a, b)}.join(" ") break end end
アフィン暗号の解読にはここを参考にした。
うーん、あんまりひどいタイムなので、他の人のコードを参考にした。すごい。
cl = [*"a".."z"] table_a = (1..26).select {|i| 26.gcd(i) == 1} b = nil $<.readlines.drop(1).each do |str| a = table_a.find do |i| b = (0..26).find do |j| nominees = str.split.select {|w| w.length == 4} ["that", "this"].map do |x| nominees.include?(x.chars.map {|c| cl[(i * cl.index(c) + j) % 26]}.join) end.any? end end table = (0..25).map {|i| (a * i + b) % 26} puts str.chomp.chars.map {|c| (c == " ") ? c : cl[table.index(cl.index(c))]}.join end