-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday5.rb
More file actions
executable file
·131 lines (101 loc) · 2.08 KB
/
day5.rb
File metadata and controls
executable file
·131 lines (101 loc) · 2.08 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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env ruby
require "debug"
def `(s)
puts s
end
module Hacks
refine Integer do
def |(other)
Rule.new(self, other)
end
end
refine String do
def -@
split("\n\n").map { _1.lines.map(&:strip) }
end
end
refine Array do
def %(other)
case other
when "middle"
self[length / 2]
else
filter! { other.call(_1) }
end
end
def **(other)
index other
end
def <(other)
delete(other)
end
def self.[](operator, array_method)
define_method(operator) do |other = nil, &block|
send(array_method) {
block ? block.call(_1) : other.call(_1)
}
end
end
self[:>=, :sum]
self[:>, :map]
self[:<=, :all?]
self[:=~, :partition]
self[:/, :select]
self[:!~, :find]
self[:>>, :none?]
end
end
using Hacks
class Rule
def initialize(first, last)
@first = first
@last = last
end
def +@
@first
end
def -@
@last
end
end
class Update
def self.[](...)
new(...)
end
def initialize(*pages)
@pages = pages
end
def <<(rules)
applicable_rules = rules / ->(rule) { (@pages**+rule) && (@pages**-rule) }
old_pages = @pages.dup
new_pages = []
until old_pages.empty?
next_page = old_pages !~ ->(page) {
applicable_rules >> ->(rule) { page == -rule }
}
applicable_rules % ->(rule) { next_page != +rule }
old_pages < next_page
new_pages << next_page
end
Update[*new_pages]
end
def ~
@pages % "middle"
end
def ===(rule)
!(@pages**+rule) || !(@pages**-rule) || @pages**+rule < @pages**-rule
end
end
input = File.read(File.basename(__FILE__, ".rb") + ".txt")
rule_data, update_data = *-input
rules = rule_data > ->(r) { eval r }
updates = update_data > ->(u) { eval "Update[#{u}]" }
valid_updates, invalid_updates = updates =~ ->(update) {
rules <= ->(rule) { update === rule }
}
part_one = valid_updates.>=(&:~@)
part_two = (invalid_updates > ->(update) {
update << rules
}).>=(&:~@)
`Part One: #{part_one}`
`Part Two: #{part_two}`