commit 26416fffb9bad00b9739f4b8f161ca37b712cb11 Author: Sijmen Schoon Date: Thu Dec 9 12:07:49 2021 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..552b246 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.in +.metals/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..c531c66 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Advent of Code 2021 + +| Day | Chicken Scheme | Scala | Python | Nim | | +|-----|----------------|--------|--------|-----|---| +| 1 | | | | | | +| 2 | | | | | | +| 3 | part 1 | part 1 | ✅ | | | +| 4 | | | ✅ | | | +| 5 | | | ✅ | | | +| 6 | | | | ✅ | | diff --git a/day03.py b/day03.py new file mode 100644 index 0000000..79c77dc --- /dev/null +++ b/day03.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +import fileinput +from copy import deepcopy + +numbers = [[int(i) for i in line.strip()] for line in fileinput.input()] +bit_count = len(numbers[0]) + +occurrences = [0] * bit_count +for number in numbers: + for i, bit in enumerate(number): + occurrences[i] += bit + +gamma, epsilon = 0, 0 +for i, freq in enumerate(occurrences): + shifted = 1 << (len(occurrences) - 1) >> i + if freq > len(numbers) // 2: + gamma |= shifted + else: + epsilon |= shifted + +print("part 1:", gamma * epsilon) + +most_common = deepcopy(numbers) +least_common = deepcopy(numbers) + +for i in range(bit_count): + ones = sum(number[i] for number in most_common) + lc = int(ones * 2 >= len(most_common)) + most_common = [number for number in most_common if number[i] == lc] + if len(most_common) == 1: + break + +for i in range(bit_count): + zeros = sum(not number[i] for number in least_common) + lc = int(zeros * 2 > len(least_common)) + least_common = [number for number in least_common if number[i] == lc] + if len(least_common) == 1: + break + +mc = int("".join(str(x) for x in most_common[0]), 2) +lc = int("".join(str(x) for x in least_common[0]), 2) +print("part 2:", mc * lc) diff --git a/day03.scala b/day03.scala new file mode 100644 index 0000000..1d1424d --- /dev/null +++ b/day03.scala @@ -0,0 +1,27 @@ +object day03 { + def main(args: Array[String]): Unit = { + val numbers = io.Source.stdin + .getLines() + .map(ln => ln.chars.map(_ - '0').toArray) + .toArray + + var occurences = Array.fill(numbers(0).length)(0) + for (number <- numbers) { + for ((bit, i) <- number.zipWithIndex) + occurences(i) += bit + } + + var gamma = 0 + var epsilon = 0 + for ((freq, i) <- occurences.zipWithIndex) { + val shifted = 1 << occurences.length - 1 >> i + if (freq > (numbers.length / 2)) + gamma |= shifted + else + epsilon |= shifted + } + + val part1 = gamma * epsilon + println(s"part1: $part1") + } +} diff --git a/day03.scm b/day03.scm new file mode 100644 index 0000000..c886379 --- /dev/null +++ b/day03.scm @@ -0,0 +1,17 @@ +(import (chicken string)) +(import (chicken format)) +(import (chicken io)) +(import srfi-14) +(import srfi-60) + +(define (add-lines l r) + (map (lambda (l r) (+ l (- (char->integer r) 48))) l r)) + +(define lines (map string->list (read-lines))) +(define counts (foldl add-lines (map (lambda (_) 0) (car lines)) lines)) + +(define hl (/ (length lines) 2)) +(define gamma (list->integer (map (lambda (x) (> x hl)) counts))) +(define epsilon (list->integer (map (lambda (x) (< x hl)) counts))) + +(format #t "part 1: ~A~%" (* gamma epsilon)) diff --git a/day04.py b/day04.py new file mode 100644 index 0000000..9e95248 --- /dev/null +++ b/day04.py @@ -0,0 +1,86 @@ +import fileinput +from typing import List, Tuple, Set + +numbers = [int(x) for x in input().split(",")] +input() + +Board = List[List[int]] + +boards: List[Board] = [] +board: Board = [] + +while True: + try: + line = input().strip() + except EOFError: + break + + if line: + board.append([int(x) for x in line.split()]) + else: + boards.append(board) + board = [] + +if board: + boards.append(board) + + +def find_bingo(drawn: Set[int], wins: Set[int]) -> Tuple[int, int]: + for n in numbers: + drawn.add(n) + + for b, board in enumerate(boards): + for row in board: + for col in row: + if col not in drawn: + break + else: + if b not in wins: + wins.add(b) + return b, n + + for x in range(len(board[0])): + for y in range(len(board)): + if board[y][x] not in drawn: + break + else: + if b not in wins: + wins.add(b) + return b, n + + raise RuntimeError("no bingo found") + + +def print_board(board, drawn=frozenset()): + for r in board: + for c in r: + if c in drawn: + print("\033[91m", end="") + print(str(c).rjust(4), end="\033[0m") + print() + print() + + +print(", ".join(str(n) for n in numbers)) +print() +for b in boards: + print_board(b) + +print("===") + +drawn = set() +wins = set() + +b, last_drawn = find_bingo(drawn, wins) +undrawn = sum(number for row in boards[b] for number in row if number not in drawn) +part1 = last_drawn * undrawn + +while len(wins) < len(boards): + b, last_drawn = find_bingo(drawn, wins) + print_board(boards[b], drawn) + +undrawn = sum(number for row in boards[b] for number in row if number not in drawn) +part2 = last_drawn * undrawn + +print("part1:", part1) +print("part2:", part2) diff --git a/day05.py b/day05.py new file mode 100755 index 0000000..46b9476 --- /dev/null +++ b/day05.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 +import fileinput + +N = 1000 + + +def main(): + diag = [[0] * N for _ in range(N)] + + vents = [ + [ + tuple(int(coord) for coord in coords.split(",")) + for coords in str(line).split(" -> ") + ] + for line in fileinput.input() + ] + + for (x1, y1), (x2, y2) in vents: + xsign = -1 if x2 < x1 else 1 + ysign = -1 if y2 < y1 else 1 + + if x1 == x2: + # vertical line + for y in range(y1, y2 + ysign, ysign): + diag[y][x1] += 1 + elif y1 == y2: + # horizontal line + for x in range(x1, x2 + xsign, xsign): + diag[y1][x] += 1 + + part1 = sum(point >= 2 for row in diag for point in row) + print("part 1:", part1) + + for (x1, y1), (x2, y2) in vents: + xsign = -1 if x2 < x1 else 1 + ysign = -1 if y2 < y1 else 1 + + if x1 != x2 and y1 != y2: + # diagonal line + y = y1 + for x in range(x1, x2 + xsign, xsign): + diag[y][x] += 1 + y += ysign + + part2 = sum(point >= 2 for row in diag for point in row) + print("part 2:", part2) + + +if __name__ == "__main__": + main() diff --git a/day06.nim b/day06.nim new file mode 100644 index 0000000..1b60d1e --- /dev/null +++ b/day06.nim @@ -0,0 +1,16 @@ +from std/strutils import split, parseInt +from std/sequtils import map, foldl + +let numbers = readLine(stdin).split(',').map(parseInt) +var buckets: array[9, int] + +for number in numbers: + buckets[number] += 1 + +for i in 0..<256: + buckets[(i + 7) mod 9] += buckets[i mod 9] + + if i == 79: + echo("part 1: ", buckets.foldl(a + b)) + +echo("part 2: ", buckets.foldl(a + b))