Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Advent18
- def perform
- ARGF.map { |line| eat_expr(line.delete!(" \t\n"), false) }.reduce(&:+)
- end
- def eat_expr(line, eagier)
- op1 = looking_at(line, '(') ? eat_expr(eat_till_closing_paren(line), false) : eat_digit(line)
- continuation(line, op1, eagier)
- end
- def continuation(line, op1, eagier)
- (line.empty? || eagier) ? op1 : eat_operation(line, op1, eagier)
- end
- def eat_operation(line, op1, eagier)
- raise "Unknown operation: #{line[0]}" unless %w[+ *].include? line[0]
- op = eat_char(line).to_sym
- partial = op1.send(op, eat_expr(line, op == :+))
- continuation(line, partial, eagier)
- end
- def looking_at(line, ch)
- eat_char(line) if result = (line[0] == ch)
- result
- end
- def eat_char(line)
- ch = line[0]
- line[0] = ''
- ch
- end
- def eat_digit(line)
- raise "Digit expected" unless line[0] =~ /\d/
- eat_char(line).to_i
- end
- def eat_till_closing_paren(line)
- expr = ''
- level = 0
- while !line.empty?
- if line[0] == ')'
- if level == 0
- eat_char(line)
- return expr
- end
- expr << eat_char(line)
- next level-= 1
- end
- level += 1 if line[0] == '('
- expr << eat_char(line)
- end
- raise "Unbalanced parens"
- end
- end
- puts "Total sum is #{Advent18.new.perform}"
Add Comment
Please, Sign In to add comment