Here is mine: https://github.com/ostcar/aoc2024/blob/main/day08.roc
part1 in 1.747ms
part2 in 4.987ms
It took me some time, because I did all the bugs that are even possible.
One of them was this
Can you see it? It took me around have of an hour. Hint: This bug will not happen anymore, when shadowing is allowed.
The fun of number suffixes
I occasionally pulled certain lambdas into separate top level functions to avoid naming issues like that.
Today went smoothly, getting more and more confortable with the standard library :)
https://github.com/RobinCamarasa/Advent-of-code/blob/master/2024/day08/RobinCamarasa/main.roc
Here's my solution... only made it as far as part 1 so far.
https://github.com/lukewilliamboswell/aoc/blob/main/2024/08.roc
TIMING:
READING INPUT: <1ms
SOLVING PART 1: 2ms
Done for me too https://github.com/thenikso/advent-of-code-2024-roc/blob/main/08.roc
Day 08 part 1: (Ok ...) [1ms]
Day 08 part 2: (Ok ...) [1ms]
Using again the excellent Array2D
Just about to start on this. Can someone explain this sentence from Part 1?
In particular, an antinode occurs at any point that is perfectly in line with two antennas of the same frequency - but only when one of the antennas is twice as far away as the other
Specifically that last clause
Looking at the examples, it doesn't seem to really mean anything?
I think it means: an antinode exists at a point directly in line with two antennas and as far from the nearest antenna as they are from each other. So if two antennas are due north/south and 2 rows apart, an antinode will occur at the point due north and 2 rows above the northern one, and due south and 2 rows below the southern one.
Thanks. That’s what I deduced from the example, but I still can’t parse that sentence to mean that :joy:
I don't disagree! It's a very confused way of explaining.
Sometimes you add debugger statements, and they lead you down an hour long rabbit hole before you figure out that the output is not what you think :rofl:
https://github.com/gamebox/aoc-2024/tree/main/day8
This instrumentation tells me both parts take less than 1ns, which does not seem right...
main =
now = Utc.now! {}
p1Start = Utc.toNanosSinceEpoch now
total = getTotal realInput
p1End =
Utc.now! {}
|> Utc.toNanosSinceEpoch
part2 = getPart2Total realInput
p2End =
Utc.now! {}
|> Utc.toNanosSinceEpoch
Stdout.line! "There are $(Num.toStr total) obstacles, and $(Num.toStr part2) with harmonics."
Stdout.line! "Part 1: $(Num.toStr (p1End - p1Start))ns"
Stdout.line! "Part 2: $(Num.toStr (p2End - p1End))ns"
Is that expected?
I don't see anything wrong with the calculation, you can paste your solution in Luke's aoc tempplate to compare measurements
@Anthony Bullard this is testing with the input.txt in the repo?
Yeah with optimized build
I definitely did NOT build my solution with perf in mind
Utc.toNanosSinceEpoch
At least for me on mac, the timer we are based off of is only timing in microseconds. I either see:
There are 305 obstacles, and 1150 with harmonics.
Part 1: 0ns
Part 2: 0ns
or:
There are 305 obstacles, and 1150 with harmonics.
Part 1: 1000ns
Part 2: 0ns
Last 3 digits of printing out the nanoseconds is always zero
That's what I was thinking
So no greater precision than ms
I'm also on Mac
us, not ms, but yeah
Makes sense, thanks for verifying that
still runs within a microsecond which is quite fast for aoc in general
Yeah, duh us
Fast is nice for AOC, but never my first goal. Especially in a language I'm still learning
Ah yeah, utc.time is based on SystemTime, which is not meant for measuring time elapsed. It is meant getting the current real world time. We should be basing time measurements on Instant.
With instant (I think wired correctly, but it is adhoc to send it through the utc.time api), I see:
Part 1: 2625ns
Part 2: 84ns
So we may want a different timer tool in basic cli for differential time measurements.
System time isn't even guaranteed to be monotonic (it can go backwards)
Actually, sorry, this is correct timing. The early one had init issues (first one was measuring locking and initializing an OnceLock in rust):
Part 1: 84ns
Part 2: 83ns
Thanks, seems like that should definitely be in the basic-cli platform
WHich reminds me ... every been any talk of working out a common interface for common types across platforms - like a POSIX for Roc platforms ? Not mandatory, but most non-client oriented platforms would strive to implement it (same interface in Roc that is)
That way if I use File in basic-cli, I could expect to find the same API available in basic-webserver?
It has been discussed a little. I have pushed for the idea of interfaces a few times. I think with static dispatch, we will get a solution (though not sure if it will be enough)
Anthony Bullard said:
WHich reminds me ... every been any talk of working out a common interface for common types across platforms - like a POSIX for Roc platforms ? Not mandatory, but most non-client oriented platforms would strive to implement it (same interface in Roc that is)
Richard has done a lot of design work on the path package, just needs implementation
https://github.com/roc-lang/path
He gave a presentation on it in this meetup https://roc.zulipchat.com/#narrow/channel/303057-gatherings/topic/Roc.20Online.20Meetup.20Aug.202024/near/464907794
So we definitely have a lowering bug with Task !
and |>
main =
now = Utc.now! {}
p1Start = Utc.toNanosSinceEpoch now
total = getTotal realInput
p1End =
Utc.now! {}
|> Utc.toNanosSinceEpoch
part2 = getPart2Total realInput
p2End =
Utc.now! {}
|> Utc.toNanosSinceEpoch
Stdout.line! "There are $(Num.toStr total) obstacles, and $(Num.toStr part2) with harmonics."
Stdout.line! "Part 1: $(Num.toStr (p1End - p1Start))ns"
Stdout.line! "Part 2: $(Num.toStr (p2End - p1End))ns"
This gives garbage times as if all of the Utc.now!
are called back to back.
If you remove the |>
and makes separate variables, the timings become reasonable.
This should work:
main =
now = Utc.now! {}
p1Start = Utc.toNanosSinceEpoch now
total = getTotal realInput
p1EndTime = Utc.now! {}
p1End = Utc.toNanosSinceEpoch p1EndTime
part2 = getPart2Total realInput
p2EndTime = Utc.now! {}
p2End = Utc.toNanosSinceEpoch p2EndTime
Stdout.line! "There are $(Num.toStr total) obstacles, and $(Num.toStr part2) with harmonics."
Stdout.line! "Part 1: $(Num.toStr (p1End - p1Start))ns"
Stdout.line! "Part 2: $(Num.toStr (p2End - p1End))ns"
Not sure if this is a bug worth fixing cause it may go away with Task
, but we should double check it isn't broken with purity inference.
CC: @Anthony Bullard roc bug breaking timing and a workaround
Thanks for looking into that @Brendan Hansknecht
Last updated: Jul 06 2025 at 12:14 UTC