From 54540fb30e994c239e3b1a2a73b116bf0d18f0f0 Mon Sep 17 00:00:00 2001 From: Akuli Date: Wed, 6 Dec 2023 12:26:21 +0200 Subject: [PATCH] aoc day 6 --- .gitignore | 4 ++ examples/aoc2023/day06/part1.jou | 66 ++++++++++++++++++++++++++ examples/aoc2023/day06/part2.jou | 40 ++++++++++++++++ examples/aoc2023/day06/sampleinput.txt | 2 + 4 files changed, 112 insertions(+) create mode 100644 examples/aoc2023/day06/part1.jou create mode 100644 examples/aoc2023/day06/part2.jou create mode 100644 examples/aoc2023/day06/sampleinput.txt diff --git a/.gitignore b/.gitignore index 8255fe1c..862ad24e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ jou_compiled # These are large text files, and each AoC user gets different input files. # Tests use sampleinput.txt files, copied from problem descriptions /examples/aoc2023/day*/input.txt + +# files created by https://github.com/scarvalhojr/aoc-cli +# not sure if I can commit these to git because copyright +/examples/aoc2023/day*/puzzle.md diff --git a/examples/aoc2023/day06/part1.jou b/examples/aoc2023/day06/part1.jou new file mode 100644 index 00000000..dfc04eb8 --- /dev/null +++ b/examples/aoc2023/day06/part1.jou @@ -0,0 +1,66 @@ +import "stdlib/str.jou" +import "stdlib/ascii.jou" +import "stdlib/io.jou" +import "stdlib/math.jou" + + +# Unlike most other AoC problems, this one is mostly math. +# +# Let T = given amount of time (button + move) +# R = record distance +# t = time button was held down = speed of boat +# +# Then getting a record means that +# +# t*(T-t) > R +# +# where t*(T-t) calculates our distance as speed*time. +# This can be rearranged to +# +# t^2 - Tt + R < 0 +# +# and then solved with the quadratic equation: +# +# +# -b +- sqrt(b^2-4ac) T +- sqrt(T^2-4R) +# tmin,tmax = --------------------- = ------------------- +# 2a 2 +# +# Then we calculate how many integers are strictly between tmin and tmax. + +def main() -> int: + times = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] + distances = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] + + f = fopen("input.txt", "r") + assert f != NULL + + line: byte[100] + while fgets(line, sizeof(line) as int, f) != NULL: + words = split_by_ascii_whitespace(line) + + assert words[0] != NULL + if strcmp(words[0], "Time:") == 0: + dest = × + else: + dest = &distances + + for i = 0; words[i+1] != NULL; i++: + assert i < sizeof(*dest)/sizeof((*dest)[0]) - 1 + (*dest)[i] = atoi(words[i+1]) + fclose(f) + + result = 1 + for i = 0; times[i] != -1 and distances[i] != -1; i++: + T = times[i] + R = distances[i] + + tmin = (T - sqrt(T*T - 4*R))/2 + tmax = (T + sqrt(T*T - 4*R))/2 + ints_between = (ceil(tmax) as int) - (floor(tmin) as int) - 1 + + assert ints_between >= 1 # must be possible to win somehow + result *= ints_between + + printf("%d\n", result) # Output: 288 + return 0 diff --git a/examples/aoc2023/day06/part2.jou b/examples/aoc2023/day06/part2.jou new file mode 100644 index 00000000..a792dc52 --- /dev/null +++ b/examples/aoc2023/day06/part2.jou @@ -0,0 +1,40 @@ +import "stdlib/str.jou" +import "stdlib/mem.jou" +import "stdlib/ascii.jou" +import "stdlib/io.jou" +import "stdlib/math.jou" + + +def remove_all_whitespace(s: byte*) -> void: + while *s != '\0': + if is_ascii_whitespace(*s): + memmove(s, &s[1], strlen(s)) + else: + s++ + + +def main() -> int: + T = -1 as long + R = -1 as long + + f = fopen("sampleinput.txt", "r") + assert f != NULL + + line: byte[100] + while fgets(line, sizeof(line) as int, f) != NULL: + remove_all_whitespace(line) + if starts_with(line, "Time:"): + T = atoll(&line[5]) + elif starts_with(line, "Distance:"): + R = atoll(&line[9]) + else: + assert False + + fclose(f) + + tmin = (T - sqrt(T*T - 4*R))/2 + tmax = (T + sqrt(T*T - 4*R))/2 + ints_between = (ceil(tmax) as int) - (floor(tmin) as int) - 1 + + printf("%d\n", ints_between) # Output: 71503 + return 0 diff --git a/examples/aoc2023/day06/sampleinput.txt b/examples/aoc2023/day06/sampleinput.txt new file mode 100644 index 00000000..28f5ae95 --- /dev/null +++ b/examples/aoc2023/day06/sampleinput.txt @@ -0,0 +1,2 @@ +Time: 7 15 30 +Distance: 9 40 200