Add solution day 20
This commit is contained in:
		
							parent
							
								
									78df933581
								
							
						
					
					
						commit
						80547b5125
					
				
					 5 changed files with 554 additions and 0 deletions
				
			
		
							
								
								
									
										15
									
								
								day_20/example.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								day_20/example.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					###############
 | 
				
			||||||
 | 
					#...#...#.....#
 | 
				
			||||||
 | 
					#.#.#.#.#.###.#
 | 
				
			||||||
 | 
					#S#...#.#.#...#
 | 
				
			||||||
 | 
					#######.#.#.###
 | 
				
			||||||
 | 
					#######.#.#...#
 | 
				
			||||||
 | 
					#######.#.###.#
 | 
				
			||||||
 | 
					###..E#...#...#
 | 
				
			||||||
 | 
					###.#######.###
 | 
				
			||||||
 | 
					#...###...#...#
 | 
				
			||||||
 | 
					#.#####.#.###.#
 | 
				
			||||||
 | 
					#.#...#.#.#...#
 | 
				
			||||||
 | 
					#.#.#.#.#.#.###
 | 
				
			||||||
 | 
					#...#...#...###
 | 
				
			||||||
 | 
					###############
 | 
				
			||||||
							
								
								
									
										141
									
								
								day_20/input.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								day_20/input.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,141 @@
 | 
				
			||||||
 | 
					#############################################################################################################################################
 | 
				
			||||||
 | 
					#...........#...#...#.....#.............#.........#...#...........#...#.......#...#...###.....#...#...#...###...#...#...#...#...#...###.....#
 | 
				
			||||||
 | 
					#.#########.#.#.#.#.#.###.#.###########.#.#######.#.#.#.#########.#.#.#.#####.#.#.#.#.###.###.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.###.###.#
 | 
				
			||||||
 | 
					#.......#...#.#.#.#.#...#.#...#.....#...#...#.....#.#.#.....#.....#.#.#...#...#.#.#.#...#...#...#...#.#.#...#.#.#.#.#.#.#.#.#.#...#...#.#...#
 | 
				
			||||||
 | 
					#######.#.###.#.#.#.###.#.###.#.###.#.#####.#.#####.#.#####.#.#####.#.###.#.###.#.#.###.###.#########.#.###.#.#.#.#.#.#.#.#.#.#######.#.#.###
 | 
				
			||||||
 | 
					###...#.#.....#...#.....#.###.#.###...#...#.#.#...#.#...#...#...#...#.....#.###.#.#.#...#...#.........#...#.#.#...#.#.#...#.#.#.......#.#...#
 | 
				
			||||||
 | 
					###.#.#.#################.###.#.#######.#.#.#.#.#.#.###.#.#####.#.#########.###.#.#.#.###.###.###########.#.#.#####.#.#####.#.#.#######.###.#
 | 
				
			||||||
 | 
					#...#.#...#...........#...#...#...#...#.#.#.#...#.#.#...#.....#.#.........#.#...#.#.#...#...#...#...###...#...#.....#...#...#.#.....###.#...#
 | 
				
			||||||
 | 
					#.###.###.#.#########.#.###.#####.#.#.#.#.#.#####.#.#.#######.#.#########.#.#.###.#.###.###.###.#.#.###.#######.#######.#.###.#####.###.#.###
 | 
				
			||||||
 | 
					#...#.###...#.........#...#.#.....#.#.#.#.#.#.....#.#.#...#...#.#...###...#.#.#...#...#...#...#...#...#.....#...#.....#.#...#.#.....#...#...#
 | 
				
			||||||
 | 
					###.#.#######.###########.#.#.#####.#.#.#.#.#.#####.#.#.#.#.###.#.#.###.###.#.#.#####.###.###.#######.#####.#.###.###.#.###.#.#.#####.#####.#
 | 
				
			||||||
 | 
					#...#...#.....#...#.....#.#.#.....#.#.#.#.#.#.#.....#.#.#.#...#...#...#...#.#.#.#...#.#...###.#.....#.#...#.#.###...#.#.#...#.#.#.....#...#.#
 | 
				
			||||||
 | 
					#.#####.#.#####.#.#.###.#.#.#####.#.#.#.#.#.#.#.#####.#.#.###.#######.###.#.#.#.#.#.#.#.#####.#.###.#.#.#.#.#.#####.#.#.#.###.#.#.#####.#.#.#
 | 
				
			||||||
 | 
					#.....#.#.......#...#...#...#...#.#.#...#...#.#.....#.#.#...#...#.....#...#.#.#...#.#.#.#...#.#...#...#.#.#.#...###.#...#...#.#...#.....#...#
 | 
				
			||||||
 | 
					#####.#.#############.#######.#.#.#.#########.#####.#.#.###.###.#.#####.###.#.#####.#.#.#.#.#.###.#####.#.#.###.###.#######.#.#####.#########
 | 
				
			||||||
 | 
					#.....#.#...#.......#.......#.#...#.....#.....#...#.#.#...#.#...#.#...#...#.#.....#.#.#.#.#.#.#...#...#.#.#...#...#...#.....#.#.....#...#...#
 | 
				
			||||||
 | 
					#.#####.#.#.#.#####.#######.#.#########.#.#####.#.#.#.###.#.#.###.#.#.###.#.#####.#.#.#.#.#.#.#.###.#.#.#.###.###.###.#.#####.#.#####.#.#.#.#
 | 
				
			||||||
 | 
					#.....#.#.#.#.....#.#...#...#...#...###.#.#...#.#.#.#.#...#...#...#.#...#.#...#...#.#.#...#...#...#.#...#...#...#.....#.#...#.#...###.#...#.#
 | 
				
			||||||
 | 
					#####.#.#.#.#####.#.#.#.#.#####.#.#.###.#.#.#.#.#.#.#.#.#######.###.###.#.###.#.###.#.###########.#.#######.###.#######.#.#.#.###.###.#####.#
 | 
				
			||||||
 | 
					#.....#...#.###...#...#.#.#.....#.#.#...#.#.#.#.#.#.#.#...#.....###.#...#...#.#...#.#.#...........#.#.......###.#.......#.#.#...#.....#.....#
 | 
				
			||||||
 | 
					#.#########.###.#######.#.#.#####.#.#.###.#.#.#.#.#.#.###.#.#######.#.#####.#.###.#.#.#.###########.#.#########.#.#######.#.###.#######.#####
 | 
				
			||||||
 | 
					#.........#...#.......#...#.#.....#.#...#.#.#...#.#.#.#...#.#...#...#.#.....#...#.#...#.#...........#.#.....#...#...#...#.#.#...#...#...#...#
 | 
				
			||||||
 | 
					#########.###.#######.#####.#.#####.###.#.#.#####.#.#.#.###.#.#.#.###.#.#######.#.#####.#.###########.#.###.#.#####.#.#.#.#.#.###.#.#.###.#.#
 | 
				
			||||||
 | 
					#...#...#.#...#.....#.....#.#.....#.#...#.#.#.....#.#.#...#...#.#...#.#.......#.#.....#...#...........#.#...#.#.....#.#.#.#.#.#...#...###.#.#
 | 
				
			||||||
 | 
					#.#.#.#.#.#.###.###.#####.#.#####.#.#.###.#.#.#####.#.###.#####.###.#.#######.#.#####.#####.###########.#.###.#.#####.#.#.#.#.#.#########.#.#
 | 
				
			||||||
 | 
					#.#.#.#...#...#...#.......#.#...#.#.#...#.#.#.#...#.#.....#.....#...#...#.....#...#...#...#...#...#...#.#.#...#...#...#.#.#...#.........#.#.#
 | 
				
			||||||
 | 
					#.#.#.#######.###.#########.#.#.#.#.###.#.#.#.#.#.#.#######.#####.#####.#.#######.#.###.#.###.#.#.#.#.#.#.#.#####.#.###.#.#############.#.#.#
 | 
				
			||||||
 | 
					#.#...#.....#...#.........#...#.#.#.#...#.#.#.#.#.#.......#.#...#.#.....#...#.....#.#...#.....#.#.#.#.#.#.#...#...#...#.#.#.............#.#.#
 | 
				
			||||||
 | 
					#.#####.###.###.#########.#####.#.#.#.###.#.#.#.#.#######.#.#.#.#.#.#######.#.#####.#.#########.#.#.#.#.#.###.#.#####.#.#.#.#############.#.#
 | 
				
			||||||
 | 
					#...#...###...#.......###.#.....#.#...#...#.#.#.#.....###.#...#...#...#...#.#...###.#.###...###.#.#.#.#.#...#.#...###.#.#.#.......#.....#.#.#
 | 
				
			||||||
 | 
					###.#.#######.#######.###.#.#####.#####.###.#.#.#####.###.###########.#.#.#.###.###.#.###.#.###.#.#.#.#.###.#.###.###.#.#.#######.#.###.#.#.#
 | 
				
			||||||
 | 
					#...#.#.....#.......#.....#...###.....#.#...#.#.....#.#...#...#.......#.#.#.#...#...#...#.#.#...#.#.#...#...#...#.#...#...#.......#.#...#.#.#
 | 
				
			||||||
 | 
					#.###.#.###.#######.#########.#######.#.#.###.#####.#.#.###.#.#.#######.#.#.#.###.#####.#.#.#.###.#.#####.#####.#.#.#######.#######.#.###.#.#
 | 
				
			||||||
 | 
					#.....#.#...###...#.........#.#...###.#.#.#...#...#.#.#...#.#...###...#.#.#.#.###...#...#.#.#...#.#...#...#...#.#.#.#.......#.......#...#.#.#
 | 
				
			||||||
 | 
					#######.#.#####.#.#########.#.#.#.###.#.#.#.###.#.#.#.###.#.#######.#.#.#.#.#.#####.#.###.#.###.#.###.#.###.#.#.#.#.#.#######.#########.#.#.#
 | 
				
			||||||
 | 
					#...#...#.#.....#.....#...#.#.#.#.#...#.#.#...#.#.#.#.#...#.#...#...#...#.#.#...#...#...#.#.#...#.#...#...#.#.#.#.#.#.#.....#.#.........#.#.#
 | 
				
			||||||
 | 
					#.#.#.###.#.#########.#.#.#.#.#.#.#.###.#.###.#.#.#.#.#.###.#.#.#.#######.#.###.#.#####.#.#.#.###.#.#####.#.#.#.#.#.#.#.###.#.#.#########.#.#
 | 
				
			||||||
 | 
					#.#.#...#.#.........#...#...#...#...###.#.#...#.#.#.#.#...#.#.#.#...#.....#...#.#...#...#.#.#.#...#...###...#...#.#.#...#...#.#.....###...#.#
 | 
				
			||||||
 | 
					#.#.###.#.#########.###################.#.#.###.#.#.#.###.#.#.#.###.#.#######.#.###.#.###.#.#.#.#####.###########.#.#####.###.#####.###.###.#
 | 
				
			||||||
 | 
					#.#.....#...#.......#.................#...#...#.#...#...#.#...#.#...#...#...#.#.#...#...#.#.#.#.#...#.#...........#.#.....#...#...#...#...#.#
 | 
				
			||||||
 | 
					#.#########.#.#######.###############.#######.#.#######.#.#####.#.#####.#.#.#.#.#.#####.#.#.#.#.#.#.#.#.###########.#.#####.###.#.###.###.#.#
 | 
				
			||||||
 | 
					#.......#...#.......#.#...............#...#...#...#...#.#.....#.#.....#.#.#.#.#.#...#...#.#.#.#.#.#...#.............#.###...#...#...#.....#.#
 | 
				
			||||||
 | 
					#######.#.#########.#.#.###############.#.#.#####.#.#.#.#####.#.#####.#.#.#.#.#.###.#.###.#.#.#.#.###################.###.###.#####.#######.#
 | 
				
			||||||
 | 
					#.......#...#.....#...#.................#.#.#...#...#.#.#...#.#.#...#.#.#.#.#.#.....#...#.#.#.#.#.#.....#...........#.....#...###...#.......#
 | 
				
			||||||
 | 
					#.#########.#.###.#######################.#.#.#.#####.#.#.#.#.#.#.#.#.#.#.#.#.#########.#.#.#.#.#.#.###.#.#########.#######.#####.###.#######
 | 
				
			||||||
 | 
					#.........#.#...#...#.....................#...#...#...#.#.#...#.#.#.#.#.#.#.#.###.......#.#...#...#...#.#.........#.#...#...#...#.....#...###
 | 
				
			||||||
 | 
					#########.#.###.###.#.###########################.#.###.#.#####.#.#.#.#.#.#.#.###.#######.###########.#.#########.#.#.#.#.###.#.#######.#.###
 | 
				
			||||||
 | 
					#.........#.....#...#.#.....................#...#.#...#.#...###.#.#...#.#.#.#...#...#...#.#######S..#.#.#.....#...#.#.#...###.#.#...#...#...#
 | 
				
			||||||
 | 
					#.###############.###.#.###################.#.#.#.###.#.###.###.#.#####.#.#.###.###.#.#.#.#########.#.#.#.###.#.###.#.#######.#.#.#.#.#####.#
 | 
				
			||||||
 | 
					#.......#...#...#...#...#...#...#.....#...#...#.#.....#...#...#.#.....#.#.#...#.#...#.#.#.#########...#...###...###.#.........#...#...#...#.#
 | 
				
			||||||
 | 
					#######.#.#.#.#.###.#####.#.#.#.#.###.#.#.#####.#########.###.#.#####.#.#.###.#.#.###.#.#.#########################.###################.#.#.#
 | 
				
			||||||
 | 
					#.......#.#...#...#...#...#...#.#...#...#.......#.......#.....#.#...#.#.#...#.#.#...#.#.#.#####...............#...#.........#...#.....#.#...#
 | 
				
			||||||
 | 
					#.#######.#######.###.#.#######.###.#############.#####.#######.#.#.#.#.###.#.#.###.#.#.#.#####.#############.#.#.#########.#.#.#.###.#.#####
 | 
				
			||||||
 | 
					#.........#...###...#.#...#.....###.###...#...###.#...#.......#...#.#.#...#.#.#.###...#...#####...#.........#.#.#...#...###...#.#.#...#...###
 | 
				
			||||||
 | 
					###########.#.#####.#.###.#.#######.###.#.#.#.###.#.#.#######.#####.#.###.#.#.#.#################.#.#######.#.#.###.#.#.#######.#.#.#####.###
 | 
				
			||||||
 | 
					#...........#...#...#.....#...#...#...#.#...#.....#.#.......#.....#.#...#...#...###############...#.......#...#.#...#.#.#...###...#.....#...#
 | 
				
			||||||
 | 
					#.#############.#.###########.#.#.###.#.###########.#######.#####.#.###.#######################.#########.#####.#.###.#.#.#.###########.###.#
 | 
				
			||||||
 | 
					#.....#...#...#...#...#.....#...#.....#...#...#...#.......#.......#.#...#.......#####.....#...#.#...#...#.......#.....#...#...#.....###...#.#
 | 
				
			||||||
 | 
					#####.#.#.#.#.#####.#.#.###.#############.#.#.#.#.#######.#########.#.###.#####.#####.###.#.#.#.#.#.#.#.#####################.#.###.#####.#.#
 | 
				
			||||||
 | 
					#.....#.#.#.#.#.....#.#...#...#...........#.#.#.#.#...#...#...#...#...#...#...#..E###...#...#...#.#.#.#...........#...........#.#...#...#...#
 | 
				
			||||||
 | 
					#.#####.#.#.#.#.#####.###.###.#.###########.#.#.#.#.#.#.###.#.#.#.#####.###.#.#########.#########.#.#.###########.#.###########.#.###.#.#####
 | 
				
			||||||
 | 
					#.......#...#...#.....#...###...#.........#.#...#...#.#.....#...#...###.....#...#.......#.........#...#.........#.#.............#.....#.....#
 | 
				
			||||||
 | 
					#################.#####.#########.#######.#.#########.#############.###########.#.#######.#############.#######.#.#########################.#
 | 
				
			||||||
 | 
					#...#.....#...#...#...#...#.....#.......#.#.........#.#...#...#...#...###...###...#.....#...............#.......#...#...#...#.....#.........#
 | 
				
			||||||
 | 
					#.#.#.###.#.#.#.###.#.###.#.###.#######.#.#########.#.#.#.#.#.#.#.###.###.#.#######.###.#################.#########.#.#.#.#.#.###.#.#########
 | 
				
			||||||
 | 
					#.#.#...#...#...#...#.#...#...#.......#.#.#.........#.#.#.#.#.#.#...#.#...#.......#...#.#...#...#.......#.#...#...#...#...#...###...#...#...#
 | 
				
			||||||
 | 
					#.#.###.#########.###.#.#####.#######.#.#.#.#########.#.#.#.#.#.###.#.#.#########.###.#.#.#.#.#.#.#####.#.#.#.#.#.###################.#.#.#.#
 | 
				
			||||||
 | 
					#.#.....#...#...#.#...#.#...#...#...#...#.#.........#...#...#.#.#...#.#...#.......#...#...#...#.#.....#.#...#...#...#...###...###.....#...#.#
 | 
				
			||||||
 | 
					#.#######.#.#.#.#.#.###.#.#.###.#.#.#####.#########.#########.#.#.###.###.#.#######.###########.#####.#.###########.#.#.###.#.###.#########.#
 | 
				
			||||||
 | 
					#...#.....#...#.#.#...#.#.#...#...#.....#.#...#.....#...#...#...#.....#...#.....#...#.....#...#.......#...........#...#.....#.....#.....#...#
 | 
				
			||||||
 | 
					###.#.#########.#.###.#.#.###.#########.#.#.#.#.#####.#.#.#.###########.#######.#.###.###.#.#.###################.#################.###.#.###
 | 
				
			||||||
 | 
					#...#.#.........#.###.#.#...#...###.....#.#.#.#...###.#.#.#...#...###...#.....#...#...###...#.....#...#.........#...#...#.....#...#...#.#...#
 | 
				
			||||||
 | 
					#.###.#.#########.###.#.###.###.###.#####.#.#.###.###.#.#.###.#.#.###.###.###.#####.#############.#.#.#.#######.###.#.#.#.###.#.#.###.#.###.#
 | 
				
			||||||
 | 
					#...#.#.........#.#...#.###...#.#...#...#...#...#...#.#.#.#...#.#.#...#...###...#...#...........#...#.#.#.......#...#.#.#...#.#.#.#...#...#.#
 | 
				
			||||||
 | 
					###.#.#########.#.#.###.#####.#.#.###.#.#######.###.#.#.#.#.###.#.#.###.#######.#.###.#########.#####.#.#.#######.###.#.###.#.#.#.#.#####.#.#
 | 
				
			||||||
 | 
					#...#.#.........#.#.#...#...#.#.#...#.#.###...#...#.#.#...#...#.#.#.#...#.....#...###.......#...#...#...#...#...#.....#.#...#.#.#.#...#...#.#
 | 
				
			||||||
 | 
					#.###.#.#########.#.#.###.#.#.#.###.#.#.###.#.###.#.#.#######.#.#.#.#.###.###.#############.#.###.#.#######.#.#.#######.#.###.#.#.###.#.###.#
 | 
				
			||||||
 | 
					#...#.#...........#...#...#...#.....#.#...#.#.###...#.#.......#.#.#...###...#.#...#...#.....#.....#.....#...#.#.....#...#...#.#.#.#...#.#...#
 | 
				
			||||||
 | 
					###.#.#################.#############.###.#.#.#######.#.#######.#.#########.#.#.#.#.#.#.###############.#.###.#####.#.#####.#.#.#.#.###.#.###
 | 
				
			||||||
 | 
					###...###...........#...#...#...#.....#...#.#...#...#.#.....###.#.#...###...#...#...#.#.....#...#.....#...#...#.....#...#...#.#.#.#...#...###
 | 
				
			||||||
 | 
					#########.#########.#.###.#.#.#.#.#####.###.###.#.#.#.#####.###.#.#.#.###.###########.#####.#.#.#.###.#####.###.#######.#.###.#.#.###.#######
 | 
				
			||||||
 | 
					#.......#.....#...#.#.....#...#...#...#...#.#...#.#.#.#.....#...#...#...#.....#.......#...#...#...###.......#...#...###...###.#.#.....#.....#
 | 
				
			||||||
 | 
					#.#####.#####.#.#.#.###############.#.###.#.#.###.#.#.#.#####.#########.#####.#.#######.#.###################.###.#.#########.#.#######.###.#
 | 
				
			||||||
 | 
					#.....#.#...#...#.#.#...###...#.....#.....#.#.#...#...#...###...#.......#.....#.###...#.#...#.......#.........###.#.#...#...#...#.......#...#
 | 
				
			||||||
 | 
					#####.#.#.#.#####.#.#.#.###.#.#.###########.#.#.#########.#####.#.#######.#####.###.#.#.###.#.#####.#.###########.#.#.#.#.#.#####.#######.###
 | 
				
			||||||
 | 
					#.....#...#.......#...#.....#.#.#...###...#.#.#...#.......#...#.#.###...#.....#...#.#.#.#...#.....#.#.............#.#.#.#.#.....#...#.....###
 | 
				
			||||||
 | 
					#.###########################.#.#.#.###.#.#.#.###.#.#######.#.#.#.###.#.#####.###.#.#.#.#.#######.#.###############.#.#.#.#####.###.#.#######
 | 
				
			||||||
 | 
					#.#...#.....................#.#...#.....#...#.....#.......#.#...#...#.#.#...#...#.#.#.#.#.........#.....#...........#.#...#...#.....#...#...#
 | 
				
			||||||
 | 
					#.#.#.#.###################.#.###########################.#.#######.#.#.#.#.###.#.#.#.#.###############.#.###########.#####.#.#########.#.#.#
 | 
				
			||||||
 | 
					#.#.#...#.....#.......#.....#...#...................#.....#.....#...#.#.#.#.....#...#.#...............#...#...........#.....#...........#.#.#
 | 
				
			||||||
 | 
					#.#.#####.###.#.#####.#.#######.#.#################.#.#########.#.###.#.#.###########.###############.#####.###########.#################.#.#
 | 
				
			||||||
 | 
					#...#...#...#.#.#...#.#.....#...#.................#...#...#...#.#.#...#.#.#...#.....#.#.........###...#.....#...........#...###...#.......#.#
 | 
				
			||||||
 | 
					#####.#.###.#.#.#.#.#.#####.#.###################.#####.#.#.#.#.#.#.###.#.#.#.#.###.#.#.#######.###.###.#####.###########.#.###.#.#.#######.#
 | 
				
			||||||
 | 
					###...#.....#...#.#.#.......#...............#.....###...#.#.#.#.#.#...#.#...#.#.###...#.......#.....#...#...#...........#.#...#.#.#.#.......#
 | 
				
			||||||
 | 
					###.#############.#.#######################.#.#######.###.#.#.#.#.###.#.#####.#.#############.#######.###.#.###########.#.###.#.#.#.#.#######
 | 
				
			||||||
 | 
					#...#...#...#...#.#...#.....#...#.........#.#.......#...#...#...#.#...#.....#.#...........###.......#.#...#.............#.#...#.#.#.#.###...#
 | 
				
			||||||
 | 
					#.###.#.#.#.#.#.#.###.#.###.#.#.#.#######.#.#######.###.#########.#.#######.#.###########.#########.#.#.#################.#.###.#.#.#.###.#.#
 | 
				
			||||||
 | 
					#...#.#...#...#.#.#...#.#...#.#.#.#...#...#.......#.###...#.......#.......#...#.....#.....#.......#...#...#...............#.....#...#...#.#.#
 | 
				
			||||||
 | 
					###.#.#########.#.#.###.#.###.#.#.#.#.#.#########.#.#####.#.#############.#####.###.#.#####.#####.#######.#.###########################.#.#.#
 | 
				
			||||||
 | 
					#...#.###...#...#.#...#.#.#...#...#.#...#.......#...#...#.#.......#.......#.....###...#...#...#...###...#...#.....#.....#...#.....#...#...#.#
 | 
				
			||||||
 | 
					#.###.###.#.#.###.###.#.#.#.#######.#####.#####.#####.#.#.#######.#.#######.###########.#.###.#.#####.#.#####.###.#.###.#.#.#.###.#.#.#####.#
 | 
				
			||||||
 | 
					#.#...#...#...#...###...#...#.......#...#.....#...#...#.#.#.......#.......#...#...#...#.#.#...#.....#.#.#...#...#.#...#.#.#.#.###.#.#.....#.#
 | 
				
			||||||
 | 
					#.#.###.#######.#############.#######.#.#####.###.#.###.#.#.#############.###.#.#.#.#.#.#.#.#######.#.#.#.#.###.#.###.#.#.#.#.###.#.#####.#.#
 | 
				
			||||||
 | 
					#.#.#...#.......#.....#.......#.....#.#.#...#...#.#...#.#.#.#...###...###.#...#.#.#.#.#.#.#.....#...#.#.#.#.....#...#.#...#.#...#.#.#...#...#
 | 
				
			||||||
 | 
					#.#.#.###.#######.###.#.#######.###.#.#.#.#.###.#.###.#.#.#.#.#.###.#.###.#.###.#.#.#.#.#.#####.#.###.#.#.#########.#.#####.###.#.#.#.#.#####
 | 
				
			||||||
 | 
					#...#.....#...###...#.#...#...#.#...#.#.#.#.#...#...#.#.#.#.#.#.#...#...#.#...#.#...#.#.#.....#.#.#...#.#.........#.#.....#...#.#.#...#...###
 | 
				
			||||||
 | 
					###########.#.#####.#.###.#.#.#.#.###.#.#.#.#.#####.#.#.#.#.#.#.#.#####.#.###.#.#####.#.#####.#.#.#.###.#########.#.#####.###.#.#.#######.###
 | 
				
			||||||
 | 
					#...........#.....#.#.###...#...#.#...#...#.#...#...#.#.#.#.#.#...###...#.#...#.....#...#.....#.#.#.###.#...#...#.#.#.....###.#.#...#...#...#
 | 
				
			||||||
 | 
					#.###############.#.#.###########.#.#######.###.#.###.#.#.#.#.#######.###.#.#######.#####.#####.#.#.###.#.#.#.#.#.#.#.#######.#.###.#.#.###.#
 | 
				
			||||||
 | 
					#...........#...#...#.#...#...#...#...#.....#...#.#...#.#.#.#.......#.#...#.....#...#.....#...#.#...#...#.#.#.#...#.#.......#...###...#...#.#
 | 
				
			||||||
 | 
					###########.#.#.#####.#.#.#.#.#.#####.#.#####.###.#.###.#.#.#######.#.#.#######.#.###.#####.#.#.#####.###.#.#.#####.#######.#############.#.#
 | 
				
			||||||
 | 
					#...........#.#.#...#...#...#...#...#.#.#...#.###.#.###...#...#...#.#.#.....#...#.#...#...#.#.#.#.....#...#...###...#...#...#.......#.....#.#
 | 
				
			||||||
 | 
					#.###########.#.#.#.#############.#.#.#.#.#.#.###.#.#########.#.#.#.#.#####.#.###.#.###.#.#.#.#.#.#####.#########.###.#.#.###.#####.#.#####.#
 | 
				
			||||||
 | 
					#...........#.#.#.#...#.........#.#.#.#...#.#.#...#.....#...#.#.#.#.#.#.....#...#.#...#.#.#.#...#.#...#.#...#...#...#.#.#...#.#.....#.....#.#
 | 
				
			||||||
 | 
					###########.#.#.#.###.#.#######.#.#.#.#####.#.#.#######.#.#.#.#.#.#.#.#.#######.#.###.#.#.#.#####.#.#.#.#.#.#.#.###.#.#.###.#.#.#########.#.#
 | 
				
			||||||
 | 
					#...........#.#...###...#.......#.#.#.#...#.#.#.#.....#.#.#...#.#.#.#.#.....#...#...#.#.#.#...#...#.#.#...#...#...#.#.#...#.#.#.#...#...#.#.#
 | 
				
			||||||
 | 
					#.###########.###########.#######.#.#.#.#.#.#.#.#.###.#.#.#####.#.#.#.#####.#.#####.#.#.#.###.#.###.#.###########.#.#.###.#.#.#.#.#.#.#.#.#.#
 | 
				
			||||||
 | 
					#.#...........#...###...#.....#...#.#.#.#...#.#.#...#.#.#...#...#.#.#.#...#.#.#...#.#.#.#.#...#.#...#.#...#...#...#.#.#...#...#...#...#.#.#.#
 | 
				
			||||||
 | 
					#.#.###########.#.###.#.#####.#.###.#.#.#####.#.###.#.#.###.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.###.#.#.#.#.#.###.#.#.###############.#.#.#
 | 
				
			||||||
 | 
					#...###.........#.....#.......#.###...#.....#.#.#...#.#.###.#...#.#.#.#.#.#.#.#.#.#.#...#.#.###...###.#.#...#.#...#.#.#.....#.....#.....#...#
 | 
				
			||||||
 | 
					#######.#######################.###########.#.#.#.###.#.###.###.#.#.#.#.#.#.#.#.#.#.#####.#.#########.#.#####.###.#.#.#####.#.###.#.#########
 | 
				
			||||||
 | 
					#.....#...#...#...........#...#.......#.....#.#.#...#...#...#...#.#.#...#.#.#.#.#...#.....#.#.........#.#...#.....#...###...#...#.#...#...###
 | 
				
			||||||
 | 
					#.###.###.#.#.#.#########.#.#.#######.#.#####.#.###.#####.###.###.#.#####.#.#.#.#####.#####.#.#########.#.#.#############.#####.#.###.#.#.###
 | 
				
			||||||
 | 
					#...#...#...#.#.#.........#.#...#...#.#...#...#.#...#.....#...#...#.....#.#.#...###...#.....#.#...#...#...#.....#...#...#.#...#.#...#...#...#
 | 
				
			||||||
 | 
					###.###.#####.#.#.#########.###.#.#.#.###.#.###.#.###.#####.###.#######.#.#.#######.###.#####.#.#.#.#.#########.#.#.#.#.#.#.#.#.###.#######.#
 | 
				
			||||||
 | 
					###.#...#.....#.#.........#.###.#.#.#.#...#.#...#...#.#...#...#...#...#.#.#.#.......#...#.....#.#.#.#.#...#...#...#...#.#...#.#...#...#.....#
 | 
				
			||||||
 | 
					###.#.###.#####.#########.#.###.#.#.#.#.###.#.#####.#.#.#.###.###.#.#.#.#.#.#.#######.###.#####.#.#.#.#.#.#.#.#########.#####.###.###.#.#####
 | 
				
			||||||
 | 
					#...#.....#.....#...#.....#...#.#.#.#.#.#...#...#...#.#.#.....#...#.#.#.#.#.#.#.....#.###...#...#...#.#.#.#.#.#...#...#.....#.....#...#.....#
 | 
				
			||||||
 | 
					#.#########.#####.#.#.#######.#.#.#.#.#.#.#####.#.###.#.#######.###.#.#.#.#.#.#.###.#.#####.#.#######.#.#.#.#.#.#.#.#.#####.#######.#######.#
 | 
				
			||||||
 | 
					#...#.....#.#.....#...#.....#.#.#.#.#.#.#...#...#...#.#...#...#.....#...#.#.#.#...#.#.#.....#.....#...#.#.#.#.#.#.#.#.#...#...#...#...#...#.#
 | 
				
			||||||
 | 
					###.#.###.#.#.#########.###.#.#.#.#.#.#.###.#.#####.#.###.#.#.###########.#.#.###.#.#.#.#########.#.###.#.#.#.#.#.#.#.#.#.###.#.#.###.#.#.#.#
 | 
				
			||||||
 | 
					#...#.#...#.#.....#...#.###.#.#...#.#.#...#.#.....#.#.#...#.#...#...#.....#.#.#...#...#.#.....#...#...#.#.#.#.#.#...#.#.#...#...#...#.#.#.#.#
 | 
				
			||||||
 | 
					#.###.#.###.#####.#.#.#.###.#.#####.#.###.#.#####.#.#.#.###.###.#.#.#.#####.#.#.#######.#.###.#.#####.#.#.#.#.#.#####.#.###.#######.#.#.#.#.#
 | 
				
			||||||
 | 
					#.....#...#.#.....#.#.#...#.#.###...#...#.#.#.....#.#.#.....#...#.#...#...#.#.#.......#...###.#.#...#...#.#.#.#.....#.#.###.#.......#.#.#.#.#
 | 
				
			||||||
 | 
					#########.#.#.#####.#.###.#.#.###.#####.#.#.#.#####.#.#######.###.#####.#.#.#.#######.#######.#.#.#.#####.#.#.#####.#.#.###.#.#######.#.#.#.#
 | 
				
			||||||
 | 
					###...###...#...#...#...#.#.#...#...#...#.#.#.....#.#...#...#.#...#...#.#.#.#.#.....#.###.....#...#...#...#.#...#...#...#...#.......#...#.#.#
 | 
				
			||||||
 | 
					###.#.#########.#.#####.#.#.###.###.#.###.#.#####.#.###.#.#.#.#.###.#.#.#.#.#.#.###.#.###.###########.#.###.###.#.#######.#########.#####.#.#
 | 
				
			||||||
 | 
					#...#...........#.....#.#.#...#...#.#...#.#.#.....#...#.#.#.#.#.#...#.#.#.#.#.#.#...#.#...#.....#...#.#...#.#...#.......#.#.....#...#.....#.#
 | 
				
			||||||
 | 
					#.###################.#.#.###.###.#.###.#.#.#.#######.#.#.#.#.#.#.###.#.#.#.#.#.#.###.#.###.###.#.#.#.###.#.#.#########.#.#.###.#.###.#####.#
 | 
				
			||||||
 | 
					#.....................#...###.....#.....#...#.........#...#...#...###...#...#...#.....#.....###...#...###...#...........#...###...###.......#
 | 
				
			||||||
 | 
					#############################################################################################################################################
 | 
				
			||||||
							
								
								
									
										66
									
								
								day_20/solve_1.test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								day_20/solve_1.test.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					import { assertEquals } from "jsr:@std/assert";
 | 
				
			||||||
 | 
					import { parseMap, toMapString } from "./solve_1.ts";
 | 
				
			||||||
 | 
					import { printPrettyMapStep } from "./solve_1.ts";
 | 
				
			||||||
 | 
					import { calculateNeedsSteps } from "./solve_1.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deno.test("parseMap", () => {
 | 
				
			||||||
 | 
					    const input = `..#\n#..`;
 | 
				
			||||||
 | 
					    const expected = [[".", ".", "#"], ["#", ".", "."]];
 | 
				
			||||||
 | 
					    assertEquals(parseMap(input), expected);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deno.test("toMapString", () => {
 | 
				
			||||||
 | 
					    const input = [[".", ".", "#"], ["#", ".", "."]];
 | 
				
			||||||
 | 
					    const expected = `..#\n#..`;
 | 
				
			||||||
 | 
					    assertEquals(toMapString(input), expected);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ExampleMap = `###############
 | 
				
			||||||
 | 
					#...#...#.....#
 | 
				
			||||||
 | 
					#.#.#.#.#.###.#
 | 
				
			||||||
 | 
					#S#...#.#.#...#
 | 
				
			||||||
 | 
					#######.#.#.###
 | 
				
			||||||
 | 
					#######.#.#...#
 | 
				
			||||||
 | 
					#######.#.###.#
 | 
				
			||||||
 | 
					###..E#...#...#
 | 
				
			||||||
 | 
					###.#######.###
 | 
				
			||||||
 | 
					#...###...#...#
 | 
				
			||||||
 | 
					#.#####.#.###.#
 | 
				
			||||||
 | 
					#.#...#.#.#...#
 | 
				
			||||||
 | 
					#.#.#.#.#.#.###
 | 
				
			||||||
 | 
					#...#...#...###
 | 
				
			||||||
 | 
					###############`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deno.test("printPrettyMapStep", ()=>{
 | 
				
			||||||
 | 
					    const map = parseMap(`...\n...\n...`);
 | 
				
			||||||
 | 
					    const actual = printPrettyMapStep(map, [
 | 
				
			||||||
 | 
					        [1,2,3],
 | 
				
			||||||
 | 
					        [4,5,6],
 | 
				
			||||||
 | 
					        [7,8,9]
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					    const expected = `123
 | 
				
			||||||
 | 
					456
 | 
				
			||||||
 | 
					789`;
 | 
				
			||||||
 | 
					    assertEquals(actual, expected);
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Deno.test("calculateNeedsSteps", () => {
 | 
				
			||||||
 | 
					    const map = parseMap(ExampleMap);
 | 
				
			||||||
 | 
					    const needsSteps = calculateNeedsSteps(map, [5, 7]);
 | 
				
			||||||
 | 
					    const expected = `###############
 | 
				
			||||||
 | 
					#210#432#87654#
 | 
				
			||||||
 | 
					#3#9#5#1#9###3#
 | 
				
			||||||
 | 
					#4#876#0#0#012#
 | 
				
			||||||
 | 
					#######9#1#9###
 | 
				
			||||||
 | 
					#######8#2#876#
 | 
				
			||||||
 | 
					#######7#3###5#
 | 
				
			||||||
 | 
					###210#654#234#
 | 
				
			||||||
 | 
					###3#######1###
 | 
				
			||||||
 | 
					#654###456#098#
 | 
				
			||||||
 | 
					#7#####3#7###7#
 | 
				
			||||||
 | 
					#8#456#2#8#456#
 | 
				
			||||||
 | 
					#9#3#7#1#9#3###
 | 
				
			||||||
 | 
					#012#890#012###
 | 
				
			||||||
 | 
					###############`;
 | 
				
			||||||
 | 
					    assertEquals(printPrettyMapStep(map, needsSteps), expected);
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
							
								
								
									
										205
									
								
								day_20/solve_1.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								day_20/solve_1.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,205 @@
 | 
				
			||||||
 | 
					import { associateBy } from "jsr:@std/collections/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Map = string[][];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Pos = [number, number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function parseMap(input: string): Map {
 | 
				
			||||||
 | 
					    return input.replaceAll("\r", "").split("\n").map((line) => line.split(""));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export async function readMap(filename: string): Promise<Map> {
 | 
				
			||||||
 | 
					    return parseMap(await Deno.readTextFile(filename));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function toMapString(map: Map): string {
 | 
				
			||||||
 | 
					    return map.map((line) => line.join("")).join("\n");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function* availableNextStep(
 | 
				
			||||||
 | 
					    map: Map,
 | 
				
			||||||
 | 
					    pos: Pos,
 | 
				
			||||||
 | 
					): Generator<Pos> {
 | 
				
			||||||
 | 
					    const [width, height] = [map[0].length, map.length];
 | 
				
			||||||
 | 
					    const [x, y] = pos;
 | 
				
			||||||
 | 
					    for (const [dx, dy] of [[-1, 0], [1, 0], [0, -1], [0, 1]]) {
 | 
				
			||||||
 | 
					        const nx = x + dx;
 | 
				
			||||||
 | 
					        const ny = y + dy;
 | 
				
			||||||
 | 
					        if (nx < 0 || nx >= width || ny < 0 || ny >= height) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (map[ny][nx] === "#") {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        yield [nx, ny] as Pos;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function calculateNeedsSteps(map: Map, startPos: Pos): number[][] {
 | 
				
			||||||
 | 
					    const needsSteps = map.map((line) => line.map(() => -1));
 | 
				
			||||||
 | 
					    const [x, y] = startPos;
 | 
				
			||||||
 | 
					    const queue: Pos[] = [startPos];
 | 
				
			||||||
 | 
					    needsSteps[y][x] = 0;
 | 
				
			||||||
 | 
					    while (queue.length > 0) {
 | 
				
			||||||
 | 
					        const [x, y] = queue.shift()!;
 | 
				
			||||||
 | 
					        const steps = needsSteps[y][x];
 | 
				
			||||||
 | 
					        for (const [nx, ny] of availableNextStep(map, [x, y])) {
 | 
				
			||||||
 | 
					            // already visited and shorter path
 | 
				
			||||||
 | 
					            if (needsSteps[ny][nx] >= 0 && needsSteps[ny][nx] <= steps + 1) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (steps < 0) {
 | 
				
			||||||
 | 
					                throw new Error("steps < 0");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            needsSteps[ny][nx] = steps + 1;
 | 
				
			||||||
 | 
					            queue.push([nx, ny]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return needsSteps;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export function printPrettyMapStep(
 | 
				
			||||||
 | 
					    map: Map,
 | 
				
			||||||
 | 
					    needsSteps: number[][],
 | 
				
			||||||
 | 
					): string {
 | 
				
			||||||
 | 
					    const result = map.map((line, y) =>
 | 
				
			||||||
 | 
					        line.map((char, x) => {
 | 
				
			||||||
 | 
					            if (char === "#") {
 | 
				
			||||||
 | 
					                return "#";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const steps = needsSteps[y][x];
 | 
				
			||||||
 | 
					            if (steps === -1) {
 | 
				
			||||||
 | 
					                return " ";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return steps.toString()[steps.toString().length - 1]; // last digit
 | 
				
			||||||
 | 
					        }).join("")
 | 
				
			||||||
 | 
					    ).join("\n");
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function findOnMap(
 | 
				
			||||||
 | 
					    map: Map,
 | 
				
			||||||
 | 
					    condition: (pos: Pos, char: string) => boolean,
 | 
				
			||||||
 | 
					): Pos[] {
 | 
				
			||||||
 | 
					    const result: Pos[] = [];
 | 
				
			||||||
 | 
					    map.forEach((line, y) => {
 | 
				
			||||||
 | 
					        line.forEach((char, x) => {
 | 
				
			||||||
 | 
					            if (condition([x, y], char)) {
 | 
				
			||||||
 | 
					                result.push([x, y]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function solve(map: Map) {
 | 
				
			||||||
 | 
					    const [startPos] = findOnMap(map, (_pos, char) => char === "S");
 | 
				
			||||||
 | 
					    const [endPos] = findOnMap(map, (_pos, char) => char === "E");
 | 
				
			||||||
 | 
					    const needsSteps = calculateNeedsSteps(map, endPos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function* jumpAvailPos(
 | 
				
			||||||
 | 
					        pos: Pos,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        const [x, y] = pos;
 | 
				
			||||||
 | 
					        const jumps = [
 | 
				
			||||||
 | 
					            [-2, 0],
 | 
				
			||||||
 | 
					            [2, 0],
 | 
				
			||||||
 | 
					            [0, -2],
 | 
				
			||||||
 | 
					            [0, 2],
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        for (const [dx, dy] of jumps) {
 | 
				
			||||||
 | 
					            const nx = x + dx;
 | 
				
			||||||
 | 
					            const ny = y + dy;
 | 
				
			||||||
 | 
					            if (nx < 0 || nx >= map[0].length || ny < 0 || ny >= map.length) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (map[ny][nx] === "#") {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            yield [nx, ny] as Pos;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function* availableJump(
 | 
				
			||||||
 | 
					        pos: Pos,
 | 
				
			||||||
 | 
					        steps: number,
 | 
				
			||||||
 | 
					    ): Generator<{
 | 
				
			||||||
 | 
					        from: Pos;
 | 
				
			||||||
 | 
					        to: Pos;
 | 
				
			||||||
 | 
					        savedSteps: number;
 | 
				
			||||||
 | 
					    }> {
 | 
				
			||||||
 | 
					        const [x, y] = pos;
 | 
				
			||||||
 | 
					        for (const [jx, jy] of jumpAvailPos(pos)) {
 | 
				
			||||||
 | 
					            const originalSteps = needsSteps[y][x];
 | 
				
			||||||
 | 
					            const cheatedSteps = needsSteps[jy][jx] + 2;
 | 
				
			||||||
 | 
					            if (cheatedSteps < originalSteps) {
 | 
				
			||||||
 | 
					                yield {
 | 
				
			||||||
 | 
					                    from: pos,
 | 
				
			||||||
 | 
					                    to: [jx, jy],
 | 
				
			||||||
 | 
					                    savedSteps: originalSteps - cheatedSteps,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const queue = [{
 | 
				
			||||||
 | 
					        pos: startPos,
 | 
				
			||||||
 | 
					        steps: 0,
 | 
				
			||||||
 | 
					    }];
 | 
				
			||||||
 | 
					    const visited = new Set<string>();
 | 
				
			||||||
 | 
					    visited.add(startPos.toString());
 | 
				
			||||||
 | 
					    const ret: {
 | 
				
			||||||
 | 
					        from: Pos;
 | 
				
			||||||
 | 
					        to: Pos;
 | 
				
			||||||
 | 
					        savedSteps: number;
 | 
				
			||||||
 | 
					    }[] = [];
 | 
				
			||||||
 | 
					    while (queue.length > 0) {
 | 
				
			||||||
 | 
					        const n = queue.shift()!;
 | 
				
			||||||
 | 
					        const {
 | 
				
			||||||
 | 
					            pos: [x, y],
 | 
				
			||||||
 | 
					            steps,
 | 
				
			||||||
 | 
					        } = n;
 | 
				
			||||||
 | 
					        if (x === endPos[0] && y === endPos[1]) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // find jump
 | 
				
			||||||
 | 
					        for (const jump of availableJump([x, y], steps)) {
 | 
				
			||||||
 | 
					            console.log(jump);
 | 
				
			||||||
 | 
					            ret.push(jump);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const nextPos of availableNextStep(map, [x, y])) {
 | 
				
			||||||
 | 
					            const key = nextPos.toString();
 | 
				
			||||||
 | 
					            if (visited.has(key)) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            visited.add(key);
 | 
				
			||||||
 | 
					            queue.push({
 | 
				
			||||||
 | 
					                pos: nextPos,
 | 
				
			||||||
 | 
					                steps: steps + 1,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const jumpMap = new Map< number, { from: Pos, to: Pos, savedSteps: number }[]>();
 | 
				
			||||||
 | 
					    for (const jump of ret) {
 | 
				
			||||||
 | 
					        const key = jump.savedSteps;
 | 
				
			||||||
 | 
					        if (!jumpMap.has(key)) {
 | 
				
			||||||
 | 
					            jumpMap.set(key, []);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        jumpMap.get(key)!.push(jump);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return jumpMap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (import.meta.main) {
 | 
				
			||||||
 | 
					    const map = await readMap("input.txt");
 | 
				
			||||||
 | 
					    console.log(toMapString(map));
 | 
				
			||||||
 | 
					    const [endPos] = findOnMap(map, (_pos, char) => char === "E");
 | 
				
			||||||
 | 
					    const needsSteps = calculateNeedsSteps(map, endPos);
 | 
				
			||||||
 | 
					    console.log(printPrettyMapStep(map, needsSteps));
 | 
				
			||||||
 | 
					    const jpm = solve(map);
 | 
				
			||||||
 | 
					    const keys = Array.from(jpm.keys()).sort((a, b) => a - b).filter((key) => key >= 100);
 | 
				
			||||||
 | 
					    const count = keys.reduce((acc, key) => acc + jpm.get(key)!.length, 0);
 | 
				
			||||||
 | 
					    console.log(count);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										127
									
								
								day_20/solve_2.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								day_20/solve_2.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,127 @@
 | 
				
			||||||
 | 
					import type { Map, Pos } from "./solve_1.ts";
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    availableNextStep,
 | 
				
			||||||
 | 
					    calculateNeedsSteps,
 | 
				
			||||||
 | 
					    findOnMap,
 | 
				
			||||||
 | 
					    printPrettyMapStep,
 | 
				
			||||||
 | 
					    readMap,
 | 
				
			||||||
 | 
					    toMapString,
 | 
				
			||||||
 | 
					} from "./solve_1.ts";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function solve(map: Map) {
 | 
				
			||||||
 | 
					    const [startPos] = findOnMap(map, (_pos, char) => char === "S");
 | 
				
			||||||
 | 
					    const [endPos] = findOnMap(map, (_pos, char) => char === "E");
 | 
				
			||||||
 | 
					    const needsSteps = calculateNeedsSteps(map, endPos);
 | 
				
			||||||
 | 
					    function* jumpAvailPos(
 | 
				
			||||||
 | 
					        pos: Pos,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        const [x, y] = pos;
 | 
				
			||||||
 | 
					        for (let dx = -20; dx <= 20; dx += 1) {
 | 
				
			||||||
 | 
					            const maxDy = 20 - Math.abs(dx);
 | 
				
			||||||
 | 
					            for (let dy = -maxDy; dy <= maxDy; dy += 1) {
 | 
				
			||||||
 | 
					                const nx = x + dx;
 | 
				
			||||||
 | 
					                const ny = y + dy;
 | 
				
			||||||
 | 
					                if (
 | 
				
			||||||
 | 
					                    nx < 0 || nx >= map[0].length || ny < 0 || ny >= map.length
 | 
				
			||||||
 | 
					                ) {
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (map[ny][nx] === "#") {
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                const jumpLength = Math.abs(dx) + Math.abs(dy);
 | 
				
			||||||
 | 
					                yield [nx, ny, jumpLength] as [number, number, number];
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function* availableJump(
 | 
				
			||||||
 | 
					        pos: Pos,
 | 
				
			||||||
 | 
					    ): Generator<{
 | 
				
			||||||
 | 
					        from: Pos;
 | 
				
			||||||
 | 
					        to: Pos;
 | 
				
			||||||
 | 
					        savedSteps: number;
 | 
				
			||||||
 | 
					    }> {
 | 
				
			||||||
 | 
					        const [x, y] = pos;
 | 
				
			||||||
 | 
					        for (const [jx, jy, steps] of jumpAvailPos(pos)) {
 | 
				
			||||||
 | 
					            const originalSteps = needsSteps[y][x];
 | 
				
			||||||
 | 
					            const cheatedSteps = needsSteps[jy][jx] + steps;
 | 
				
			||||||
 | 
					            if (cheatedSteps < originalSteps) {
 | 
				
			||||||
 | 
					                yield {
 | 
				
			||||||
 | 
					                    from: pos,
 | 
				
			||||||
 | 
					                    to: [jx, jy],
 | 
				
			||||||
 | 
					                    savedSteps: originalSteps - cheatedSteps,
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const queue = [{
 | 
				
			||||||
 | 
					        pos: startPos,
 | 
				
			||||||
 | 
					        steps: 0,
 | 
				
			||||||
 | 
					    }];
 | 
				
			||||||
 | 
					    const visited = new Set<string>();
 | 
				
			||||||
 | 
					    visited.add(startPos.toString());
 | 
				
			||||||
 | 
					    const ret: {
 | 
				
			||||||
 | 
					        from: Pos;
 | 
				
			||||||
 | 
					        to: Pos;
 | 
				
			||||||
 | 
					        savedSteps: number;
 | 
				
			||||||
 | 
					    }[] = [];
 | 
				
			||||||
 | 
					    while (queue.length > 0) {
 | 
				
			||||||
 | 
					        const n = queue.shift()!;
 | 
				
			||||||
 | 
					        const {
 | 
				
			||||||
 | 
					            pos: [x, y],
 | 
				
			||||||
 | 
					            steps,
 | 
				
			||||||
 | 
					        } = n;
 | 
				
			||||||
 | 
					        if (x === endPos[0] && y === endPos[1]) {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // find jump
 | 
				
			||||||
 | 
					        for (const jump of availableJump([x, y])) {
 | 
				
			||||||
 | 
					            ret.push(jump);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (const nextPos of availableNextStep(map, [x, y])) {
 | 
				
			||||||
 | 
					            const key = nextPos.toString();
 | 
				
			||||||
 | 
					            if (visited.has(key)) {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            visited.add(key);
 | 
				
			||||||
 | 
					            queue.push({
 | 
				
			||||||
 | 
					                pos: nextPos,
 | 
				
			||||||
 | 
					                steps: steps + 1,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const jumpMap = new Map<
 | 
				
			||||||
 | 
					        number,
 | 
				
			||||||
 | 
					        { from: Pos; to: Pos; savedSteps: number }[]
 | 
				
			||||||
 | 
					    >();
 | 
				
			||||||
 | 
					    for (const jump of ret) {
 | 
				
			||||||
 | 
					        const key = jump.savedSteps;
 | 
				
			||||||
 | 
					        if (!jumpMap.has(key)) {
 | 
				
			||||||
 | 
					            jumpMap.set(key, []);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        jumpMap.get(key)!.push(jump);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return jumpMap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (import.meta.main) {
 | 
				
			||||||
 | 
					    const map = await readMap("input.txt");
 | 
				
			||||||
 | 
					    console.log(toMapString(map));
 | 
				
			||||||
 | 
					    const [endPos] = findOnMap(map, (_pos, char) => char === "E");
 | 
				
			||||||
 | 
					    const needsSteps = calculateNeedsSteps(map, endPos);
 | 
				
			||||||
 | 
					    console.log(printPrettyMapStep(map, needsSteps));
 | 
				
			||||||
 | 
					    const jpm = solve(map);
 | 
				
			||||||
 | 
					    const keys = Array.from(jpm.keys()).sort((a, b) => a - b).filter((key) =>
 | 
				
			||||||
 | 
					        key >= 100
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    for (const key of keys) {
 | 
				
			||||||
 | 
					        console.log(`key: ${key} (${jpm.get(key)!.length})`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const count = keys.reduce((acc, key) => acc + jpm.get(key)!.length, 0);
 | 
				
			||||||
 | 
					    console.log(count);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue