class Day18 : AdventOfCode({ val parsed = input.lines().map { it.extractInts() }.map { (x, y) -> x to y } fun floodFill( set: Set, walk: Boolean = false, start: Set = setOf(ORIGIN), end: Point, gridSize: Int ): MutableSet? { var frontier = start val visited = mutableSetOf() while(frontier.isNotEmpty() && end !in visited){ val nextFrontier = mutableSetOf() for(point in frontier){ if(point.y in 0 .. gridSize && point.x in 0 .. gridSize && point in set == walk && visited.add(point)){ nextFrontier.addAll(point.cardinals()) } } frontier = nextFrontier } return visited.takeIf { end in it } } fun solvePart2(initialPoint: Int, sizeOfGrid: Int): Point? { val actualEnd = sizeOfGrid to sizeOfGrid var route = floodFill(parsed.take(initialPoint).toSet(), end = actualEnd, gridSize = sizeOfGrid) ?: return null for(byte in parsed.drop(initialPoint)){ if(route.remove(byte)){ val neighbours = byte.cardinals().filter { it in route } if(neighbours.size >= 2){ val start = neighbours.take(neighbours.size - 1).toSet() val end = neighbours.last() if(floodFill(route, true, start, end, sizeOfGrid) == null){ route = floodFill(route, true, setOf(ORIGIN), actualEnd, sizeOfGrid) ?: return byte } } } } return null } part2 { solvePart2(1024, 70) } })