initial commit

This commit is contained in:
Sijmen Schoon 2021-12-09 12:07:49 +01:00
commit 26416fffb9
Signed by: vijfhoek
GPG key ID: DAF7821E067D9C48
8 changed files with 250 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.in
.metals/

10
README.md Normal file
View file

@ -0,0 +1,10 @@
# Advent of Code 2021
| Day | Chicken Scheme | Scala | Python | Nim | |
|-----|----------------|--------|--------|-----|---|
| 1 | | | | | |
| 2 | | | | | |
| 3 | part 1 | part 1 | ✅ | | |
| 4 | | | ✅ | | |
| 5 | | | ✅ | | |
| 6 | | | | ✅ | |

42
day03.py Normal file
View file

@ -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)

27
day03.scala Normal file
View file

@ -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")
}
}

17
day03.scm Normal file
View file

@ -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))

86
day04.py Normal file
View file

@ -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)

50
day05.py Executable file
View file

@ -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()

16
day06.nim Normal file
View file

@ -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))