aoc-2020-zig

git clone https://git.sinitax.com/sinitax/aoc-2020-zig
Log | Files | Refs | README | sfeed.txt

commit 0f0e042ff46d956bcd06d885859518ba5dbe2662
parent 0d74166d177df1853679d83d11c45bfd0358a4a0
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sat, 12 Dec 2020 13:50:57 +0100

added day 12

Diffstat:
Mlib/aoc.zig | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day12/input | 786+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day12/input-test | 5+++++
Asrc/day12/main.zig | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day12/part1 | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day12/part2 | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/day13/main.zig | 16++++++++++++++++
7 files changed, 1036 insertions(+), 0 deletions(-)

diff --git a/lib/aoc.zig b/lib/aoc.zig @@ -45,3 +45,66 @@ pub fn gen_main(comptime part1: part_type, comptime part2: part_type) fn () anye }; return impl.main; } + +pub const Pos = struct { + x: i64, + y: i64, + const Self = @This(); + + pub fn add(self: Self, other: Self) Self { + return Self{ .x = self.x + other.x, .y = self.y + other.y }; + } + + pub fn mult(self: Self, val: i64) Self { + return Self{ .x = self.x * val, .y = self.y * val }; + } +}; + +pub const Dir = struct { + pub const East = Pos{ .x = 1, .y = 0 }; + pub const West = Pos{ .x = -1, .y = 0 }; + pub const South = Pos{ .x = 0, .y = -1 }; + pub const North = Pos{ .x = 0, .y = 1 }; + + pub const Name = enum { + EAST = 0, WEST = 1, SOUTH = 2, NORTH = 3 + }; + pub const dirs = [_]Pos{ East, South, West, North }; + + pub fn get(name: Name) Pos { + return dirs[@enumToInt(name)]; + } + + pub fn nextCW(dir: usize, offset: usize) usize { + return (dir + @intCast(u32, offset)) % @intCast(u32, dirs.len); + } + + pub fn nextCCW(dir: usize, offset: usize) usize { + const constrained = offset % dirs.len; + if (dir >= constrained) { + return dir - constrained; + } else { + return dirs.len - (constrained - dir); + } + } + + const cos90vs = [_]i32{ 1, 0, -1, 0 }; + const sin90vs = [_]i32{ 0, 1, 0, -1 }; + + pub fn rotCW(pos: Pos, offset: usize) Pos { + const constrained = (4 - offset % 4) % 4; + return Pos{ + .x = cos90vs[constrained] * pos.x - sin90vs[constrained] * pos.y, + .y = sin90vs[constrained] * pos.x + cos90vs[constrained] * pos.y, + }; + } + + pub fn rotCCW(pos: Pos, offset: usize) Pos { + const constrained = offset % 4; + std.debug.print("{}\n", .{constrained}); + return Pos{ + .x = cos90vs[constrained] * pos.x - sin90vs[constrained] * pos.y, + .y = sin90vs[constrained] * pos.x + cos90vs[constrained] * pos.y, + }; + } +}; diff --git a/src/day12/input b/src/day12/input @@ -0,0 +1,786 @@ +L90 +F67 +R270 +W1 +R180 +F5 +E5 +F59 +E4 +L180 +F70 +S2 +F35 +N3 +E5 +F58 +L90 +N1 +F46 +R90 +S1 +R90 +E1 +L180 +W4 +F99 +N2 +F84 +N1 +R90 +N5 +W4 +F26 +E1 +F97 +N1 +F36 +W1 +F21 +S4 +F31 +S3 +F76 +S5 +S1 +L90 +S4 +W4 +R90 +E4 +F14 +R90 +S2 +R90 +S3 +F21 +N1 +W4 +S4 +E1 +L180 +N5 +F30 +N3 +F4 +N5 +F100 +N2 +R270 +E1 +S1 +F79 +N4 +F72 +W4 +F50 +L90 +W5 +S4 +E2 +N5 +E4 +S5 +W5 +L90 +E4 +L90 +S4 +E4 +R90 +N1 +W5 +R270 +W5 +N4 +R180 +E5 +F86 +L90 +W3 +F79 +W5 +F87 +L180 +N4 +E2 +S1 +W3 +N3 +F31 +W2 +N1 +F86 +E1 +L90 +L90 +F2 +E3 +F8 +L90 +F54 +W3 +S5 +E3 +F89 +N5 +R90 +E3 +F70 +N2 +R90 +F55 +W3 +R90 +F44 +E2 +F36 +L90 +E3 +S2 +F23 +N4 +F2 +W5 +L180 +E4 +N4 +W3 +F58 +W1 +R90 +W1 +L90 +E1 +F99 +W4 +S4 +E5 +N2 +R180 +E5 +F82 +N3 +F99 +L90 +N4 +E4 +S5 +R90 +N3 +F17 +S5 +E4 +F58 +E1 +N1 +E5 +R90 +F32 +N1 +R90 +F84 +E4 +W4 +R180 +E4 +R90 +N1 +F26 +W4 +R90 +F96 +E5 +S2 +F86 +R90 +F95 +S4 +F81 +R90 +W4 +F44 +N3 +W3 +N5 +L180 +L90 +F71 +S4 +R90 +E5 +N4 +F63 +W2 +F75 +N3 +R90 +S2 +E3 +F75 +R90 +W3 +F4 +L90 +E3 +F96 +L180 +F53 +W5 +L90 +F12 +N2 +F100 +W2 +R270 +S1 +F37 +E4 +S1 +E1 +L270 +W2 +S5 +F10 +L90 +N3 +F63 +L90 +F96 +S3 +W1 +N4 +R180 +E2 +F51 +L90 +N4 +F27 +W3 +N5 +R90 +N4 +L180 +F4 +N1 +L180 +F71 +E5 +S5 +F94 +L90 +F98 +E3 +N4 +E5 +R90 +F75 +S1 +F19 +E2 +F53 +S3 +L90 +F29 +R180 +F88 +R180 +F3 +S2 +E5 +F16 +L90 +E1 +S2 +E3 +F28 +E5 +F22 +L180 +S2 +E1 +S1 +F6 +E2 +S3 +F14 +R90 +N4 +S5 +F77 +L90 +N3 +R90 +N2 +L180 +F99 +E2 +F85 +S3 +F81 +N1 +W1 +F91 +F31 +N5 +W5 +R90 +S1 +F40 +N2 +E1 +S3 +L90 +E5 +R180 +E2 +L90 +F88 +R90 +F45 +R270 +W4 +F67 +W4 +S1 +W4 +F65 +L90 +F19 +R90 +F83 +S1 +R90 +E2 +R180 +F78 +E1 +E1 +L180 +S1 +E1 +N4 +W5 +F98 +L90 +E4 +L90 +N2 +E1 +N4 +E1 +N5 +L90 +S3 +F52 +W5 +F55 +S4 +R180 +F56 +S5 +E1 +R90 +F97 +E5 +N4 +L90 +E1 +N1 +W1 +N4 +L270 +F7 +N3 +L90 +W3 +L270 +F27 +E2 +N5 +F90 +N3 +R90 +F79 +N4 +F58 +L90 +W5 +F90 +F9 +E5 +R90 +F16 +E4 +F50 +S1 +R90 +N5 +E2 +F86 +E3 +L270 +W3 +L90 +W1 +F17 +N2 +L180 +N1 +W4 +R180 +F10 +N3 +W3 +L90 +E2 +F12 +S5 +L90 +N3 +W4 +N3 +F19 +E5 +F54 +E1 +F34 +F2 +S4 +F14 +R90 +S4 +F2 +N1 +E3 +N2 +L180 +E5 +F67 +L180 +F66 +E3 +S4 +W3 +F51 +L270 +N5 +F51 +W3 +S2 +E2 +N2 +F27 +W5 +F77 +E4 +N5 +E2 +F20 +N5 +E4 +S5 +F67 +S2 +F81 +L90 +F68 +E4 +F71 +L90 +F48 +N3 +F1 +N5 +R90 +F76 +W5 +S5 +F74 +S1 +E2 +F52 +R90 +W1 +S4 +F13 +F69 +L180 +F59 +N3 +F34 +F84 +R90 +F63 +W2 +L90 +F12 +L90 +W5 +F25 +F83 +E4 +N1 +R90 +F36 +S1 +W2 +F41 +R90 +N3 +W1 +R180 +W2 +L90 +N4 +F87 +E3 +S4 +F10 +S3 +F33 +R90 +E1 +L180 +F32 +W5 +S3 +F23 +R90 +F44 +L90 +F45 +E2 +L270 +F41 +W1 +F54 +L180 +F31 +R90 +F43 +S3 +F91 +F88 +L180 +F2 +W2 +N5 +W2 +S1 +L180 +F12 +N2 +F2 +N3 +W2 +R90 +S2 +E4 +F66 +S2 +W4 +F94 +S5 +E1 +L180 +N5 +F2 +N2 +R180 +E3 +F3 +E1 +R90 +S3 +F28 +L90 +F12 +L90 +S2 +F100 +L90 +F84 +E2 +R90 +W4 +F14 +N1 +W3 +F33 +W1 +N5 +R180 +F93 +W5 +N2 +E4 +L180 +W3 +F2 +S1 +W4 +L90 +F8 +W2 +F83 +E5 +R180 +W4 +S4 +R90 +E4 +R180 +F84 +E2 +N3 +W3 +N1 +L90 +F76 +W1 +F9 +E1 +S1 +E5 +L90 +S1 +S5 +W4 +S3 +F20 +N2 +F52 +R180 +F21 +W4 +N2 +L90 +F42 +S3 +E5 +N4 +F100 +E5 +N5 +F56 +L90 +F90 +S1 +E2 +N2 +F42 +E3 +L90 +W4 +R180 +F22 +L90 +R90 +F48 +E4 +N4 +E5 +F10 +L90 +N5 +F99 +S4 +E3 +R90 +N5 +E3 +F85 +F83 +W1 +R180 +L90 +W4 +R90 +W1 +L90 +S4 +L90 +N3 +W5 +L90 +R90 +F68 +N2 +W5 +N4 +W3 +L90 +E1 +W1 +L180 +R90 +F45 +E5 +R90 +W5 +S4 +F5 +L180 +N1 +R90 +S4 +E3 +F22 +R180 +W4 +L180 +S3 +L90 +N5 +E5 +N1 +F6 +S5 +W1 +F86 +R180 +S1 +R90 +E5 +N2 +L90 +W4 +N1 +W3 +R90 +F1 +R180 +F94 +L90 +E5 +F7 +R90 +F72 +R90 +N3 +N1 +L180 +N4 +L90 +N5 +E1 +N1 +L270 +S2 +R90 +F8 +N4 +E2 +F8 +S5 +E2 +S3 +L90 +F67 +E4 +F54 +E1 +F100 +N2 +F20 diff --git a/src/day12/input-test b/src/day12/input-test @@ -0,0 +1,5 @@ +F10 +N3 +F7 +R90 +F11 diff --git a/src/day12/main.zig b/src/day12/main.zig @@ -0,0 +1,60 @@ +const std = @import("std"); +const aoc = @import("aoc"); +const Pos = aoc.Pos; +const Dir = aoc.Dir; + +const Ship = struct { pos: Pos, waypoint: Pos, dir: usize }; + +fn part1(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void { + var ship = Ship{ .pos = Pos{ .x = 0, .y = 0 }, .waypoint = Pos{ .x = 0, .y = 0 }, .dir = 0 }; + var lineit = std.mem.tokenize(input, "\n"); + while (lineit.next()) |line| { + const val = try std.fmt.parseInt(u32, line[1..], 10); + switch (line[0]) { + 'N' => ship.pos = ship.pos.add(Dir.North.mult(val)), + 'S' => ship.pos = ship.pos.add(Dir.South.mult(val)), + 'E' => ship.pos = ship.pos.add(Dir.East.mult(val)), + 'W' => ship.pos = ship.pos.add(Dir.West.mult(val)), + 'L' => ship.dir = Dir.nextCCW(ship.dir, @divExact(val, 90)), + 'R' => ship.dir = Dir.nextCW(ship.dir, @divExact(val, 90)), + 'F' => ship.pos = ship.pos.add(Dir.dirs[ship.dir].mult(val)), + else => { + return aoc.Error.InvalidInput; + }, + } + } + + std.debug.print("{}\n", .{std.math.absCast(ship.pos.x) + std.math.absCast(ship.pos.y)}); +} + +fn part2(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void { + var ship = Ship{ .pos = Pos{ .x = 0, .y = 0 }, .waypoint = Pos{ .x = 10, .y = 1 }, .dir = 0 }; + var lineit = std.mem.tokenize(input, "\n"); + while (lineit.next()) |line| { + const val = try std.fmt.parseInt(u32, line[1..], 10); + switch (line[0]) { + 'N' => ship.waypoint = ship.waypoint.add(Dir.North.mult(val)), + 'S' => ship.waypoint = ship.waypoint.add(Dir.South.mult(val)), + 'E' => ship.waypoint = ship.waypoint.add(Dir.East.mult(val)), + 'W' => ship.waypoint = ship.waypoint.add(Dir.West.mult(val)), + // WORKAROUND for language bug (parameter is implicitly passed as reference and assignment order) + 'L' => { + var new = Dir.rotCCW(ship.waypoint, @divExact(val, 90)); + ship.waypoint = new; + }, + 'R' => { + var new = Dir.rotCW(ship.waypoint, @divExact(val, 90)); + ship.waypoint = new; + }, + 'F' => ship.pos = ship.pos.add(ship.waypoint.mult(val)), + else => { + return aoc.Error.InvalidInput; + }, + } + std.debug.print("{} {} {} {} {}\n", .{ line, ship.waypoint.x, ship.waypoint.y, ship.pos.x, ship.pos.y }); + } + + std.debug.print("{}\n", .{std.math.absCast(ship.pos.x) + std.math.absCast(ship.pos.y)}); +} + +pub const main = aoc.gen_main(part1, part2); diff --git a/src/day12/part1 b/src/day12/part1 @@ -0,0 +1,57 @@ +--- Day 12: Rain Risk --- + +Your ferry made decent progress toward the island, but the storm came in faster than anyone +expected. The ferry needs to take evasive actions! + +Unfortunately, the ship's navigation computer seems to be malfunctioning; rather than giving a route +directly to safety, it produced extremely circuitous instructions. When the captain uses the PA +system to ask if anyone can help, you quickly volunteer. + +The navigation instructions (your puzzle input) consists of a sequence of single-character +actions paired with integer input values. After staring at them for a few +minutes, you work out what they probably mean: + + + - Action N means to move north by the given value. + - Action S means to move south by the given value. + - Action E means to move east by the given value. + - Action W means to move west by the given value. + - Action L means to turn left the given number of degrees. + - Action R means to turn right the given number of degrees. + - Action F means to move forward by the given value in the direction the +ship is currently facing. + + +The ship starts by facing east. Only the L and R actions change the direction the ship +is facing. (That is, if the ship is facing east and the next instruction is N10, the ship would move +north 10 units, but would still move east if the following action were F.) + +For example: + +F10 +N3 +F7 +R90 +F11 + +These instructions would be handled as follows: + + + - F10 would move the ship 10 units east (because the ship starts by facing east) to east +10, north 0. + - N3 would move the ship 3 units north to east 10, north 3. + - F7 would move the ship another 7 units east (because the ship is still facing east) to +east 17, north 3. + - R90 would cause the ship to turn right by 90 degrees and face south; it remains at +east 17, north 3. + - F11 would move the ship 11 units south to east 17, south 8. + + +At the end of these instructions, the ship's Manhattan distance (sum of the absolute values of its +east/west position and its north/south position) from its starting position is 17 + 8 = +25. + +Figure out where the navigation instructions lead. What is the Manhattan distance between +that location and the ship's starting position? + + diff --git a/src/day12/part2 b/src/day12/part2 @@ -0,0 +1,49 @@ +--- Part Two --- + +Before you can give the destination to the captain, you realize that the actual action meanings were +printed on the back of the instructions the whole time. + +Almost all of the actions indicate how to move a waypoint which is relative to the +ship's position: + + + - Action N means to move the waypoint north by the given value. + - Action S means to move the waypoint south by the given value. + - Action E means to move the waypoint east by the given value. + - Action W means to move the waypoint west by the given value. + - Action L means to rotate the waypoint around the ship left +(counter-clockwise) the given number of degrees. + - Action R means to rotate the waypoint around the ship right +(clockwise) the given number of degrees. + - Action F means to move forward to the waypoint a number of times equal +to the given value. + + +The waypoint starts 10 units east and 1 unit north relative to the ship. The waypoint +is relative to the ship; that is, if the ship moves, the waypoint moves with it. + +For example, using the same instructions as above: + + + - F10 moves the ship to the waypoint 10 times (a total of 100 units east and 10 units +north), leaving the ship at east 100, north 10. The waypoint stays 10 units east +and 1 unit north of the ship. + - N3 moves the waypoint 3 units north to 10 units east and 4 units north of the ship. +The ship remains at east 100, north 10. + - F7 moves the ship to the waypoint 7 times (a total of 70 units east and 28 units +north), leaving the ship at east 170, north 38. The waypoint stays 10 units east +and 4 units north of the ship. + - R90 rotates the waypoint around the ship clockwise 90 degrees, moving it to 4 units east +and 10 units south of the ship. The ship remains at east 170, north 38. + - F11 moves the ship to the waypoint 11 times (a total of 44 units east and 110 units +south), leaving the ship at east 214, south 72. The waypoint stays 4 units east and +10 units south of the ship. + + +After these operations, the ship's Manhattan distance from its starting position is 214 + 72 = +286. + +Figure out where the navigation instructions actually lead. What is the Manhattan distance +between that location and the ship's starting position? + + diff --git a/src/day13/main.zig b/src/day13/main.zig @@ -0,0 +1,16 @@ +const std = @import("std"); +const aoc = @import("aoc"); + +fn part1(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void { + var answer: u32 = 0; + + std.debug.print("{}\n", .{answer}); +} + +fn part2(allocator: *std.mem.Allocator, input: []u8, args: [][]u8) !void { + var answer: u32 = 0; + + std.debug.print("{}\n", .{answer}); +} + +pub const main = aoc.gen_main(part1, part2);