4 Commits

Author SHA1 Message Date
443ff2cee6 Reduce part 2 to O(n) 2024-12-01 18:04:13 +01:00
f4a5ffe3ce Part 2 and actual testing 2024-12-01 17:05:41 +01:00
73f886359b Implement day 1 part 1 in Terraform 2024-12-01 16:51:45 +01:00
26ee876f7a Minor fixes 2024-12-01 15:21:55 +01:00
7 changed files with 75 additions and 7 deletions

3
.gitignore vendored
View File

@@ -67,3 +67,6 @@ flamegraph.svg
# Ignore saved inputs # Ignore saved inputs
inputs/ inputs/
# Terraform dir
.terraform

28
2024/bonus/day01/main.tf Normal file
View File

@@ -0,0 +1,28 @@
variable "input" {
type = string
}
locals {
cleaned_input = replace(var.input, "/ +/", " ")
lines = split("\n", trim(local.cleaned_input, "\n"))
lines_split = [for line in local.lines: split(" ", line)]
left = [for line in local.lines_split: parseint(line[0], 10)]
right = [for line in local.lines_split: parseint(line[1], 10)]
left_sorted = sort(local.left)
right_sorted = sort(local.right)
diffs = [for i in range(length(local.left_sorted)): abs(local.left_sorted[i] - local.right_sorted[i])]
counts = {for num in local.right: num => num...}
matching = [for left in local.left: left * length(lookup(local.counts, left, []))]
}
output "part1" {
value = sum(local.diffs)
}
output "part2" {
value = sum(local.matching)
}

View File

@@ -0,0 +1,19 @@
variables {
input = file("../../tests/samples/01.txt")
}
run "run" {
command = plan
assert {
condition = output.part1 == 11
error_message = "Part1 output is wrong"
}
assert {
condition = output.part2 == 31
error_message = "Part2 output is wrong"
}
}

16
2024/bonus/main.tf Normal file
View File

@@ -0,0 +1,16 @@
terraform {
}
module "day01" {
source = "./day01"
input = file("../inputs/01.txt")
}
output "day01_1" {
value = module.day01.part1
}
output "day01_2" {
value = module.day01.part2
}

View File

@@ -22,11 +22,11 @@ from aoc import days
@click.argument("day", required=True) @click.argument("day", required=True)
def main(day: int, timing: bool, data: IO[str]) -> None: def main(day: int, timing: bool, data: IO[str]) -> None:
runner_class = days.get_runner(day) runner_class = days.get_runner(day)
data = data.read() contents = data.read()
start = time.perf_counter_ns() start = time.perf_counter_ns()
part1, part2 = runner_class.run_both(data) part1, part2 = runner_class.run_both(contents)
if timing: if timing:
elapsed = time.perf_counter_ns() - start elapsed = time.perf_counter_ns() - start

View File

@@ -10,8 +10,7 @@ from . import CombinedRunner
class DayRunner(CombinedRunner): class DayRunner(CombinedRunner):
@classmethod @classmethod
def run_both(cls, data: str) -> tuple[Any, Any]: def run_both(cls, data: str) -> tuple[Any, Any]:
data = StringIO(data) nums = numpy.loadtxt(StringIO(data), dtype=numpy.int32)
nums = numpy.loadtxt(data, dtype=numpy.int32)
left = nums[..., 0] left = nums[..., 0]
right = nums[..., 1] right = nums[..., 1]
@@ -21,7 +20,7 @@ class DayRunner(CombinedRunner):
diff = numpy.abs(left - right).sum() diff = numpy.abs(left - right).sum()
counts = defaultdict(int) counts: defaultdict[int, int] = defaultdict(int)
for val in right: for val in right:
counts[val] += 1 counts[val] += 1

View File

@@ -2,13 +2,16 @@ import os
from aoc.days.day1 import DayRunner from aoc.days.day1 import DayRunner
def get_data() -> str: def get_data() -> str:
sample = os.path.dirname(__file__) + "/samples/01.txt" sample = os.path.dirname(__file__) + "/samples/01.txt"
with open(sample, mode="rt", encoding="utf-8") as f: with open(sample, mode="rt", encoding="utf-8") as f:
return f.read() return f.read()
def test_sample_part1():
def test_sample_part1() -> None:
assert DayRunner.part1(get_data()) == 11 assert DayRunner.part1(get_data()) == 11
def test_sample_part2():
def test_sample_part2() -> None:
assert DayRunner.part2(get_data()) == 31 assert DayRunner.part2(get_data()) == 31