mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
Compare commits
3 Commits
0c7c54b5c9
...
2d49907692
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d49907692 | |||
| edb0767201 | |||
| c871a9ea24 |
@@ -3,22 +3,17 @@ variable "input" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
muls = regexall("mul\\((\\d+),(\\d+)\\)", var.input)
|
filtered = replace(var.input, "/(?s)don't\\(\\).*?do\\(\\)/", "")
|
||||||
ops = regexall("(don't\\(\\)|do\\(\\)|mul\\((\\d+),(\\d+)\\))", var.input)
|
filtered2 = replace(local.filtered, "/(?s)don't\\(\\).*/", "")
|
||||||
}
|
|
||||||
|
|
||||||
module "should_execute" {
|
muls = regexall("mul\\((\\d+),(\\d+)\\)", var.input)
|
||||||
count = length(local.ops)
|
filtered_muls = regexall("mul\\((\\d+),(\\d+)\\)", local.filtered2)
|
||||||
source = "./should_execute"
|
|
||||||
|
|
||||||
index = count.index
|
|
||||||
ops = local.ops
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output "part1" {
|
output "part1" {
|
||||||
value = sum([for mul in local.muls : parseint(mul[1], 10) * parseint(mul[0], 10)])
|
value = sum([for mul in local.muls : tonumber(mul[1]) * tonumber(mul[0])])
|
||||||
}
|
}
|
||||||
|
|
||||||
output "part2" {
|
output "part2" {
|
||||||
value = sum(module.should_execute[*].value)
|
value = sum([for mul in local.filtered_muls : tonumber(mul[1]) * tonumber(mul[0])])
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
variable "ops" {
|
|
||||||
type = list(list(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "index" {
|
|
||||||
type = number
|
|
||||||
}
|
|
||||||
|
|
||||||
locals {
|
|
||||||
is_mul = startswith(var.ops[var.index][0], "mul")
|
|
||||||
subslice = reverse(slice(var.ops[*][0], 0, var.index))
|
|
||||||
|
|
||||||
do_pos = try(index(local.subslice, "do()"), var.index)
|
|
||||||
dont_pos = try(index(local.subslice, "don't()"), var.index + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
output "value" {
|
|
||||||
value = (local.is_mul && local.do_pos < local.dont_pos) ? (parseint(var.ops[var.index][1], 10) * parseint(var.ops[var.index][2], 10)) : 0
|
|
||||||
}
|
|
||||||
21
2024/bonus/day05/is_correct/main.tf
Normal file
21
2024/bonus/day05/is_correct/main.tf
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
variable "update" {
|
||||||
|
type = list(number)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disallow_rules" {
|
||||||
|
type = map(list(number))
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
not_disallowed = alltrue([
|
||||||
|
for i in range(1, length(var.update)) :
|
||||||
|
!contains(
|
||||||
|
flatten([for j in range(i) : lookup(var.disallow_rules, var.update[j], [])]),
|
||||||
|
var.update[i]
|
||||||
|
)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
output "valid" {
|
||||||
|
value = local.not_disallowed ? var.update[floor(length(var.update) / 2)] : 0
|
||||||
|
}
|
||||||
23
2024/bonus/day05/main.tf
Normal file
23
2024/bonus/day05/main.tf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
variable "input" {
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
parts = split("\n\n", chomp(var.input))
|
||||||
|
rules = [for rule_line in split("\n", local.parts[0]) : [for v in split("|", rule_line) : tonumber(v)]]
|
||||||
|
disallow_rules = { for rule in local.rules : rule[1] => rule[0]... }
|
||||||
|
|
||||||
|
updates = [for update_line in split("\n", local.parts[1]) : [for v in split(",", update_line) : tonumber(v)]]
|
||||||
|
}
|
||||||
|
|
||||||
|
module "is_valid" {
|
||||||
|
source = "./is_correct"
|
||||||
|
count = length(local.updates)
|
||||||
|
|
||||||
|
update = local.updates[count.index]
|
||||||
|
disallow_rules = local.disallow_rules
|
||||||
|
}
|
||||||
|
|
||||||
|
output "part1" {
|
||||||
|
value = sum(module.is_valid[*].valid)
|
||||||
|
}
|
||||||
@@ -56,3 +56,12 @@ output "day03_2" {
|
|||||||
# output "day04_2" {
|
# output "day04_2" {
|
||||||
# value = module.day04.part2
|
# value = module.day04.part2
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
module "day05" {
|
||||||
|
source = "./day05"
|
||||||
|
input = file("../inputs/05.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
output "day05_1" {
|
||||||
|
value = module.day05.part1
|
||||||
|
}
|
||||||
|
|||||||
@@ -113,3 +113,20 @@ run "day4" {
|
|||||||
error_message = "Part2 output is wrong"
|
error_message = "Part2 output is wrong"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run "day5_1" {
|
||||||
|
command = plan
|
||||||
|
|
||||||
|
module {
|
||||||
|
source = "./day05"
|
||||||
|
}
|
||||||
|
|
||||||
|
variables {
|
||||||
|
input = file("../tests/samples/05.txt")
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {
|
||||||
|
condition = output.part1 == 143
|
||||||
|
error_message = "Part1 output is wrong"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
61
2024/src/aoc/days/day7.py
Normal file
61
2024/src/aoc/days/day7.py
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
from . import SeparateRunner
|
||||||
|
|
||||||
|
|
||||||
|
def parse_input(input: str) -> tuple[int, list[int]]:
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for line in input.strip().split("\n"):
|
||||||
|
test, nums = line.split(": ")
|
||||||
|
result.append((int(test), list(map(int, nums.split(" ")))))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def is_possible(target: int, nums: list[int], cur: int) -> bool:
|
||||||
|
if cur == target and not nums:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if cur > target or not nums:
|
||||||
|
return False
|
||||||
|
|
||||||
|
head = nums[0]
|
||||||
|
remainder = nums[1:]
|
||||||
|
|
||||||
|
return is_possible(target, remainder, cur + head) or is_possible(
|
||||||
|
target, remainder, cur * head
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_possible2(target: int, nums: list[int], cur: int) -> bool:
|
||||||
|
if cur == target and not nums:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if cur > target or not nums:
|
||||||
|
return False
|
||||||
|
|
||||||
|
head = nums[0]
|
||||||
|
remainder = nums[1:]
|
||||||
|
|
||||||
|
return (
|
||||||
|
is_possible2(target, remainder, cur + head)
|
||||||
|
or is_possible2(target, remainder, cur * head)
|
||||||
|
or is_possible2(target, remainder, int(f"{cur}{head}"))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class DayRunner(SeparateRunner):
|
||||||
|
@classmethod
|
||||||
|
def part1(cls, input: str) -> int:
|
||||||
|
lines = parse_input(input)
|
||||||
|
|
||||||
|
return sum(
|
||||||
|
target for target, nums in lines if is_possible(target, nums[1:], nums[0])
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def part2(cls, input: str) -> int:
|
||||||
|
lines = parse_input(input)
|
||||||
|
|
||||||
|
return sum(
|
||||||
|
target for target, nums in lines if is_possible2(target, nums[1:], nums[0])
|
||||||
|
)
|
||||||
9
2024/tests/samples/07.txt
Normal file
9
2024/tests/samples/07.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
190: 10 19
|
||||||
|
3267: 81 40 27
|
||||||
|
83: 17 5
|
||||||
|
156: 15 6
|
||||||
|
7290: 6 8 6 15
|
||||||
|
161011: 16 10 13
|
||||||
|
192: 17 8 14
|
||||||
|
21037: 9 7 18 13
|
||||||
|
292: 11 6 16 20
|
||||||
17
2024/tests/test_day07.py
Normal file
17
2024/tests/test_day07.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from aoc.days.day7 import DayRunner
|
||||||
|
|
||||||
|
|
||||||
|
def get_data() -> str:
|
||||||
|
sample = os.path.dirname(__file__) + "/samples/07.txt"
|
||||||
|
with open(sample, mode="rt", encoding="utf-8") as f:
|
||||||
|
return f.read()
|
||||||
|
|
||||||
|
|
||||||
|
def test_sample_part1() -> None:
|
||||||
|
assert DayRunner.part1(get_data()) == 3749
|
||||||
|
|
||||||
|
|
||||||
|
def test_sample_part2() -> None:
|
||||||
|
assert DayRunner.part2(get_data()) == 11387
|
||||||
Reference in New Issue
Block a user