1
0
Fork 0
mirror of https://github.com/HenkKalkwater/aoc-2020 synced 2024-12-22 16:35:18 +00:00

Add day 13, part 1

This commit is contained in:
Chris Josten 2020-12-13 11:39:50 +01:00
parent 2b2ecdc26b
commit fb9815b6ec
Signed by: chris
GPG key ID: 1795A594046530AB
4 changed files with 139 additions and 8 deletions

2
in/13.txt Normal file
View file

@ -0,0 +1,2 @@
1011416
41,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,911,x,x,x,x,x,x,x,x,x,x,x,x,13,17,x,x,x,x,x,x,x,x,23,x,x,x,x,x,29,x,827,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,19

View file

@ -20,6 +20,7 @@ import day9;
import day10;
import day11;
import day12;
import day13;
import dayutil;
immutable string progName = "aoc-2020";
@ -41,6 +42,7 @@ Variant function(int, File, bool, string[])[] programs = [
&day10.run,
&day11.run,
&day12.run,
&day13.run,
];
void printUsage(string message = null) {

View file

@ -18,7 +18,8 @@ struct Move {
Variant run(int part, File input, bool bigboy, string[] args) {
auto parsedInput = parseInput(input.byLine);
return Variant(parts!int(part,
() => part1(parsedInput)));
() => part1(parsedInput),
() => part2(parsedInput)));
}
auto parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) {
@ -57,6 +58,12 @@ auto parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(Elem
});
}
int betterModulus(int number, int divisor) pure {
int tmp = number % divisor;
if (tmp < 0) tmp += divisor;
return tmp;
}
int part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range == Move)) {
int x, y;
Direction direction = Direction.EAST;
@ -81,14 +88,8 @@ int part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range ==
}
}
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);
//writefln("Facing %s (%d,%d)", direction, x, y);
final switch(move.direction) {
case Direction.NORTH:
case Direction.SOUTH:
@ -111,6 +112,80 @@ int part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range ==
import std.math;
return abs(x) + abs(y);
}
int part2(Range)(Range range) if (isInputRange!Range && is(ElementType!Range == Move)) {
int waypointX = 10;
int waypointY = 1;
int x, y;
foreach(move; range) {
//writefln("Ship (%d,%d), waypoint (%d,%d)", x, y, waypointX, waypointY);
final switch(move.direction) {
case Direction.NORTH:
waypointY += move.amount;
break;
case Direction.SOUTH:
waypointY -= move.amount;
break;
case Direction.WEST:
waypointX -= move.amount;
break;
case Direction.EAST:
waypointX += move.amount;
break;
case Direction.LEFT:
int direction = betterModulus(move.amount / 90, 4);
switch(direction) {
case 0:
break;
case 1:
int tmp = waypointY;
waypointY = waypointX;
waypointX = -tmp;
break;
case 2:
waypointY = -waypointY;
waypointX = -waypointX;
break;
case 3:
int tmp = waypointY;
waypointY = -waypointX;
waypointX = tmp;
break;
default: assert("Modulus went out of bounds");
}
break;
case Direction.RIGHT:
int direction = betterModulus(move.amount / 90, 4);
switch(direction) {
case 0:
break;
case 1:
int tmp = waypointY;
waypointY = -waypointX;
waypointX = tmp;
break;
case 2:
waypointY = -waypointY;
waypointX = -waypointX;
break;
case 3:
int tmp = waypointY;
waypointY = waypointX;
waypointX = -tmp;
break;
default: assert("Modulus went out of bounds");
}
break;
case Direction.FORWARD:
x += waypointX * move.amount;
y += waypointY * move.amount;
break;
}
}
import std.math;
return abs(x) + abs(y);
}
unittest {
string input = q"EOS
@ -122,4 +197,5 @@ F11
EOS";
assert(parseInput(input.lineSplitter).part1() == 25);
assert(parseInput(input.lineSplitter).part2() == 286);
}

51
source/day13.d Normal file
View file

@ -0,0 +1,51 @@
import dayutil;
struct ParsedInput {
int timestamp;
int[] busses;
}
Variant run(int part, File input, bool bigboy, string[] args) {
ParsedInput pInput = input.byLineCopy.array.parseInput();
Variant result = parts!int(part,
() => part1(pInput));
return result;
}
ParsedInput parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) {
import std.conv;
ParsedInput input;
input.timestamp = to!int(range[0]);
input.busses = range[1].splitter(',').filter!(c => c != "x").map!(to!int).array;
writeln(input);
return input;
}
int part1(ParsedInput input) {
import std.math;
int earliestBus = 0;
int earliestBusTimestamp = int.max;
foreach(int bus; input.busses) {
int closestTimestamp = (input.timestamp / bus + 1 ) * bus;
writeln(closestTimestamp);
if (closestTimestamp < earliestBusTimestamp) {
earliestBusTimestamp = closestTimestamp;
earliestBus = bus;
}
}
writefln("Bus %d at %d", earliestBus, earliestBusTimestamp);
return earliestBus * (earliestBusTimestamp - input.timestamp);
}
unittest {
string[] input = [
"939",
"7,13,x,x,59,x,31,19"
];
ParsedInput pInput = parseInput(input);
assert(part1(pInput) == 295);
}