mirror of
https://github.com/HenkKalkwater/aoc-2020
synced 2024-11-22 11:05:18 +00:00
Add day 13, part 1
This commit is contained in:
parent
2b2ecdc26b
commit
fb9815b6ec
2
in/13.txt
Normal file
2
in/13.txt
Normal 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
|
|
@ -20,6 +20,7 @@ import day9;
|
||||||
import day10;
|
import day10;
|
||||||
import day11;
|
import day11;
|
||||||
import day12;
|
import day12;
|
||||||
|
import day13;
|
||||||
import dayutil;
|
import dayutil;
|
||||||
|
|
||||||
immutable string progName = "aoc-2020";
|
immutable string progName = "aoc-2020";
|
||||||
|
@ -41,6 +42,7 @@ Variant function(int, File, bool, string[])[] programs = [
|
||||||
&day10.run,
|
&day10.run,
|
||||||
&day11.run,
|
&day11.run,
|
||||||
&day12.run,
|
&day12.run,
|
||||||
|
&day13.run,
|
||||||
];
|
];
|
||||||
|
|
||||||
void printUsage(string message = null) {
|
void printUsage(string message = null) {
|
||||||
|
|
|
@ -18,7 +18,8 @@ struct Move {
|
||||||
Variant run(int part, File input, bool bigboy, string[] args) {
|
Variant run(int part, File input, bool bigboy, string[] args) {
|
||||||
auto parsedInput = parseInput(input.byLine);
|
auto parsedInput = parseInput(input.byLine);
|
||||||
return Variant(parts!int(part,
|
return Variant(parts!int(part,
|
||||||
() => part1(parsedInput)));
|
() => part1(parsedInput),
|
||||||
|
() => part2(parsedInput)));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parseInput(Range)(Range range) if (isInputRange!Range && isSomeString!(ElementType!Range)) {
|
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 part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range == Move)) {
|
||||||
int x, y;
|
int x, y;
|
||||||
Direction direction = Direction.EAST;
|
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) {
|
foreach(move; range) {
|
||||||
writefln("Facing %s (%d,%d)", direction, x, y);
|
//writefln("Facing %s (%d,%d)", direction, x, y);
|
||||||
final switch(move.direction) {
|
final switch(move.direction) {
|
||||||
case Direction.NORTH:
|
case Direction.NORTH:
|
||||||
case Direction.SOUTH:
|
case Direction.SOUTH:
|
||||||
|
@ -111,6 +112,80 @@ int part1(Range)(Range range) if (isInputRange!Range && is(ElementType!Range ==
|
||||||
import std.math;
|
import std.math;
|
||||||
return abs(x) + abs(y);
|
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 {
|
unittest {
|
||||||
string input = q"EOS
|
string input = q"EOS
|
||||||
|
@ -122,4 +197,5 @@ F11
|
||||||
EOS";
|
EOS";
|
||||||
|
|
||||||
assert(parseInput(input.lineSplitter).part1() == 25);
|
assert(parseInput(input.lineSplitter).part1() == 25);
|
||||||
|
assert(parseInput(input.lineSplitter).part2() == 286);
|
||||||
}
|
}
|
||||||
|
|
51
source/day13.d
Normal file
51
source/day13.d
Normal 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);
|
||||||
|
}
|
Loading…
Reference in a new issue