Day 7: Laboratories

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • Amy@piefed.blahaj.zone
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    3 days ago

    Haskell

    That was a fun little problem.

    import Data.Map qualified as Map  
    import Data.Set qualified as Set  
    import Data.Tuple (swap)  
    
    readInput s =  
      Map.fromDistinctAscList  
        [((i, j), c) | (i, l) <- zip [0 ..] $ lines s, (j, c) <- zip [0 ..] l]  
    
    beamPaths input = scanl step (Map.singleton startX 1) [startY .. endY]  
      where  
        Just (startY, startX) = lookup 'S' $ map swap $ Map.assocs input  
        Just ((endY, _), _) = Map.lookupMax input  
        step beams y =  
          Map.unionsWith (+) $  
            [ if input Map.!? (y + 1, j) == Just '^'  
                then Map.fromList [(j - 1, n), (j + 1, n)]  
                else Map.singleton j n  
              | (j, n) <- Map.assocs beams  
            ]  
    
    part1 = sum . map Set.size . (zipWith (Set.\\) <*> tail) . map Map.keysSet . beamPaths  
    
    part2 = sum . last . beamPaths  
    
    main = do  
      input <- readInput <$> readFile "input07"  
      print $ part1 input  
      print $ part2 input  
    
    • Amy@piefed.blahaj.zone
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      3 days ago

      And here’s a super-simple version, because why not.

      import Data.List (elemIndex, elemIndices)  
      import Data.Map qualified as Map  
      import Data.Maybe (fromJust)  
      import Data.Set qualified as Set  
      
      main = do  
        (start : rows) <- lines <$> readFile "input07"  
        let splitsByRow =  
              zipWith  
                ( \row beams ->  
                    Set.intersection (Map.keysSet beams)  
                      . Set.fromDistinctAscList  
                      $ elemIndices '^' row  
                )  
                rows  
                beamsByRow  
            beamsByRow =  
              scanl  
                ( \beams splits ->  
                    let unsplit = beams `Map.withoutKeys` splits  
                        split = beams `Map.restrictKeys` splits  
                        splitLeft = Map.mapKeysMonotonic pred split  
                        splitRight = Map.mapKeysMonotonic succ split  
                     in Map.unionsWith (+) [unsplit, splitLeft, splitRight]  
                )  
                (Map.singleton (fromJust $ elemIndex 'S' start) 1)  
                splitsByRow  
        print . sum $ map Set.size splitsByRow  
        print . sum $ last beamsByRow