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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 4 points 10 months ago* (last edited 10 months ago) (1 child)

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  
  • source
  • hideshow 1 child comment
  • [โ€“] 1 point 10 months 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  
    
  • source
  • parent