Last active
December 18, 2015 16:12
-
-
Save desrtfx/2aa5947a4de71d347d6b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
public class Day18 { | |
private final static String FILENAME = ".\\InputDay18.txt"; | |
private final static int ITERATIONS = 100; | |
private boolean[][] board = new boolean[100][100]; | |
private boolean[][] origBoard = new boolean[100][100]; | |
public Day18() { | |
List<String> input = FileIO.getFileAsList(Day18.FILENAME); | |
for (int i = 0; i < input.size(); i++) { | |
String s = input.get(i); | |
for (int j = 0; j < s.length(); j++) { | |
origBoard[i][j] = (s.charAt(j) == '#'); | |
} | |
} | |
} | |
public static void main(String[] args) { | |
Day18 day18 = new Day18(); | |
System.out.println("Part 1: Lights on: " + day18.solve(false)); | |
System.out.println("Part 2: Lights on: " + day18.solve(true)); | |
} | |
private int solve(boolean part2) { | |
board = origBoard.clone(); | |
for (int i = 0; i < Day18.ITERATIONS; i++) { | |
tick(part2); | |
} | |
return countLightsOn(); | |
} | |
private void tick(boolean part2) { | |
boolean[][] newBoard = new boolean[100][100]; | |
for (int i = 0; i < board.length; i++) { | |
for (int j = 0; j < board[i].length; j++) { | |
newBoard[i][j] = play(i, j); | |
} | |
} | |
if (part2) { | |
newBoard[0][0] = true; | |
newBoard[0][newBoard[0].length - 1] = true; | |
newBoard[newBoard.length - 1][0] = true; | |
newBoard[newBoard.length - 1][newBoard[newBoard.length - 1].length - 1] = true; | |
} | |
board = newBoard; | |
} | |
private int countLightsOn() { | |
int count = 0; | |
for (boolean[] row : board) | |
for (boolean cell : row) { | |
if (cell) { | |
count++; | |
} | |
} | |
return count; | |
} | |
private boolean play(int i, int j) { | |
int neighbors = countNeighbors(i, j); | |
// check if cell is alive | |
// Here is a little boolean algebra: | |
// A means board[i][j] | |
// B means neighbors == 2 | |
// C means neighbors == 3 | |
// | |
// The rules say: | |
// If a cell is alive (A) it stays alive if it has 2(B) or 3(C) | |
// neighbors | |
// If a cell is dead (!A) it becomes alive if it has exactly 3(C) | |
// neighbors | |
// so, this can be converted into the boolean expression: | |
// alive = A(B + C) + !AC which can be expanded to: AB + AC + !AC -> AB | |
// + (A + !A)C | |
// which can then be simplified to: AB + C | |
return (neighbors == 3) || (board[i][j] && (neighbors == 2)); | |
} | |
private int countNeighbors(int i, int j) { | |
int count = 0; | |
for (int y = ((i == 0) ? 0 : -1); y <= ((i == board.length - 1) ? 0 : 1); y++) { | |
for (int x = ((j == 0) ? 0 : -1); x <= ((j == board[i + y].length - 1) ? 0 : 1); x++) { | |
if (!((y == 0) && (x == 0))) { | |
if (board[i + y][j + x]) { | |
count++; | |
if (count > 3) { // early termination - only values up | |
// to 4 are interesting | |
return count; | |
} | |
} | |
} | |
} | |
} | |
return count; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment