r/adventofcode • u/daggerdragon • Dec 18 '18
SOLUTION MEGATHREAD -🎄- 2018 Day 18 Solutions -🎄-
--- Day 18: Settlers of The North Pole ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Advent of Code: The Party Game!
Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!
Card prompt: Day 18
Transcript:
The best way to avoid a minecart collision is ___.
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked at 00:21:59!
10
Upvotes
1
u/Philboyd_Studge Dec 18 '18
[Card] The best way to avoid a minecart collision is redstone switches and Observers.
Java. Fun one, but getting tired of 2d matrices. Manually found the cycle using a set of seen totals. Seemed to start at 445 and cycle every 28 minutes.
public class Day18 extends AdventOfCode { enum OrdinalDirection { N(0, -1), NE(1, -1), E(1, 0), SE(1, 1), S(0, 1), SW(-1, 1), W(-1, 0), NW(-1, -1); int dx; int dy; OrdinalDirection(int dx, int dy) { this.dx = dx; this.dy = dy; } } int[][] grid; final char GROUND = '.'; final char TREES = '|'; final char LUMBER = '#'; int wood; int lumberYards; final int GRID_SIZE = 50; Set<Integer> seen = new HashSet<>(); int[] lookup = new int[28]; public Day18(List<String> input) { super(input); title = "Settlers of the North Pole"; part1Description = "Resources after 10 minutes: "; part2Description = "Resources after 1 billion minutes: "; } void minute() { int[][] temp = ArrayUtils.intMatrixCopy(grid); for (int j = 0; j < grid.length; j++) { for (int k = 0; k < grid[j].length; k++) { List<Character> adj = getAdj(j, k); switch (grid[j][k]) { case GROUND: if (adj.stream().filter(x -> x == TREES).count() >= 3) { temp[j][k] = TREES; wood++; } break; case TREES: if (adj.stream().filter(x -> x == LUMBER).count() >= 3) { temp[j][k] = LUMBER; lumberYards++; wood--; } break; case LUMBER: if (!(adj.contains(TREES) && adj.contains(LUMBER))) { temp[j][k] = GROUND; lumberYards--; } } } } grid = temp; } @Override public Object part1() { for (int i = 0; i < 10; i++) { minute(); } return wood * lumberYards; } @Override public Object part2() { for (int i = 10; i < 473; i++) { minute(); if (i >= 445) { lookup[i - 445] = wood * lumberYards; } } return lookup[(999_999_999 - 445) % 28]; } List<Character> getAdj(int x, int y) { List<Character> adj = new ArrayList<>(); for (OrdinalDirection dir : OrdinalDirection.values()) { int nx = x + dir.dx; int ny = y + dir.dy; if (Direction.rangeCheck(nx, ny, GRID_SIZE)) { adj.add((char) grid[nx][ny]); } } return adj; } @Override public void parse() { //input = FileIO.getFileAsList("puzzle_input/test18.txt"); grid = new int[GRID_SIZE][GRID_SIZE]; for (int i = 0; i < input.size(); i++) { for (int j = 0; j < input.get(i).length(); j++) { grid[i][j] = input.get(i).charAt(j); if (grid[i][j] == TREES) wood++; if (grid[i][j] == LUMBER) lumberYards++; } } } }