Stream: advent of code

Topic: 2025 Day 1


view this post on Zulip Fabian Schmalzried (Dec 04 2025 at 15:37):

app [main!] { pf: platform "../test/fx/platform/main.roc" }

import pf.Stdout

input = \\L68
        \\L30
        \\R48
        \\L5
        \\R60
        \\L55
        \\L1
        \\L99
        \\R14
        \\L82

main! = || {
    lines = input.split_on("\n")

    count = part1(lines)

    Stdout.line!(count.to_str())
}

# not sure why => is required
part1 : List(Str) => U64
part1 = |lines| {
    var $pos = 50
    var $count = 0
    for line in lines {
        u8_line = line.to_utf8()
        match u8_line {
            ['L', ..a] => {
                amount = i64_from_ascii_digits(a)
                $pos = ($pos - amount).mod_by(100)
                if ($pos == 0) {
                    $count = $count + 1
                }
            }
            ['R', ..a] => {
                amount = i64_from_ascii_digits(a)
                $pos = ($pos + amount).mod_by(100)
                if ($pos == 0) {
                    $count = $count + 1
                }
            }
            _ => dbg "Error"
        }
    }
    $count
}

i64_from_ascii_digits : List(U8) -> I64
i64_from_ascii_digits = |ascii| {
    ascii.map(|b| (b - '0').to_i64()).fold(0, |n,b| n * 10 + b)
}

This runs with the example input :tada:.
But for the actual puzzle input I get a Roc crashed: Error evaluating from shared memory: StackOverflow after about 15 seconds (current main, compiled with -Doptimize=ReleaseFast)

view this post on Zulip Richard Feldman (Dec 04 2025 at 15:39):

I'll try bumping the default stack size :smile:

view this post on Zulip Fabian Schmalzried (Dec 04 2025 at 15:41):

Small optimization, and now it runs with the puzzle input, I will have a look at part 2 now

i64_from_ascii_digits : List(U8) -> I64
i64_from_ascii_digits = |ascii| {
    ascii.fold(0, |n,b| n * 10 + ((b - '0').to_i64()))
}

view this post on Zulip Fabian Schmalzried (Dec 04 2025 at 15:42):

I saw that map is currently doing a fold an creating a new list, so just one fold is much better :-)

view this post on Zulip Richard Feldman (Dec 04 2025 at 15:54):

nice! I have a PR which (among other things) bumps default stack size from 8MB to 64MB. We can certainly go higher than that if necessary.

view this post on Zulip Michał Kowieski (Dec 04 2025 at 16:20):

Does Roc have while loop? I wonder if I can read lines from Stdin until the line is empty without using recursion?

view this post on Zulip Fabian Schmalzried (Dec 04 2025 at 16:23):

Yes you can do while (True). But there is a bug in the Stdin.line!that discards the rest of it's internal buffer after the first newline if you pipe in a file, that I wanted to report but forgot.

view this post on Zulip Johannes Maas (Dec 09 2025 at 08:14):

I'm starting a list of things that I'm missing so we can check whether they are accidentally broken, known issues or not yet implemented:

view this post on Zulip Johannes Maas (Dec 09 2025 at 08:16):

I guess Str.to_u32() missing means it does not really make sense for me to proceed right now, but I can already see the language and like it very much!

view this post on Zulip Matthieu Pizenberg (Dec 09 2025 at 08:18):

You have U32.from_str. The list of available builtins are in that file https://github.com/roc-lang/roc/blob/main/src/build/roc/Builtin.roc

view this post on Zulip Anton (Dec 09 2025 at 09:32):

I made #8596 to provide a useful tip when using Str.to_u32().

view this post on Zulip Johannes Maas (Dec 09 2025 at 09:37):

Oh, thanks! So I'm probably looking at the old docs on the website when I thought those were the new. I'll look for where to find the new docs.

view this post on Zulip Anton (Dec 09 2025 at 09:39):

We don't have new docs yet :sweat_smile: but you can check this file for now: https://github.com/roc-lang/roc/blob/main/src/build/roc/Builtin.roc

view this post on Zulip Johannes Maas (Dec 09 2025 at 09:41):

That's fine and what I would have looked for, thanks!

view this post on Zulip Johannes Maas (Dec 09 2025 at 10:43):

Ok, it's rough, just as I was warned. Hopefully this helps somehow:

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.4/6XA8JLWhmG1FSgb8GxPjBs9cGrtRqopohR3KAHYo722z.tar.zst" }

import pf.Stdout
import pf.Stdin

main! = |_args| {
    parsed = parse_input(puzzle_input)
    output_n = parsed
        #.map(|instruction| instruction.ok_or(0).to_str())
        #.map(|n| n.to_str())
    #Stdout.line!(output)

    # The first `map` above fails with `Roc crashed: Builtin.Str does not implement ok_or`, but the following works, proving that the elements are actually Try, not Str.
    for n in output_n {
        Stdout.line!(n.ok_or(0).to_str())
    }


    Stdout.line!("stdout")
    Ok({})
}

parse_input = |input| {
    input
        .split_on("\n")
        .drop_if(|line| line.is_empty())
        .map(|line| {
            if line.starts_with("R") {
                U32.from_str(line.drop_prefix("R"))
            } else if line.starts_with("L") {
                U32.from_str(line.drop_prefix("L"))
            } else {
                Err(InvalidLine(line))
            }
        })
        # If I uncomment the following line, I get a `Roc crashed: Error evaluating from shared memory: InvalidMethodReceiver`.
        #.keep_if(|result| result.is_ok())
        #.map(|result| result.ok_or(0)
}

puzzle_input = "R21\nR37\nL39\nL11"

There are two places where I've added comments indicating the errors I'm running into. Hopefully, it makes sense. Otherwise, please ask. :)

view this post on Zulip Notification Bot (Dec 09 2025 at 12:13):

A message was moved from this topic to #ideas > streams API by Anton.


Last updated: Dec 21 2025 at 12:15 UTC