Day 4: Scratchcards


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)
  • Code block support is not fully rolled out yet but likely will be in the middle of the event. Try to share solutions as both code blocks and using something such as https://topaz.github.io/paste/ or pastebin (code blocks to future proof it for when 0.19 comes out and since code blocks currently function in some apps and some instances as well if they are running a 0.19 beta)

FAQ


🔒This post will be unlocked when there is a decent amount of submissions on the leaderboard to avoid cheating for top spots

🔓 Unlocked after 8 mins

8 points

I had to give Uiua another go today. (run it here)

{"Card 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53"
 "Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19"
 "Card 3:  1 21 53 59 44 | 69 82 63 72 16 21 14  1"
 "Card 4: 41 92 73 84 69 | 59 84 76 51 58  5 54 83"
 "Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36"
 "Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11"}

LtoDec ← ∧(+ ×10:) :0
StoDec ← LtoDec▽≥0. ▽≤9. -@0

# Split on spaces, drop dross, parse ints
≡(⊜□≠0.⊐∵(StoDec)↘ 2⊜(□)≠@\s.⊔)

# Find matches
≡(/+/+⊠(⌕)⊃(⊔⊢↙ 1)(⊔⊢↙¯1))

# part 1
/+ⁿ:2-1 ▽±..

# part 2 - start with matches and initial counts
=..:
# len times: get 1st of each, rotate both, add new counts
⍥(⬚0+↯: ⊙⊙∩(↻1) ⊙:∩(⊢.))⧻.
/+⊙;
permalink
report
reply
3 points

what if code obfuscation was built into the language?

permalink
report
parent
reply
3 points

WTF

permalink
report
parent
reply
2 points

I’m fascinated and horrified

permalink
report
parent
reply
6 points

Rust

This one wasn’t too bad. The example for part 2 even tells you how to process everything by visiting each card once in order. Another option could be to recursively look at all won copies, but that’s probably much less efficient.

permalink
report
reply
5 points

Nim

This one was pretty simple, just parse the numbers into sets and check the size of the intersection. Part 2 just made the scoring mechanism a little more complicated.

permalink
report
reply
1 point

Hi there! Looks like you linked to a Lemmy community using a URL instead of its name, which doesn’t work well for people on different instances. Try fixing it like this: !nim@programming.dev

permalink
report
parent
reply
1 point

That’s some elegant code! Then again, I suppose that’s the beauty of nim.

permalink
report
parent
reply
3 points

I’m rather spoiled by python, so I feel like it could be more elegant. xD

But yeah, I do like how this one turned out, and nim runs a whole lot faster than python does. I really like nim’s “method call syntax”. Instead of having methods associated with an individual type, you can just call any procedure as x.f(remaining_args) to call f with x as its first argument. Makes it easy to chain procedures. Since nim is strongly typed, it’ll know which procedure you mean to use by the signature.

permalink
report
parent
reply
3 points

Aside from the general conciseness, the “universal function call syntax” is my favorite aspect of nim.

If you want to take chaining procedures to the next level, try a concatenative language like Factor (I have a day 4 solution in this thread – with no assignment to variables).

I also suggest having a look at Roc if you want a functional programming adventure, which offers great chaining syntax, a very friendly community, and is in an exciting development phase.

permalink
report
parent
reply
5 points
*

LANGUAGE: Nim

Welcome to the advent of parsing!
Took me a lot more time than it should (Please, don’t check prior commits 😅).

day_04.nim

permalink
report
reply
2 points

Please, don’t check prior commits

This should be the motto of AoC

permalink
report
parent
reply
4 points

Haskell

11:39 – I spent most of the time reading the scoring rules and (as usual) writing a parser…

import Control.Monad
import Data.Bifunctor
import Data.List

readCard :: String -> ([Int], [Int])
readCard =
  join bimap (map read) . second tail . break (== "|") . words . tail . dropWhile (/= ':')

countShared = length . uncurry intersect

part1 = sum . map ((\n -> if n > 0 then 2 ^ (n - 1) else 0) . countShared)

part2 = sum . foldr ((\n a -> 1 + sum (take n a) : a) . countShared) []

main = do
  input <- map readCard . lines <$> readFile "input04"
  print $ part1 input
  print $ part2 input
permalink
report
reply
2 points

I’m really impressed by your part 2. And I thought my solution was short…

permalink
report
parent
reply
2 points

Not familiar with Lean4 but it looks like the same approach. High five!

permalink
report
parent
reply
2 points

Still trying to make sense of it but that part two fold is just jummy!

permalink
report
parent
reply

Advent Of Code

!advent_of_code@programming.dev

Create post

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 2023

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

  • Follow the programming.dev instance rules
  • Keep all content related to advent of code in some way
  • If what youre posting relates to a day, put in brackets the year and then day number in front of the post title (e.g. [2023 Day 10])
  • When an event is running, keep solutions in the solution megathread to avoid the community getting spammed with posts

Relevant Communities

Relevant Links

Credits

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

console.log('Hello World')

Community stats

  • 1

    Monthly active users

  • 75

    Posts

  • 857

    Comments