diff --git a/in/12.txt b/in/12.txt new file mode 100644 index 0000000..bd7a01d --- /dev/null +++ b/in/12.txt @@ -0,0 +1,795 @@ +N5 +W1 +F61 +W2 +R90 +F50 +N2 +F40 +E4 +F48 +R180 +F17 +W4 +N5 +F3 +W3 +F1 +R90 +S2 +F23 +L90 +S3 +W3 +S4 +E4 +L90 +W3 +S3 +E4 +N2 +F28 +S2 +W2 +L180 +E3 +R90 +E3 +F83 +W5 +S4 +W3 +N2 +W5 +F90 +N2 +F82 +N2 +F2 +S4 +L90 +N3 +L90 +S2 +F12 +S3 +F40 +L90 +F56 +N1 +F29 +W2 +S2 +R270 +S4 +F14 +E4 +R90 +E2 +S2 +E2 +F82 +L90 +N3 +R180 +R90 +S1 +W1 +L90 +S2 +F78 +W2 +F52 +N4 +W5 +F38 +L90 +W2 +S2 +L90 +F66 +R90 +F62 +E3 +S5 +L90 +F99 +F2 +E4 +R90 +N3 +W4 +N1 +F71 +E2 +N3 +N2 +R90 +E2 +F66 +S4 +R90 +E5 +F29 +E5 +L90 +W2 +N2 +E3 +F18 +L180 +F17 +W1 +R90 +W3 +S5 +R90 +S3 +R180 +N5 +F69 +W1 +W3 +L180 +F72 +W5 +N1 +R180 +W3 +W4 +F85 +W4 +L90 +E4 +N5 +F73 +R90 +F70 +E4 +F79 +S5 +R180 +E2 +F35 +E4 +L270 +W2 +L90 +N5 +R90 +N4 +F64 +W2 +R270 +F33 +N5 +E4 +F94 +W1 +N1 +R90 +F79 +F46 +E1 +R180 +S3 +W3 +F72 +E1 +W4 +F95 +W2 +L90 +N3 +L90 +F85 +W3 +W1 +F54 +N3 +E1 +N4 +E5 +L90 +F61 +W2 +F7 +L180 +F87 +N4 +W1 +F87 +F3 +E3 +F63 +R90 +S4 +R180 +S4 +R180 +R90 +R90 +E5 +N4 +E2 +F86 +S3 +F98 +N4 +F70 +L90 +E4 +F26 +W4 +F19 +L90 +S4 +W4 +F84 +N1 +E4 +L180 +S2 +F74 +S1 +F86 +R90 +S2 +F78 +N4 +S2 +W1 +N5 +E2 +F38 +W4 +N1 +F75 +S1 +E1 +N3 +S1 +F54 +N3 +F88 +N5 +L180 +F15 +S2 +S2 +E2 +N3 +F97 +S3 +N3 +E3 +N5 +E3 +R90 +F87 +L90 +F15 +L90 +E5 +R90 +F70 +N3 +W2 +F47 +W2 +W3 +F17 +R90 +F95 +E4 +F28 +W4 +R90 +E2 +R180 +N4 +R180 +W4 +R270 +F73 +W1 +N2 +L90 +S1 +F65 +E1 +F42 +N2 +F74 +R90 +F21 +W5 +S1 +N5 +R90 +E4 +N5 +S5 +F99 +W4 +L180 +W1 +F83 +N2 +W2 +F87 +E2 +S3 +W1 +L180 +F89 +S1 +W2 +E2 +L90 +S2 +W1 +S5 +R180 +E5 +N1 +F82 +S3 +F7 +L90 +F31 +L90 +N3 +F84 +W3 +N4 +F100 +N1 +E2 +R90 +F90 +N3 +F43 +R90 +F2 +W4 +L90 +F87 +L90 +E3 +F71 +L180 +N1 +L90 +E4 +N3 +F31 +W1 +F80 +R270 +N1 +E4 +N1 +F22 +N4 +E1 +F57 +R90 +N3 +W2 +L180 +N3 +L180 +W4 +F59 +S4 +F10 +N5 +L90 +S3 +L90 +E1 +F96 +E4 +N3 +F54 +L180 +F47 +W1 +N4 +E1 +S4 +R180 +L90 +N1 +R90 +N3 +R90 +N4 +R90 +S3 +F59 +N5 +L90 +E4 +F72 +W4 +F76 +R90 +E3 +F70 +L180 +N3 +W2 +R90 +F65 +L90 +F71 +S3 +F43 +R90 +W2 +N2 +R90 +W1 +R90 +S4 +R180 +S1 +E3 +F72 +L90 +F61 +L90 +F75 +S1 +S5 +F15 +R90 +E3 +N2 +L270 +F48 +N1 +R180 +W2 +F69 +E4 +R90 +R90 +W1 +S5 +W5 +R90 +S4 +S3 +F51 +F43 +E2 +N5 +L180 +F89 +W1 +R90 +F59 +R90 +E2 +F51 +R90 +F91 +W4 +S5 +E4 +L90 +S5 +R90 +F44 +F47 +E4 +W1 +F77 +S5 +R90 +N2 +F87 +N4 +R90 +W5 +R90 +W5 +F89 +L90 +F61 +E2 +F29 +N4 +R90 +F31 +S1 +L90 +E5 +N2 +F7 +L180 +S4 +F63 +W4 +N5 +S2 +N1 +E5 +F87 +S5 +R180 +F14 +W4 +R180 +E1 +L90 +F67 +E2 +L90 +E5 +S2 +L90 +W2 +R90 +F94 +W4 +R90 +W3 +S3 +R90 +N5 +F55 +L90 +F43 +L90 +N5 +F16 +E4 +N2 +L270 +W3 +E1 +N2 +R180 +F51 +N5 +N1 +F36 +W4 +F38 +N5 +W1 +F29 +R180 +L90 +N1 +W3 +E1 +F78 +E1 +N1 +E2 +F57 +E4 +F83 +W5 +F32 +N3 +W4 +F36 +N2 +E3 +F74 +N4 +F54 +W5 +L90 +S1 +F42 +W4 +S5 +E3 +F64 +W2 +R180 +S2 +E1 +N2 +R90 +W3 +F36 +N3 +R90 +S2 +F53 +W2 +F85 +E5 +N2 +F9 +E1 +F83 +L90 +E5 +F44 +L90 +F92 +W5 +R270 +E4 +S1 +F6 +L90 +F96 +R90 +N1 +E4 +N1 +W3 +S2 +S4 +F39 +E1 +S1 +F82 +S3 +F78 +L90 +N4 +E1 +N2 +R90 +F63 +S3 +L180 +F52 +W2 +F49 +W2 +L270 +N1 +R180 +E3 +F79 +F73 +N1 +R90 +N3 +R180 +S2 +F35 +S1 +F43 +S1 +R90 +S4 +W4 +F12 +S1 +F2 +N3 +E4 +L90 +F51 +R90 +N4 +F90 +R90 +F99 +E3 +N1 +R90 +S3 +L270 +W5 +L90 +R270 +F50 +N5 +F33 +S3 +F18 +L90 +E4 +L180 +W4 +R90 +F21 +W4 +F24 +W2 +E5 +N3 +W1 +R90 +W3 +S3 +F82 +W1 +S1 +F12 +N3 +L90 +F37 +R180 +F36 +F27 +E3 +S3 +F36 +W4 +S1 +F6 +R90 +F59 +S1 +E1 +R180 +S2 +W3 +L90 +F45 +R90 +E1 +F29 +S5 +W3 +S5 +W4 +L270 +S2 +F13 +E4 +F28 +R90 +F80 +S4 +E1 +S2 +F62 +R90 +F26 +L180 +F19 +W2 +L180 +W5 +F15 +N1 +F68 +E4 +F75 +S2 +F58 +S4 +R180 +E3 +N1 +L90 +S2 +F12 +R90 +E5 +S5 +W4 +N5 +W1 +R180 +S1 +F70 +R90 +F97 +L90 +E3 +S3 +L270 +E1 +F51 +N4 +L180 +N1 +R90 +F42 diff --git a/source/app.d b/source/app.d index 3e537c5..a3e8139 100644 --- a/source/app.d +++ b/source/app.d @@ -19,6 +19,7 @@ import day8; import day9; import day10; import day11; +import day12; import dayutil; immutable string progName = "aoc-2020"; @@ -39,6 +40,7 @@ Variant function(int, File, bool, string[])[] programs = [ &day9.run, &day10.run, &day11.run, + &day12.run, ]; void printUsage(string message = null) { diff --git a/source/day12.d b/source/day12.d new file mode 100644 index 0000000..72a39b4 --- /dev/null +++ b/source/day12.d @@ -0,0 +1,125 @@ +import dayutil; + +enum Direction { + NORTH, + EAST, + SOUTH, + WEST, + LEFT, + RIGHT, + FORWARD +} + +struct Move { + Direction direction; + int amount; +} + +Variant run(int part, File input, bool bigboy, string[] args) { + auto parsedInput = parseInput(input.byLine); + return Variant(parts!int(part, + () => part1(parsedInput))); +} + +auto parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) { + return range.map!((line) { + Move move; + + switch(line[0]) { + case 'N': + move.direction = Direction.NORTH; + break; + case 'S': + move.direction = Direction.SOUTH; + break; + case 'E': + move.direction = Direction.EAST; + break; + case 'W': + move.direction = Direction.WEST; + break; + case 'L': + move.direction = Direction.LEFT; + break; + case 'R': + move.direction = Direction.RIGHT; + break; + case 'F': + move.direction = Direction.FORWARD; + break; + default: + assert(false, "Parse error"); + } + + import std.conv; + move.amount = to!int(line[1..$]); + return move; + }); +} + +int part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range == Move)) { + int x, y; + Direction direction = Direction.EAST; + + void applyWithDirection(Direction direction, int amount) { + switch(direction) { + case Direction.NORTH: + y += amount; + break; + case Direction.SOUTH: + y -= amount; + break; + case Direction.WEST: + x += amount; + break; + case Direction.EAST: + x -= amount; + break; + default: + import std.format; + assert(false, "Move called with wrong arguments (%s)".format(direction)); + } + } + + int betterModulus(int number, int divisor) pure { + int tmp = number % divisor; + if (tmp < 0) tmp += divisor; + return tmp; + } + + foreach(move; range) { + writefln("Facing %s (%d,%d)", direction, x, y); + final switch(move.direction) { + case Direction.NORTH: + case Direction.SOUTH: + case Direction.WEST: + case Direction.EAST: + applyWithDirection(move.direction, move.amount); + break; + case Direction.LEFT: + direction = cast(Direction) betterModulus((cast(int) direction - move.amount / 90), 4); + break; + case Direction.RIGHT: + direction = cast(Direction) betterModulus((cast(int) direction + move.amount / 90), 4); + break; + case Direction.FORWARD: + applyWithDirection(direction, move.amount); + break; + } + } + + import std.math; + return abs(x) + abs(y); +} + +unittest { + string input = q"EOS +F10 +N3 +F7 +R90 +F11 +EOS"; + + assert(parseInput(input.lineSplitter).part1() == 25); +} diff --git a/source/dayutil.d b/source/dayutil.d index ab067c7..9fb25ff 100644 --- a/source/dayutil.d +++ b/source/dayutil.d @@ -1,3 +1,11 @@ +public import std.array; +public import std.algorithm; +public import std.range; +public import std.string; +public import std.stdio; +public import std.traits; +public import std.variant; + import std.conv; import std.exception; import std.format;