parent
5126ad233a
commit
a91994d28d
@ -1,62 +1,120 @@
|
||||
registers, program = DATA.read.split("\n\n")
|
||||
|
||||
a, b, c = registers.scan(/\d+/).map(&:to_i)
|
||||
program = program.scan(/\d+/).map(&:to_i)
|
||||
def run(a, b, c, program)
|
||||
return enum_for(__method__, a, b, c, program) unless block_given?
|
||||
|
||||
combo = ->(operand) {
|
||||
case operand
|
||||
when 0, 1, 2, 3 then operand
|
||||
when 4 then a
|
||||
when 5 then b
|
||||
when 6 then c
|
||||
else
|
||||
fail
|
||||
end
|
||||
}
|
||||
|
||||
ip = 0
|
||||
out = []
|
||||
while (0...program.size).cover?(ip)
|
||||
opcode = program.fetch(ip)
|
||||
operand = program.fetch(ip+1)
|
||||
case opcode
|
||||
when 0
|
||||
a = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
when 1
|
||||
b = b ^ operand
|
||||
ip += 2
|
||||
when 2
|
||||
b = combo[operand] % 8
|
||||
ip += 2
|
||||
when 3
|
||||
if a.zero?
|
||||
combo = ->(operand) {
|
||||
case operand
|
||||
when 0, 1, 2, 3 then operand
|
||||
when 4 then a
|
||||
when 5 then b
|
||||
when 6 then c
|
||||
else
|
||||
fail
|
||||
end
|
||||
}
|
||||
|
||||
ip = 0
|
||||
while (0...program.size).cover?(ip)
|
||||
opcode = program.fetch(ip)
|
||||
operand = program.fetch(ip+1)
|
||||
case opcode
|
||||
when 0
|
||||
a = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
when 1
|
||||
b = b ^ operand
|
||||
ip += 2
|
||||
when 2
|
||||
b = combo[operand] % 8
|
||||
ip += 2
|
||||
when 3
|
||||
if a.zero?
|
||||
ip += 2
|
||||
else
|
||||
ip = operand
|
||||
end
|
||||
when 4
|
||||
b = b ^ c
|
||||
ip += 2
|
||||
when 5
|
||||
yield combo[operand] % 8
|
||||
ip += 2
|
||||
when 6
|
||||
b = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
when 7
|
||||
c = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
else
|
||||
ip = operand
|
||||
fail
|
||||
end
|
||||
when 4
|
||||
b = b ^ c
|
||||
ip += 2
|
||||
when 5
|
||||
out << combo[operand] % 8
|
||||
ip += 2
|
||||
when 6
|
||||
b = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
when 7
|
||||
c = (a / 2**combo[operand]).to_i
|
||||
ip += 2
|
||||
else
|
||||
fail
|
||||
end
|
||||
end
|
||||
|
||||
puts out.join(?,)
|
||||
a, b, c = registers.scan(/\d+/).map(&:to_i)
|
||||
program = program.scan(/\d+/).map(&:to_i)
|
||||
|
||||
# puts (211000000..).find {|a|
|
||||
# pp a if a % 100_000 == 0
|
||||
# program.each.lazy.zip(run(a, b, c, program)).all? { _1 == _2 }
|
||||
# }
|
||||
|
||||
def run(a)
|
||||
return enum_for(__method__, a) unless block_given?
|
||||
|
||||
# 14: 3 0 # jnz
|
||||
until a.zero?
|
||||
# 0: 2 4 # bst
|
||||
# 2: 1 2 # bxl
|
||||
# b = ((a & 0b111) ^ 0b010)
|
||||
|
||||
# 4: 7 5 # cdv
|
||||
# c = a >> ((a & 0b111) ^ 0b010)
|
||||
|
||||
# 8: 1 7 # bxl
|
||||
# 10: 4 1 # bxc
|
||||
# b = ((a & 0b111) ^ 0b010) ^ c ^ 0b111
|
||||
# b = ((a & 0b111) ^ 0b010) ^ (a >> ((a & 0b111) ^ 0b010)) ^ 0b111
|
||||
b = (a & 0b111) ^ 0b101 ^ (a >> ((a & 0b111) ^ 0b010))
|
||||
|
||||
# 12: 5 5 # out
|
||||
yield b & 0b111
|
||||
|
||||
# 6: 0 3 # adv
|
||||
a >>= 3
|
||||
end
|
||||
end
|
||||
|
||||
def run(a)
|
||||
return enum_for(__method__, a) unless block_given?
|
||||
|
||||
a.to_s(8).chars.map(&:to_i).reverse.map.with_index {|x,i|
|
||||
yield (x ^ 0b101 ^ (a >> 3*i >> (x ^ 0b010))) & 0b111
|
||||
}
|
||||
end
|
||||
|
||||
pp run(27334280).to_a.join(?,)
|
||||
|
||||
TARGET = "2412750317415530".chars.map(&:to_i)
|
||||
def solve(a)
|
||||
return [a] if a.size == 16
|
||||
|
||||
(0..7)
|
||||
.map { a + [_1] }
|
||||
.select {|a|
|
||||
TARGET.reverse[0,a.size].zip(
|
||||
run(a.join.ljust(14, ?0).to_i(8)).to_a.reverse
|
||||
).all? { _1 == _2 }
|
||||
}.flat_map { solve(_1) }
|
||||
end
|
||||
|
||||
pp solve([]).map(&:join).map { _1.to_i(8) }.min
|
||||
pp run(190615597431823).to_a == program
|
||||
|
||||
__END__
|
||||
Register A: 729
|
||||
Register A: 27334280
|
||||
Register B: 0
|
||||
Register C: 0
|
||||
|
||||
Program: 0,1,5,4,3,0
|
||||
Program: 2,4,1,2,7,5,0,3,1,7,4,1,5,5,3,0
|
||||
|
Loading…
Reference in new issue