this post was submitted on 08 Dec 2024
21 points (95.7% liked)

Advent Of Code

920 readers
2 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 8: Resonant Collinearity

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
[โ€“] [email protected] 3 points 1 month ago (4 children)

Haskell

Not a very pretty solution today, I'm afraid.

import Control.Arrow
import Control.Monad
import Data.Biapplicative
import Data.Ix
import Data.Map (Map)
import Data.Map qualified as Map
import Data.Set qualified as Set

type Coords = (Int, Int)

readInput :: String -> Map Coords Char
readInput s =
  Map.fromAscList
    [ ((i, j), c)
      | (i, l) <- zip [0 ..] (lines s),
        (j, c) <- zip [0 ..] l
    ]

(.+.), (.-.) :: Coords -> Coords -> Coords
(.+.) = join biliftA2 (+)
(.-.) = join biliftA2 (-)

part1, part2 :: (Coords -> Bool) -> (Coords, Coords) -> [Coords]
part1 valid (p1, p2) =
  let s = p2 .-. p1
   in filter valid [p1 .-. s, p2 .+. s]
part2 valid (p1, p2) =
  let (si, sj) = p2 .-. p1
      d = gcd si sj
      s = (si `div` d, sj `div` d)
   in takeWhile valid (iterate (.+. s) p1)
        ++ takeWhile valid (drop 1 $ iterate (.-. s) p2)

pairs (x : xs) = map (x,) xs ++ pairs xs
pairs _ = []

main = do
  input <- readInput <$> readFile "input08"
  let antennas = Map.filter (/= '.') input
      antennaGroups =
        Map.foldrWithKey
          (\p c m -> Map.insertWith (++) c [p] m)
          Map.empty
          antennas
      valid =
        inRange
          . (Set.findMin &&& Set.findMax)
          $ Map.keysSet input
      antiNodes model =
        Set.fromList
          . concatMap (concatMap (model valid) . pairs)
          $ antennaGroups
  print . Set.size $ antiNodes part1
  print . Set.size $ antiNodes part2
[โ€“] VegOwOtenks 2 points 1 month ago* (last edited 1 month ago) (3 children)

Whaaat? It is possible to declare mutliple signatures on one line? ๐Ÿคฏ
Does that function (.+.) add tuples/coordinates?

[โ€“] [email protected] 2 points 1 month ago (2 children)

Yup, that's right! The function monad is a bit of a mind-bender, but (join f) x == f x x is a useful thing to remember.

[โ€“] VegOwOtenks 2 points 1 month ago (1 children)

This is so cool, it's going to replace the lambda in my function pipeline for calculating pairs.

[โ€“] [email protected] 1 points 1 month ago

BTW, for more in-depth vector stuff I usually use the Linear package.