You are reading a single comment by @DavidM_ and its replies. Click here to read the full conversation.
  • Part of the fun is seeing how other people approach each day.

    Also seeing what people use as their measure of "done".

    For some it is just a case of getting both stars and moving on to the next problem, but many are only happy when they have something that is relatively optimal in terms of CPU and/or memory (some times it's impossible to do both).

    I have everything just in one file

    Haven't done this for any of the previous years but I'm tempted to do this at the end, partly because it will make timing the entire run of the year much easier.

  • Also seeing what people use as their measure of "done".

    Agreed - that's what I'm often most interested in when viewing how others approach the problem.

    If my immediate approach to getting the answer is suboptimal - especially when compared to other clean, but efficient methods written by others - then I'll make a mental note of that better approach and take it with me to the next problem. I've found from previous years that if I'm too caught up in worrying about writing 'imperfect' solutions then I'll not get anything done, so I figure at least getting something which is not horrifically slow should suffice.

    I figured I'd do a little bit of input modification for today's solution so that I didn't spend more than a few minutes on some regex which would invariably fail:

    Lesson learned from today is to always verify my output from parsing before moving on to writing the solver. Was a right pain when I realised my initial parsing approach resulted in a shifted crate.

    Day 5 solution (tried keeping this hidden/collapsible but well formatted and failing):

      "Day 5" - {
    
        enum CraneMoverModel:
          case `9000`, `9001`
    
        case class Instruction(from: Int, to: Int, number: Int)
    
        val crateRegex = """\[([A-Z-])\]""".r
        val instructionRegex = """^move\s(\d+)\sfrom\s(\d+)\sto\s(\d+)$""".r
    
        def gatherInstructions(instructionsInput: String): Array[Instruction] =
          instructionsInput.split("\\n").map {
            case instructionRegex(number, from, to) => Instruction(from.toInt, to.toInt, number.toInt)
          }
    
        def gatherCrates(cratesInput: String): Map[Int, Array[Char]] =
          cratesInput.split("\\n")
            .map: crate =>
              crateRegex.findAllMatchIn(crate).map(_.group(1)).toArray
            .transpose
            .map: crates =>
              crates
                .reverse
                .filterNot(_ == "-") // input blank crates have been changed to hyphens for convenience
                .map(_.charAt(0))
            .zipWithIndex.map { (crateArray, idx) =>
              (idx + 1, crateArray)
            }.toMap
    
        /*
            Following modifications made to input:
              - stack number line removed
              - empty crates have been relabelled as [-]
        */
        def parseInput(input: String): (Array[Instruction], Map[Int, Array[Char]]) =
          val Array(crateInfo, instructionInfo) = input.split("\\n\\n")
          (gatherInstructions(instructionInfo), gatherCrates(crateInfo))
          
        def solve(input: String, craneMoverModel: CraneMoverModel): String =
          val (instructions, cratesMap) = parseInput(input)
          val result = instructions.foldLeft(cratesMap) { (currentCrates, instruction) =>
            val from        = currentCrates(instruction.from)
            val to          = currentCrates(instruction.to)
            val valuesToAdd = from.takeRight(instruction.number)
            val add         = craneMoverModel match
              case CraneMoverModel.`9000` => valuesToAdd.reverse
              case CraneMoverModel.`9001` => valuesToAdd
            currentCrates
              .updated(instruction.from, from.dropRight(instruction.number))
              .updated(instruction.to, to ++: add)
          }
          result
            .toArray
            .sortBy: (idx, _) =>
              idx
            .flatMap: (_, crates) =>
              crates.lastOption
            .mkString
    
        "sample part a" in:
          inputStringFor(Day.`5`, Input.sample, Part.a).use: input =>
            IO.println(solve(input, CraneMoverModel.`9000`))
    
        "part a" in :
          inputStringFor(Day.`5`, Input.real, Part.a).use: input =>
            IO.println(solve(input, CraneMoverModel.`9000`))
        
        "sample part b" in:
          inputStringFor(Day.`5`, Input.sample, Part.b).use: input =>
            IO.println(solve(input, CraneMoverModel.`9001`))
    
        "part b" in :
          inputStringFor(Day.`5`, Input.real, Part.b).use: input =>
            IO.println(solve(input, CraneMoverModel.`9001`))  
    
      }
    
About

Avatar for DavidM_ @DavidM_ started