AOJ(問題集)23

0220 Binary Digit A Doctor Loved

小数の2進表現かあ。勉強になるなあ。なお、10進表現で循環小数でなくとも、2進表現で循環小数になる場合がある。

def calc(r, str = "")
  return str if str.length > 4
  a = r * 2
  b = a.to_i
  str += b.to_s
  c = a - b
  if c.zero?
    return str
  else
    calc(c, str)
  end
end


until (n = gets.to_f.rationalize) < 0
  integer_part = n.to_i
  decimal_part = n - integer_part
  
  result = "NA"
  str = integer_part.to_s(2)
  if str.length <= 8
    str = str.rjust(8, "0")
    tmp = calc(decimal_part)
    if tmp.length <= 4
      result = str + "." + tmp.ljust(4, "0")
    end
  end
  
  puts result
end

 

0221 FizzBuzz

発言データを一気読みしていなくてハマった。0.24秒。

e = Enumerator.new do |y|
  i = 1
  loop do
    y << case
         when (i % 15).zero? then "FizzBuzz"
         when (i %  3).zero? then "Fizz"
         when (i %  5).zero? then "Buzz"
         else i.to_s
         end
    i += 1
  end
end

until (given = gets.chomp) == "0 0"
  m, n = given.split.map(&:to_i)
  data = n.times.map {gets.chomp}
  table = Array.new(m, true)
  pointer = 0
  count = m
  
  inc = ->{
    pointer += 1
    pointer = 0 if pointer >= m
  }
  
  data.each do |said|
    break if count == 1
    inc.() until table[pointer]
    if said != e.next
      table[pointer] = false
      count -= 1
    end
    inc.()
  end
  
  puts table.map.with_index {|a, i| a ? (i + 1).to_s : nil}.compact.join(" ")
  e.rewind
end

 
これで0.21秒。あまり変わらないな。

e = Enumerator.new do |y|
  i = 1
  loop do
    y << case
         when (i % 15).zero? then "FizzBuzz"
         when (i %  3).zero? then "Fizz"
         when (i %  5).zero? then "Buzz"
         else i.to_s
         end
    i += 1
  end
end

until (given = gets.chomp) == "0 0"
  m, n = given.split.map(&:to_i)
  data = n.times.map {gets.chomp}
  table = (1..m).map(&:itself)
  pointer = 0
  
  data.each do |said|
    if said != e.next
      table.delete_at(pointer)
      break if table.size == 1
    else
      pointer += 1
    end
    pointer = 0 if pointer >= table.size
  end
  
  puts table.join(" ")
  e.rewind
end

 

0225 Kobutanukitsuneko

時間切れ。素朴な DFS。

loop do
  n = io.gets.to_i
  break if n.zero?
  words = n.times.map { io.gets.chomp }
  
  goal = words[0][0]
  try = ->(num, word) {
    if num.zero?
      word[-1] == goal
    else
      words.delete(word)
      words.select { |w| word[-1] == w[0] }.each do |w|
        f = try.(num - 1, w)
        return f if f
      end
      false
    end
  }
  puts try.(n - 1, words[0]) ? "OK" : "NG"
end

 

0226 Hit and Blow

loop do
  r, a = gets.split.map(&:chars)
  break if r == ["0"] && a == ["0"]
  
  r1, a1 = [], []
  hit = 0
  r.size.times do |i|
    if r[i] == a[i]
      hit += 1
    else
      r1 << r[i]
      a1 << a[i]
    end
  end
  blow = (r1 & a1).size
  puts "#{hit} #{blow}"
end

 

0227 Thanksgiving

loop do
  n, m = gets.split.map(&:to_i)
  break if n.zero? && m.zero?
  ps = gets.split.map(&:to_i).sort.reverse
  
  price = 0
  ps.each_slice(m) do |ary|
    if ary.size == m
      price += ary[0, m - 1].sum
    else
      price += ary.sum
    end
  end
  puts price
end

 

0228 Seven Segments

Pats = %w(0111111 0000110 1011011 1001111 1100110) +
       %w(1101101 1111101 0100111 1111111 1101111)

loop do
  n = gets.to_i
  break if n < 0
  ds = n.times.map { gets.to_i }
  
  disp = 0
  ds.each do |d|
    pat = Pats[d].to_i(2)
    puts "%07b" % (pat ^ disp)
    disp = pat
  end
end

 

0229 Big Hit !

loop do
  b, r, g, c, s, t = gets.split.map(&:to_i)
  break if b + r + g + c + s + t == 0
  
  medals = 100
  bonus = ->{
    medals += 15 + 1
  }
  b.times do
    medals += 15
    5.times { bonus.() }
  end
  r.times do
    medals += 15
    3.times { bonus.() }
  end
  medals += 7 * g
  medals += 2 * c
  medals += 3 * s
  medals -= 3 * t
  
  puts medals
end