Skip to content

Commit

Permalink
2017 day 18 solution
Browse files Browse the repository at this point in the history
Signed-off-by: Lance-Drane <ldraneutk@gmail.com>
  • Loading branch information
Lance-Drane committed Feb 5, 2024
1 parent 6b4ce00 commit 4467dc8
Show file tree
Hide file tree
Showing 9 changed files with 262 additions and 79 deletions.
2 changes: 1 addition & 1 deletion 2015/22/1.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Effects(TypedDict):


def take_turn( # noqa: PLR0913
player_turn: bool, # noqa: FBT001
player_turn: bool,
player_hp: int,
player_mana: int,
spent_mana: int,
Expand Down
2 changes: 1 addition & 1 deletion 2015/22/2.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Effects(TypedDict):


def take_turn( # noqa: PLR0913
player_turn: bool, # noqa: FBT001
player_turn: bool,
player_hp: int,
player_mana: int,
spent_mana: int,
Expand Down
148 changes: 72 additions & 76 deletions 2016/25/1.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,84 +5,80 @@
base_instructions: list[list[str, str, str]] = [line.split() for line in sys.stdin.readlines()]
curr = 0

try:
for init in count(start=1):
registers = defaultdict(int, {'a': init})
curr = 0
instructions = base_instructions.copy()
out = []
next_value = 0
while curr < len(instructions):
instruct = instructions[curr]
# print(init, instruct, dict(registers), file=sys.stderr)
for init in count(start=1):
registers = defaultdict(int, {'a': init})
curr = 0
instructions = base_instructions.copy()
out = []
next_value = 0
while curr < len(instructions):
instruct = instructions[curr]

if instruct[0] == 'cpy':
if instruct[2][0].isalpha():
registers[instruct[2]] = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
curr += 1
elif instruct[0] == 'inc':
if instruct[1][0].isalpha():
registers[instruct[1]] += 1
curr += 1
elif instruct[0] == 'dec':
if instruct[1][0].isalpha():
registers[instruct[1]] -= 1
curr += 1
elif instruct[0] == 'jnz':
jnz_check = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
if jnz_check != 0:
amount = registers[instruct[2]] if instruct[2][0].isalpha() else int(instruct[2])
# you'll want to optimize for multiplication based on the amount from here
if amount == -2:
if (
instructions[curr - 2][0] == 'inc'
and instructions[curr - 1][0] == 'dec'
and instruct[1] == instructions[curr - 1][1]
):
registers[instructions[curr - 2][1]] += jnz_check + 1
registers[instruct[1]] = 0
curr += 1
elif (
instructions[curr - 2][0] == 'dec'
and instructions[curr - 1][0] == 'inc'
and instruct[1] == instructions[curr - 2][1]
):
registers[instructions[curr - 1][1]] += jnz_check + 1
registers[instruct[1]] = 0
curr += 1
else:
curr += amount
elif amount == -5:
# this is the main optimization to be done
last_5_instructions = [instructions[i] for i in range(curr - 5, curr)]
if last_5_instructions[0][0] == 'cpy':
product = (
registers[last_5_instructions[0][1]]
if last_5_instructions[0][1][0].isalpha()
else int(last_5_instructions[0][1])
)
for i in last_5_instructions[1:]:
if i[0] == 'inc':
register_key = i[1]
break
registers[register_key] += jnz_check * product - 1
registers[instruct[1]] = 0
curr += 1
else:
curr += amount
if instruct[0] == 'cpy':
if instruct[2][0].isalpha():
registers[instruct[2]] = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
curr += 1
elif instruct[0] == 'inc':
if instruct[1][0].isalpha():
registers[instruct[1]] += 1
curr += 1
elif instruct[0] == 'dec':
if instruct[1][0].isalpha():
registers[instruct[1]] -= 1
curr += 1
elif instruct[0] == 'jnz':
jnz_check = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
if jnz_check != 0:
amount = registers[instruct[2]] if instruct[2][0].isalpha() else int(instruct[2])
# you'll want to optimize for multiplication based on the amount from here
if amount == -2:
if (
instructions[curr - 2][0] == 'inc'
and instructions[curr - 1][0] == 'dec'
and instruct[1] == instructions[curr - 1][1]
):
registers[instructions[curr - 2][1]] += jnz_check + 1
registers[instruct[1]] = 0
curr += 1
elif (
instructions[curr - 2][0] == 'dec'
and instructions[curr - 1][0] == 'inc'
and instruct[1] == instructions[curr - 2][1]
):
registers[instructions[curr - 1][1]] += jnz_check + 1
registers[instruct[1]] = 0
curr += 1
else:
curr += amount
elif amount == -5:
# this is the main optimization to be done
last_5_instructions = [instructions[i] for i in range(curr - 5, curr)]
if last_5_instructions[0][0] == 'cpy':
product = (
registers[last_5_instructions[0][1]]
if last_5_instructions[0][1][0].isalpha()
else int(last_5_instructions[0][1])
)
for i in last_5_instructions[1:]:
if i[0] == 'inc':
register_key = i[1]
break
registers[register_key] += jnz_check * product - 1
registers[instruct[1]] = 0
curr += 1
else:
curr += amount
else:
curr += 1
else: # 'out'
trans_value = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
if trans_value != next_value:
break
next_value = 0 if next_value == 1 else 1
out.append(trans_value)
if len(out) == 100:
print(init)
sys.exit(0)
curr += amount
else:
curr += 1
except KeyboardInterrupt:
print(init)
else: # 'out'
trans_value = registers[instruct[1]] if instruct[1][0].isalpha() else int(instruct[1])
if trans_value != next_value:
break
next_value = 0 if next_value == 1 else 1
out.append(trans_value)
if len(out) == 100:
print(init)
sys.exit(0)
curr += 1
42 changes: 42 additions & 0 deletions 2017/18/1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import sys
from collections import defaultdict

registers = defaultdict(int)
instructions: list[list[str, str, str]] = [line.split() for line in sys.stdin.readlines()]
last_sound = 0


def get_next_value(val: str) -> int:
return int(val) if not val[0].isalpha() else registers[val]


curr = 0
while curr < len(instructions):
instruct = instructions[curr]

if instruct[0] == 'snd':
last_sound = get_next_value(instruct[1])
curr += 1
elif instruct[0] == 'set':
registers[instruct[1]] = get_next_value(instruct[2])
curr += 1
elif instruct[0] == 'add':
registers[instruct[1]] += get_next_value(instruct[2])
curr += 1
elif instruct[0] == 'mul':
registers[instruct[1]] *= get_next_value(instruct[2])
curr += 1
elif instruct[0] == 'mod':
registers[instruct[1]] %= get_next_value(instruct[2])
curr += 1
elif instruct[0] == 'rcv':
next_val = get_next_value(instruct[1])
if next_val != 0:
print(last_sound)
break
curr += 1
# jgz
elif get_next_value(instruct[1]) > 0:
curr += get_next_value(instruct[2])
else:
curr += 1
1 change: 1 addition & 0 deletions 2017/18/1_out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9423
103 changes: 103 additions & 0 deletions 2017/18/2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import sys
from collections import defaultdict, deque

instructions: list[list[str, str, str]] = [line.split() for line in sys.stdin.readlines()]


class Program:
def __init__(self, pid: int):
self.registers = defaultdict(int, {'p': pid})
self.curr = 0
self.msg_q = deque()
self.next_receive: str | None = None
self.sent_count = 0

def get_next_value(self, val: str) -> int:
return int(val) if not val[0].isalpha() else self.registers[val]

def register_message_endpoint(self, callback):
"""
allow for one program to send a message to another program
"""
self.message_endpoint_other = callback

def message_endpoint(self, value: int):
"""
called from the other program when it sends a value, just add the value to the message queue
for now.
"""
self.msg_q.append(value)

def register_execute(self, callback):
"""
allow for one program to tell the other program to start executing its instructions
"""
self.execute_other = callback

def execute(self):
"""
start executing instructions. call the other program's execution function by
"self.execute_other()"
"""
if not self.msg_q:
# deadlock
return
if self.next_receive:
self.registers[self.next_receive] = self.msg_q.popleft()
if not self.msg_q:
# deadlock
return
self.next_receive = None
self.execute_instructions()

def execute_instructions(self):
"""
this is the main loop. normally called from "execute", but the initial back-and-forth
needs to start from here.
"""
while self.curr < len(instructions):
instruct = instructions[self.curr]

if instruct[0] == 'snd':
self.curr += 1
self.message_endpoint_other(self.get_next_value(instruct[1]))
self.sent_count += 1
elif instruct[0] == 'set':
self.registers[instruct[1]] = self.get_next_value(instruct[2])
self.curr += 1
elif instruct[0] == 'add':
self.registers[instruct[1]] += self.get_next_value(instruct[2])
self.curr += 1
elif instruct[0] == 'mul':
self.registers[instruct[1]] *= self.get_next_value(instruct[2])
self.curr += 1
elif instruct[0] == 'mod':
self.registers[instruct[1]] %= self.get_next_value(instruct[2])
self.curr += 1
elif instruct[0] == 'rcv':
self.curr += 1
if self.msg_q:
self.registers[instruct[1]] = self.msg_q.popleft()
else:
self.next_receive = instruct[1]
break
# jgz
elif self.get_next_value(instruct[1]) > 0:
self.curr += self.get_next_value(instruct[2])
else:
self.curr += 1

self.execute_other()


program_0 = Program(0)
program_1 = Program(1)

program_0.register_execute(program_1.execute)
program_1.register_execute(program_0.execute)
program_0.register_message_endpoint(program_1.message_endpoint)
program_1.register_message_endpoint(program_0.message_endpoint)

program_0.execute_instructions()

print(program_1.sent_count)
1 change: 1 addition & 0 deletions 2017/18/2_out.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
7620
41 changes: 41 additions & 0 deletions 2017/18/in.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
set i 31
set a 1
mul p 17
jgz p p
mul a 2
add i -1
jgz i -2
add a -1
set i 127
set p 622
mul p 8505
mod p a
mul p 129749
add p 12345
mod p a
set b p
mod b 10000
snd b
add i -1
jgz i -9
jgz a 3
rcv b
jgz b -1
set f 0
set i 126
rcv a
rcv b
set p a
mul p -1
add p b
jgz p 4
snd a
set a b
jgz 1 3
snd b
set f 1
add i -1
jgz i -11
snd a
jgz f -16
jgz a -19
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extend-select = [
'C90',
'I',
'UP',
'FBT',
'B',
'A',
'COM',
Expand Down

0 comments on commit 4467dc8

Please sign in to comment.