Day 14 is about robots patrolling the bathroom. Part 2 is an interesting challenge, more of a thought exercise but not really a hard one to code. I thought sure part 2 was gonna require some insanely large number of seconds of movement, so I prepared for that in part 1. It turned out my guess was wrong, but my preparations still helped for part 2. I created a class RobotGrid
. For part 1 I had to deal with the negative delta directions in an extra step because Java does some weirdness with negative mods, but otherwise it was fairly straight-forward. Part 2 was even more straight-forward once I came up with an approach to try.
final class RobotGrid
{
record Coord(int x, int y) {}
record Vector(Coord location, Coord direction) {}
private final int height;
private final int width;
private final List<Vector> robots = new ArrayList<>();
public RobotGrid(final String[] robotPositionsAndVectors, final int inputHeight, final int inputWidth)
{
this.height = inputHeight;
this.width = inputWidth;
parseRobotPositionsAndVectors(robotPositionsAndVectors);
}
private static final Pattern ROBOT_VECTOR_LINE = Pattern.compile("p=([0-9]+),([0-9]+) v=([-]?[0-9]+),([-]?[0-9]+)");
private void parseRobotPositionsAndVectors(final String[] robotPositionsAndVectors)
{
for (final String line : robotPositionsAndVectors)
{
final Matcher robotPositionAndVector = ROBOT_VECTOR_LINE.matcher(line);
if (!robotPositionAndVector.matches()) throw new IllegalStateException(line);
final int x = Integer.parseInt(robotPositionAndVector.group(1));
final int y = Integer.parseInt(robotPositionAndVector.group(2));
final int dx = Integer.parseInt(robotPositionAndVector.group(3));
final int dy = Integer.parseInt(robotPositionAndVector.group(4));
robots.add(new Vector(new Coord(x, y), new Coord(dx, dy)));
}
}
public long getResultAfterSeconds(int numberOfSeconds) // part 1
{
final int[] counts = new int[5]; // 4 quadrants + centre (which we'll ignore)
for(final Vector robot : robots)
{
final Coord newRobotLocation = moveRobot(robot, numberOfSeconds);
final int quadrant = getQuadrant(newRobotLocation);
counts[quadrant]++;
}
int result = 1;
for (int i=0; i<4; i++)
{
result *= counts[i];
}
return result;
}
// Java does some weirdness with mods of negative numbers. Rather than deal
// with that, I just used abs() and then added an extra unit of the mod value
// to pull the number positive again
private Coord moveRobot(final Vector startLocation, int numberOfSecondsToMove)
{
final int x = startLocation.location().x();
final int y = startLocation.location().y();
final int dx = startLocation.direction().x();
final int dy = startLocation.direction().y();
int xMove = (Math.abs(dx) * numberOfSecondsToMove) % width;
if (dx < 0) xMove = 0 - xMove;
int yMove = (Math.abs(dy) * numberOfSecondsToMove) % height;
if (dy < 0) yMove = 0 - yMove;
final int newX = (x + xMove + width) % width;
final int newY = (y + yMove + height) % height;
return new Coord(newX, newY);
}
// The quadrant mapping is almost irrelevant because the numbers will be multiplied
private int getQuadrant(final Coord location)
{
final int midY = height/2;
final int midX = width/2;
final int x = location.x();
final int y = location.y();
// ignore robots in the middle as instructed
if ((x == midX) || (y == midY)) return 4;
if (x < midX)
{
if (y < midY)
return 0;
else
return 1;
}
if (y < midY)
return 2;
else
return 3;
}
public long howLongForXmasTreeEasterEgg() // part 2
{
int robotMovementSeconds = 1;
Set<Coord> robots = moveRobots(robotMovementSeconds);
while (!inXmasArrangement(robots))
{
robotMovementSeconds++;
robots = moveRobots(robotMovementSeconds);
}
dumpRobots(robots);
return robotMovementSeconds;
}
private Set<Coord> moveRobots(final int numberOfSeconds)
{
final Set<Coord> result = new HashSet<>();
for(final Vector robot : robots)
{
final Coord newRobotLocation = moveRobot(robot, numberOfSeconds);
result.add(newRobotLocation);
}
return result;
}
// Initial assumption that the easter egg means every robot is in a
// unique position proved itself out
private boolean inXmasArrangement(final Set<Coord> robotArrangement)
{
if (robotArrangement.size() == robots.size()) return true;
return false;
}
private void dumpRobots(final Set<Coord> robotArrangement)
{
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
final Coord c = new Coord(x, y);
if (robotArrangement.contains(c))
System.out.print("*");
else
System.out.print(".");
}
System.out.println();
}
System.out.println();
}
}
And here’s the part 2 output
...............................*...........*......................................*..................
...........................................*.......................*.................................
.....................................................................................................
........................................*............................................................
.....................................................................................................
..............................................*................................*.....................
.....................................................................................................
..........................................*......................................*...................
...................................................................*.....................*...........
..............*...................................................*.......*..........................
.........................*................................................................*..........
.................................*...................................................................
.....................................................................................................
..*..................................................................................................
.....................................................................................................
................*.................*......................*...........................................
...........................................*.........................................................
.....................................................................................................
........................................*..................................*.........................
..............*.................................................................*..................*.
.........................................................*...........................................
.....................................................................................................
..........................................................................................*..........
...........................*...................*.................................................*...
...........................*................................................*........................
.....................................................................................................
.......*......................*......................*....*..........................................
.....................................................................................................
............*........................................................................................
................................*........................................*...........................
...........................................................*.........................................
..................................................................*..................................
.....................................................................................................
........................*.......*...............*....................................................
...............................*.................*...............*............................*......
.....................................................................................................
.....................................................................................................
.................................................................................*...................
...*........*.................................*......................................................
...............................................................................................*.....
.....................................................................................................
..........*............*................................*......................................*.....
...................................*..................*.....................*........................
.................................................................................................*...
............................................................................*........................
........................*............*.............*...............*............................*....
...................................................................*.................................
.....................................................................................................
.................................................*******************************.....................
....*..........*.............................*...*.............................*.....................
............*.....*.*............................*.............................*.....................
....................*.........................*..*.............................*.....................
...........*..................................*..*.............................*........*............
.................................................*..............*..............*...............*.....
.................................................*.............***.............*.....................
...........*.....................................*............*****............*.....................
.................*.......*.......................*...........*******...........*.....................
.................................................*..........*********..........*.....................
.............*...................................*............*****............*.............*.......
.................................................*...........*******...........*.....................
.....*...........................................*..........*********..........*..................*..
.................................................*.........***********.........*....*................
...........................*................*....*........*************........*.....................
...........**....................................*..........*********..........*.....................
.......................................*.........*.........***********.........*.....................
.................................................*........*************........*.....................
.................................................*.......***************.......*.....................
.................................................*......*****************......*.....................
.................................................*........*************........*.....................
.................................................*.......***************.......*.....................
.................................................*......*****************......*.....................
.................................................*.....*******************.....*...............*.....
.................................................*....*********************....*.....................
........................................*........*.............***.............*.....................
............................*....................*.............***.............*...........*....*....
......................................*........*.*.............***.............*.....................
.................................................*.............................*.....................
.................................................*.............................*.....................
.................................................*.............................*....*................
.................................................*.............................*.....................
..............................*.........*........*******************************.....................
.....................................*...............................................*...............
...............................................*.......*...*....................*....................
.......*.......................*.....................................................................
...................................*...........................................*.....................
................................*....*...............................................................
........................................................*...............*...........*................
.....................................................................................................
.........................*.........................*...........................*.....................
.....................................................................................................
............................*..............................*..........*..............................
.....................................................................................................
.....................................................................................................
.........................*.....................*.....................................................
.....................................................................................................
..............................*......................**.......*......................................
..............................................................*.....*............**..........*.......
............................*................................*.....*.................................
.....................................................................................................
..............*......................................................................................
...................*.................................................................*...............
*...............................*....................................................................
.............................................*.......................................................
The runtime was pretty reasonable
Part 1: 0.0110099s
Part 2: 0.2041993s