cem 0.1.3 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/cem.gemspec +5 -3
- data/examples/aoc2018/.gitignore +2 -0
- data/examples/aoc2018/day1.rb +13 -0
- data/examples/aoc2018/day10.rb +61 -0
- data/examples/aoc2018/day11.rb +66 -0
- data/examples/aoc2018/day12.rb +61 -0
- data/examples/aoc2018/day13.rb +167 -0
- data/examples/aoc2018/day14.rb +31 -0
- data/examples/aoc2018/day14_2.rb +71 -0
- data/examples/aoc2018/day15.rb +271 -0
- data/examples/aoc2018/day16.rb +158 -0
- data/examples/aoc2018/day17.rb +203 -0
- data/examples/aoc2018/day18.rb +113 -0
- data/examples/aoc2018/day18_rspec.rb +131 -0
- data/examples/aoc2018/day19.rb +145 -0
- data/examples/aoc2018/day1_part2.rb +30 -0
- data/examples/aoc2018/day2.rb +20 -0
- data/examples/aoc2018/day20.rb +103 -0
- data/examples/aoc2018/day21.rb +158 -0
- data/examples/aoc2018/day21_v2.rb +137 -0
- data/examples/aoc2018/day21_v3.rb +157 -0
- data/examples/aoc2018/day21_v4.rb +141 -0
- data/examples/aoc2018/day22.rb +212 -0
- data/examples/aoc2018/day23.rb +148 -0
- data/examples/aoc2018/day24.rb +156 -0
- data/examples/aoc2018/day25.rb +52 -0
- data/examples/aoc2018/day2_2.rb +27 -0
- data/examples/aoc2018/day3.rb +71 -0
- data/examples/aoc2018/day4.rb +46 -0
- data/examples/aoc2018/day5.rb +23 -0
- data/examples/aoc2018/day5_part2.rb +29 -0
- data/examples/aoc2018/day6.rb +53 -0
- data/examples/aoc2018/day7.rb +110 -0
- data/examples/aoc2018/day8.rb +39 -0
- data/examples/aoc2018/day8_part2.rb +65 -0
- data/examples/aoc2018/day9.rb +51 -0
- data/examples/aoc2018/day9_circular.rb +125 -0
- data/examples/aoc2018/inputs/day10_input.txt +395 -0
- data/examples/aoc2018/inputs/day11_input.txt +1 -0
- data/examples/aoc2018/inputs/day12_input.txt +34 -0
- data/examples/aoc2018/inputs/day12_input2.txt +16 -0
- data/examples/aoc2018/inputs/day13_input.txt +150 -0
- data/examples/aoc2018/inputs/day13_test.txt +6 -0
- data/examples/aoc2018/inputs/day14_input.txt +1 -0
- data/examples/aoc2018/inputs/day15_input.txt +32 -0
- data/examples/aoc2018/inputs/day15_input10.txt +32 -0
- data/examples/aoc2018/inputs/day15_input11.txt +32 -0
- data/examples/aoc2018/inputs/day15_input12.txt +32 -0
- data/examples/aoc2018/inputs/day15_input13.txt +32 -0
- data/examples/aoc2018/inputs/day15_input14.txt +32 -0
- data/examples/aoc2018/inputs/day15_input2.txt +7 -0
- data/examples/aoc2018/inputs/day15_input3.txt +9 -0
- data/examples/aoc2018/inputs/day15_input4.txt +7 -0
- data/examples/aoc2018/inputs/day15_input5.txt +7 -0
- data/examples/aoc2018/inputs/day15_input6.txt +7 -0
- data/examples/aoc2018/inputs/day15_input7.txt +7 -0
- data/examples/aoc2018/inputs/day15_input8.txt +5 -0
- data/examples/aoc2018/inputs/day15_input9.txt +7 -0
- data/examples/aoc2018/inputs/day15_test.txt +9 -0
- data/examples/aoc2018/inputs/day16_input.txt +3865 -0
- data/examples/aoc2018/inputs/day17_input.txt +2229 -0
- data/examples/aoc2018/inputs/day17_input_test.txt +8 -0
- data/examples/aoc2018/inputs/day18_input.txt +50 -0
- data/examples/aoc2018/inputs/day18_test.txt +10 -0
- data/examples/aoc2018/inputs/day19_input.txt +48 -0
- data/examples/aoc2018/inputs/day1_input.txt +955 -0
- data/examples/aoc2018/inputs/day20_input.txt +1 -0
- data/examples/aoc2018/inputs/day21_input.txt +32 -0
- data/examples/aoc2018/inputs/day22_input.txt +2 -0
- data/examples/aoc2018/inputs/day23_input.txt +1000 -0
- data/examples/aoc2018/inputs/day23_input2.txt +9 -0
- data/examples/aoc2018/inputs/day24_input.txt +24 -0
- data/examples/aoc2018/inputs/day25_input.txt +1483 -0
- data/examples/aoc2018/inputs/day2_input.txt +250 -0
- data/examples/aoc2018/inputs/day3_input.txt +1233 -0
- data/examples/aoc2018/inputs/day4_input.txt +1140 -0
- data/examples/aoc2018/inputs/day5_input.txt +1 -0
- data/examples/aoc2018/inputs/day6_input.txt +50 -0
- data/examples/aoc2018/inputs/day7_input.txt +101 -0
- data/examples/aoc2018/inputs/day8_input.txt +1 -0
- data/examples/aoc2018/inputs/day9_input.txt +1 -0
- data/lib/cem/ccommon.rb +67 -12
- data/lib/cem/cflame/popen.rb +89 -0
- data/lib/cem/cflame.rb +2 -0
- data/lib/cem/cruzzles.rb +198 -50
- data/lib/cem/version.rb +1 -1
- data/lib/cem.rb +0 -6
- metadata +91 -11
@@ -0,0 +1,137 @@
|
|
1
|
+
#
|
2
|
+
# https://adventofcode.com/2018/day/21 part 1 and part 2
|
3
|
+
#
|
4
|
+
# Does not use any 'cem' functions
|
5
|
+
#
|
6
|
+
# Using Lambdas instead of interpreting each command.
|
7
|
+
#
|
8
|
+
require 'set'
|
9
|
+
|
10
|
+
lines = File.readlines("inputs/day21_input.txt", chomp: true)
|
11
|
+
|
12
|
+
commandQueue = []
|
13
|
+
|
14
|
+
@reg = [0,0,0,0,0,0]
|
15
|
+
@s = Set.new
|
16
|
+
@last = nil
|
17
|
+
|
18
|
+
ip = nil
|
19
|
+
lines.each { |line|
|
20
|
+
|
21
|
+
if line =~ /^#ip ([+-]?\d+)$/
|
22
|
+
ip = $1.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
if line =~ /^(\w+) ([+-]?\d+) ([+-]?\d+) ([+-]?\d+)$/
|
26
|
+
verb = $1
|
27
|
+
v1 = $2.to_i
|
28
|
+
v2 = $3.to_i
|
29
|
+
v3 = $4.to_i
|
30
|
+
|
31
|
+
commandQueue << case verb
|
32
|
+
|
33
|
+
when "addr"
|
34
|
+
# addr (add @register) stores into @register C the result of adding @register A and @register B.
|
35
|
+
Proc.new { @reg[v3] = @reg[v1] + @reg[v2] }
|
36
|
+
|
37
|
+
when "addi"
|
38
|
+
# addi (add immediate) stores into @register C the result of adding @register A and value B.
|
39
|
+
Proc.new { @reg[v3] = @reg[v1] + v2 }
|
40
|
+
|
41
|
+
when "mulr"
|
42
|
+
# mulr (multiply @register) stores into @register C the result of multiplying @register A and @register B.
|
43
|
+
Proc.new { @reg[v3] = @reg[v1] * @reg[v2] }
|
44
|
+
|
45
|
+
when "muli"
|
46
|
+
# muli (multiply immediate) stores into @register C the result of multiplying @register A and value B.
|
47
|
+
Proc.new { @reg[v3] = @reg[v1] * v2 }
|
48
|
+
|
49
|
+
when "banr"
|
50
|
+
# banr (bitwise AND @register) stores into @register C the result of the bitwise AND of @register A and @register B.
|
51
|
+
Proc.new { @reg[v3] = @reg[v1] & @reg[v2] }
|
52
|
+
|
53
|
+
when "bani"
|
54
|
+
# bani (bitwise AND immediate) stores into @register C the result of the bitwise AND of @register A and value B.
|
55
|
+
Proc.new { @reg[v3] = @reg[v1] & v2 }
|
56
|
+
|
57
|
+
when "borr"
|
58
|
+
# borr (bitwise OR @register) stores into @register C the result of the bitwise OR of @register A and @register B.
|
59
|
+
Proc.new { @reg[v3] = @reg[v1] | @reg[v2] }
|
60
|
+
|
61
|
+
when "bori"
|
62
|
+
# bori (bitwise OR immediate) stores into @register C the result of the bitwise OR of @register A and value B.
|
63
|
+
Proc.new { @reg[v3] = @reg[v1] | v2 }
|
64
|
+
|
65
|
+
when "setr"
|
66
|
+
# setr (set @register) copies the contents of @register A into @register C. (Input B is ignored.)
|
67
|
+
Proc.new { @reg[v3] = @reg[v1] }
|
68
|
+
|
69
|
+
when "seti"
|
70
|
+
# seti (set immediate) stores value A into @register C. (Input B is ignored.)
|
71
|
+
Proc.new { @reg[v3] = v1 }
|
72
|
+
|
73
|
+
when "gtir"
|
74
|
+
# gtir (greater-than immediate/@register) sets @register C to 1 if value A is greater than @register B. Otherwise, @register C is set to 0.
|
75
|
+
Proc.new { @reg[v3] = v1 > @reg[v2] ? 1 : 0 }
|
76
|
+
|
77
|
+
when "gtri"
|
78
|
+
# gtri (greater-than @register/immediate) sets @register C to 1 if @register A is greater than value B. Otherwise, @register C is set to 0.
|
79
|
+
Proc.new { @reg[v3] = @reg[v1] > v2 ? 1 : 0 }
|
80
|
+
|
81
|
+
when "gtrr"
|
82
|
+
# gtrr (greater-than @register/@register) sets @register C to 1 if @register A is greater than @register B. Otherwise, @register C is set to 0.
|
83
|
+
Proc.new { @reg[v3] = @reg[v1] > @reg[v2] ? 1 : 0 }
|
84
|
+
|
85
|
+
when "eqir"
|
86
|
+
# eqir (equal immediate/register) sets register C to 1 if value A is equal to register B. Otherwise, register C is set to 0.
|
87
|
+
Proc.new { @reg[v3] = v1 == @reg[v2] ? 1 : 0 }
|
88
|
+
|
89
|
+
when "eqri"
|
90
|
+
# eqri (equal register/immediate) sets register C to 1 if register A is equal to value B. Otherwise, register C is set to 0.
|
91
|
+
Proc.new { @reg[v3] = @reg[v1] == v2 ? 1 : 0 }
|
92
|
+
|
93
|
+
|
94
|
+
when "eqrr"
|
95
|
+
# eqrr (equal register/register) sets register C to 1 if register A is equal to register B. Otherwise, register C is set to 0.
|
96
|
+
Proc.new { @reg[v3] = @reg[v1] == @reg[v2] ? 1 : 0
|
97
|
+
|
98
|
+
if v2 == 0
|
99
|
+
if @s.size == 0
|
100
|
+
puts "Part 1: #{@reg[v1]}"
|
101
|
+
end
|
102
|
+
|
103
|
+
puts "#{@s.size.to_s.rjust(10)} - #{@reg[v1]}" if @s.size % 64 == 0
|
104
|
+
|
105
|
+
if @s.include?(@reg[v1])
|
106
|
+
puts "Part 2: #{@last}"
|
107
|
+
exit
|
108
|
+
end
|
109
|
+
@s.add @reg[v1]
|
110
|
+
@last = @reg[v1]
|
111
|
+
end
|
112
|
+
}
|
113
|
+
|
114
|
+
else
|
115
|
+
puts "error" # raise "Error"
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
}
|
120
|
+
|
121
|
+
ipp = 0
|
122
|
+
iteration = 0
|
123
|
+
|
124
|
+
while ipp >= 0 && ipp < commandQueue.size
|
125
|
+
|
126
|
+
@reg[ip] = ipp
|
127
|
+
commandQueue[ipp].call()
|
128
|
+
ipp = @reg[ip]
|
129
|
+
ipp += 1
|
130
|
+
|
131
|
+
#puts iteration.to_s.rjust(13) + " " + command.inspect.ljust(40) + " " + reg.inspect if iteration % (1024*1024) == 0
|
132
|
+
#iteration += 1
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
puts @reg.inspect
|
137
|
+
puts @reg[0]
|
@@ -0,0 +1,157 @@
|
|
1
|
+
#
|
2
|
+
# https://adventofcode.com/2018/day/21 part 1 and part 2
|
3
|
+
#
|
4
|
+
# Does not use any 'cem' functions
|
5
|
+
#
|
6
|
+
# Version 3: Put everything into a single Proc (did not help much)
|
7
|
+
#
|
8
|
+
require 'set'
|
9
|
+
|
10
|
+
lines = File.readlines("inputs/day21_input.txt", chomp: true)
|
11
|
+
|
12
|
+
commandQueue = []
|
13
|
+
|
14
|
+
@reg = [0,0,0,0,0,0]
|
15
|
+
@s = Set.new
|
16
|
+
@last = nil
|
17
|
+
|
18
|
+
def command(verb, v1, v2, v3)
|
19
|
+
|
20
|
+
case verb
|
21
|
+
when "addr"
|
22
|
+
# addr (add @register) stores into @register C the result of adding @register A and @register B.
|
23
|
+
" @reg[#{v3}] = @reg[#{v1}] + @reg[#{v2}] "
|
24
|
+
|
25
|
+
when "addi"
|
26
|
+
# addi (add immediate) stores into @register C the result of adding @register A and value B.
|
27
|
+
" @reg[#{v3}] = @reg[#{v1}] + #{v2} "
|
28
|
+
|
29
|
+
when "mulr"
|
30
|
+
# mulr (multiply @register) stores into @register C the result of multiplying @register A and @register B.
|
31
|
+
" @reg[#{v3}] = @reg[#{v1}] * @reg[#{v2}] "
|
32
|
+
|
33
|
+
when "muli"
|
34
|
+
# muli (multiply immediate) stores into @register C the result of multiplying @register A and value B.
|
35
|
+
" @reg[#{v3}] = @reg[#{v1}] * #{v2} "
|
36
|
+
|
37
|
+
when "banr"
|
38
|
+
# banr (bitwise AND @register) stores into @register C the result of the bitwise AND of @register A and @register B.
|
39
|
+
" @reg[#{v3}] = @reg[#{v1}] & @reg[#{v2}] "
|
40
|
+
|
41
|
+
when "bani"
|
42
|
+
# bani (bitwise AND immediate) stores into @register C the result of the bitwise AND of @register A and value B.
|
43
|
+
" @reg[#{v3}] = @reg[#{v1}] & #{v2} "
|
44
|
+
|
45
|
+
when "borr"
|
46
|
+
# borr (bitwise OR @register) stores into @register C the result of the bitwise OR of @register A and @register B.
|
47
|
+
" @reg[#{v3}] = @reg[#{v1}] | @reg[#{v2}] "
|
48
|
+
|
49
|
+
when "bori"
|
50
|
+
# bori (bitwise OR immediate) stores into @register C the result of the bitwise OR of @register A and value B.
|
51
|
+
" @reg[#{v3}] = @reg[#{v1}] | #{v2} "
|
52
|
+
|
53
|
+
when "setr"
|
54
|
+
# setr (set @register) copies the contents of @register A into @register C. (Input B is ignored.)
|
55
|
+
" @reg[#{v3}] = @reg[#{v1}] "
|
56
|
+
|
57
|
+
when "seti"
|
58
|
+
# seti (set immediate) stores value A into @register C. (Input B is ignored.)
|
59
|
+
" @reg[#{v3}] = #{v1} "
|
60
|
+
|
61
|
+
when "gtir"
|
62
|
+
# gtir (greater-than immediate/@register) sets @register C to 1 if value A is greater than @register B. Otherwise, @register C is set to 0.
|
63
|
+
" @reg[#{v3}] = #{v1} > @reg[#{v2}] ? 1 : 0 "
|
64
|
+
|
65
|
+
when "gtri"
|
66
|
+
# gtri (greater-than @register/immediate) sets @register C to 1 if @register A is greater than value B. Otherwise, @register C is set to 0.
|
67
|
+
" @reg[#{v3}] = @reg[#{v1}] > #{v2} ? 1 : 0 "
|
68
|
+
|
69
|
+
when "gtrr"
|
70
|
+
# gtrr (greater-than @register/@register) sets @register C to 1 if @register A is greater than @register B. Otherwise, @register C is set to 0.
|
71
|
+
" @reg[#{v3}] = @reg[#{v1}] > @reg[#{v2}] ? 1 : 0 "
|
72
|
+
|
73
|
+
when "eqir"
|
74
|
+
# eqir (equal immediate/register) sets register C to 1 if value A is equal to register B. Otherwise, register C is set to 0.
|
75
|
+
" @reg[#{v3}] = #{v1} == @reg[#{v2}] ? 1 : 0 "
|
76
|
+
|
77
|
+
when "eqri"
|
78
|
+
# eqri (equal register/immediate) sets register C to 1 if register A is equal to value B. Otherwise, register C is set to 0.
|
79
|
+
" @reg[#{v3}] = @reg[#{v1}] == #{v2} ? 1 : 0 "
|
80
|
+
|
81
|
+
when "eqrr"
|
82
|
+
# eqrr (equal register/register) sets register C to 1 if register A is equal to register B. Otherwise, register C is set to 0.
|
83
|
+
" @reg[#{v3}] = @reg[#{v1}] == @reg[#{v2}] ? 1 : 0
|
84
|
+
|
85
|
+
if #{v2} == 0
|
86
|
+
if @s.size == 0
|
87
|
+
puts \"Part 1: \#{@reg[#{v1}]}\"
|
88
|
+
end
|
89
|
+
|
90
|
+
puts \"\#{@s.size.to_s.rjust(10)} - \#{@reg[#{v1}]}\" if @s.size % 64 == 0
|
91
|
+
|
92
|
+
if @s.include?(@reg[#{v1}])
|
93
|
+
puts \"Part 2: \#{@last}\"
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
@s.add @reg[#{v1}]
|
97
|
+
@last = @reg[#{v1}]
|
98
|
+
end
|
99
|
+
"
|
100
|
+
|
101
|
+
else
|
102
|
+
puts "error" # raise "Error"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
ipid = 0
|
109
|
+
ip = nil
|
110
|
+
lines.each { |line|
|
111
|
+
|
112
|
+
if line =~ /^#ip ([+-]?\d+)$/
|
113
|
+
ip = $1.to_i
|
114
|
+
end
|
115
|
+
|
116
|
+
if line =~ /^(\w+) ([+-]?\d+) ([+-]?\d+) ([+-]?\d+)$/
|
117
|
+
verb = $1
|
118
|
+
v1 = $2.to_i
|
119
|
+
v2 = $3.to_i
|
120
|
+
v3 = $4.to_i
|
121
|
+
|
122
|
+
p = command(verb, v1, v2, v3)
|
123
|
+
|
124
|
+
puts p
|
125
|
+
|
126
|
+
commandQueue << p
|
127
|
+
|
128
|
+
end
|
129
|
+
}
|
130
|
+
|
131
|
+
ippMax = commandQueue.size
|
132
|
+
|
133
|
+
commandQueue = "case ipp\n" + commandQueue.each_with_index.map { |v, i|
|
134
|
+
"when #{i}\n #{v}\n"
|
135
|
+
}.join("\n") + "\nend"
|
136
|
+
|
137
|
+
ipp = 0
|
138
|
+
iteration = 0
|
139
|
+
|
140
|
+
puts commandQueue
|
141
|
+
commandQueue = eval("
|
142
|
+
while #ipp >= 0 && ipp < ippMax
|
143
|
+
|
144
|
+
@reg[ip] = ipp
|
145
|
+
|
146
|
+
#{commandQueue}
|
147
|
+
|
148
|
+
ipp = @reg[ip]
|
149
|
+
ipp += 1
|
150
|
+
|
151
|
+
end")
|
152
|
+
|
153
|
+
#{commandQueue} }")
|
154
|
+
|
155
|
+
|
156
|
+
puts @reg.inspect
|
157
|
+
puts @reg[0]
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#
|
2
|
+
# https://adventofcode.com/2018/day/21 part 1 and part 2
|
3
|
+
#
|
4
|
+
# Does not use any 'cem' functions
|
5
|
+
#
|
6
|
+
# Rev 4: Replace the register array access with local variables => Double speed up.
|
7
|
+
#
|
8
|
+
require 'cem'
|
9
|
+
require 'set'
|
10
|
+
|
11
|
+
lines = File.readlines("inputs/day21_input.txt", chomp: true)
|
12
|
+
|
13
|
+
commandQueue = []
|
14
|
+
|
15
|
+
r0 = r1 = r2 = r3 = r4 = r5 = 0
|
16
|
+
@s = Set.new
|
17
|
+
@last = nil
|
18
|
+
|
19
|
+
def command(verb, v1, v2, v3)
|
20
|
+
|
21
|
+
case verb
|
22
|
+
when "addr"
|
23
|
+
# addr (add @register) stores into @register C the result of adding @register A and @register B.
|
24
|
+
" r#{v3} = r#{v1} + r#{v2} "
|
25
|
+
|
26
|
+
when "addi"
|
27
|
+
# addi (add immediate) stores into @register C the result of adding @register A and value B.
|
28
|
+
" r#{v3} = r#{v1} + #{v2} "
|
29
|
+
|
30
|
+
when "mulr"
|
31
|
+
# mulr (multiply @register) stores into @register C the result of multiplying @register A and @register B.
|
32
|
+
" r#{v3} = r#{v1} * r#{v2} "
|
33
|
+
|
34
|
+
when "muli"
|
35
|
+
# muli (multiply immediate) stores into @register C the result of multiplying @register A and value B.
|
36
|
+
" r#{v3} = r#{v1} * #{v2} "
|
37
|
+
|
38
|
+
when "banr"
|
39
|
+
# banr (bitwise AND @register) stores into @register C the result of the bitwise AND of @register A and @register B.
|
40
|
+
" r#{v3} = r#{v1} & r#{v2} "
|
41
|
+
|
42
|
+
when "bani"
|
43
|
+
# bani (bitwise AND immediate) stores into @register C the result of the bitwise AND of @register A and value B.
|
44
|
+
" r#{v3} = r#{v1} & #{v2} "
|
45
|
+
|
46
|
+
when "borr"
|
47
|
+
# borr (bitwise OR @register) stores into @register C the result of the bitwise OR of @register A and @register B.
|
48
|
+
" r#{v3} = r#{v1} | r#{v2} "
|
49
|
+
|
50
|
+
when "bori"
|
51
|
+
# bori (bitwise OR immediate) stores into @register C the result of the bitwise OR of @register A and value B.
|
52
|
+
" r#{v3} = r#{v1} | #{v2} "
|
53
|
+
|
54
|
+
when "setr"
|
55
|
+
# setr (set @register) copies the contents of @register A into @register C. (Input B is ignored.)
|
56
|
+
" r#{v3} = r#{v1} "
|
57
|
+
|
58
|
+
when "seti"
|
59
|
+
# seti (set immediate) stores value A into @register C. (Input B is ignored.)
|
60
|
+
" r#{v3} = #{v1} "
|
61
|
+
|
62
|
+
when "gtir"
|
63
|
+
# gtir (greater-than immediate/@register) sets @register C to 1 if value A is greater than @register B. Otherwise, @register C is set to 0.
|
64
|
+
" r#{v3} = #{v1} > r#{v2} ? 1 : 0 "
|
65
|
+
|
66
|
+
when "gtri"
|
67
|
+
# gtri (greater-than @register/immediate) sets @register C to 1 if @register A is greater than value B. Otherwise, @register C is set to 0.
|
68
|
+
" r#{v3} = r#{v1} > #{v2} ? 1 : 0 "
|
69
|
+
|
70
|
+
when "gtrr"
|
71
|
+
# gtrr (greater-than @register/@register) sets @register C to 1 if @register A is greater than @register B. Otherwise, @register C is set to 0.
|
72
|
+
" r#{v3} = r#{v1} > r#{v2} ? 1 : 0 "
|
73
|
+
|
74
|
+
when "eqir"
|
75
|
+
# eqir (equal immediate/register) sets register C to 1 if value A is equal to register B. Otherwise, register C is set to 0.
|
76
|
+
" r#{v3} = #{v1} == r#{v2} ? 1 : 0 "
|
77
|
+
|
78
|
+
when "eqri"
|
79
|
+
# eqri (equal register/immediate) sets register C to 1 if register A is equal to value B. Otherwise, register C is set to 0.
|
80
|
+
" r#{v3} = r#{v1} == #{v2} ? 1 : 0 "
|
81
|
+
|
82
|
+
when "eqrr"
|
83
|
+
# eqrr (equal register/register) sets register C to 1 if register A is equal to register B. Otherwise, register C is set to 0.
|
84
|
+
" r#{v3} = r#{v1} == r#{v2} ? 1 : 0
|
85
|
+
|
86
|
+
if #{v2} == 0
|
87
|
+
if @s.size == 0
|
88
|
+
puts \"Part 1: \#{r#{v1}}\"
|
89
|
+
end
|
90
|
+
|
91
|
+
puts \"\#{@s.size.to_s.rjust(10)} - \#{r#{v1}}\" if @s.size % 64 == 0
|
92
|
+
|
93
|
+
if @s.include?(r#{v1})
|
94
|
+
puts \"Part 2: \#{@last}\"
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
@s.add r#{v1}
|
98
|
+
@last = r#{v1}
|
99
|
+
end
|
100
|
+
"
|
101
|
+
else
|
102
|
+
puts "error" # raise "Error"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
ip = nil
|
108
|
+
lines.each { |line|
|
109
|
+
|
110
|
+
if line =~ /^#ip ([+-]?\d+)$/
|
111
|
+
ip = $1.to_i
|
112
|
+
end
|
113
|
+
|
114
|
+
if line =~ /^(\w+) ([+-]?\d+) ([+-]?\d+) ([+-]?\d+)$/
|
115
|
+
verb = $1
|
116
|
+
v1 = $2.to_i
|
117
|
+
v2 = $3.to_i
|
118
|
+
v3 = $4.to_i
|
119
|
+
|
120
|
+
commandQueue << command(verb, v1, v2, v3)
|
121
|
+
end
|
122
|
+
}
|
123
|
+
|
124
|
+
ndigits = commandQueue.size.digits.size
|
125
|
+
|
126
|
+
commandQueue = <<~EOS
|
127
|
+
while
|
128
|
+
|
129
|
+
case r#{ip}
|
130
|
+
#{commandQueue.each_with_index.map { |v, i| "when #{i.to_s.rjust(ndigits)} then #{v}"}.join("\n")}
|
131
|
+
else
|
132
|
+
raise
|
133
|
+
end
|
134
|
+
|
135
|
+
r#{ip} += 1
|
136
|
+
|
137
|
+
end
|
138
|
+
EOS
|
139
|
+
|
140
|
+
puts commandQueue
|
141
|
+
eval(commandQueue)
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#
|
2
|
+
# https://adventofcode.com/2018/day/22 part 1 and 2
|
3
|
+
#
|
4
|
+
# Demonstrates some use of Grid and Point2D
|
5
|
+
#
|
6
|
+
# Why this was hard: Did not read spec precisely!
|
7
|
+
|
8
|
+
require 'set'
|
9
|
+
require 'cem'
|
10
|
+
|
11
|
+
EXTRAX = 10
|
12
|
+
EXTRAY = 10
|
13
|
+
|
14
|
+
verbose = false
|
15
|
+
|
16
|
+
lines = File.readlines("inputs/day22_input.txt", chomp: true)
|
17
|
+
|
18
|
+
depth = nil
|
19
|
+
target = nil
|
20
|
+
|
21
|
+
lines.each { |line|
|
22
|
+
|
23
|
+
if line =~ /^depth: ([+-]?\d+)$/
|
24
|
+
depth = $1.to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
if line =~ /^target: ([+-]?\d+),([+-]?\d+)$/
|
28
|
+
target = Point2D.new($1.to_i, $2.to_i)
|
29
|
+
end
|
30
|
+
}
|
31
|
+
|
32
|
+
@depth = depth
|
33
|
+
@target = target
|
34
|
+
|
35
|
+
def erode(x)
|
36
|
+
return (x + @depth) % 20183
|
37
|
+
end
|
38
|
+
|
39
|
+
grid = Grid.new(target.x + EXTRAX + 1, target.y + EXTRAY + 1)
|
40
|
+
grid[0,0] = 0
|
41
|
+
|
42
|
+
(1..target.x + EXTRAX).each { |x|
|
43
|
+
grid[0,x] = erode(x * 16807)
|
44
|
+
}
|
45
|
+
(1..target.y + EXTRAY).each { |y|
|
46
|
+
grid[y,0] = erode(y * 48271)
|
47
|
+
}
|
48
|
+
|
49
|
+
(1..target.y + EXTRAY).each { |y|
|
50
|
+
(1..target.x + EXTRAX).each { |x|
|
51
|
+
if target.x == x && target.y == y
|
52
|
+
grid[y,x] = erode(0)
|
53
|
+
else
|
54
|
+
grid[y,x] = erode(grid[y-1,x] * grid[y,x-1])
|
55
|
+
end
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
puts "Part 1: #{grid[0..target.y, 0..target.x].flatten.sum { |g| g % 3 }}"
|
60
|
+
|
61
|
+
if verbose
|
62
|
+
grid[0..target.y, 0..target.x].each { |y|
|
63
|
+
y.each { |c|
|
64
|
+
case c % 3
|
65
|
+
when 0
|
66
|
+
print '.'
|
67
|
+
when 1
|
68
|
+
print '='
|
69
|
+
when 2
|
70
|
+
print '|'
|
71
|
+
end
|
72
|
+
}
|
73
|
+
puts
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Part 2
|
79
|
+
#
|
80
|
+
|
81
|
+
neighter = 0
|
82
|
+
torch = 1
|
83
|
+
gear = 2
|
84
|
+
|
85
|
+
toolGrid = [0,1,2,4].map { |t| Grid.new(target.x + EXTRAX + 1, target.y + EXTRAY + 1, -1)}
|
86
|
+
|
87
|
+
toolGrid[torch][0,0] = 0
|
88
|
+
|
89
|
+
define_method :toChar do |p|
|
90
|
+
case grid[p] % 3
|
91
|
+
when 0
|
92
|
+
'.'
|
93
|
+
when 1
|
94
|
+
'='
|
95
|
+
when 2
|
96
|
+
'|'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
define_method :supportedTools do |p|
|
101
|
+
|
102
|
+
case grid[p] % 3
|
103
|
+
when 0 # rocky
|
104
|
+
[gear, torch]
|
105
|
+
when 1 # wet
|
106
|
+
[neighter, gear]
|
107
|
+
when 2 # narrow
|
108
|
+
[neighter, torch]
|
109
|
+
else
|
110
|
+
raise
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
q = [[Point2D.new(0,0), torch]]
|
115
|
+
while q.size > 0
|
116
|
+
|
117
|
+
p, tool = q.shift
|
118
|
+
|
119
|
+
#puts "#{p.inspect} - #{tool} - #{toolGrid[tool][p]} - #{supportedTools(p)}"
|
120
|
+
|
121
|
+
sTools = supportedTools(p)
|
122
|
+
otherTools = ([0,1,2] - [tool]) & supportedTools(p)
|
123
|
+
|
124
|
+
otherTools.each { |t|
|
125
|
+
raise if t == tool
|
126
|
+
raise if !sTools.any? { |t2| t == t2 }
|
127
|
+
}
|
128
|
+
|
129
|
+
raise if toolGrid[tool][p] == -1
|
130
|
+
|
131
|
+
otherTools.each { |other|
|
132
|
+
if (toolGrid[other][p] == -1) || toolGrid[tool][p] + 7 < toolGrid[other][p]
|
133
|
+
toolGrid[other][p] = toolGrid[tool][p] + 7
|
134
|
+
q << [p, other]
|
135
|
+
end
|
136
|
+
}
|
137
|
+
|
138
|
+
grid.nsew_index(p).each { |p2|
|
139
|
+
# puts "#{p2.inspect} is adjacent to #{p} and supports the following tools #{supportedTools(p2)}"
|
140
|
+
|
141
|
+
if supportedTools(p2).include?(tool) && (toolGrid[tool][p2] == -1 || toolGrid[tool][p] + 1 < toolGrid[tool][p2])
|
142
|
+
toolGrid[tool][p2] = toolGrid[tool][p] + 1
|
143
|
+
q << [p2, tool]
|
144
|
+
end
|
145
|
+
}
|
146
|
+
|
147
|
+
q.sort_by! { |n|
|
148
|
+
p, tool = n
|
149
|
+
toolGrid[tool][p]
|
150
|
+
}
|
151
|
+
|
152
|
+
end
|
153
|
+
|
154
|
+
puts "Part 2: #{[toolGrid[torch][target], toolGrid[gear][target] + 7].min}"
|
155
|
+
|
156
|
+
if 0 == 1
|
157
|
+
(0..target.y + EXTRAY).each { |y|
|
158
|
+
(0..target.x + EXTRAX).each { |x|
|
159
|
+
|
160
|
+
case grid[y,x] % 3
|
161
|
+
|
162
|
+
when 0
|
163
|
+
print '.'
|
164
|
+
when 1
|
165
|
+
print '='
|
166
|
+
when 2
|
167
|
+
print '|'
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
print (toolGrid[torch][y,x].to_s + "," + toolGrid[neighter][y,x].to_s + "," +toolGrid[gear][y,x].to_s).rjust(8)
|
172
|
+
}
|
173
|
+
puts ""
|
174
|
+
} if DEBUG
|
175
|
+
|
176
|
+
reversePath = [[target, toolGrid[torch][target], torch]]
|
177
|
+
p = target
|
178
|
+
curTool = torch
|
179
|
+
while !(p.x == 0 && p.y == 0)
|
180
|
+
|
181
|
+
moves = grid.nsew_index(p).select { |p2| supportedTools(p2).include?(curTool) }.map { |p2| [p2, toolGrid[curTool][p2], curTool]} +
|
182
|
+
(supportedTools(p) - [curTool]).map { |t| [p, toolGrid[t][p], t, :toolChange] }
|
183
|
+
|
184
|
+
p moves
|
185
|
+
bestMove = moves.min_by { |x| x[1] }
|
186
|
+
|
187
|
+
reversePath.unshift bestMove
|
188
|
+
|
189
|
+
# puts p.inspect
|
190
|
+
|
191
|
+
p = bestMove[0]
|
192
|
+
curTool = bestMove[2]
|
193
|
+
end
|
194
|
+
|
195
|
+
reversePath.each { |x|
|
196
|
+
puts "[#{x[0].x}, #{x[0].y}, #{x[2]}] #{toChar(x[0])} #{x[1]} #{x.size > 3 ? x[3] : ""}"
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
|