Day 25: Code Chronicle
Megathread guidelines
- Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
- You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL
FAQ
- What is this?: Here is a post with a large amount of details: https://programming.dev/post/6637268
- Where do I participate?: https://adventofcode.com/
- Is there a leaderboard for the community?: We have a programming.dev leaderboard with the info on how to join in this post: https://programming.dev/post/6631465
Haskell
A total inability to write code correctly today slowed me down a bit, but I got there in the end. Merry Christmas, everyone <3
import Data.Either
import Data.List
import Data.List.Split
readInput = partitionEithers . map readEntry . splitOn [""] . lines
where
readEntry ls =
(if head (head ls) == '#' then Left else Right)
. map (length . head . group)
$ transpose ls
main = do
(locks, keys) <- readInput <$> readFile "input25"
print . length $ filter (and . uncurry (zipWith (<=))) ((,) <$> locks <*> keys)
C
Merry Christmas everyone!
Code
#include "common.h"
int
main(int argc, char **argv)
{
static char buf[7];
static short h[500][5]; /* heights */
static short iskey[500];
int p1=0, nh=0, i,j,k;
if (argc > 1)
DISCARD(freopen(argv[1], "r", stdin));
for (nh=0; !feof(stdin) && !ferror(stdin); nh++) {
assert(nh < (int)LEN(h));
for (i=0; i<7; i++) {
fgets(buf, 7, stdin);
if (i==0)
iskey[nh] = buf[0] == '#';
for (j=0; j<5; j++)
h[nh][j] += buf[j] == '#';
}
/* skip empty line */
fgets(buf, 7, stdin);
}
for (i=0; i<nh; i++)
for (j=0; j<nh; j++)
if (iskey[i] && !iskey[j]) {
for (k=0; k<5 && h[i][k] + h[j][k] <= 7; k++) ;
p1 += k == 5;
}
printf("25: %d\n", p1);
return 0;
}
https://codeberg.org/sjmulder/aoc/src/branch/master/2024/c/day25.c
Made the 1 second challenge with most of it to spare! π
$ time bmake bench
day01 0:00.00 1912 Kb 0+88 faults
day02 0:00.00 1992 Kb 0+91 faults
day03 0:00.00 1920 Kb 0+93 faults
day04 0:00.00 1912 Kb 0+90 faults
day05 0:00.00 2156 Kb 0+91 faults
day06 0:00.03 1972 Kb 0+100 faults
day07 0:00.06 1892 Kb 0+89 faults
day08 0:00.00 1772 Kb 0+87 faults
day09 0:00.02 2024 Kb 0+137 faults
day10 0:00.00 1876 Kb 0+87 faults
day11 0:00.00 6924 Kb 0+3412 faults
day12 0:00.00 1952 Kb 0+103 faults
day13 0:00.00 1908 Kb 0+88 faults
day14 0:00.05 1944 Kb 0+92 faults
day15 0:00.00 2040 Kb 0+89 faults
day16 0:00.03 2020 Kb 0+250 faults
day17 0:00.00 1896 Kb 0+88 faults
day18 0:00.00 1952 Kb 0+107 faults
day19 0:00.01 1904 Kb 0+91 faults
day20 0:00.01 2672 Kb 0+325 faults
day21 0:00.00 1804 Kb 0+86 faults
day22 0:00.03 2528 Kb 0+371 faults
day23 0:00.02 2064 Kb 0+152 faults
day24 0:00.00 1844 Kb 0+89 faults
day25 0:00.00 1788 Kb 0+89 faults
real 0m0,359s
Dart
Quick and dirty, and slightly tipsy, code.
Happy Christmas everyone!
Thanks to Eric and the team at Advent of Code, to @Ategon@programming.dev and @CameronDev@programming.dev for giving us somewhere to share and discuss our solutions, and to everyone here for the friendly and supportive community.
See you all next year!
import 'package:collection/collection.dart';
import 'package:more/more.dart';
part1(List<String> lines) {
var (w, h) = (lines.first.length, lines.indexOf(''));
var (falsey: keys, truthy: locks) = (lines..insert(0, ''))
.splitBefore((l) => l.isEmpty)
.map((g) => [
for (var x in 0.to(w)) [for (var y in 1.to(h + 1)) g[y][x]]
])
.partition((g) => g[0][0] == '#');
return keys
.map((l) => locks.count((k) =>
0.to(w).every((r) => (l[r] + k[r]).count((e) => e == '#') < 8)))
.sum;
}
Haskell
Have a nice christmas if youβre still celebrating today, otherwise hope you had a nice evening yesterday.
import Control.Arrow
import Control.Monad (join)
import Data.Bifunctor (bimap)
import qualified Data.List as List
heights = List.transpose
>>> List.map (pred . List.length . List.takeWhile (== '#'))
parse = lines
>>> init
>>> List.groupBy (curry (snd >>> (/= "")))
>>> List.map (List.filter (/= ""))
>>> List.partition ((== "#####") . head)
>>> second (List.map List.reverse)
>>> join bimap (List.map heights)
cartesianProduct xs ys = [(x, y) | x <- xs, y <- ys]
part1 = uncurry cartesianProduct
>>> List.map (uncurry (List.zipWith (+)))
>>> List.filter (List.all (<6))
>>> List.length
part2 = const 0
main = getContents
>>= print
. (part1 &&& part2)
. parse
Haskell
Merry Christmas!
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Data.Either
import Data.Text hiding (all, head, zipWith)
import Data.Text qualified as T
import Data.Text.IO as TIO
type Pins = [Int]
toKeyLock :: [Text] -> Either Pins Pins
toKeyLock v = (if T.head (head v) == '#' then Left else Right) $ fmap (pred . count "#") v
solve keys locks = sum [1 | k <- keys, l <- locks, fit k l]
where
fit a b = all (<= 5) $ zipWith (+) a b
main = TIO.getContents >>= print . uncurry solve . partitionEithers . fmap (toKeyLock . transpose . T.lines) . splitOn "\n\n"