Advent of Code 2025
This is a thread to discuss solutions to Advent of Code 2025. As mentioned inejolson wrote: ↑Wed May 07, 2025 5:18 pmLooking through the forum there have been threads for Advent of Code starting in 2020.
viewtopic.php?t=293084
viewtopic.php?t=325236
viewtopic.php?t=343515
viewtopic.php?t=360011
viewtopic.php?t=380295
viewtopic.php?p=2347868#p2347868
there will only be twelve puzzles to pass the time until Christmas this year. That is good because other years I nearly missed Christmas on account of still working the puzzles.
Speaking of missing things, that Raspberry Pi 5 from last Christmas is still not a NAS and I just missed a sale for 24 TB hard disks. Fortunately, the Pi 5 is currently nailed to a piece of wood, running off the Pi 4 power supply and ready for the code produced by Scratchy, Purr, Shy and myself.
I'll miss Fido this Advent.
Is anyone else planning to do Advent of Code with a Raspberry Pi this year?
Re: Advent of Code 2025
The hardware is ready. There are 24 hours before the first puzzle unlocks, so I thought I'd check the software. Software is always more difficult.
Scratchy suggested doing the puzzles in C. Purr blinked but Shy was too shy to blink.
That's great, I said, then everything is ready to go. At this Purr pounced on Scratchy who fell off the cat tree onto Shy who started to mew.
I think some additional software will be required.
Re: Advent of Code 2025
Shy looked shyly up from underneath the pileup of kittens and mewed shyly, IBM Fortran G, Microsoft Power Automate and Kotlin?
Those were hard choices, but after what happened I felt compelled to agree. Although Fortran G runs only on System/360 mainframes, Hercules runs on a Pi and can emulate 50-year-old hardware.
After reflecting on the likely outcome of a chatbot powered code review, I questioned a lack of string handling. Shy crawled out from under the other kittens and looked shyly at the ground, clearly thinking about four-character Hollerith constants lovingly stored in 32-bit integer variables.
As Power Automate is an expensive software-as-a-service low-code solution, I suggested Kotlin. At this Shy happily rolled on the ground feet kicking into the air. If the Java virtual machine is too slow can I switch to Fortran? Suddenly I felt shy.
I hope Purr asks for a language easily installed by an operating system package.
Re: Advent of Code 2025
Purr obviously did not think C was purrfect.
Rather than wait for another impractical request, I decided to negotiate. That constant purring must have distracted me from the danger.
There's a nice kitty, I began, how about Rust. Purr blinked, continued purring and replied Hare.
Image
https://harelang.org/
It looked interesting, especially as it does not use the LLVM or GCC backends. However, I suspected an ulterior motive and feared for that cute bunny.
Excellent choice I continued, I think Free Pascal is similar and the mascot is a cat like you.
Image
https://www.freepascal.org/
The purring stopped and Purr blinked again.
I tried one more time. How about Go?
Image
https://go.dev/
Luckily Purr started purring again. The kitten went on for a time and then replied Swift.
Image
https://www.swift.org/
I should have known kittens would be attracted to birds. I worried that the next choice would have a seafood mascot, but then remembered my first suggestion had been Rust.
Considering how much trouble there was building the Swift runtime a few years ago, Hare started to look more reasonable. So I gave in.
I wonder what the chatbots will say about Hare in the code reviews.
Re: Advent of Code 2025
With only 5 hours before the first puzzle opens
I worked on bootstrapping Hare from source while the kittens played a game and sang:
Little bunny Foo Foo
hopping through the datacenter,
scooping up the computer mice
and clicking them on the buttons.
Out came the Unix greybeard who said,
little bunny Foo Foo I don't want to see you
scooping up the computer mice
and clicking them on the buttons.
I'll give you three more chances
and then compile you into a goon.
Little bunny Foo Foo
hopping through the datacenter,
scooping up the computer mice
and clicking them on the buttons.
Out came the Unix greybeard who said,
little bunny Foo Foo I don't want to see you
scooping up the computer mice
and clicking them on the buttons.
I'll give you two more chances
and then compile you into a goon.
Little bunny Foo Foo
hopping through the datacenter,
scooping up the computer mice
and clicking them on the buttons.
Out came the Unix greybeard who said,
little bunny Foo Foo I don't want to see you
scooping up the computer mice
and clicking them on the buttons.
I'll give you one more chance
and then compile you into a goon.
Little bunny Foo Foo
hopping through the datacenter,
scooping up the computer mice
and clicking them on the buttons.
Out came the Unix greybeard who said,
that was your last chance.
The greybeard logged into a terminal and said,
now I'll compile you into a goon.
And the moral of the story is
Hare today goon tomorrow.
During the above commotion I managed to identify the QBE backend was generating AMD64 rather than ARM64 assembly and fixed it. Not counting the debugging, a full bootstrap of the compiler and runtime using the packaged version of QBE took less than a minute on the Pi 5.
After installing Hare today, next up is Kotlin.
Re: Advent of Code 2025
Kotlin was even easier. All I did was download version 2.2.21 from
https://github.com/JetBrains/kotlin/releases
unzip it into /usr/local and create links from /usr/local/kotlinc/bin to /usr/local/bin. It just worked after that. Moreover, Shy seems very happy.
I now have templates in C, Kotlin, Hare and Go which do nothing
Code: Select all
Advent of Code 2025 Day 1 (c)
Total execution time 1.11e-07 seconds.
Code: Select all
-rwxr-xr-x 1 ejolson users 74160 Dec 1 05:13 day01-c
-rwxr-xr-x 1 ejolson users 2298509 Dec 1 05:13 day01-go
-rwxr-xr-x 1 ejolson users 841616 Dec 1 05:12 day01-ha
-rw-r--r-- 1 ejolson users 5125643 Dec 1 05:13 day01.jar
The day 1 puzzle has opened, but the mice are nonfunctional after the singing and everyone is tired. I'll post solutions as they come in.
Has anyone else started?
Re: Advent of Code 2025
Scratchy finished first, but admittedly needed 6 tries to get the right answer to part 2.
Code: Select all
$ ./day01-c
Advent of Code 2025 Day 1 Secret Entrance (c)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.000571019 seconds.
Code: Select all
/* Advent of Code 2025 Day 1 Secret Entrance (c)
Written December 2025 by Eric Olson */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
static struct timespec tic_start;
void tic(){
clock_gettime(CLOCK_MONOTONIC_RAW,&tic_start);
}
double toc(){
struct timespec tic_stop;
clock_gettime(CLOCK_MONOTONIC_RAW,&tic_stop);
double sec=tic_stop.tv_sec-tic_start.tv_sec;
return sec+(tic_stop.tv_nsec-tic_start.tv_nsec)*1.0e-9;
}
void dowork(){
FILE *fp=fopen("day01.txt","r");
int p1=0,p2=0;
int d=50;
while(!feof(fp)){
char c; int x;
if(fscanf(fp,"%c%d\n",&c,&x)!=2) break;
int r;
switch(c){
case 'L':
if(d>0){
d-=x;
r=(100-d)/100;
} else {
d-=x;
r=-d/100;
}
d=(d%100+100)%100;
break;
case 'R':
d+=x;
r=d/100;
d%=100;
break;
default:
fprintf(stderr,"Unknown direction %c!\n",c);
exit(1);
}
if(d==0) p1++;
p2+=r;
}
fclose(fp);
printf("Part 1 The actual password is %d\n",p1);
printf("Part 2 Following method 0x434C49434B gives %d\n",p2);
}
int main(){
printf("Advent of Code 2025 Day 1 Secret Entrance (c)\n\n");
tic();
dowork();
double t=toc();
printf("\nTotal execution time %g seconds.\n",t);
exit(0);
}
Re: Advent of Code 2025
I couldn't sleep because my nose is plugged, so I finished the Go template.
Code: Select all
$ ./day01-go # Pi
Advent of Code Day 01 (go)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.00258147 seconds.
The code is
Code: Select all
/* Advent of Code 2025 Day 01 Secret Entrance (go)
Written December 2025 by Eric Olson */
package main
import("fmt"; "os"; "time"; "bufio")
var tictime time.Time
func tic(){
tictime=time.Now()
}
func toc() float64 {
now:=time.Now()
elapsed:=now.Sub(tictime)
return elapsed.Seconds()
}
func dowork(){
fd,err:=os.Open("day01.txt")
if err!=nil {
fmt.Fprintf(os.Stderr,"Unable to open file input file!\n")
os.Exit(0)
}
defer fd.Close()
fp:=bufio.NewReader(fd)
p1:=0; p2:=0; d:=50
for {
var (c rune; x int)
r,err:=fmt.Fscanf(fp,"%c%d\n",&c,&x)
if r!=2||err!=nil { break }
switch c {
case 'L':
d=(d-100)%100
d-=x
r=-d/100
case 'R':
d=(d+100)%100
d+=x
r=d/100
default:
fmt.Fprintf(os.Stderr,"Unknown direction %c!\n",c)
os.Exit(1)
}
d%=100
if d==0 { p1++ }
p2+=r
}
fmt.Printf("Part 1 The actual password is %d\n",p1);
fmt.Printf("Part 2 Following method 0x434C49434B gives %d\n",p2);
}
func main(){
fmt.Printf("Advent of Code Day 01 Secret Entrance (go)\n\n")
tic()
dowork()
t:=toc()
fmt.Printf("\nTotal execution time %.6g seconds.\n",t)
os.Exit(0)
}
Surprisingly, it is not possible to write
Code: Select all
p1+=int(d==0)
I thought about trying zig
https://ziglang.org/
but it looked like too much syntax.
Re: Advent of Code 2025
Code: Select all
#include <iostream>
#include <chrono>
#include <fstream>
int main()
{
// file must not have blank line at end
const char* filename = "data.txt";
std::chrono::time_point<std::chrono::system_clock> start,stop;
start = std::chrono::system_clock::now();
std::cout << "Advent of code 2025 day 1" << "\n";
std::ifstream file(filename);
int dial = 50; // dial position
const int num = 100; // number of dial positions
int part1 = 0; // answer fo part 1
int extras = 0; // extras due to "method 0x434C49434B"
if(file)
{
while(!file.eof())
{
int i;
char c;
file >> c >> i;
// i maybe > 100
int turns = i / num;
if(turns)
{
extras += turns;
i -= num * turns;
}
// do not bump extras if dial is zero before or after change
bool doextras = (dial != 0);
// move the dial
if(c == 'R')
{
dial += i;
if(dial > num - 1)
{
dial -= num ;
if(doextras && dial)
extras++;
}
}
else
{
dial -= i;
if(dial < 0)
{
dial += num;
if(doextras && dial)
extras++;
}
}
if(dial == 0)
part1 += 1;
}
}
std::cout << "Part 1 " << part1 << "\n";
std::cout << "Part 2 " << part1 + extras << "\n";
stop = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = stop - start;
std::cout << "Elapsed time " << elapsed.count() << " seconds" << "\n";
return 0;
}
Re: Advent of Code 2025
Woohoo! Welcome to the party!
I think it's interesting how you avoided using the % modulo operator.
Purr just finished the Hare solution:
Code: Select all
$ ./day01-ha # Pi 5
Advent of Code 2025 Day 01 Secret Entrance (ha)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 2.07877e-3 seconds.
Code: Select all
// Advent of Code 2025 Day 1 Secret Entrance (ha)
// Written December 2025 by Eric Olson
use fmt;
use os;
use time;
use io;
use bufio;
use types;
use strconv;
use strings;
use fs;
let tic_start:time::instant=time::INSTANT_ZERO;
fn tic() void = {
tic_start=time::now(time::clock::MONOTONIC);
};
fn toc() f64 = {
const tic_stop=time::now(time::clock::MONOTONIC);
return time::diff(tic_start,tic_stop):f64*1e-9;
};
// Routine read_file generated by Claude from the prompt
//
// I am writing a program in the Hare programming language and
// want to read a text file line by line. The file consists
// of natural numbers with a prefix 'L' or 'R' that indicates
// whether the number following should be counted as positive
// or negative. 'L' means negative and 'R' means positive. Could
// you write a routine to read the file day01.txt and store the
// resulting signed integers in an array? The routine should
// handle all errors internally by printing an error message and
// exiting with an appropriate error code, rather than returning
// error types to the caller.
//
// plus lots of back and forth to fix errors.
//
fn read_file(path: str) []int = {
// Open the file
const file = match (os::open(path)) {
case let f: io::file =>
yield f;
case let err: fs::error =>
fmt::fatalf("Error opening file: {}", fs::strerror(err));
};
defer io::close(file)!;
// Create buffered reader
const scanner = bufio::newscanner(file, types::SIZE_MAX);
defer bufio::finish(&scanner);
// Dynamic array to store results
let numbers: []int = [];
for (true) {
const line = match (bufio::scan_line(&scanner)) {
case io::EOF =>
break;
case let err: io::error =>
fmt::fatalf("Error reading file: {}", io::strerror(err));
case let line: const str =>
yield line;
};
// Skip empty lines
if (len(line) == 0) {
continue;
};
// Parse the line
const prefix = strings::sub(line, 0, 1);
const num_str = strings::sub(line, 1, strings::end);
// Parse the number
const num = match (strconv::stoi(num_str)) {
case let n: int =>
yield n;
case =>
fmt::fatalf("Error parsing number: '{}'", num_str);
};
// Apply sign based on prefix
const signed_num = switch (prefix) {
case "L" =>
yield -num;
case "R" =>
yield num;
case =>
fmt::fatalf("Invalid prefix '{}' on line: {}", prefix, line);
};
match (append(numbers, signed_num)) {
case void =>
yield;
case =>
fmt::fatalf("Error: Out of memory");
};
};
return numbers;
};
fn part1(numbers: []int) int = {
let p1 = 0, dial = 50;
for (let i = 0z; i < len(numbers); i += 1) {
dial = (dial+numbers[i])%100;
if (dial==0) p1 += 1;
};
return p1;
};
fn part2(numbers: []int) int = {
let p2 = 0, dial = 50;
for (let i = 0z; i < len(numbers); i += 1) {
if (numbers[i]<0) {
dial = (dial-100)%100 + numbers[i];
p2 += -dial/100;
} else {
dial = (dial+100)%100 + numbers[i];
p2 += dial/100;
};
dial %= 100;
};
return p2;
};
fn dowork() void = {
const numbers = read_file("day01.txt");
const p1 = part1(numbers);
fmt::printfln("Part 1 The actual password is {}",p1)!;
const p2 = part2(numbers);
fmt::printfln("Part 2 Following method 0x434C49434B gives {}",p2)!;
free(numbers);
};
export fn main() void = {
fmt::print("Advent of Code 2025 Day 01 Secret Entrance (ha)\n\n")!;
tic();
dowork();
const t = toc();
fmt::printf("\nTotal execution time {:.6g} seconds.\n",t)!;
os::exit(0);
};
For example, the line
Code: Select all
const prefix = strings::sub(line, 0, 1);
Code: Select all
const prefix = line[0];
Shy looked at the all the semicolons and shyly asked, did the rabbit leave those?
Re: Advent of Code 2025
Avoiding zig was a fortunate accident as it's on the list of software incompatible with the 16K kernel page size used by Raspberry Pi OS on the Pi 5.ejolson wrote: ↑Mon Dec 01, 2025 12:52 pmI thought about trying zig
https://ziglang.org/
but it looked like too much syntax.
viewtopic.php?p=2351173#p2351173
In other news, the kitten named Shy is working on a solution to Day 1 in Kotlin. As coding assistants seem popular, I'm expecting a request for IntelliJ IDEA as soon as the mice are fixed.
Re: Advent of Code 2025
Shy shyly mewed the puzzle is done.ejolson wrote: ↑Mon Dec 01, 2025 9:19 pmAvoiding zig was a fortunate accident as it's on the list of software incompatible with the 16K kernel page size used by Raspberry Pi OS on the Pi 5.ejolson wrote: ↑Mon Dec 01, 2025 12:52 pmI thought about trying zig
https://ziglang.org/
but it looked like too much syntax.
viewtopic.php?p=2351173#p2351173
In other news, the kitten named Shy is now working on a solution to Day 1 in Kotlin. As AI coding assistants seem popular, I'm expecting a request for IntelliJ IDEA as soon as the mice are fixed.
Code: Select all
$ ./day01-kt # Pi 5
Advent of Code 2025 Day 01 (kt)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.0553859 seconds.
Code: Select all
#!/bin/bash
exec java -jar day01.jar "$@"
Code: Select all
/* Advent of Code 2025 Day 01 Secret Entrance (kt)
Written December 2025 by Eric Olson */
import java.io.File
var tic_time=0.0
fun tic() {
tic_time=System.nanoTime()*1e-9
}
fun toc(): Double {
return System.nanoTime()*1e-9-tic_time
}
fun dowork(){
val data=File("day01.txt").readLines()
var p1=0; var p2=0; var d=50
for(s in data){
val x=s.substring(1).toInt()
when(s[0]){
'R'->{
d=(d+100)%100+x
p2+=d/100
}
'L'->{
d=(d-100)%100-x
p2-=d/100
}
}
d%=100
if(d==0) p1++
}
println("Part 1 The actual password is %d".format(p1))
println("Part 2 Following method 0x434C49434B gives %d".format(p2))
return
}
fun main(){
print("Advent of Code 2025 Day 01 (kt)\n\n")
tic()
dowork()
var t=toc()
println("\nTotal execution time %.6g seconds.\n".format(t))
return
}
Re: Advent of Code 2025
I fixed the difficulty with a trailing newline in the input file by changing
Code: Select all
file >> c >> i;
Code: Select all
if(!(file >> c >> i)) break;
Code: Select all
$ ./day01-cpp
Advent of code 2025 day 1
Part 1 997
Part 2 5978
Elapsed time 0.000432798 seconds
Scratchy meowed, include the C++ code with the others. I wasn't sure. Purr purred, it's perfect. Shy still hid under the cat tree. If it were big enough, I'd hide under there too.
Re: Advent of Code 2025
Before moving on to a chatbot-powered code review, here are some quantitative results:
Compile times are
Code: Select all
$ for i in day01-ha day01-kt day01-go day01-c day01-cpp
do time make $i
done
hare build -o day01-ha day01.ha
real 0m0.046s
user 0m0.034s
sys 0m0.012s
kotlinc day01.kt -include-runtime -d day01.jar
./mkjarun day01.jar
real 0m7.396s
user 0m15.800s
sys 0m0.654s
go build -o day01-go day01.go
real 0m0.180s
user 0m0.227s
sys 0m0.044s
gcc -O2 -Wall -fwrapv -o day01-c day01.c
real 0m0.091s
user 0m0.061s
sys 0m0.030s
g++ -O2 -Wall -fwrapv -o day01-cpp day01.cpp
real 0m0.691s
user 0m0.625s
sys 0m0.065s
Code: Select all
.SUFFIXES: .ha .jar .kt
TARGETS=day01-ha day01-kt day01-go day01-c day01-cpp
all: $(TARGETS)
clean:
rm -f $(TARGETS)
rm -f *.jar
%-go: %.go
go build -o $@ $<
%-c: %.c
gcc -O2 -Wall -fwrapv -o $@ $<
%-cpp: %.cpp
g++ -O2 -Wall -fwrapv -o $@ $<
%-ha: %.ha
hare build -o $@ $<
%-kt: %.kt
kotlinc $< -include-runtime -d $*.jar
./mkjarun $*.jar
Sizes of the source codes are
Code: Select all
$ wc day01.ha day01.kt day01.go day01.c day01.cpp
142 531 3928 day01.ha
44 98 974 day01.kt
59 134 1311 day01.go
62 127 1447 day01.c
77 230 1932 day01.cpp
384 1120 9592 total
Code: Select all
$ ls -l day01-ha day01.jar day01-go day01-c day01-cpp
-rwxr-xr-x 1 ejolson users 74440 Dec 1 22:21 day01-c
-rwxr-xr-x 1 ejolson users 74856 Dec 1 22:21 day01-cpp
-rwxr-xr-x 1 ejolson users 2479193 Dec 1 22:21 day01-go
-rwxr-xr-x 1 ejolson users 850128 Dec 1 22:21 day01-ha
-rw-r--r-- 1 ejolson users 5126318 Dec 1 22:21 day01.jar
Code: Select all
$ for i in day01-ha day01-kt day01-go day01-c day01-cpp
do time ./$i
done
Advent of Code 2025 Day 01 Secret Entrance (ha)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 2.10695e-3 seconds.
real 0m0.003s
user 0m0.003s
sys 0m0.000s
Advent of Code 2025 Day 01 (kt)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.0539526 seconds.
real 0m0.152s
user 0m0.184s
sys 0m0.032s
Advent of Code Day 01 Secret Entrance (go)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.00256284 seconds.
real 0m0.004s
user 0m0.000s
sys 0m0.004s
Advent of Code 2025 Day 1 Secret Entrance (c)
Part 1 The actual password is 997
Part 2 Following method 0x434C49434B gives 5978
Total execution time 0.00057187 seconds.
real 0m0.001s
user 0m0.001s
sys 0m0.000s
Advent of code 2025 day 1
Part 1 997
Part 2 5978
Elapsed time 0.000433001 seconds
real 0m0.002s
user 0m0.002s
sys 0m0.000s
Purr silently climbed down from top of the cat tree and hid where Shy was hiding.
Re: Advent of Code 2025
In graph form the results from the Pi 5 are
Image
Note that the first two groups of bar charts are measured in seconds on the left while the last two are keyed to bytes on the right. With respect to runtime the Hare and Go results are friends, the C and C++ results are friends but Kotlin is too shy to have any friends. I wonder if things will change when solving a more complicated puzzle.
Re: Advent of Code 2025
I did use it for part 1 but then I needed the number of full revolutions for part 2 so kept it simple.
I have used a similar solution to the end of file problem in the past. I now just use mousepad to write the data files because that does not insist on adding a newline at the end.
Glad you found it quick.
Re: Advent of Code 2025
The problem with being Shy meowed the kitten programming in Kotlin is you end up with too many friends. I looked and all the kittens were crowded together under the cat tree hiding.
They began to sing:
Three little kittens
with coding were smitten
and they began to cry.
Oh greybeard dear we greatly fear
our program we did erase.
Meow, meow, meow, me-ow.
What naughty kittens
to lose what you've written,
the greybeard did reply.
Meow, meow, meow, me-ow.
No more Raspberry Pi.
Then three little kittens
they looked for a smidgeon
a thumb drive they did spy.
Oh greybeard dear look here look here
a backup we did find.
Meow, meow, meow, me-ow.
What clever kittens
to save what you've written,
the greybeard gave a sigh.
Meow, meow, meow, me-ow.
Have some Raspberry Pi.
Then three little kittens
restored what they'd written
and powered up the Pi.
Oh greybeard dear it does appear
our program has a bug.
Meow, meow, meow, me-ow.
What naughty kittens
you saved the wrong version,
the greybeard swatted a fly.
Meow, meow, meow, me-ow.
No more bugs there did lie.
Then three little kittens
ran the code they'd written
on the Raspberry Pi.
Oh greybeard dear they gave a cheer
our program now does work.
Meow, meow, meow, me-ow.
What good little kittens...
At that point I sneezed and the singing stopped. It seems my cold is worse. Aside from the song, no progress has been made on Day 2.
Re: Advent of Code 2025
I wrote a simple brute force solution for Day 2 Part 1 using 8th programming language:
Code: Select all
"2.txt" f:slurp ( "," s:/ ( "-" s:/ ' >n a:map ) a:map ) s:eachline constant ranges
a:new ( >s dup s:+ >n a:push ) 1 99999 loop constant doubles
: app:main
ranges ( >r doubles ( r@ a:open n:between ) a:filter rdrop ) a:map a:squash
' n:+ 0 a:reduce . cr ;
Re: Advent of Code 2025
I always find it amazing how concise 8th code is compared to what I'm used to.jalih wrote: ↑Tue Dec 02, 2025 8:45 pmI wrote a simple brute force solution for Day 2 Part 1 using 8th programming language:Code: Select all
"2.txt" f:slurp ( "," s:/ ( "-" s:/ ' >n a:map ) a:map ) s:eachline constant ranges a:new ( >s dup s:+ >n a:push ) 1 99999 loop constant doubles : app:main ranges ( >r doubles ( r@ a:open n:between ) a:filter rdrop ) a:map a:squash ' n:+ 0 a:reduce . cr ;
I now have one star for Day 2.
Part 2 seems similar except I have to refactor (of course) and avoid double counting.
Re: Advent of Code 2025
Purr was asleep. Scratchy was asleep. But the last kitten was awake. However, instead of working on the puzzle which just opened, Shy was watching television. Luckily, before saying something snarky I noticed it was the Advent of Code channel
https://blog.jetbrains.com/kotlin/2025/ ... tlin-2025/
Now I understand why Shy asked for Kotlin.
Re: Advent of Code 2025
Code: Select all
: build-table
a:new ( >r ( r@ swap 2 a:close a:push ) r@ n:1+ 99 loop rdrop ) 0 98 loop ;
build-table constant indices
: app:main
a:new "3.txt" f:slurp
( "" s:/ indices ( a:@ "" a:join >n ) a:map nip ' n:cmp a:sort -1 a:_@ a:push ) s:eachline
' n:+ 0 a:reduce . cr ;
Re: Advent of Code 2025
To avoid double counting I used a priority queue--essentially a unique sort that avoids consuming O(n) storage where n is the number of invalid IDs.
The refactoring was more extensive than I had expected. In the process I deleted the code from part 1 which found the correct starting point for the pattern based on the lower endpoint of the interval. I also removed the recursive bit which handled integer ranges spanning a different orders of magnitude. I liked the recursion, but never mind.
The result was
Code: Select all
$ ./day02-go # Pi 5
Advent of Code Day 02 Gift Shop (go)
Part 1 The invalid ID sum is 24747430309
Part 2 The corrected ID sum is 30962646823
Total execution time 0.00399479 seconds.
viewtopic.php?p=2351556#p2351556
and consequently made no progress. It's almost always a bad idea to argue with a cat, so I've left them alone for now.
For reference the Go code for Day 2 is
Code: Select all
/* Advent of Code 2025 Day 02 Gift Shop (go)
Written December 2025 by Eric Olson */
package main
import("fmt"; "os"; "time"; "bufio")
var tictime time.Time
func tic(){
tictime=time.Now()
}
func toc() float64 {
now:=time.Now()
elapsed:=now.Sub(tictime)
return elapsed.Seconds()
}
type abspec struct {
a,b int64
}
func mkidrange(fn string)[]abspec {
fd,err:=os.Open(fn)
if err!=nil {
fmt.Fprintf(os.Stderr,"Unable to open %s for input!\n",fn)
os.Exit(1)
}
defer fd.Close()
fp:=bufio.NewReader(fd)
idrange:=make([]abspec,0,128)
for {
var a,b int64
r,err:=fmt.Fscanf(fp,"%d-%d",&a,&b)
if r!=2||err!=nil { break }
idrange=append(idrange,abspec{a,b})
_,err=fmt.Fscanf(fp,",")
if err!=nil { break }
}
return idrange
}
type patspec struct {
x,d,s int64
n int
}
var heap=make([]patspec,0,100)
func enqueue(p patspec){
var r=len(heap)
heap=append(heap,p)
for {
s:=(r+1)/2-1
if s<0 { break }
if heap[s].x<=p.x{
break
}
heap[r]=heap[s]
r=s
}
heap[r]=p
}
func dequeue()patspec {
if len(heap)==0 {
fmt.Printf("Tried to remove nonexistent point!\n")
os.Exit(1)
}
t:=heap[len(heap)-1]; heap=heap[:len(heap)-1]
if len(heap)==0 { return t }
p:=heap[0]
s0:=0
for {
r1:=2*(s0+1); r0:=r1-1
if r0>=len(heap){ break }
s1:=r0
if r1<len(heap){
if heap[r0].x>heap[r1].x{
s1=r1
}
}
if t.x<=heap[s1].x {
break;
}
heap[s0]=heap[s1]
s0=s1
}
heap[s0]=t
return p
}
func mkpat(d,s int64, n int)int64 {
r:=d
for i:=1;i<n;i++ { r=r*s+d }
return r
}
func tallyn(x abspec)(int64,int64){
s:=int64(10)
for i:=0;i<9;i++ {
var pat patspec
n:=2; s2:=s*s
for {
if x.a<s2-1 {
pat.d=s/10
pat.s=s
pat.n=n
pat.x=mkpat(pat.d,pat.s,pat.n)
if pat.x>x.b { break }
enqueue(pat)
}
n+=1; s2*=s
}
s*=10
}
p1:=int64(0); x1:=int64(0)
p2:=int64(0); x2:=int64(0)
for len(heap)>0 {
pat:=dequeue()
if pat.x>=x.a {
if x1!=pat.x&&pat.n==2 {
x1=pat.x
p1+=x1
}
if x2!=pat.x {
x2=pat.x
p2+=x2
}
}
pat.d+=1
if pat.d<pat.s {
pat.x=mkpat(pat.d,pat.s,pat.n)
if pat.x<=x.b {
enqueue(pat)
}
}
}
return p1,p2
}
func dowork(){
p1:=int64(0); p2:=int64(0)
idrange:=mkidrange("day02.txt")
for _,x:=range idrange {
r1,r2:=tallyn(x)
p1+=r1; p2+=r2
}
fmt.Printf("Part 1 The invalid ID sum is %d\n",p1)
fmt.Printf("Part 2 The corrected ID sum is %d\n",p2)
}
func main(){
fmt.Printf("Advent of Code Day 02 Gift Shop (go)\n\n")
tic()
dowork()
t:=toc()
fmt.Printf("\nTotal execution time %.6g seconds.\n",t)
os.Exit(0)
}
Re: Advent of Code 2025
Code: Select all
#include <iostream>
#include <chrono>
#include <fstream>
#include <set>
const char* filename = "data.txt";
const int tens[] = {1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
inline bool isodd(int i)
{
return i & 1;
}
int digits(long num)
{
int ret = 0;
while(num)
{
num /= 10;
ret++;
}
return ret;
}
long checkrange(long r1, long r2, int d, int num, std::set<long>& found)
{
// check range for repeated patterns of num digits;
// r1 and r2 are assumed to have the same number of digits
// d is the number of digits in ranges
// num is the number of digits of the pattern to check
if(d % num)
return 0;
// s is the number of repeats of the pattern
int s = d / num;
long ret = 0;
int p = tens[num];
long x = 1; // this could be improved
while(x < (p * s))
{
// make t the repeated pattern
long t = x;
for(int i = 0; i < s - 1; i++)
t = (t * p) + x;
// check if repeated pattern is in range
if((r1 <= t) && (r2 >= t))
{
// avoid duplicates
if(found.find(t) == found.cend())
{
ret += t;
found.insert(t);
}
}
if(t > r2)
break;
x++;
}
return ret;
}
long checkpatterns(long r1, long r2, int digits)
{
// my data has at most 10 digits
// we need to look for sequences of 2,3,4,5 digits
// some calls will be invalid but checkrange will sort
// set found set stops repeats e.g 11 4 times and 1111 twice
long ret = 0;
std::set<long> found;
for(int p = 1; p <= digits/2; p++)
ret += checkrange(r1, r2, digits, p, found);
return ret;
}
long check2(long r1, long r2)
{
// if neccessary split range so limits have same digits
// call checkrange for all possible pattern sizes
long ret = 0;
int d1 = digits(r1);
int d2 = digits(r2);
if(d1 != d2)
{
ret += checkpatterns(r1,tens[d1] -1, d1);
ret += checkpatterns(tens[d2 - 1],r2, d2);
}
else
ret += checkpatterns(r1,r2,d1);
return ret;
}
long check1(long r1, long r2)
{
// some range limits have different number of digits
// invalid id must have even number of digits
int d1 = digits(r1);
int d2 = digits(r2);
int d;
// r1 and r2 must be even
// in my data range limits differ by at most one digit in size
if(d1 != d2)
{
if(isodd(d1))
{
r1 = tens[d1];
d = d2;
}
else
{
r2 = tens[d2 - 1];
d = d1;
}
}
else
d = d1;
if(isodd(d))
return 0;
// generate numbers ofthe form xyzxyz
// and then test if in range;
long ret = 0;
int p = tens[d/2];
long x = r1 / p;
while(x < p)
{
long t = x + x*p;
if(r1 <= t && t <= r2)
ret += t;
if(t > r2)
break;
x++;
}
return ret;
}
int main()
{
std::chrono::time_point<std::chrono::system_clock> start,stop;
start = std::chrono::system_clock::now();
std::cout << "Advent of code 2025 day 2 \n";
std::ifstream file(filename);
long part1 = 0;
long part2 = 0;
if(file)
{
while(!file.eof())
{
long l1,l2;
char c;
file >> l1 >> l2 >> c;
//std::cout << l1 << " " << -l2 << " " << digits(-l2) << std::endl;
part1 += check1(l1, -l2);
part2 += check2(l1, -l2);
}
}
std::cout << "Part 1 " << part1 << "\n";
std::cout << "Part 2 " << part2 << "\n";
stop = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed = stop - start;
std::cout << "Elapsed time " << elapsed.count() << " seconds" << "\n";
return 0;
}
Code: Select all
Advent of code 2025 day 2
Part 1 21139440284
Part 2 38731915928
Elapsed time 0.000861608 seconds
Re: Advent of Code 2025
Idea is simple, build and traverse a graph. Part 2 can be solved by marking nodes for paper roll removal when traversing and removing paper rolls from marked nodes afterwards. Just repeat this until no more paper rolls can be removed.
Code: Select all
137 constant COLS
a:new "4.txt" f:slurp ( "." "0" s:replace! "@" "1" s:replace! a:push ) s:eachline "" a:join "" s:/ ' >n a:map constant data
: index> \ n1 n2 -- [row,col]
n:/mod swap 2 a:close ;
: build-graph \ a cols -- gr
>r a:new 2 a:close ["nodes", "edges"] swap m:zip gr:new
\ connect and filter edges
gr:connect gr:edges
( [0,1] a:_@ ( r@ index> ) a:map a:open ( n:- n:abs 2 n:< ) a:2map a:open and ) a:filter rdrop
gr:edges! ;
: app:main
data COLS build-graph
0 >r false 0 ( swap if gr:neighbors data swap a:_@ ' n:+ 0 a:reduce 4 n:< if 1 n:r+ then else drop then ) gr:traverse
r> . cr ;
Return to "Teaching and learning resources"
- Community
- General discussion
- Announcements
- Other languages
- Deutsch
- Español
- Français
- Italiano
- Nederlands
- 日本語
- Polski
- Português
- Русский
- Türkçe
- User groups and events
- Raspberry Pi Official Magazine
- Using the Raspberry Pi
- Beginners
- Troubleshooting
- Advanced users
- Assistive technology and accessibility
- Education
- Picademy
- Teaching and learning resources
- Staffroom, classroom and projects
- Astro Pi
- Mathematica
- High Altitude Balloon
- Weather station
- Programming
- C/C++
- Java
- Python
- Scratch
- Other programming languages
- Windows 10 for IoT
- Wolfram Language
- Bare metal, Assembly language
- Graphics programming
- OpenGLES
- OpenVG
- OpenMAX
- General programming discussion
- Projects
- Networking and servers
- Automation, sensing and robotics
- Graphics, sound and multimedia
- Other projects
- Gaming
- Media centres
- AIY Projects
- Hardware and peripherals
- Camera board
- Compute Module
- Official Display
- HATs and other add-ons
- Device Tree
- Interfacing (DSI, CSI, I2C, etc.)
- Keyboard computers (400, 500, 500+)
- Raspberry Pi Pico
- General
- SDK
- MicroPython
- Other RP2040 boards
- Zephyr
- Rust
- AI Accelerator
- AI Camera - IMX500
- Hailo
- Software
- Raspberry Pi OS
- Raspberry Pi Connect
- Raspberry Pi Desktop for PC and Mac
- Beta testing
- Other
- Android
- Debian
- FreeBSD
- Gentoo
- Linux Kernel
- NetBSD
- openSUSE
- Plan 9
- Puppy
- Arch
- Pidora / Fedora
- RISCOS
- Ubuntu
- Ye Olde Pi Shoppe
- For sale
- Wanted
- Off topic
- Off topic discussion