2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								require "advent"
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								require "benchmark"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								INPUT = input(2020, 17).lines.map(&.chars) 
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								def solve(input, dim)
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  step = input.clone
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  cubes = Set(Array(Int32)).new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  new_cubes = Set(Array(Int32)).new
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  input.each_with_index do |row, y|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    row.each_with_index do |c, x|
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      cubes << [x,y].concat([0] * (dim-2)) if c == '#'
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  8.times do |i|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    print '.'
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    neighbor_count = Hash(Array(Int32), Int32).new(0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Array.product([[-1,0,1]] * dim).each do |diff|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      next if diff.all? &.==(0)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      cubes.each do |c|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        neighbor_count[c.zip_with(diff) { |a,b| a+b }] += 1
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    new_cubes.clear
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    neighbor_count.each do |n, i|
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      new_cubes << n if i == 3 || (cubes.includes?(n) && i == 2)
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    new_cubes, cubes = cubes, new_cubes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  cubes.size
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								def part1(input)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  solve(input, 3)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								def part2(input)
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  solve(input, 4)
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-16 21:29:26 -08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2020-12-20 00:31:30 -08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								(3..).each do |i|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  print "Dim #{i} "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  bm = Benchmark.measure { puts " #{solve(INPUT, i)}" }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  puts bm.real * 1000
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 |