Advent of Code 2025 on Raspberry Pi Pico
Background
Advent of Code is an annual programming challenge where participants complete daily puzzles. In 2025 there were 12 puzzles from Dec 1st to Dec 12th. It’s a friendly competition and participants can use any programming language and any computing resource to complete.
I completed the challenge normally (repo). Now for bonus points, let’s go for an extra challenge of implementing the solution on a Raspberry Pi Pico.

To make it clear, it’s much easier to solve the puzzle on a regular computer (with an OS!) first. Then the solution and understanding of the problem can be ported to the much more constrained environment.
Raspberry Pi Pico specs
Speaking of constrained, let’s list some of the specs of the hardware we have to working with. For this application the two most important specs are:
- Dual-core Arm Cortex M0+ processor, flexible clock running up to 133 MHz
- 264 kB of SRAM, and 2 MB of on-board flash memory
That’s not a lot of processor, but more critically, thats not a lot of RAM. We can always wait longer for a calculation, but not enough RAM means we sometimes need to rethink an algorithm or constantly recalculate something because we can’t afford to store the intermediate results.
Project Settings
The features that I am using are stdio support over USB and C++ code (no RTTI and no exceptions). Also I am going to be using ETL instead of STL as much as possible.

In order to use the stdio communication, we need a program to connect to the terminal. I am using putty on Windows, and really the only configuration is selecting the COM port and setting the baud rate to 115200.

I/O Programming
For program input, I want something pretty close to the std::getline API. Here is normal C++ for reading from a file;
std::ifstream infile("input.txt");
//getline also optionally takes a delimiter parameter
for (std::string line; std::getline(infile, line);) {
//parse the line
}
So in our embedded application the following API is developed.
template <size_t n>
bool getline(etl::string<n> &line, char delim = 0)
{
line.clear();
int read_char{ 0 };
while (read_char = getchar(), read_char != EOF && read_char != '\x1A' && read_char != '\n' && read_char != delim) {
line.append(1, static_cast<char>(read_char));
}
//trim \r if windows line endings are sent
etl::trim_from_right(line, "\r");
//`\x1A` is used to indicate the end of the file
if (read_char == EOF || read_char == '\x1A')
return false;
return true;
}
using str_line_t = etl::string<31>;
//getline also optionally takes a delimiter input
for (str_line_t line; advt::getline(line);) {
}
Because we are reading the characters from the terminal input, we need a way to indicate that the transmission is finished. The byte 0x1A SUB is a special character used to indicate the end of file and it is inserted as the last character of the text file puzzle inputs.

On the PC side, the putty utility plink is used to transmit the file.
"C:\Program Files\PuTTY\plink.exe" pi_pico < C:\repos\advent2025_pico\day1\input.txt
For output, just the typical printf function has been used. In the future, it would be nice to wrap this in a interface similar to std::print.
ETL
ETL is used in place of the STL as much as possible. ETL provides many classes with similar APIs to the STL counterparts, but without memory allocation and can be configured to not use exceptions. I instead configured ETL to assert on error.
The ETL configuration is set using the etl_profile.h file.
Because ETL does not do memory allocation, the container capacities need to be set at compile time. Thankfully, with errors enabled, if a container runs out of capacity then the program will assert and halt. Then I can determine if the container size can be increased or if the approach needs to be reworked.
Day 1 Example
This screenshots shows the solution to the day 1 example input.

Link to the repo.