Day 25 (Python)
This commit is contained in:
parent
bfd58e36d1
commit
ba57fdfe90
6 changed files with 197 additions and 0 deletions
24
25-comboBreaker/README.md
Normal file
24
25-comboBreaker/README.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# [Day 25: Combo Breaker](https://adventofcode.com/2020/day/25)
|
||||
|
||||
Merry Christmas!
|
||||
|
||||
That's Advent of Code done for this year. At the time of writing this, I've not gotten all 49 stars up to this point, so I've got no way to get the 50th star. Even so, I feel slightly cheated out of a part two haha.
|
||||
|
||||
I might go back and try some of the other challenges from this year that I didn't complete.
|
||||
|
||||
<details><summary>Script output</summary>
|
||||
|
||||
```
|
||||
❯ python .\python\ ft
|
||||
AoC 2020: day 25 - Combo Breaker
|
||||
Python 3.8.5
|
||||
|
||||
Test cases
|
||||
1.1 pass in 0.0 seconds
|
||||
|
||||
Answers
|
||||
Part 1: 297257 in 7.745995283126831 seconds
|
||||
Part 2: 0 in 0.0 seconds
|
||||
```
|
||||
|
||||
</details>
|
14
25-comboBreaker/info.json
Normal file
14
25-comboBreaker/info.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"year": "2020",
|
||||
"day": "25",
|
||||
"title": "Combo Breaker",
|
||||
"testCases": {
|
||||
"one": [
|
||||
{
|
||||
"input": "5764801\n17807724",
|
||||
"expected": 14897079
|
||||
}
|
||||
],
|
||||
"two": []
|
||||
}
|
||||
}
|
118
25-comboBreaker/python/__main__.py
Normal file
118
25-comboBreaker/python/__main__.py
Normal file
|
@ -0,0 +1,118 @@
|
|||
import json
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
|
||||
from rich import print
|
||||
|
||||
from partOne import partOne
|
||||
from partTwo import partTwo
|
||||
|
||||
|
||||
force_time = False
|
||||
|
||||
|
||||
def run_and_time(f):
|
||||
st = time.time()
|
||||
x = f()
|
||||
et = time.time()
|
||||
return x, et - st
|
||||
|
||||
|
||||
def run_tests(test_cases):
|
||||
do_tests = True
|
||||
if len(test_cases) == 0:
|
||||
do_tests = False
|
||||
elif len(test_cases["one"]) == 0 and len(test_cases["two"]) == 0:
|
||||
do_tests = False
|
||||
|
||||
if not do_tests:
|
||||
print("Info: no test cases specified. Skipping tests\n")
|
||||
return
|
||||
|
||||
print("Test cases")
|
||||
|
||||
def rt(tcs, f, n):
|
||||
for i, tc in enumerate(tcs):
|
||||
readable_test_num = f"{n}.{i+1}"
|
||||
print(f"Running {readable_test_num}...", end="\r")
|
||||
|
||||
expectedInt = tc["expected"]
|
||||
|
||||
result, t = run_and_time(lambda: f(str(tc["input"])))
|
||||
|
||||
output_string = f"{readable_test_num} "
|
||||
|
||||
if result == expectedInt:
|
||||
output_string += "[green]pass[/green]"
|
||||
else:
|
||||
output_string += (
|
||||
f"[red]fail[/red] (got {result}, expected {expectedInt})"
|
||||
)
|
||||
|
||||
if t > 15 or force_time:
|
||||
output_string += f" in {t} seconds"
|
||||
|
||||
print(output_string + " " * 12)
|
||||
|
||||
rt(test_cases["one"], partOne, 1)
|
||||
rt(test_cases["two"], partTwo, 2)
|
||||
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
info = open("info.json").read()
|
||||
except FileNotFoundError:
|
||||
print("Error: could not open info.json")
|
||||
sys.exit(-1)
|
||||
|
||||
info = json.loads(info)
|
||||
|
||||
year = info["year"]
|
||||
day = info["day"]
|
||||
title = info["title"]
|
||||
|
||||
print(f"[yellow]AoC {year}[/yellow]: day {day} - {title}")
|
||||
print(f"Python {platform.python_version()}\n")
|
||||
|
||||
try:
|
||||
challenge_input = open("input.txt").read()
|
||||
except FileNotFoundError:
|
||||
print("Error: could not open input.txt")
|
||||
sys.exit(-1)
|
||||
|
||||
if "vis" in sys.argv:
|
||||
import visualise
|
||||
|
||||
print("[green]Running visualisation....[/green]")
|
||||
|
||||
visualise.visualise(challenge_input)
|
||||
sys.exit()
|
||||
|
||||
if "ft" in sys.argv:
|
||||
force_time = True
|
||||
|
||||
run_tests(info["testCases"])
|
||||
|
||||
if "debug" in sys.argv:
|
||||
sys.exit()
|
||||
|
||||
print("Answers")
|
||||
|
||||
print("Running part 1...", end="\r")
|
||||
output_string = "Part 1: "
|
||||
x, t = run_and_time(lambda: partOne(challenge_input))
|
||||
output_string += str(x)
|
||||
if t > 15 or force_time:
|
||||
output_string += f" in {t} seconds"
|
||||
print(output_string + " " * 12)
|
||||
|
||||
print("Running part 2...", end="\r")
|
||||
output_string = "Part 2: "
|
||||
x, t = run_and_time(lambda: partTwo(challenge_input))
|
||||
output_string += str(x)
|
||||
if t > 15 or force_time:
|
||||
output_string += f" in {t} seconds"
|
||||
print(output_string + " " * 12)
|
5
25-comboBreaker/python/common.py
Normal file
5
25-comboBreaker/python/common.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
from typing import List
|
||||
|
||||
|
||||
def parse(instr: str) -> List[int]:
|
||||
return [int(x) for x in instr.strip().split("\n")]
|
34
25-comboBreaker/python/partOne.py
Normal file
34
25-comboBreaker/python/partOne.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from common import *
|
||||
|
||||
|
||||
def single_transformation(v:int, subject_number:int=7) -> int:
|
||||
return (v * subject_number) % 20201227
|
||||
|
||||
|
||||
def transform(loop_size:int, subject_number:int=7) -> int:
|
||||
v = 1
|
||||
for _ in range(loop_size):
|
||||
v = single_transformation(v, subject_number=subject_number)
|
||||
return v
|
||||
|
||||
|
||||
def find_loop_size(target_pubkey:int) -> int:
|
||||
c = 0
|
||||
v = 1
|
||||
while True:
|
||||
c += 1
|
||||
v = single_transformation(v)
|
||||
if v == target_pubkey:
|
||||
return c
|
||||
|
||||
|
||||
def partOne(instr: str) -> int:
|
||||
pubkey_one, pubkey_two = parse(instr)
|
||||
|
||||
loop_size_one = find_loop_size(pubkey_one)
|
||||
loop_size_two = find_loop_size(pubkey_two)
|
||||
|
||||
encryption_key = transform(loop_size_two, subject_number=pubkey_one)
|
||||
assert encryption_key == transform(loop_size_one, subject_number=pubkey_two), "encryption keys do not match"
|
||||
|
||||
return encryption_key
|
2
25-comboBreaker/python/partTwo.py
Normal file
2
25-comboBreaker/python/partTwo.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
def partTwo(instr: str) -> int:
|
||||
return 0
|
Loading…
Add table
Add a link
Reference in a new issue