-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday10.rb
More file actions
82 lines (71 loc) · 2.56 KB
/
day10.rb
File metadata and controls
82 lines (71 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# frozen_string_literal: true
# https://adventofcode.com/2021/day/10
class Checker
attr_accessor :loc, :illegal_char_scores, :autocomplete_char_scores, :opening_brackets, :opening_to_closing,
:closing_brackets, :closing_to_opening
def initialize(input_data_filename)
@loc = File.readlines(input_data_filename).map(&:chomp)
@illegal_char_scores = { ')' => 3, ']' => 57, '}' => 1_197, '>' => 25_137, false => 0 }
@autocomplete_char_scores = { ')' => 1, ']' => 2, '}' => 3, '>' => 4}
@opening_brackets = ['('../inputs/2021/, '[', '{', '<']
@opening_to_closing = { '('../inputs/2021/ => ')', '[' => ']', '{' => '}', '<' => '>' }
@closing_brackets = [')', ']', '}', '>']
@closing_to_opening = { ')' => '('../inputs/2021/, ']' => '[', '}' => '{', '>' => '<' }
end
# Return the first illegal closing braket, if there is one
def illegal(line)
unclosed_brackets = []
line.chars.each do |c|
if opening_brackets.include? c
unclosed_brackets << c
else
return c unless unclosed_brackets[-1] == closing_to_opening[c]
unclosed_brackets.pop
end
end
false
end
# Part 1
def total_syntax_error_score
loc.reduce(0) { |score, line| score + illegal_char_scores[illegal(line)] }
end
def autocomplete(line)
unclosed_brackets = []
line.chars.each do |c|
if opening_brackets.include? c
unclosed_brackets << c
else
return [] unless unclosed_brackets[-1] == closing_to_opening[c]
unclosed_brackets.pop
end
end
unclosed_brackets.map { |c| opening_to_closing[c] }.reverse
end
def autocomplete_score(line)
score = 0
autocomplete(line).each do |c|
score *= 5
score += autocomplete_char_scores[c]
end
score
end
# Part 2
def middle_autocomplete_score
scores = loc.map { |line| autocomplete_score(line) }.select(&:positive?).sort
scores[scores.length / 2]
end
end
puts "\nPART ONE"
puts "\nTest dataset:"
data = Checker.new('../inputs/2021/day10-input-test.txt')
puts "The total syntax error score is #{data.total_syntax_error_score}"
puts "\nFull dataset:"
data = Checker.new('../inputs/2021/day10-input-01.txt')
puts "The total syntax error score is #{data.total_syntax_error_score}"
puts "\nPART TWO"
puts "\nTest dataset:"
data = Checker.new('../inputs/2021/day10-input-test.txt')
puts "The middle autocomplete score is #{data.middle_autocomplete_score}"
puts "\nFull dataset:"
data = Checker.new('../inputs/2021/day10-input-01.txt')
puts "The middle autocomplete score is #{data.middle_autocomplete_score}"