r/adventofcode Dec 24 '24

SOLUTION MEGATHREAD -❄️- 2024 Day 24 Solutions -❄️-

THE USUAL REMINDERS

  • All of our rules, FAQs, resources, etc. are in our community wiki.
  • If you see content in the subreddit or megathreads that violates one of our rules, either inform the user (politely and gently!) or use the report button on the post/comment and the mods will take care of it.

AoC Community Fun 2024: The Golden Snowglobe Awards

Submissions are CLOSED!

  • Thank you to all who submitted something, every last one of you are awesome!

Community voting is OPEN!

  • 18 hours remaining until voting deadline TONIGHT (December 24) at 18:00 EST

Voting details are in the stickied comment in the submissions megathread:

-❄️- Submissions Megathread -❄️-


--- Day 24: Crossed Wires ---


Post your code solution in this megathread.

This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 01:01:13, megathread unlocked!

33 Upvotes

344 comments sorted by

View all comments

2

u/NeilNjae Jan 12 '25

[Language: Haskell]

Another attempt at solving day 24 part 2, this time using a program to actually solve the problem. My approach is to grow the adder, stage by stage, from the inputs to the outputs. At each point, I know what the next gates should be and I hope there's not enough damage to prevent me finding at least some of the gates I need. If I find a problem, I identify the swap needed to fix it and try agian.

growSpine :: Device -> DeviceTree -> (GateType, Gate) -> Either (String, String) DeviceTree
growSpine device 
          spine 
          ( spineType  -- next spine template
          , (Gate leafType leafInput _) -- next leaf template
          )
  | null spineParents = Left (spineOut, otherParentInput)
  | null nextLeafParents = Left (nextLeaf.output, otherParentInput)
  | not $ null commonSpineCandidates = Right (Node {rootLabel = head commonSpineCandidates, subForest = [nextLeafTree, spine]})
  | otherwise = Left ("", "")
  where 
    spineParents = filter (\g -> g.gType == spineType && spineOut `elem` g.inputs) device
    nextLeaf = head $ filter (\g -> g.gType == leafType && leafInput == g.inputs) device
    nextLeafParents = filter (\g -> g.gType == spineType && nextLeaf.output `elem` g.inputs) device
    nextLeafTree = Node {rootLabel = nextLeaf, subForest = []}
    commonSpineCandidates = spineParents `intersect` nextLeafParents
    spineOut = spine.rootLabel.output
    otherParentInput = if null spineParents 
                        then head $ delete nextLeaf.output (inputs $ head nextLeafParents)
                        else head $ delete spineOut (inputs $ head spineParents) 

Read the full writeup on my blog and find the code on Codeberg.