day 16 puzzle 1
This commit is contained in:
		| @@ -5,11 +5,11 @@ This repo contains my attempt at this year's Advent of Code (2023) | ||||
| I will try and do some problems (probably not all of them) in Scala | ||||
|  | ||||
| ## Progress: | ||||
| #### Stars: 28 / 50 | ||||
| #### Stars: 29 / 50 | ||||
| |        Mon         |        Tue        |        Wed         |        Thu         |        Fri         |        Sat        |        Sun         | | ||||
| |:------------------:|:-----------------:|:------------------:|:------------------:|:------------------:|:-----------------:|:------------------:| | ||||
| |                    |                   |                    |                    | 1<br>:star::star:  | 2<br>:star::star: | 3<br>:star::star:  | | ||||
| | 4<br>:star::star:  | 5<br>:star::star: | 6<br>:star::star:  | 7<br>:star::star:  | 8<br>:star::star:  | 9<br>:star::star: | 10<br>:star::star: | | ||||
| | 11<br>:star::star: |        12         | 13<br>:star::star: | 14<br>:star::star: | 15<br>:star::star: |        16         |         17         | | ||||
| | 11<br>:star::star: |        12         | 13<br>:star::star: | 14<br>:star::star: | 15<br>:star::star: |   16<br>:star:    |         17         | | ||||
| |         18         |        19         |         20         |         21         |         22         |        23         |         24         | | ||||
| |         25         |                   |                    |                    |                    |                   |                    | | ||||
							
								
								
									
										10
									
								
								src/day16/Mirrors.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/day16/Mirrors.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| package day16 | ||||
|  | ||||
| object Mirrors extends Enumeration { | ||||
|   type Mirror = Value | ||||
|   val NONE = Value(".") | ||||
|   val DIAGONAL_TL_BR = Value("\\") | ||||
|   val DIAGONAL_BL_TR = Value("/") | ||||
|   val SPLITTER_HOR = Value("-") | ||||
|   val SPLITTER_VER = Value("|") | ||||
| } | ||||
							
								
								
									
										103
									
								
								src/day16/Puzzle1.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/day16/Puzzle1.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| package day16 | ||||
|  | ||||
| import day16.Mirrors.{DIAGONAL_BL_TR, DIAGONAL_TL_BR, Mirror, NONE, SPLITTER_HOR, SPLITTER_VER} | ||||
|  | ||||
| import scala.collection.mutable.ArrayBuffer | ||||
| import scala.io.{BufferedSource, Source} | ||||
|  | ||||
| object Puzzle1 { | ||||
|   var mirrors: Array[Array[Mirror]] = Array.empty | ||||
|   var energized: Array[Array[Boolean]] = Array.empty | ||||
|   var width: Int = 0 | ||||
|   var height: Int = 0 | ||||
|   val OFFSETS: Array[(Int, Int)] = Array( | ||||
|     (1, 0), (0, 1), (-1, 0), (0, -1) | ||||
|   ) | ||||
|   val path: ArrayBuffer[(Int, Int, Int)] = new ArrayBuffer() | ||||
|  | ||||
|   def loadInput(path: String): Unit = { | ||||
|     val source: BufferedSource = Source.fromFile(path) | ||||
|     val lines: Array[String] = source.getLines().toArray | ||||
|  | ||||
|     height = lines.length | ||||
|     width = if (height == 0) 0 else lines(0).length | ||||
|     mirrors = Array.ofDim(height, width) | ||||
|     energized = Array.ofDim(height, width) | ||||
|  | ||||
|     for ((line: String, y: Int) <- lines.zipWithIndex) { | ||||
|       for ((c: Char, x: Int) <- line.zipWithIndex) { | ||||
|         val mirror: Mirror = Mirrors.withName(""+c) | ||||
|         mirrors(y)(x) = mirror | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     source.close() | ||||
|   } | ||||
|  | ||||
|   def shootBeam(startX: Int, startY: Int, startDir: Int): Unit = { | ||||
|     if (startX < 0 || startX >= width || startY < 0 || startY >= height) return | ||||
|     var x: Int = startX | ||||
|     var y: Int = startY | ||||
|     var dir: Int = startDir | ||||
|     var continue: Boolean = true | ||||
|     do { | ||||
|       if (path.contains((x, y, dir))) return | ||||
|       path.addOne((x, y, dir)) | ||||
|  | ||||
|       energized(y)(x) = true | ||||
|  | ||||
|       mirrors(y)(x) match { | ||||
|         case NONE => {} | ||||
|         case DIAGONAL_TL_BR => { | ||||
|           dir = Math.floorDiv(dir, 2)*2 + 1 - (dir % 2) | ||||
|         } | ||||
|         case DIAGONAL_BL_TR => { | ||||
|           dir = 3 - dir | ||||
|         } | ||||
|         case SPLITTER_HOR => { | ||||
|           if (dir % 2 == 1) { | ||||
|             continue = false | ||||
|             shootBeam(x+1, y, 0) | ||||
|             shootBeam(x-1, y, 2) | ||||
|           } | ||||
|         } | ||||
|         case SPLITTER_VER => { | ||||
|           if (dir % 2 == 0) { | ||||
|             continue = false | ||||
|             shootBeam(x, y+1, 1) | ||||
|             shootBeam(x, y-1, 3) | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       if (continue) { | ||||
|         val offset: (Int, Int) = OFFSETS(dir) | ||||
|         x += offset._1 | ||||
|         y += offset._2 | ||||
|       } | ||||
|  | ||||
|       if (x < 0 || x >= width) continue = false | ||||
|       if (y < 0 || y >= height) continue = false | ||||
|     } while (continue) | ||||
|   } | ||||
|  | ||||
|   def solve(path: String): Int = { | ||||
|     loadInput(path) | ||||
|     shootBeam(0, 0, 0) | ||||
|  | ||||
|     var solution: Int = 0 | ||||
|  | ||||
|     for (y: Int <- 0 until height) { | ||||
|       for (x: Int <- 0 until width) { | ||||
|         if (energized(y)(x)) solution += 1 | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     return solution | ||||
|   } | ||||
|  | ||||
|   def main(args: Array[String]): Unit = { | ||||
|     val solution: Int = solve("./res/day16/input1.txt") | ||||
|     println(solution) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										9
									
								
								tests/day16/Puzzle1Test.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/day16/Puzzle1Test.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| package day16 | ||||
|  | ||||
| import org.scalatest.funsuite.AnyFunSuite | ||||
|  | ||||
| class Puzzle1Test extends AnyFunSuite { | ||||
|   test("Puzzle1.solve") { | ||||
|     assert(Puzzle1.solve("tests_res/day16/input1.txt") == 46) | ||||
|   } | ||||
| } | ||||
							
								
								
									
										10
									
								
								tests_res/day16/input1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests_res/day16/input1.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| .|...\.... | ||||
| |.-.\..... | ||||
| .....|-... | ||||
| ........|. | ||||
| .......... | ||||
| .........\ | ||||
| ..../.\\.. | ||||
| .-.-/..|.. | ||||
| .|....-|.\ | ||||
| ..//.|.... | ||||
		Reference in New Issue
	
	Block a user