Day Ten, Part One
This commit is contained in:
		
							parent
							
								
									14efab3450
								
							
						
					
					
						commit
						ad781d6a6b
					
				
							
								
								
									
										24
									
								
								src/day_ten.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/day_ten.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| import {getFurthestDistance} from "./day_ten"; | ||||
| 
 | ||||
| describe('Day Ten', () => { | ||||
| 	it.each([ | ||||
| 		[`.....
 | ||||
| .S-7. | ||||
| .|.|. | ||||
| .L-J. | ||||
| .....`, 4], [
 | ||||
| 			`-L|F7
 | ||||
| 7S-7| | ||||
| L|7|| | ||||
| -L-J| | ||||
| L|-JF`, 4],
 | ||||
| 		[`..F7.
 | ||||
| .FJ|. | ||||
| SJ.L7 | ||||
| |F--J | ||||
| LJ...`, 8]
 | ||||
| 	])('should calculate the number of steps to the exit', (input, expected) => { | ||||
| 		const result = getFurthestDistance(input); | ||||
| 		expect(result).toEqual(expected); | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										108
									
								
								src/day_ten.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/day_ten.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| import fs from "fs"; | ||||
| 
 | ||||
| type Grid = Tile[][]; | ||||
| type Cell = [number, number]; | ||||
| type Tile = 'S' | 'F' | 'J' | 'L' | '7' | '-' | '|' | '.'; | ||||
| 
 | ||||
| const isTile = (value: string): value is Tile => { | ||||
| 	return ['S', 'F', 'J', 'L', '7', '-', '|', '.'].includes(value); | ||||
| } | ||||
| 
 | ||||
| const toString = (cell: Cell): string => { | ||||
| 	return cell.toString(); | ||||
| } | ||||
| 
 | ||||
| const getStart = (grid: Grid): Cell => { | ||||
| 	const row = grid.findIndex(row => row.includes('S')); | ||||
| 	const col = grid[row].findIndex(cell => cell === 'S'); | ||||
| 	return [row, col]; | ||||
| } | ||||
| 
 | ||||
| const getSurrounding = (grid: Grid, [row, col]: Cell): Cell[] => { | ||||
| 	return ([ | ||||
| 		[row - 1, col], | ||||
| 		[row + 1, col], | ||||
| 		[row, col - 1], | ||||
| 		[row, col + 1], | ||||
| 		[row - 1, col - 1], | ||||
| 		[row - 1, col + 1], | ||||
| 		[row + 1, col - 1], | ||||
| 		[row + 1, col + 1], | ||||
| 	] as Cell[]).filter((cell) => { | ||||
| 		const valid = isValid(grid, cell); | ||||
| 		const neighbour = neighbours(grid, cell).map(toString); | ||||
| 
 | ||||
| 		return valid && neighbour.includes([row, col].toString()); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| const neighbours = (grid: Grid, [row, col]: Cell): Cell[] => { | ||||
| 	const value = grid[row][col]; | ||||
| 	switch (value) { | ||||
| 		case 'F': | ||||
| 			return [ | ||||
| 				[row, col + 1], | ||||
| 				[row + 1, col], | ||||
| 			]; | ||||
| 		case 'J': | ||||
| 			return [ | ||||
| 				[row - 1, col], | ||||
| 				[row, col - 1] | ||||
| 			]; | ||||
| 		case 'L': | ||||
| 			return [ | ||||
| 				[row, col + 1], | ||||
| 				[row - 1, col] | ||||
| 			]; | ||||
| 		case '7': | ||||
| 			return [ | ||||
| 				[row + 1, col], | ||||
| 				[row, col - 1] | ||||
| 			]; | ||||
| 		case '-': | ||||
| 			return [ | ||||
| 				[row, col + 1], | ||||
| 				[row, col - 1] | ||||
| 			]; | ||||
| 		case '|': | ||||
| 			return [ | ||||
| 				[row - 1, col], | ||||
| 				[row + 1, col] | ||||
| 			]; | ||||
| 		default: | ||||
| 			return []; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| const isValid = (grid: Grid, [row, col]: Cell): boolean => { | ||||
| 	return row >= 0 && row < grid.length && col >= 0 && col < grid[row].length && grid[row][col] !== '.'; | ||||
| } | ||||
| 
 | ||||
| export const getFurthestDistance = (input: string): number => { | ||||
| 	const grid = input.split('\n').map(line => line.split('').filter(isTile)); | ||||
| 
 | ||||
| 	const start = getStart(grid); | ||||
| 	const queue = getSurrounding(grid, start); | ||||
| 	console.log(start, queue); | ||||
| 	const visited = new Set<string>([start.toString()]); | ||||
| 
 | ||||
| 	while (queue.length > 0) { | ||||
| 		const current = queue.shift()!; | ||||
| 		const next = neighbours(grid, current); | ||||
| 
 | ||||
| 		next.forEach(cell => { | ||||
| 			if (!visited.has(cell.toString()) && isValid(grid, cell)) { | ||||
| 				queue.push(cell); | ||||
| 				visited.add(cell.toString()); | ||||
| 			} | ||||
| 		}); | ||||
| 	} | ||||
| 
 | ||||
| 	return visited.size / 2; | ||||
| } | ||||
| 
 | ||||
| export const runDayTen = () => { | ||||
| 	const input = fs.readFileSync('./inputs/day_ten_input.txt', 'utf8').trimEnd(); | ||||
| 	const result = getFurthestDistance(input); | ||||
| 	console.log(`Day Ten: ${result}`); | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user