You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
input = ARGF.read.split("\n")
|
|
|
|
|
|
|
|
class IllegalCharacter < StandardError
|
|
|
|
attr_reader :char
|
|
|
|
def initialize(char)
|
|
|
|
@char = char
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
COMPLEMENTS = %w[ () [] {} <> ].map(&:chars).to_h
|
|
|
|
OPENING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.keys.join)}]")
|
|
|
|
CLOSING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.values.join)}]")
|
|
|
|
def parse(line)
|
|
|
|
stack = []
|
|
|
|
|
|
|
|
s = line.chars
|
|
|
|
until s.empty?
|
|
|
|
case char = s.shift
|
|
|
|
when OPENING_REGEXP
|
|
|
|
stack << char
|
|
|
|
when CLOSING_REGEXP
|
|
|
|
raise IllegalCharacter.new(char) unless stack.pop == COMPLEMENTS.invert.fetch(char)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
stack
|
|
|
|
end
|
|
|
|
|
|
|
|
# points = {
|
|
|
|
# ?) => 3,
|
|
|
|
# ?] => 57,
|
|
|
|
# ?} => 1197,
|
|
|
|
# ?> => 25137,
|
|
|
|
# }
|
|
|
|
|
|
|
|
# p input.sum {|line|
|
|
|
|
# begin
|
|
|
|
# parse(line)
|
|
|
|
# 0
|
|
|
|
# rescue IllegalCharacter => e
|
|
|
|
# points.fetch(e.char)
|
|
|
|
# end
|
|
|
|
# }
|
|
|
|
|
|
|
|
def score(closing) = closing
|
|
|
|
.map { COMPLEMENTS.values.index(_1) + 1 }
|
|
|
|
.inject(0) {|n,i| n*5 + i }
|
|
|
|
|
|
|
|
scores = input
|
|
|
|
.filter_map { parse(_1) rescue nil }
|
|
|
|
.map {|remaining| remaining.reverse.map { COMPLEMENTS.fetch(_1) }}
|
|
|
|
.map { score(_1) }
|
|
|
|
p scores.sort.fetch(scores.length / 2)
|