commit ea1a403cae04ab96ecd127ce76bf03d321e09bf6
parent 8ef4f7d2a088937384a42d8b145d6822a874b3a7
Author: Louis Burda <quent.burda@gmail.com>
Date: Sun, 20 Dec 2020 18:54:30 +0100
added test script, reordered dirs in aoc lib, added day20 (needs some cleaning)
Diffstat:
M | lib/aoc.zig | | | 9 | +++++++-- |
A | scripts/test | | | 9 | +++++++++ |
A | src/day20/input | | | 1728 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/day20/input-test | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/day20/input-test2 | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/day20/main.zig | | | 463 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/day20/part1 | | | 183 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | src/day20/part2 | | | 110 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
8 files changed, 2716 insertions(+), 2 deletions(-)
diff --git a/lib/aoc.zig b/lib/aoc.zig
@@ -72,9 +72,9 @@ pub const Dir = struct {
pub const North = Pos{ .x = 0, .y = 1 };
pub const Name = enum {
- EAST = 0, WEST = 1, SOUTH = 2, NORTH = 3
+ NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3
};
- pub const dirs = [_]Pos{ East, South, West, North };
+ pub const dirs = [_]Pos{ North, East, South, West };
pub fn get(name: Name) Pos {
return dirs[@enumToInt(name)];
@@ -113,3 +113,8 @@ pub const Dir = struct {
};
}
};
+
+pub fn assertV(v: anytype) !@TypeOf(v.?) {
+ if (v == null) return Error.InvalidInput;
+ return v.?;
+}
diff --git a/scripts/test b/scripts/test
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+[ -z "$REPOROOT" ] && exit 1
+
+[ ! -e "$REPOROOT/cache" ] && mkdir "$REPOROOT/cache"
+zig test --cache-dir "$REPOROOT/cache" \
+ --pkg-begin "console8" "$REPOROOT/lib/console8.zig" --pkg-end \
+ --pkg-begin "aoc" "$REPOROOT/lib/aoc.zig" --pkg-end \
+ main.zig
diff --git a/src/day20/input b/src/day20/input
@@ -0,0 +1,1728 @@
+Tile 2539:
+#.##......
+##......#.
+#.#...#..#
+###..#...#
+....#.#.##
+#........#
+..#..###.#
+#..#..#...
+.....#####
+##.##..##.
+
+Tile 2909:
+....##..#.
+#........#
+....##....
+..###..#..
+#..#......
+#...#..###
+.........#
+#...#...#.
+....#.....
+.##..##.##
+
+Tile 1373:
+#..###.##.
+#......#.#
+..#.....##
+..##.#...#
+........##
+....#...#.
+..........
+#..##.#.#.
+.....#...#
+..##.#....
+
+Tile 2953:
+######....
+........#.
+..#.......
+#.#.......
+##........
+##........
+..#.....##
+#.#......#
+##..#....#
+#.####.###
+
+Tile 2437:
+#..##..##.
+.....#...#
+#.#..##...
+.#......##
+#.....#..#
+#......#..
+...#.#...#
+#...#....#
+#.........
+.##.....#.
+
+Tile 1823:
+##.....###
+##.#..#..#
+....##....
+#.........
+..#.....#.
+#..#......
+..#.......
+..#.#....#
+.....#..#.
+####....#.
+
+Tile 3889:
+..##...#.#
+#........#
+#.......##
+.......###
+..........
+....#..#..
+..#...#..#
+.##...#..#
+##.....#.#
+.######.#.
+
+Tile 2549:
+..#.#.###.
+..........
+.........#
+#........#
+#.........
+#..#....##
+..........
+#.....#...
+#.#...####
+#...#####.
+
+Tile 3797:
+#.#.#..#..
+#........#
+.#.##.....
+#........#
+#........#
+#.........
+#.#...##..
+#..#.....#
+#.#.##....
+.#######..
+
+Tile 1249:
+.##..##...
+.....#....
+#....#...#
+..#......#
+###..#...#
+...#....#.
+#.....#..#
+.#.#......
+#.#.##.#.#
+#.#.##..#.
+
+Tile 3821:
+.####.##.#
+.........#
+#...##...#
+.##.#...##
+##..#.##..
+.....#.#.#
+..#...#.##
+#.......##
+...#.....#
+....#.###.
+
+Tile 3329:
+##.##.###.
+......#...
+...#....##
+....#....#
+#.........
+..#...#...
+....#.....
+..#......#
+..........
+...#.##..#
+
+Tile 1279:
+##...#....
+#.#.#...##
+.#..#...#.
+.#....#.#.
+.##......#
+.........#
+##......##
+..........
+.#........
+..#..##...
+
+Tile 3907:
+.#....##.#
+#.#...###.
+##.....###
+##......#.
+..####....
+.#...#....
+#....#..#.
+#.#.......
+.#......#.
+##....###.
+
+Tile 3833:
+....#.###.
+.......#.#
+...#...#..
+#.#.......
+..#.....##
+#.........
+.....#.#..
+#.....#...
+..#..#....
+.#####....
+
+Tile 2011:
+.#...#...#
+#.#.......
+#..#....##
+.....#....
+.......#..
+.#.......#
+......#.#.
+#.##...###
+##..#..###
+###..#.###
+
+Tile 3881:
+###..#...#
+#..#.....#
+##..#...##
+.....#.##.
+.........#
+.#.......#
+....#..#.#
+..#.....##
+##......##
+...#..#.#.
+
+Tile 2341:
+.....##.#.
+#....#..#.
+....#.#...
+#.....#...
+.....#....
+#.......#.
+.........#
+##....#..#
+.........#
+##.#..###.
+
+Tile 2917:
+###.##....
+##.......#
+#........#
+#......#..
+#.........
+........##
+.........#
+....#....#
+#.##...#..
+..#######.
+
+Tile 2333:
+#####.....
+.....#...#
+....##...#
+..........
+...#...#.#
+....##....
+....#.....
+.......#..
+###....#.#
+..##.#..#.
+
+Tile 2287:
+.#..#.#.#.
+##...#....
+....#.....
+.......#..
+.....#...#
+#....#.###
+.........#
+#.##..###.
+#......#.#
+.##.#.#.##
+
+Tile 3391:
+#..#.#..#.
+......#...
+#......#..
+#.#.#....#
+....#....#
+#..#....##
+....#....#
+..#.....##
+#........#
+.###.#..##
+
+Tile 2677:
+#..#.#....
+..#...#..#
+#...##...#
+##.......#
+.........#
+..........
+#...##.###
+#....#....
+..##..#.#.
+...#...##.
+
+Tile 2273:
+.###.####.
+##.##...##
+.....###.#
+#..#..#..#
+.##......#
+#.#..#...#
+#........#
+#.........
+........##
+####.#....
+
+Tile 3967:
+....#..##.
+..#......#
+#....##...
+#.....#.##
+...#...#.#
+#.#.#..##.
+#.......#.
+#.......##
+...##.#..#
+...#.#..##
+
+Tile 1553:
+.###.#..#.
+##...#....
+.....#...#
+......#.##
+.........#
+..........
+#..##.#..#
+#...#.....
+#.........
+..#..##..#
+
+Tile 1291:
+.#.......#
+..#......#
+......#..#
+##.#..#..#
+##........
+..........
+.........#
+......#.#.
+##....#.##
+##...#.#.#
+
+Tile 2003:
+..####.##.
+##.##....#
+#......##.
+.........#
+..........
+...#.##..#
+#.#.....#.
+..#.#....#
+#..#.....#
+..##..##.#
+
+Tile 2267:
+..#...#...
+...#....#.
+#..#..#...
+#...#.....
+...#.....#
+.#........
+#.#...#..#
+...#..#...
+#.#......#
+.####.#...
+
+Tile 1237:
+#.#....##.
+.......#.#
+.....#....
+...#.##...
+....#.....
+#.#.#....#
+#..#......
+##........
+#.........
+#.#.##..#.
+
+Tile 3187:
+#.####..##
+.....#....
+#..#......
+.#.#......
+..##....##
+..#......#
+...#.#....
+#........#
+.....##.#.
+.###.#.##.
+
+Tile 2393:
+#.#.###.##
+#.........
+#..#.#...#
+#.#.......
+#.#....#.#
+#.#...#...
+...#.....#
+#.#....#.#
+#...#....#
+..#.###...
+
+Tile 3413:
+.##...#...
+#.....#...
+#.........
+#..#..#..#
+#....#.#..
+##..#.....
+#.....####
+#........#
+....##....
+###.###.##
+
+Tile 3083:
+#####.####
+#..##.....
+..........
+........#.
+.#.......#
+.........#
+#...#.#..#
+#....##.#.
+##..#.##.#
+....####.#
+
+Tile 1523:
+###..##..#
+.#.#..#..#
+....#...##
+.....#....
+#..#.....#
+#....#...#
+........##
+..........
+##.....#..
+#.#..##..#
+
+Tile 3673:
+#.####.###
+#........#
+.#...#..#.
+.........#
+##.....#..
+..........
+#.........
+......#..#
+##.#.....#
+.#..##..##
+
+Tile 2111:
+#.#.#.####
+......#.#.
+..#......#
+........##
+#.....##..
+.........#
+#..#......
+........#.
+#........#
+..#..#.#..
+
+Tile 1153:
+.#.#..#..#
+#.....##..
+...#.....#
+...#.....#
+#..#.....#
+##.#......
+#.####....
+#........#
+#.........
+..#.....#.
+
+Tile 3457:
+..#......#
+#.##...#..
+#.........
+...#...##.
+....#.....
+.#........
+#........#
+......##.#
+..........
+#.#.....#.
+
+Tile 2693:
+.####.....
+#........#
+..#....#..
+.......###
+..#...#...
+.....##...
+#.#.#....#
+#.#.......
+##.##.#..#
+.####.#..#
+
+Tile 1367:
+##...##.#.
+.......#..
+...#..#...
+#....#....
+##........
+##....##.#
+#......#.#
+#...#.##.#
+#...#.#..#
+.##.....##
+
+Tile 2543:
+#..###.#.#
+#....###.#
+##......#.
+...#.....#
+#....#..##
+......#..#
+#..#.#.#..
+...#....#.
+....##.###
+#...######
+
+Tile 1229:
+#.#....##.
+#...#...##
+.##.......
+#...#..#.#
+#.#.#..#..
+#..#..#..#
+##....#...
+#...#...##
+#.#.......
+##.#.#..#.
+
+Tile 2833:
+.#...#..#.
+........#.
+#.#..#....
+...##..#.#
+#....#....
+........##
+.........#
+.........#
+#........#
+.###.#.#.#
+
+Tile 2089:
+.####.###.
+..###....#
+#....#.#..
+##........
+..#......#
+###...#..#
+###...#.##
+......#...
+#.........
+.###...##.
+
+Tile 3209:
+.######..#
+.#......#.
+#.#.#.....
+##.....#.#
+#......###
+##...##...
+......#...
+#.#.......
+#..#....#.
+...#...###
+
+Tile 1979:
+#...###.##
+#.......##
+#.#.#....#
+....#.....
+...#.#..##
+#.##...#..
+##.#.....#
+#...#.....
+.....#....
+....##..#.
+
+Tile 3779:
+##.##..#..
+..#......#
+#.#.....#.
+.#........
+#...##..##
+##.....#..
+...#.#....
+##........
+#..#...#..
+.###.##.##
+
+Tile 3089:
+##.#.##..#
+#..#......
+..#......#
+...#....#.
+#.#.......
+..........
+#.....#...
+#........#
+#......#.#
+.####.##.#
+
+Tile 1627:
+#..#....#.
+.#.####.#.
+#...#.....
+...##.#.##
+....#...#.
+...#.##.##
+.......#.#
+#..#..#..#
+#.....##.#
+#...##.#.#
+
+Tile 2389:
+.##...#.#.
+#..#..#...
+#.........
+.........#
+.....#....
+....#...#.
+.#.#...#.#
+....###..#
+#....##.#.
+####..#.##
+
+Tile 1193:
+.#.##.####
+.#......##
+#...##...#
+..##..#.#.
+..........
+.....##.##
+#......#..
+...#.##...
+....#..##.
+##.#######
+
+Tile 3323:
+#..#...###
+........#.
+##.....#.#
+#....#...#
+....#.....
+#...#..#..
+#.........
+.#.....#.#
+..#......#
+#..#.#....
+
+Tile 2719:
+####......
+..#.....#.
+.#....#...
+#...#..#..
+#.........
+#......#..
+#..#....##
+.....#....
+#.##...##.
+#.#.#..#.#
+
+Tile 2399:
+#..##.####
+.........#
+#.........
+...#...##.
+.........#
+#...#....#
+..........
+........##
+..........
+.#.#...#..
+
+Tile 1543:
+##..#.####
+....#....#
+....######
+#..####.##
+...##..#..
+#..#.#...#
+#.#.......
+...#....#.
+##..###.#.
+#.##.....#
+
+Tile 1723:
+.#.##..#..
+...#....#.
+...#......
+##....#.##
+.#....##..
+#.#......#
+##.##....#
+.....#...#
+..#.......
+#..#.##..#
+
+Tile 2503:
+..###...##
+..........
+#..#.##..#
+...#.#...#
+...###..##
+.....#....
+#.....#..#
+.#.#.#.##.
+#......#.#
+..####..##
+
+Tile 2887:
+......##.#
+##........
+.#........
+#.......##
+#.##...##.
+#...#...##
+##.....##.
+....#.....
+........##
+#.######..
+
+Tile 3467:
+#..#..#.#.
+....###...
+....##...#
+....#.#...
+..........
+........#.
+......#.#.
+#.#...#..#
+#........#
+#.##.##.##
+
+Tile 3677:
+....##...#
+#.##..#...
+.#....##..
+.#.#......
+#.##..#...
+....#.....
+......#.#.
+#..###..#.
+#.#....#..
+.####.##..
+
+Tile 1493:
+.##.#...##
+#.##...##.
+.#...#####
+#..#....#.
+#.#......#
+.........#
+##......#.
+#......#.#
+#....#.#.#
+#.#...#..#
+
+Tile 2687:
+.##.##..##
+.......#.#
+#........#
+##...##..#
+...#....##
+.....#.#..
+#.##.#.#.#
+#.........
+#....#...#
+###.....##
+
+Tile 1861:
+####..##..
+...#..#...
+.......#.#
+#.........
+#.........
+#........#
+...#.....#
+#.#......#
+#.#..##.#.
+.#..#..#.#
+
+Tile 2081:
+#..#####.#
+...#.....#
+.#......#.
+#........#
+.......#.#
+#....####.
+#....###.#
+.#....####
+....#.....
+.##.##...#
+
+Tile 2113:
+#..#..##..
+.#.....##.
+.....#.#.#
+#........#
+.......#.#
+...##.##..
+......##..
+#....#.#.#
+#.....#..#
+#...#..#.#
+
+Tile 2203:
+.#.##..#.#
+....###..#
+.#.#....##
+#...#.....
+##.#...#.#
+..#..#..#.
+#..#......
+#......#..
+#...###...
+.#...##.#.
+
+Tile 3943:
+#....###..
+#.....##.#
+#....#...#
+#..#....##
+###..#...#
+.#.#.#...#
+.......##.
+#....##..#
+.#.......#
+.#..#.#.##
+
+Tile 2579:
+.#...###..
+#.........
+#........#
+.......#.#
+##.#......
+....#....#
+#.......#.
+.#...#....
+.....#...#
+..#.##..##
+
+Tile 1103:
+.#.##.###.
+#......#.#
+....#....#
+....#.#...
+#......#.#
+..........
+..........
+#...#....#
+#........#
+....#####.
+
+Tile 1993:
+.##..#....
+....#.#..#
+##...#....
+.........#
+#...#....#
+..........
+..#..#.#..
+.....##...
+.##...##.#
+..##.##...
+
+Tile 1801:
+#..##.####
+#.......##
+#......#.#
+#.#....#.#
+#.##....#.
+.#..#.###.
+...#......
+#.....##.#
+.#.......#
+##.###..##
+
+Tile 3319:
+.###.##.#.
+##......#.
+.#........
+#.#......#
+#..#...#.#
+#.#......#
+.#.......#
+#........#
+#......#..
+....###..#
+
+Tile 3229:
+###...###.
+#....##..#
+....#...##
+...#......
+..#.#....#
+.......#.#
+......#.#.
+.##..#.#.#
+...#..###.
+##...#.#..
+
+Tile 1033:
+#..#.##.##
+....##....
+#.......#.
+#......#.#
+#........#
+##.......#
+#..##..#.#
+.......###
+#.........
+.##.#.#..#
+
+Tile 3769:
+###...#.##
+........#.
+#.........
+#........#
+..#.#.####
+#...#...##
+.#.#.....#
+..........
+#........#
+#.##.#...#
+
+Tile 1571:
+.####.....
+#......#.#
+#.#.#.#.#.
+.........#
+##.......#
+.......#.#
+..#.....#.
+#.........
+#..#....#.
+######...#
+
+Tile 1657:
+...#.#.##.
+........##
+#.........
+#.#..#....
+#..#.#.#.#
+...#.###..
+....#.....
+...#.....#
+#.....##.#
+#####.#.##
+
+Tile 3541:
+.####.####
+..........
+#......##.
+#......#..
+#........#
+#.....#..#
+........#.
+##.....#.#
+.......#..
+#.#.###.##
+
+Tile 3019:
+...##..##.
+#..##...#.
+#....##...
+#........#
+#..#.#...#
+#..#.....#
+.#........
+#.#..#...#
+...#.....#
+.#......##
+
+Tile 2383:
+.#.#....##
+#....#....
+......#..#
+#.....#..#
+#.##.#..#.
+#..#....##
+.....#...#
+....#...#.
+#.....#.#.
+.#.#.#.###
+
+Tile 3929:
+...#.###.#
+#.#..#....
+.........#
+..#......#
+.#......##
+#.....#.##
+#...#...##
+#.##......
+#.....##..
+#...##....
+
+Tile 1697:
+##.##.....
+...#.....#
+#..#.....#
+.........#
+...#...##.
+.#..#...##
+...###...#
+#..#..#...
+.#.#..#...
+..#...#...
+
+Tile 1999:
+..##....#.
+.........#
+...#.#...#
+#.........
+..#.#.#...
+#......#.#
+.#.##...#.
+#....#...#
+#....#.#.#
+#.#..##...
+
+Tile 1289:
+#..###....
+...#......
+....#.....
+#.....##.#
+#.##....#.
+...#.#..##
+#.#...#...
+..........
+..#......#
+####..###.
+
+Tile 1163:
+.###.#..#.
+#..#....#.
+#...#...##
+...#.....#
+#.....#...
+.........#
+..........
+###.......
+#........#
+###...####
+
+Tile 3121:
+##....#...
+#..#.#.#.#
+.#....#...
+..#......#
+#....#.#..
+.##......#
+......#.##
+....#.#...
+...#......
+#...#...#.
+
+Tile 2939:
+..##.#.###
+#....##..#
+....#..###
+###....#..
+#..###..#.
+..##.....#
+#..#....##
+..#.#.....
+#......#..
+.#.#.#..##
+
+Tile 1129:
+....#..#.#
+#........#
+...#.#....
+...#...#.#
+#........#
+..........
+..#...####
+...#.#....
+#....#..##
+##.#.##..#
+
+Tile 1877:
+..##..#...
+#.#...#...
+..#...##.#
+#......#..
+......#.##
+.##....#.#
+....#..#..
+......#...
+#..#..#..#
+#..#..##..
+
+Tile 3061:
+..#.#.....
+.#........
+..........
+#...#.#...
+..#......#
+........##
+#......#..
+#..#.....#
+#.#....#..
+.####.#.##
+
+Tile 2851:
+.#####..##
+..##...###
+#......#..
+.#..#....#
+.....###..
+.........#
+.......###
+.....#.###
+#......#..
+.##.##..##
+
+Tile 1409:
+##.##..###
+#.........
+#...###..#
+.........#
+........##
+#.#.#...#.
+.#...#.##.
+....#..#..
+#..#...#.#
+#.###.....
+
+Tile 3853:
+...###.#.#
+##.#......
+.....##.#.
+.#.......#
+....#....#
+#.#.#..#.#
+....##....
+........##
+#.#.......
+.#.#.##.##
+
+Tile 2803:
+.#...####.
+#..##...#.
+#.#..#....
+.....#...#
+.........#
+#....##...
+#........#
+##....#...
+#..#..#..#
+..#.#...##
+
+Tile 1709:
+....#.....
+.........#
+.........#
+....#....#
+..##.#....
+....#.....
+#.#.......
+#.......##
+#...#....#
+.#.....#.#
+
+Tile 2351:
+..#.#.#...
+##.......#
+....#.#...
+......#..#
+..........
+.......#.#
+##........
+#.......#.
+.....#..#.
+.#...##..#
+
+Tile 2347:
+###..#..##
+###......#
+#..##.#.##
+#...#...#.
+#.........
+.....#.###
+...#....##
+#......#..
+#.#.##...#
+.###..#...
+
+Tile 1307:
+##..#####.
+.#....#..#
+..........
+#...#..#..
+.....#....
+#.##.#...#
+###..##.#.
+.##.#..#.#
+#.#.#.....
+..######.#
+
+Tile 1901:
+######..#.
+##.#.....#
+#....#.#.#
+........#.
+....#....#
+#.......##
+#........#
+.......#.#
+.#..##...#
+.#.#.#####
+
+Tile 2029:
+#...##.##.
+#........#
+##....##.#
+#.#..#....
+.##..#....
+.#....#...
+.##......#
+..........
+##..#.....
+#.......##
+
+Tile 3571:
+##...#.#.#
+##....#..#
+....#.#...
+..#......#
+#......#.#
+..#....###
+..........
+#.#......#
+.##.....##
+.##.#...##
+
+Tile 1399:
+...###...#
+......#..#
+##...#.#.#
+#........#
+#.#.#.#..#
+....####..
+#.....#..#
+.....#.#.#
+#......#.#
+#...#..#.#
+
+Tile 1381:
+#..#....#.
+#....#...#
+......##..
+#....#...#
+..#.#...#.
+##..#....#
+#....#...#
+.....#....
+#.......##
+#####..#.#
+
+Tile 1549:
+##...####.
+........#.
+........#.
+..#...##.#
+.........#
+#.#.#.#..#
+.#.....#.#
+.....##.#.
+##.......#
+..#.##....
+
+Tile 3623:
+..#....###
+...#...#..
+.......#..
+.##......#
+..#..##...
+.........#
+#...#.....
+..#......#
+..#......#
+..##..###.
+
+Tile 2143:
+#.#..#.#..
+#...#...#.
+#......#..
+.#..#...##
+#.....#.##
+......##.#
+..#.#...#.
+..........
+#...#....#
+#....#..##
+
+Tile 3631:
+#######...
+#.......##
+..........
+.....##..#
+........##
+#..#.#....
+.......#.#
+........#.
+#.......#.
+..####..##
+
+Tile 3359:
+#..#...#..
+...#......
+...#.#.#.#
+.......#..
+...#.#....
+##.....#.#
+#.........
+#..#......
+#........#
+#.....#.##
+
+Tile 2239:
+......#.#.
+###.#.....
+.#....#...
+..##......
+##.####..#
+..........
+..#...#..#
+#..##....#
+##...#....
+##.#.#...#
+
+Tile 1741:
+....###.##
+##...#...#
+....##...#
+#.......##
+#.#.......
+...###...#
+#.......#.
+.##....#..
+#.........
+..###.####
+
+Tile 1597:
+..#..###..
+#...##.###
+#.#..#....
+#.#...#..#
+#....#...#
+#.......##
+......#..#
+##...##...
+#.####....
+..#.#....#
+
+Tile 3761:
+#.###.####
+..#.#.#..#
+....#.##.#
+.###....#.
+#......#.#
+#......#..
+#.#......#
+##.......#
+#.#.......
+.#..#.#.#.
+
+Tile 3203:
+#......#.#
+#.....#...
+#.#.#..#..
+......#...
+#..##.....
+##...#...#
+.....#...#
+..#...#..#
+#.........
+.#.#..###.
+
+Tile 1579:
+###.#.....
+.#.###..#.
+.....###.#
+#...#.##.#
+...#..#...
+...#.....#
+...#.....#
+#.......##
+..#.#..#..
+###.....#.
+
+Tile 3617:
+#......#..
+#.....#...
+.....#.##.
+#....#.#.#
+...#..#..#
+......#.#.
+#..##....#
+##....#...
+.#...#....
+#.....##.#
+
+Tile 1667:
+#.....#.##
+##....#..#
+..........
+##........
+.#..#.....
+#........#
+...#.#.#.#
+#.........
+.#........
+..#.#.###.
+
+Tile 2153:
+....##.##.
+........#.
+.#..#.....
+....###..#
+..##...#..
+.#.....###
+.#...###..
+#.#..#.##.
+..##....##
+####.#....
+
+Tile 1721:
+.###..##..
+#.#....#.#
+.....##..#
+#.........
+##...#...#
+#......#.#
+.#......##
+#........#
+...#...###
+####..#...
+
+Tile 3539:
+#.##.#.#.#
+.........#
+#..#.....#
+.....#....
+..#.......
+##.#....##
+..#.##...#
+........##
+#....#....
+#.#..#.#.#
+
+Tile 3313:
+...#..####
+.......#.#
+#........#
+.....#.#..
+#..#..##..
+#...#.....
+#..#...#.#
+...#......
+##....#.#.
+.#.###..#.
+
+Tile 3851:
+...#..##..
+#......#.#
+...#..##..
+#........#
+#....#...#
+#.....#..#
+#...##.##.
+##.......#
+.#.##..##.
+..###..#..
+
+Tile 3389:
+.####.##..
+.#...#..##
+..........
+.#......##
+.##.......
+###......#
+...#.#...#
+.....#...#
+#.#....#.#
+..####.#.#
+
+Tile 1933:
+..###.#..#
+..#......#
+#.#....#.#
+#..#......
+##...#....
+.....#....
+....#..#.#
+.#..##...#
+#......#..
+......#.#.
+
+Tile 1361:
+#..##...##
+..........
+.........#
+#.#......#
+#........#
+..##..#..#
+..#..#..##
+.....#....
+....#....#
+#.#.###.#.
+
+Tile 2789:
+.##.##.###
+#....#.#.#
+.....#.#..
+..........
+...#.#...#
+.........#
+....#.....
+......##..
+#......#..
+#.###.####
+
+Tile 3637:
+.##.##....
+###...#...
+###...#.#.
+..........
+###......#
+#.......##
+##.....###
+....###..#
+#.......#.
+...##..#.#
+
+Tile 2411:
+.##.#.###.
+......#.#.
+#...#..###
+##.#....##
+#.........
+..####....
+#..#.#...#
+..........
+#...#..#.#
+#.##...##.
+
+Tile 1487:
+...#.#...#
+.#..##...#
+#....#....
+###.###..#
+..##..#..#
+#..#......
+##...##...
+..#..#....
+.....#.#..
+.....##.##
+
+Tile 1061:
+.#####..#.
+#.......#.
+...#......
+....#...#.
+....#.#...
+#.###...#.
+....##...#
+###.....#.
+...##...#.
+#....#.#..
+
+Tile 1669:
+##...##..#
+#........#
+.#.#......
+.###.##...
+#...#.....
+..#.....##
+#...#..#.#
+#.##....#.
+#........#
+##.#.#.##.
+
+Tile 1123:
+...###...#
+....#.....
+#...#....#
+...#.....#
+#.........
+#....#..#.
+.........#
+.#....##.#
+......##.#
+#.#..#.#..
+
+Tile 2767:
+..###.####
+#...##....
+.........#
+.........#
+#....##...
+#.#.......
+.........#
+.#........
+#........#
+#...#...##
+
+Tile 1931:
+##..###...
+##..##..##
+..##..##..
+.#...#....
+...#......
+#...##....
+.#.......#
+...#.....#
+....#.....
+.#.#.###.#
+
+Tile 2731:
+...#.#..##
+..........
+..#......#
+##....#..#
+..#..#.#.#
+..........
+#.....#...
+.##.##.#..
+#....##...
+.###..#.#.
+
+Tile 2689:
+###.#..###
+.......###
+.#....#..#
+......##.#
+##...#...#
+........##
+#...#...##
+.........#
+....##....
+....##.#.#
+
+Tile 2897:
+#.........
+#.#...#...
+##.#......
+....#.##.#
+#........#
+#.......#.
+.#....#...
+.....#...#
+.....#..##
+..#.####.#
+
+Tile 3931:
+#.#..##.#.
+#......#..
+#...###.#.
+.##.##....
+#...###..#
+#...###...
+.....#.#.#
+#......##.
+.........#
+#.#######.
+
+Tile 1783:
+#......###
+.........#
+##....#..#
+.#..#.#.##
+........#.
+#..#......
+..........
+..........
+##...#...#
+...##.#.##
+
+Tile 2293:
+##...#...#
+..###.....
+.........#
+.........#
+..#..#....
+.....#...#
+#....##.#.
+#.........
+...#.....#
+.###..#.##
+
+Tile 3709:
+#####.###.
+.###......
+#..#....#.
+#........#
+##..#.#..#
+.#.......#
+.....#...#
+........#.
+####..##..
+.#..##.###
+
+Tile 2357:
+.#..###..#
+##..#....#
+.....#..##
+#...#.....
+..........
+##...#...#
+.#....#..#
+##.#....##
+....#.#...
+#.##.#...#
+
+Tile 3331:
+#.#..#.###
+#...##.###
+....#.#...
+..#..#...#
+.#.##..#.#
+#.....#.#.
+..#....#..
+#.#.##.#..
+#...###...
+##..####.#
+
+Tile 1297:
+..####.###
+#..#....#.
+#....#...#
+#.........
+###.#....#
+....#..#..
+.##.......
+.........#
+#..#......
+#...#.....
+
diff --git a/src/day20/input-test b/src/day20/input-test
@@ -0,0 +1,108 @@
+Tile 2311:
+..##.#..#.
+##..#.....
+#...##..#.
+####.#...#
+##.##.###.
+##...#.###
+.#.#.#..##
+..#....#..
+###...#.#.
+..###..###
+
+Tile 1951:
+#.##...##.
+#.####...#
+.....#..##
+#...######
+.##.#....#
+.###.#####
+###.##.##.
+.###....#.
+..#.#..#.#
+#...##.#..
+
+Tile 1171:
+####...##.
+#..##.#..#
+##.#..#.#.
+.###.####.
+..###.####
+.##....##.
+.#...####.
+#.##.####.
+####..#...
+.....##...
+
+Tile 1427:
+###.##.#..
+.#..#.##..
+.#.##.#..#
+#.#.#.##.#
+....#...##
+...##..##.
+...#.#####
+.#.####.#.
+..#..###.#
+..##.#..#.
+
+Tile 1489:
+##.#.#....
+..##...#..
+.##..##...
+..#...#...
+#####...#.
+#..#.#.#.#
+...#.#.#..
+##.#...##.
+..##.##.##
+###.##.#..
+
+Tile 2473:
+#....####.
+#..#.##...
+#.##..#...
+######.#.#
+.#...#.#.#
+.#########
+.###.#..#.
+########.#
+##...##.#.
+..###.#.#.
+
+Tile 2971:
+..#.#....#
+#...###...
+#.#.###...
+##.##..#..
+.#####..##
+.#..####.#
+#..#.#..#.
+..####.###
+..#.#.###.
+...#.#.#.#
+
+Tile 2729:
+...#.#.#.#
+####.#....
+..#.#.....
+....#..#.#
+.##..##.#.
+.#.####...
+####.#.#..
+##.####...
+##..#.##..
+#.##...##.
+
+Tile 3079:
+#.#.#####.
+.#..######
+..#.......
+######....
+####.#..#.
+.#...#.##.
+#.#####.##
+..#.###...
+..#.......
+..#.###...
+
diff --git a/src/day20/input-test2 b/src/day20/input-test2
@@ -0,0 +1,108 @@
+Tile 2311:
+..##.#..#.
+##..#.....
+#...##..#.
+####.#...#
+##.##.###.
+##...#.###
+.#.#.#..##
+..#....#..
+###...#.#.
+..###..###
+
+Tile 1951:
+#.##...##.
+#.####...#
+.....#..##
+#...######
+.##.#....#
+.###.#####
+###.##.##.
+.###....#.
+..#.#..#.#
+#...##.#..
+
+Tile 1171:
+####...##.
+#..##.#..#
+##.#..#.#.
+.###.####.
+..###.####
+.##....##.
+.#...####.
+#.##.####.
+####..#...
+.....##...
+
+Tile 1427:
+###.##.#..
+.#..#.##..
+.#.##.#..#
+#.#.#.##.#
+....#...##
+...##..##.
+...#.#####
+.#.####.#.
+..#..###.#
+..##.#..#.
+
+Tile 1489:
+##.#.#....
+..##...#..
+.##..##...
+..#...#...
+#####...#.
+#..#.#.#.#
+...#.#.#..
+##.#...##.
+..##.##.##
+###.##.#..
+
+Tile 2473:
+#....####.
+#..#.##...
+#.##..#...
+######.#.#
+.#...#.#.#
+.#########
+.###.#..#.
+########.#
+##...##.#.
+..###.#.#.
+
+Tile 2971:
+..#.#....#
+#...###...
+#.#.###...
+##.##..#..
+.#####..##
+.#..####.#
+#..#.#..#.
+..####.###
+..#.#.###.
+...#.#.#.#
+
+Tile 2729:
+...#.#.#.#
+####.#....
+..#.#.....
+....#..#.#
+.##..##.#.
+.#.####...
+####.#.#..
+##.####...
+##..#.##..
+#.##...##.
+
+Tile 3079:
+#.#.#####.
+.#..######
+..#.......
+######....
+####.#..#.
+.#...#.##.
+#.#####.##
+..#.###...
+..#.......
+..#.###...
+
diff --git a/src/day20/main.zig b/src/day20/main.zig
@@ -0,0 +1,463 @@
+const std = @import("std");
+const aoc = @import("aoc");
+
+const tile_width: u32 = 10;
+const Tile = struct {
+ id: u32,
+ data: [tile_width * tile_width]u1,
+ sides: [4][tile_width]u1, // NOTE: update these values when placed accordingly
+ adj: [4]?usize,
+ pos: aoc.Pos,
+};
+const Flip = enum { NONE, HOR, VERT };
+const flips = [_]Flip{ Flip.NONE, Flip.HOR, Flip.VERT };
+
+const seamonster = [_][]const u8{
+ " # ",
+ "# ## ## ###",
+ " # # # # # # ",
+};
+
+const dirs = [4]aoc.Pos{
+ aoc.Pos{ .x = 0, .y = -1 },
+ aoc.Pos{ .x = 1, .y = 0 },
+ aoc.Pos{ .x = 0, .y = 1 },
+ aoc.Pos{ .x = -1, .y = 0 },
+};
+
+fn printGrid(tiles: []Tile, grid: []?usize, grid_width: u32) void {
+ var y: u32 = 0;
+ while (y < grid_width * tile_width) : (y += 1) {
+ var x: u32 = 0;
+ if (y > 0 and y % tile_width == 0) std.debug.print("\n", .{});
+ while (x < grid_width * tile_width) : (x += 1) {
+ if (x > 0 and x % tile_width == 0) std.debug.print(" ", .{});
+ var tile_index: ?usize = grid[@divFloor(y, tile_width) * grid_width + @divFloor(x, tile_width)];
+ if (tile_index) |ti| {
+ var tile = tiles[tile_index.?];
+ var c: u8 = if (tile.data[(y % tile_width) * tile_width + (x % tile_width)] == 1) '#' else '.';
+ std.debug.print("{c}", .{c});
+ } else {
+ std.debug.print("?", .{});
+ }
+ }
+ std.debug.print("\n", .{});
+ }
+ std.debug.print("\n\n", .{});
+}
+
+fn printTile(data: []u1, width: u32) void {
+ var y: u32 = 0;
+ while (y < width) : (y += 1) {
+ printTileSlice(data[y * width .. (y + 1) * width]);
+ std.debug.print("\n", .{});
+ }
+}
+
+fn printTileSlice(slice: []const u1) void {
+ var i: u32 = 0;
+ while (i < slice.len) : (i += 1) {
+ var c: u8 = if (slice[i] == 1) '#' else '.';
+ std.debug.print("{c}", .{c});
+ }
+}
+
+fn couldMatch(side1: [tile_width]u1, side2: [tile_width]u1) bool {
+ var side1_cpy = side1;
+ if (std.mem.eql(u1, side1_cpy[0..], side2[0..])) return true;
+ std.mem.reverse(u1, side1_cpy[0..]);
+ if (std.mem.eql(u1, side1_cpy[0..], side2[0..])) return true;
+ return false;
+}
+
+fn parseTiles(tiles: *std.ArrayList(Tile), input: []u8) !void {
+ var tileit = std.mem.split(input, "\n\n");
+ while (tileit.next()) |tilestr| {
+ if (tilestr.len <= 1) continue;
+ var tile: Tile = undefined;
+ var lineit = std.mem.tokenize(tilestr, "\n");
+
+ // read tile id
+ var numstr = (try aoc.assertV(lineit.next()))[5..9];
+ tile.id = try std.fmt.parseInt(u32, numstr, 10);
+
+ // read tile data
+ var i: u32 = 0;
+ var line: []const u8 = undefined;
+ while (i < tile_width * tile_width) : (i += 1) {
+ if (i % tile_width == 0) line = try aoc.assertV(lineit.next());
+ tile.data[i] = @boolToInt(line[i % tile_width] == '#');
+ }
+
+ // read side bits
+ i = 0;
+ while (i < 4) : (i += 1) {
+ var sidebits: [tile_width]u1 = undefined;
+ for (sidebits) |_, k| {
+ sidebits[k] = switch (i) {
+ @enumToInt(aoc.Dir.Name.NORTH) => tile.data[k],
+ @enumToInt(aoc.Dir.Name.WEST) => tile.data[(tile_width - 1 - k) * tile_width],
+ @enumToInt(aoc.Dir.Name.EAST) => tile.data[tile_width - 1 + k * tile_width],
+ @enumToInt(aoc.Dir.Name.SOUTH) => tile.data[tile_width * tile_width - 1 - k],
+ else => unreachable,
+ };
+ }
+ tile.sides[i] = sidebits;
+ }
+
+ // init misc data
+ tile.adj = [_]?usize{ null, null, null, null };
+
+ try tiles.append(tile);
+ }
+}
+
+fn matchTiles(tiles: *std.ArrayList(Tile)) void {
+ // for each items's side, look for another item with a matching side
+ for (tiles.items) |*tile, tile_index| {
+ sides_loop: for (tile.sides) |_, i| {
+ for (tiles.items) |*otile, otile_index| {
+ if (tile_index == otile_index) continue;
+
+ for (otile.sides) |_, oi| {
+ if (tile.adj[i] == null and otile.adj[oi] == null and couldMatch(tile.sides[i], otile.sides[oi])) {
+ tile.adj[i] = otile_index;
+ otile.adj[oi] = tile_index;
+ continue :sides_loop;
+ }
+ }
+ }
+ }
+
+ if (aoc.debug) {
+ std.debug.print("{}:\nSIDES ", .{tile.id});
+ for (tile.sides) |side| {
+ for (side) |b| {
+ var c: u8 = if (b == 1) '#' else '.';
+ std.debug.print("{c}", .{c});
+ }
+ std.debug.print(" ", .{});
+ }
+ std.debug.print("\n", .{});
+ for (tile.adj) |adj, i| {
+ if (tile.adj[i] == null) {
+ std.debug.print("null ", .{});
+ } else {
+ var adjtile = tiles.items[adj.?];
+ std.debug.print("{} ", .{adjtile.id});
+ }
+ }
+ std.debug.print("\n\n", .{});
+ }
+ }
+}
+
+fn checkSides(tiles: []Tile, grid: []?usize, grid_width: u32, p: aoc.Pos, adj: [4]?usize, sides: [4][10]u1) bool {
+ var rot: u32 = 0;
+ while (rot < 4) : (rot += 1) {
+ const np = p.add(dirs[rot]);
+ std.debug.print("{}\n", .{@intToEnum(aoc.Dir.Name, @intCast(u2, rot))});
+ std.debug.print("{} {}\n", .{ np.x, np.y });
+
+ var side: ?[tile_width]u1 = undefined;
+ if (np.x < 0 or np.x >= grid_width or np.y < 0 or np.y >= grid_width) {
+ std.debug.print("Side is null\n", .{});
+ if (adj[rot] == null) {
+ continue;
+ } else {
+ std.debug.print("Side {} should be NULL!\n", .{@intToEnum(aoc.Dir.Name, @intCast(u2, rot))});
+ return false;
+ }
+ }
+
+ var ti: ?usize = grid[@intCast(u32, np.y * @intCast(i64, grid_width) + np.x)] orelse continue;
+
+ var otherside = tiles[ti.?].sides[aoc.Dir.nextCW(rot, 2)];
+ std.mem.reverse(u1, otherside[0..]);
+ printTileSlice(otherside[0..]);
+ std.debug.print(" vs ", .{});
+ printTileSlice(sides[rot][0..]);
+ std.debug.print("\n", .{});
+
+ if (!std.mem.eql(u1, otherside[0..], sides[rot][0..])) return false;
+ }
+ return true;
+}
+
+fn rotateData(newdata: *[]u1, olddata: []u1, width: u32, rot: usize) void {
+ for (olddata) |v, di| {
+ const dy = @divFloor(di, width);
+ const dx = di % width;
+ var nx = dx;
+ var ny = dy;
+ switch (rot) {
+ @enumToInt(aoc.Dir.Name.NORTH) => {},
+ @enumToInt(aoc.Dir.Name.EAST) => {
+ nx = width - 1 - dy;
+ ny = dx;
+ },
+ @enumToInt(aoc.Dir.Name.SOUTH) => {
+ nx = width - 1 - dx;
+ ny = width - 1 - dy;
+ },
+ @enumToInt(aoc.Dir.Name.WEST) => {
+ nx = dy;
+ ny = width - 1 - dx;
+ },
+ else => {},
+ }
+ newdata.*[ny * width + nx] = v;
+ }
+}
+
+fn flipData(data: []u1, width: u32, flip: Flip) void {
+ switch (flip) {
+ Flip.HOR => {
+ var y: u32 = 0;
+ while (y < width) : (y += 1) {
+ std.mem.reverse(u1, data[y * width .. (y + 1) * width]);
+ }
+ },
+ Flip.VERT => {
+ var x: u32 = 0;
+ while (x < width) : (x += 1) {
+ var y: u32 = 0;
+ while (y < width / 2) : (y += 1) {
+ std.mem.swap(u1, &data[x + y * width], &data[x + (width - 1 - y) * width]);
+ }
+ }
+ },
+ else => {},
+ }
+}
+
+fn manipulateAndPlace(allocator: *std.mem.Allocator, tiles: []Tile, grid: []?usize, grid_width: u32, p: aoc.Pos, tile_index: usize) !void {
+ var tile = &tiles[tile_index];
+
+ for (dirs) |_, rot| {
+ for (flips) |flip| {
+ // apply manipulation to only sides first for checking
+ var sides = tile.sides;
+ var tmp_sides = tile.sides;
+ var adj = tile.adj;
+ var tmp_adj = tile.adj;
+ switch (flip) {
+ Flip.HOR => {
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.NORTH)][0..]);
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.SOUTH)][0..]);
+ tmp_sides[@enumToInt(aoc.Dir.Name.WEST)] = sides[@enumToInt(aoc.Dir.Name.EAST)];
+ tmp_sides[@enumToInt(aoc.Dir.Name.EAST)] = sides[@enumToInt(aoc.Dir.Name.WEST)];
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.EAST)][0..]);
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.WEST)][0..]);
+ std.mem.swap(?usize, &adj[@enumToInt(aoc.Dir.Name.EAST)], &adj[@enumToInt(aoc.Dir.Name.WEST)]);
+ },
+ Flip.VERT => {
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.WEST)][0..]);
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.EAST)][0..]);
+ tmp_sides[@enumToInt(aoc.Dir.Name.NORTH)] = sides[@enumToInt(aoc.Dir.Name.SOUTH)];
+ tmp_sides[@enumToInt(aoc.Dir.Name.SOUTH)] = sides[@enumToInt(aoc.Dir.Name.NORTH)];
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.NORTH)][0..]);
+ std.mem.reverse(u1, tmp_sides[@enumToInt(aoc.Dir.Name.SOUTH)][0..]);
+ std.mem.swap(?usize, &adj[@enumToInt(aoc.Dir.Name.NORTH)], &adj[@enumToInt(aoc.Dir.Name.SOUTH)]);
+ },
+ else => {},
+ }
+ sides = tmp_sides;
+
+ for (dirs) |_, i| {
+ tmp_sides[i] = sides[aoc.Dir.nextCCW(i, rot)];
+ tmp_adj[i] = adj[aoc.Dir.nextCCW(i, rot)];
+ }
+
+ std.debug.print("\nROT: {}\n", .{rot});
+ std.debug.print("FLIP: {}\n", .{flip});
+ std.debug.print("SIDES: \n", .{});
+ for (tmp_sides) |side| {
+ printTileSlice(side[0..]);
+ std.debug.print("\n", .{});
+ }
+ const valid = checkSides(tiles, grid, grid_width, p, tmp_adj, tmp_sides);
+
+ // now apply manipulations to image data
+ if (valid) {
+ // for (tile.sides) |side| {
+ // printTileSlice(side[0..]);
+ // std.debug.print("\n", .{});
+ // }
+ std.debug.print("{} {} {}\n", .{ tile.id, flip, rot });
+ printTile(tile.data[0..], tile_width);
+ std.debug.print("\n", .{});
+ tile.sides = tmp_sides;
+ tile.pos = p;
+ tile.adj = tmp_adj;
+ grid[@intCast(u32, p.y * @intCast(i64, grid_width) + p.x)] = tile_index;
+
+ flipData(tile.data[0..], tile_width, flip);
+
+ var newdata = try allocator.alloc(u1, tile_width * tile_width);
+ defer allocator.free(newdata);
+
+ rotateData(&newdata, tile.data[0..], tile_width, rot);
+ std.mem.copy(u1, tile.data[0..], newdata);
+ return;
+ }
+ }
+ }
+ return aoc.Error.InvalidInput;
+}
+
+fn part1(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void {
+ var tiles = std.ArrayList(Tile).init(allocator);
+ defer tiles.deinit();
+
+ try parseTiles(&tiles, input);
+
+ matchTiles(&tiles);
+
+ var answer: u64 = 1;
+ for (tiles.items) |tile| {
+ var unknown: u32 = 0;
+ for (tile.adj) |v| {
+ unknown += @boolToInt(v == null);
+ }
+ if (unknown == 2) answer *= tile.id;
+ }
+
+ std.debug.print("{}\n", .{answer});
+}
+
+fn part2(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void {
+ var tiles = std.ArrayList(Tile).init(allocator);
+ defer tiles.deinit();
+
+ try parseTiles(&tiles, input);
+
+ matchTiles(&tiles);
+
+ var grid = try allocator.alloc(?usize, tiles.items.len);
+ defer allocator.free(grid);
+ var grid_width = @intCast(u32, std.math.sqrt(tiles.items.len));
+
+ var left = std.ArrayList(usize).init(allocator);
+ defer left.deinit();
+
+ for (tiles.items) |_, tile_index| {
+ try left.append(tile_index);
+ }
+
+ // add a corner as first item to add onto
+ for (tiles.items) |tile, tile_index| {
+ var unknown: u32 = 0;
+ for (tile.adj) |v| {
+ unknown += @boolToInt(v == null);
+ }
+ if (unknown == 2) {
+ try manipulateAndPlace(allocator, tiles.items, grid, grid_width, aoc.Pos{ .x = 0, .y = 0 }, tile_index);
+ _ = left.swapRemove(tile_index);
+ break;
+ }
+ }
+
+ // find adjacents and manipulate until they fit
+ next_tile: while (left.items.len > 0) {
+ if (aoc.debug) printGrid(tiles.items, grid, grid_width);
+
+ for (grid) |_, gi| {
+ std.debug.print("POS {}\n", .{gi});
+ const tile_index: ?usize = grid[gi] orelse continue;
+ std.debug.print("POS {} YES\n", .{gi});
+
+ var placed = &tiles.items[tile_index.?];
+ for (placed.adj) |want, dir| {
+ if (want == null) continue;
+ // std.debug.print("LOOKING FOR {}\n", .{want.?});
+ // for (left.items) |item| {
+ // std.debug.print("> {}\n", .{item});
+ // }
+ if (std.mem.indexOfScalar(usize, left.items, want.?)) |left_index| {
+ const new_index = left.items[left_index];
+ const new_tile = tiles.items[new_index];
+ var npos = placed.pos.add(dirs[dir]);
+ std.debug.print("TRYING TO PLACE {} NEW AT: {} {}\n", .{ new_tile.id, npos.x, npos.y });
+
+ try manipulateAndPlace(allocator, tiles.items, grid, grid_width, npos, new_index);
+
+ _ = left.swapRemove(left_index);
+ continue :next_tile;
+ }
+ }
+ }
+ return aoc.Error.InvalidInput;
+ }
+
+ if (aoc.debug) printGrid(tiles.items, grid, grid_width);
+
+ // convert grid to image
+ var image = try allocator.alloc(u1, grid.len * (tile_width - 2) * (tile_width - 2));
+ defer allocator.free(image);
+
+ const image_width = grid_width * (tile_width - 2);
+ var y: u32 = 0;
+ while (y < grid_width) : (y += 1) {
+ var x: u32 = 0;
+ while (x < grid_width) : (x += 1) {
+ var tile = tiles.items[grid[y * grid_width + x].?];
+ var doff = (y * grid_width * (tile_width - 2) + x) * (tile_width - 2);
+ var dy: u32 = 1;
+ while (dy < tile_width - 1) : (dy += 1) {
+ var dx: u32 = 1;
+ while (dx < tile_width - 1) : (dx += 1) {
+ image[doff + (dy - 1) * image_width + (dx - 1)] = tile.data[dy * tile_width + dx];
+ }
+ }
+ }
+ }
+
+ y = 0;
+ while (y < grid_width * (tile_width - 2)) : (y += 1) {
+ printTileSlice(image[y * grid_width * (tile_width - 2) .. (y + 1) * grid_width * (tile_width - 2)]);
+ std.debug.print("\n", .{});
+ }
+
+ // rotate image till we find a sea monster
+ var image_copy = try allocator.dupe(u1, image);
+ defer allocator.free(image_copy);
+
+ var rot: usize = 0;
+ while (rot < 4) : (rot += 1) {
+ for (flips) |flip| {
+ flipData(image, image_width, flip);
+ rotateData(&image_copy, image, image_width, rot);
+
+ y = 0;
+ var count: u32 = 0;
+ while (y < image_width - seamonster.len) : (y += 1) {
+ var x: u32 = 0;
+ check_next: while (x < image_width - seamonster[0].len) : (x += 1) {
+ var sy: u32 = 0;
+ while (sy < seamonster.len) : (sy += 1) {
+ var sx: u32 = 0;
+ while (sx < seamonster[0].len) : (sx += 1) {
+ if (seamonster[sy][sx] == '#' and image_copy[(y + sy) * image_width + (x + sx)] != 1)
+ continue :check_next;
+ }
+ }
+ count += 1;
+ }
+ }
+
+ if (count > 0) {
+ var image_count = std.mem.count(u1, image_copy, ([_]u1{1})[0..]);
+ var seamonster_count: usize = 0;
+ var sy: u32 = 0;
+ while (sy < seamonster.len) : (sy += 1) {
+ seamonster_count += std.mem.count(u8, seamonster[sy], "#");
+ }
+ std.debug.print("{}\n", .{image_count - count * seamonster_count});
+ return;
+ }
+ }
+ }
+}
+
+pub const main = aoc.gen_main(part1, part2);
diff --git a/src/day20/part1 b/src/day20/part1
@@ -0,0 +1,183 @@
+--- Day 20: Jurassic Jigsaw ---
+
+The high-speed train leaves the forest and quickly carries you south. You can even see a desert in
+the distance! Since you have some spare time, you might as well see if there was anything
+interesting in the image the Mythical Information Bureau satellite captured.
+
+After decoding the satellite messages, you discover that the data actually contains many small
+images created by the satellite's [1m[37mcamera array[0m. The camera array consists of many
+cameras; rather than produce a single square image, they produce many smaller square image
+[1m[37mtiles[0m that need to be [1m[37mreassembled back into a single image[0m.
+
+Each camera in the camera array returns a single monochrome [1m[37mimage tile[0m with a random
+unique [1m[37mID number[0m. The tiles (your puzzle input) arrived in a random order.
+
+Worse yet, the camera array appears to be malfunctioning: each image tile has been [1m[37mrotated
+and flipped to a random orientation[0m. Your first task is to reassemble the original image by
+orienting the tiles so they fit together.
+
+To show how the tiles should be reassembled, each tile's image data includes a border that should
+line up exactly with its adjacent tiles. All tiles have this border, and the border lines up exactly
+when the tiles are both oriented correctly. Tiles at the edge of the image also have this border,
+but the outermost edges won't line up with any other tiles.
+
+For example, suppose you have the following nine tiles:
+
+Tile 2311:
+..##.#..#.
+##..#.....
+#...##..#.
+####.#...#
+##.##.###.
+##...#.###
+.#.#.#..##
+..#....#..
+###...#.#.
+..###..###
+
+Tile 1951:
+#.##...##.
+#.####...#
+.....#..##
+#...######
+.##.#....#
+.###.#####
+###.##.##.
+.###....#.
+..#.#..#.#
+#...##.#..
+
+Tile 1171:
+####...##.
+#..##.#..#
+##.#..#.#.
+.###.####.
+..###.####
+.##....##.
+.#...####.
+#.##.####.
+####..#...
+.....##...
+
+Tile 1427:
+###.##.#..
+.#..#.##..
+.#.##.#..#
+#.#.#.##.#
+....#...##
+...##..##.
+...#.#####
+.#.####.#.
+..#..###.#
+..##.#..#.
+
+Tile 1489:
+##.#.#....
+..##...#..
+.##..##...
+..#...#...
+#####...#.
+#..#.#.#.#
+...#.#.#..
+##.#...##.
+..##.##.##
+###.##.#..
+
+Tile 2473:
+#....####.
+#..#.##...
+#.##..#...
+######.#.#
+.#...#.#.#
+.#########
+.###.#..#.
+########.#
+##...##.#.
+..###.#.#.
+
+Tile 2971:
+..#.#....#
+#...###...
+#.#.###...
+##.##..#..
+.#####..##
+.#..####.#
+#..#.#..#.
+..####.###
+..#.#.###.
+...#.#.#.#
+
+Tile 2729:
+...#.#.#.#
+####.#....
+..#.#.....
+....#..#.#
+.##..##.#.
+.#.####...
+####.#.#..
+##.####...
+##..#.##..
+#.##...##.
+
+Tile 3079:
+#.#.#####.
+.#..######
+..#.......
+######....
+####.#..#.
+.#...#.##.
+#.#####.##
+..#.###...
+..#.......
+..#.###...
+
+By rotating, flipping, and rearranging them, you can find a square arrangement that causes all
+adjacent borders to line up:
+
+#...##.#.. ..###..### #.#.#####.
+..#.#..#.# ###...#.#. .#..######
+.###....#. ..#....#.. ..#.......
+###.##.##. .#.#.#..## ######....
+.###.##### ##...#.### ####.#..#.
+.##.#....# ##.##.###. .#...#.##.
+#...###### ####.#...# #.#####.##
+.....#..## #...##..#. ..#.###...
+#.####...# ##..#..... ..#.......
+#.##...##. ..##.#..#. ..#.###...
+
+#.##...##. ..##.#..#. ..#.###...
+##..#.##.. ..#..###.# ##.##....#
+##.####... .#.####.#. ..#.###..#
+####.#.#.. ...#.##### ###.#..###
+.#.####... ...##..##. .######.##
+.##..##.#. ....#...## #.#.#.#...
+....#..#.# #.#.#.##.# #.###.###.
+..#.#..... .#.##.#..# #.###.##..
+####.#.... .#..#.##.. .######...
+...#.#.#.# ###.##.#.. .##...####
+
+...#.#.#.# ###.##.#.. .##...####
+..#.#.###. ..##.##.## #..#.##..#
+..####.### ##.#...##. .#.#..#.##
+#..#.#..#. ...#.#.#.. .####.###.
+.#..####.# #..#.#.#.# ####.###..
+.#####..## #####...#. .##....##.
+##.##..#.. ..#...#... .####...#.
+#.#.###... .##..##... .####.##.#
+#...###... ..##...#.. ...#..####
+..#.#....# ##.#.#.... ...##.....
+
+For reference, the IDs of the above tiles are:
+
+[1m[37m1951[0m 2311 [1m[37m3079[0m
+2729 1427 2473
+[1m[37m2971[0m 1489 [1m[37m1171[0m
+
+To check that you've assembled the image correctly, multiply the IDs of the four corner tiles
+together. If you do this with the assembled tiles from the example above, you get 1951 * 3079 * 2971
+* 1171 = [1m[37m20899048083289[0m.
+
+Assemble the tiles into an image. [1m[37mWhat do you get if you multiply together the IDs of the
+four corner tiles?[0m
+
+
diff --git a/src/day20/part2 b/src/day20/part2
@@ -0,0 +1,110 @@
+--- Part Two ---
+
+Now, you're ready to [1m[37mcheck the image for sea monsters[0m.
+
+The borders of each tile are not part of the actual image; start by removing them.
+
+In the example above, the tiles become:
+
+.#.#..#. ##...#.# #..#####
+###....# .#....#. .#......
+##.##.## #.#.#..# #####...
+###.#### #...#.## ###.#..#
+##.#.... #.##.### #...#.##
+...##### ###.#... .#####.#
+....#..# ...##..# .#.###..
+.####... #..#.... .#......
+
+#..#.##. .#..###. #.##....
+#.####.. #.####.# .#.###..
+###.#.#. ..#.#### ##.#..##
+#.####.. ..##..## ######.#
+##..##.# ...#...# .#.#.#..
+...#..#. .#.#.##. .###.###
+.#.#.... #.##.#.. .###.##.
+###.#... #..#.##. ######..
+
+.#.#.### .##.##.# ..#.##..
+.####.## #.#...## #.#..#.#
+..#.#..# ..#.#.#. ####.###
+#..####. ..#.#.#. ###.###.
+#####..# ####...# ##....##
+#.##..#. .#...#.. ####...#
+.#.###.. ##..##.. ####.##.
+...###.. .##...#. ..#..###
+
+Remove the gaps to form the actual image:
+
+.#.#..#.##...#.##..#####
+###....#.#....#..#......
+##.##.###.#.#..######...
+###.#####...#.#####.#..#
+##.#....#.##.####...#.##
+...########.#....#####.#
+....#..#...##..#.#.###..
+.####...#..#.....#......
+#..#.##..#..###.#.##....
+#.####..#.####.#.#.###..
+###.#.#...#.######.#..##
+#.####....##..########.#
+##..##.#...#...#.#.#.#..
+...#..#..#.#.##..###.###
+.#.#....#.##.#...###.##.
+###.#...#..#.##.######..
+.#.#.###.##.##.#..#.##..
+.####.###.#...###.#..#.#
+..#.#..#..#.#.#.####.###
+#..####...#.#.#.###.###.
+#####..#####...###....##
+#.##..#..#...#..####...#
+.#.###..##..##..####.##.
+...###...##...#...#..###
+
+Now, you're ready to search for sea monsters! Because your image is monochrome, a sea monster will
+look like this:
+
+ #
+# ## ## ###
+ # # # # # #
+
+When looking for this pattern in the image, [1m[37mthe spaces can be anything[0m; only the # need
+to match. Also, you might need to rotate or flip your image before it's oriented correctly to find
+sea monsters. In the above image, [1m[37mafter flipping and rotating it[0m to the appropriate
+orientation, there are [1m[37mtwo[0m sea monsters (marked with [1m[37mO[0m):
+
+.####...#####..#...###..
+#####..#..#.#.####..#.#.
+.#.#...#.###...#.##.[1m[37mO[0m#..
+
+#.[1m[37mO[0m.##.[1m[37mO[0m[1m[37mO[0m#.#.[1m[37mO[0m[1m[37mO[0m.##.[1m[37mO[0m[1m[37mO[0m[1m[37mO[0m##
+
+..#[1m[37mO[0m.#[1m[37mO[0m#.[1m[37mO[0m##[1m[37mO[0m..[1m[37mO[0m.#[1m[37mO[0m##.##
+...#.#..##.##...#..#..##
+#.##.#..#.#..#..##.#.#..
+.###.##.....#...###.#...
+#.####.#.#....##.#..#.#.
+##...#..#....#..#...####
+..#.##...###..#.#####..#
+....#.##.#.#####....#...
+..##.##.###.....#.##..#.
+#...#...###..####....##.
+.#.##...#.##.#.#.###...#
+#.###.#..####...##..#...
+#.###...#.##...#.##[1m[37mO[0m###.
+
+.[1m[37mO[0m##.#[1m[37mO[0m[1m[37mO[0m.###[1m[37mO[0m[1m[37mO[0m##..[1m[37mO[0m[1m[37mO[0m[1m[37mO[0m##.
+
+..[1m[37mO[0m#.[1m[37mO[0m..[1m[37mO[0m..[1m[37mO[0m.#[1m[37mO[0m##[1m[37mO[0m##.###
+#.#..##.########..#..##.
+#.#####..#.#...##..#....
+#....##..#.#########..##
+#...#.....#..##...###.##
+#..###....##.#...##.##.#
+
+Determine how rough the waters are in the sea monsters' habitat by counting the number of # that are
+[1m[37mnot[0m part of a sea monster. In the above example, the habitat's water roughness is
+[1m[37m273[0m.
+
+[1m[37mHow many # are not part of a sea monster?[0m
+
+