advent2022

Advent of Code 2022 Solutions
git clone https://todayiwilllaunchmyinfantsonintoorbit.com/advent2022.git
Log | Files | Refs

commit 66665329bede75b8ab7bd11fed7b6b99b52588c2
Author: Decay <decay@todayiwilllaunchmyinfantsonintoorbit.com>
Date:   Mon,  5 Dec 2022 20:01:34 -0800

Solutions up to day five

Diffstat:
A.gitignore | 3+++
A1/1.lisp | 27+++++++++++++++++++++++++++
A2/2a.pl | 23+++++++++++++++++++++++
A2/2b.pl | 35+++++++++++++++++++++++++++++++++++
A3/3a.c | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A3/3b.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A4/4a.sno | 15+++++++++++++++
A4/4b.sno | 15+++++++++++++++
A5/Five.java | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 371 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +input +**/*~ +**/*.class diff --git a/1/1.lisp b/1/1.lisp @@ -0,0 +1,27 @@ +(defpackage #:advent + (:use :cl)) +(in-package #:advent) + +(defun asset-path (name &optional ext) + (let* ((this-file #.(or *compile-file-truename* *load-truename*)) + (assets-dir (pathname-directory this-file))) + (make-pathname :name name :type ext :directory assets-dir :defaults this-file))) + +(defparameter +input+ (asset-path "input")) + +(defun read-diets () + (mapcar (lambda (diet) (apply #'+ diet)) + (with-open-file (s +input+) + (loop for line = (read-line s nil :eof) + for diet = new-diet + for new-diet = (when (and (not (eql line :eof)) (not (string= line ""))) + (cons (parse-integer line) diet)) + when (not new-diet) + collect diet + until (eql line :eof))))) + +(defun solve1 () + (apply #'max (read-diets))) + +(defun solve2 () + (apply #'+ (subseq (sort (read-diets) #'>) 0 3))) diff --git a/2/2a.pl b/2/2a.pl @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +my $score = 0; +while (<>) { + chomp; + /^([ABC]) ([XYZ])$/ || die "Fuck!"; + (my $them, $me) = (ord($1) - 64, ord($2) - 87); + $score += $me; + if ((($them > $me) && !($me == 1 && $them == 3))|| ($them == 1 && $me == 3)) { + # Nothing! + print "Them\n"; + } elsif (($me > $them) || ($me == 1 && $them == 3)) { + print "Me\n"; + $score += 6; + } elsif ($me == $them) { + print "Tie\n"; + $score += 3; + } else { + print "What the fuck\n"; + } + print "Score is now $score\n"; +} +print "$score\n"; diff --git a/2/2b.pl b/2/2b.pl @@ -0,0 +1,35 @@ +#!/usr/bin/perl + +my $score = 0; +while (<>) { + chomp; + /^([ABC]) ([XYZ])$/ || die "Fuck!"; + (my $them, $meInst) = (ord($1) - 64, $2); + my $me; + print "$meInst\n"; + if ($meInst eq "X") { + print "They win\n"; + $me = ($them == 1) ? 3 : $them - 1; + } elsif ($meInst eq "Y") { + print "Tie\n"; + $me = $them; + } else { + print "I win\n"; + $me = ($them % 3) + 1; + } + $score += $me; + if ((($them > $me) && !($me == 1 && $them == 3))|| ($them == 1 && $me == 3)) { + # Nothing! + print "Them\n"; + } elsif (($me > $them) || ($me == 1 && $them == 3)) { + print "Me\n"; + $score += 6; + } elsif ($me == $them) { + print "Tie\n"; + $score += 3; + } else { + print "What the fuck\n"; + } + print "Score is now $score\n"; +} +print "$score\n"; diff --git a/3/3a.c b/3/3a.c @@ -0,0 +1,73 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int compare_char(const char *first, const char *second) { + return *first - *second; +} + +int main(void) { + FILE *input = fopen("input", "r"); + char *line_in = NULL; + size_t buf_len; + unsigned int prio_sum = 0; + + while (!feof(input)) { + if (getline(&line_in, &buf_len, input) != -1) { + size_t len = strlen(line_in); + if (len > 2 && line_in[len - 1] == '\n') { + // Truncate + line_in[len - 1] = 0; + len -= 1; + } + if (len % 2) { + fprintf(stderr, "Bad line!\n"); + exit(EXIT_FAILURE); + } + size_t half_len = (len / 2) + 1; + + // Split the compartments + char *first_half = malloc(half_len); + char *second_half = malloc(half_len); + strncpy(first_half, line_in, half_len - 1); + strncpy(second_half, line_in + (half_len - 1), half_len - 1); + + // Sort both sides + qsort(first_half, half_len - 1, sizeof(char), compare_char); + qsort(second_half, half_len - 1, sizeof(char), compare_char); + + // Spin over the two compartments and find any duplicates + for (int i = 0, j = 0;i < half_len && j < half_len;i++) { + // Run to the end of the current run + while (i < (half_len - 1) && first_half[i] == first_half[i + 1]) + i++; + + // Skip any characters less than first_half[i] + while (j < half_len && second_half[j] < first_half[i]) + j++; + + if (first_half[i] == second_half[j]) { + char dup = first_half[i]; + if (dup >= 'a' && dup <= 'z') { + prio_sum += dup - 96; + } else { + prio_sum += dup - 38; + } + } + } + + free(line_in); + line_in = NULL; + } else { + free(line_in); + if (errno) { + strerror(NULL); + exit(EXIT_FAILURE); + } + } + } + printf("Priority sum: %i\n", prio_sum); + + fclose(input); +} diff --git a/3/3b.c b/3/3b.c @@ -0,0 +1,89 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +int compare_char(const char *first, const char *second) { + return *first - *second; +} + +int main(void) { + FILE *input = fopen("input", "r"); + char *line_1 = NULL, *line_2 = NULL, *line_3 = NULL; + size_t buf_len; + unsigned int prio_sum = 0; + + while (!feof(input)) { + if (getline(&line_1, &buf_len, input) != -1 + && getline(&line_2, &buf_len, input) != -1 + && getline(&line_3, &buf_len, input) != -1) { + + // Get line lengths + size_t len_1 = strlen(line_1); + if (len_1 > 2 && line_1[len_1 - 1] == '\n') { + // Truncate + line_1[len_1 - 1] = 0; + len_1 -= 1; + } + size_t len_2 = strlen(line_2); + if (len_2 > 2 && line_2[len_2 - 1] == '\n') { + // Truncate + line_2[len_2 - 1] = 0; + len_2 -= 1; + } + size_t len_3 = strlen(line_3); + if (len_3 > 2 && line_3[len_3 - 1] == '\n') { + // Truncate + line_3[len_3 - 1] = 0; + len_3 -= 1; + } + + // Sort all three sacks + qsort(line_1, len_1, sizeof(char), compare_char); + qsort(line_2, len_2, sizeof(char), compare_char); + qsort(line_3, len_3, sizeof(char), compare_char); + + // Spin over the three compartments and find any duplicates + for (int i = 0, j = 0, k = 0;i < len_1 && j < len_2 && k < len_3;i++) { + // Run to the end of the current run + while (i < (len_1 - 1) && line_1[i] == line_1[i + 1]) + i++; + + // Skip any characters less than first_half[i] + while (j < len_2 && line_2[j] < line_1[i]) + j++; + while (k < len_3 && line_3[k] < line_1[i]) + k++; + + //printf("Comparing %c, %c, %c\n", line_1[i], line_2[j], line_3[k]); + + if (j < len_2 && k < len_3 && line_1[i] == line_2[j] && line_1[i] == line_3[k]) { + char dup = line_1[i]; + if (dup >= 'a' && dup <= 'z') { + prio_sum += dup - 96; + } else { + prio_sum += dup - 38; + } + } + } + + free(line_1); + free(line_2); + free(line_3); + line_1 = line_2 = line_3 = NULL; + } else { + free(line_1); + if (line_2) + free(line_2); + if (line_3) + free(line_3); + if (errno) { + strerror(NULL); + exit(EXIT_FAILURE); + } + } + } + printf("Priority sum: %i\n", prio_sum); + + fclose(input); +} diff --git a/4/4a.sno b/4/4a.sno @@ -0,0 +1,14 @@ + &TRIM = 1 + COUNT = 0 + DIGITS = '0123456789' + INPUT('IN', 1, , 'input') :S(START) + OUTPUT = "Couldn't open input" :(FINISH) +START LINE = IN :F(FINISH) + LINE SPAN(DIGITS) . S1START '-' SPAN(DIGITS) . S1END ',' SPAN(DIGITS) . S2START '-' SPAN(DIGITS) . S2END :F(START) + EQ(S1START, S2START) :S(COUNT) + LT(S1START, S2START) :S(S2INS1) + GE(S2END, S1END) :S(COUNT) F(START) +S2INS1 GE(S1END, S2END) :F(START) +COUNT COUNT = COUNT + 1 :(START) +FINISH OUTPUT = COUNT +END +\ No newline at end of file diff --git a/4/4b.sno b/4/4b.sno @@ -0,0 +1,14 @@ + &TRIM = 1 + COUNT = 0 + DIGITS = '0123456789' + INPUT('IN', 1, , 'input') :S(START) + OUTPUT = "Couldn't open input" :(FINISH) +START LINE = IN :F(FINISH) + LINE SPAN(DIGITS) . S1START '-' SPAN(DIGITS) . S1END ',' SPAN(DIGITS) . S2START '-' SPAN(DIGITS) . S2END :F(START) + EQ(S1START, S2START) :S(COUNT) + LT(S1START, S2START) :S(S1ENDINS2) + GE(S2END, S1START) :S(COUNT) F(START) +S1ENDINS2 GE(S1END, S2START) :F(START) +COUNT COUNT = COUNT + 1 :(START) +FINISH OUTPUT = COUNT +END +\ No newline at end of file diff --git a/5/Five.java b/5/Five.java @@ -0,0 +1,91 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +class Five { + private static void reverseList(ArrayList<Character> list) { + for (int idx = 0; idx < list.size() / 2; idx++) { + Character a = list.get(idx); + list.set(idx, list.get((list.size() - 1) - idx)); + list.set((list.size() - 1) - idx, a); + } + } + + private static void moveA(int n, ArrayList<Character> from, ArrayList<Character> to) { + for (int i = 0; i < n; i++) { + to.add(from.remove(from.size() - 1)); + } + } + + private static void moveB(int n, ArrayList<Character> from, ArrayList<Character> to) { + int rangeFrom = from.size() - n; + int rangeTo = from.size(); + if (rangeFrom < 0 || rangeTo < 0) { + System.err.println("Trying to move " + n + " boxes from " + from + " to " + to + "!"); + throw new RuntimeException("What the fuck"); + } + List<Character> toMove = from.subList(rangeFrom, rangeTo); + to.addAll(toMove); + for (int i = 0; i < n; i++) { + from.remove(from.size() - 1); + } + } + + public static void main(String[] args) { + Boolean isSecondStar = (args.length > 0) && (args[0].equals("2")); + Charset utf8 = Charset.forName("UTF-8"); + Path input = FileSystems.getDefault().getPath("input"); + try (BufferedReader reader = Files.newBufferedReader(input, utf8)) { + String line = null; + + // Read in the stacks + ArrayList<ArrayList<Character>> stacks = new ArrayList<ArrayList<Character>>(); + while ((line = reader.readLine()) != null && !line.equals("")) { + // Construct the initial columns based on the first part of the input + int col = 0; + while ((col * 4) < (line.length() - 1)) { + String box = line.substring(col * 4, col * 4 + 3); + Character boxName = box.charAt(1); + if ('A' <= boxName && 'Z' >= boxName) { + while (stacks.size() <= col) { + stacks.add(new ArrayList<Character>()); + } + stacks.get(col).add(boxName); + } else if ('0' <= boxName && '9' >= boxName) { + // Bottom of columns, just finish + break; + } + col++; + } + } + stacks.stream().forEach(Five::reverseList); + + // Loop over the instructions + while ((line = reader.readLine()) != null) { + String[] instr = line.split(" "); + if (!instr[0].equals("move")) { + throw new RuntimeException("Bad instruction!"); + } + int n = Integer.parseInt(instr[1]); + int from = Integer.parseInt(instr[3]); + int to = Integer.parseInt(instr[5]); + ArrayList<Character> fromList = stacks.get(from - 1); + ArrayList<Character> toList = stacks.get(to - 1); + if (isSecondStar) { + moveB(n, fromList, toList); + } else { + moveA(n, fromList, toList); + } + } + stacks.stream().map(stack -> stack.get(stack.size() - 1)).forEach(c -> System.out.print(c)); + System.out.println(); + } catch (IOException x) { + System.err.format("IOException: %s%n", x); + } + } +}