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)
I'll try bumping the default stack size :smile:
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()))
}
I saw that map is currently doing a fold an creating a new list, so just one fold is much better :-)
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.
Does Roc have while loop? I wonder if I can read lines from Stdin until the line is empty without using recursion?
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.
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:
dbg not working [It's a platform bug.]Str.to_u32() is not found. (Str.to_u32 does not exist. Str is in scope, but it has no associated to_u32.) [It's U32.from_str() instead.]List.keep_oks() or List.filter_map() missing in new compiler.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!
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
I made #8596 to provide a useful tip when using Str.to_u32().
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.
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
That's fine and what I would have looked for, thanks!
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. :)
A message was moved from this topic to #ideas > streams API by Anton.
Last updated: Dec 21 2025 at 12:15 UTC