-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.rb
executable file
·73 lines (59 loc) · 1.42 KB
/
main.rb
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
#!/usr/bin/ruby
require 'set'
DATA = File
.read('data.txt')
HAVE_PLANT = DATA
.scan(/.{5} => #/)
.map{ |s| s[0...5] }
.to_set
BUF = '.' * 300
INPUT = DATA
.each_line
.first
.scan(/[\.#]/)
.join
.yield_self{ |s| "#{BUF}#{s}#{BUF}" }
.each_char
.to_a
.freeze
def do_round arr
arr.each_with_index.map do |c, i|
pattern = ((i-2)..(i+2))
.map{ |idx| idx >= 0 ? arr.fetch(idx, '.') : '.' }
.join
has = HAVE_PLANT.include? pattern
has ? '#' : '.'
end
end
def calc_score arr
arr.each_with_index
.select{ |c, i| c == '#' }
.map{ |c, i| i - BUF.size }
.sum
end
def part1 arr
20.times{ arr = do_round arr }
calc_score arr
end
def part2 arr
patterns = {}
BUF.size.times do |i|
arr = do_round arr
pattern = arr.join.gsub('.', ' ').strip
if patterns.include? pattern
if i - 1 != patterns[pattern]
puts "Unexpected cycle length! #{i - patterns[pattern]}"
end
cycles_left = 50000000000 - i - 1
score = calc_score arr
score_diff = calc_score(do_round arr) - score
return score + cycles_left * score_diff
end
patterns[pattern] = i
end
raise "Buffer to small! (#{BUF.size})"
end
PART1 = part1 INPUT
PART2 = part2 INPUT
puts 'Part 1: %s' % PART1
puts 'Part 2: %s' % PART2