Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jobs:

- name: Compile all solutions for current year
run: zig build
working-directory: 2025
env:
AOC_COOKIE: ${{ secrets.AOC_COOKIE }}

1 change: 0 additions & 1 deletion .zigversion

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions 2025/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Avoid commiting puzzle inputs
input/**/*
29 changes: 29 additions & 0 deletions 2025/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Advent of Code 2025
### Summary


# Day 01
### Part 1
Easy start. Some tipps:
- Parse `L` and `R` into `-1` and `1`
- Use `@mod` for the rotational arithmetic of the dial
- Don't forget to initialise the dial to `50`!

### Part 2
Somehow tried to be smart and calculate the amount of rotations first with:
```zig
const rotation_count = @abs(@divTrunc(dial, change));
```



# Day 02


# Day 03
- Order is important


# Day 04
- Find `rows` and `columns` size upfront. Ensure to trim!
- Index the one-dimensional buffer with index `(x * rows) + y`
4 changes: 0 additions & 4 deletions 2025/SUMMARY.md

This file was deleted.

31 changes: 31 additions & 0 deletions 2025/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const std = @import("std");
const aoc = @import("aoc");

const YEAR = 2025;
var DAY: u5 = 1;

pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

if (b.args) |args| {
DAY = std.fmt.parseInt(u5, args[0], 10) catch 1;
std.debug.print("🎅🏼 Running day {d:0>2}\n", .{DAY});
const exe = try aoc.setupDay(b, target, optimize, YEAR, DAY);
aoc.runDay(b, exe);
} else {
const src_dir = try std.fs.cwd().openDir("src/", .{
.no_follow = true,
.iterate = true,
.access_sub_paths = false,
});
var it = src_dir.iterate();
while (try it.next()) |f| {
if (f.name[0] == '.') continue;
const name = std.fs.path.stem(f.name);
const day = try std.fmt.parseInt(aoc.types.Day, name[3..], 10);
std.debug.print("🎅🏼 Building day {d:0>2}\n", .{day});
_ = try aoc.setupDay(b, target, optimize, YEAR, day);
}
}
}
17 changes: 17 additions & 0 deletions 2025/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.{
.name = .advent_of_code2025,
.fingerprint = 0x775c1acd7871bd1a,
.version = "0.0.1",
.minimum_zig_version = "0.15.2",
.dependencies = .{
.aoc = .{ .path = "../modules/aoc" },
.libs = .{ .path = "../modules/libs" },
},
.paths = .{
"README.md",
"build.zig",
"build.zig.zon",
"src",
"modules",
},
}
Empty file added 2025/input/example/.gitkeep
Empty file.
Empty file added 2025/input/puzzle/.gitkeep
Empty file.
56 changes: 56 additions & 0 deletions 2025/src/day01.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const std = @import("std");
const aoc = @import("aoc");

const YEAR: u12 = 2025;
const DAY: u5 = 1;

const Allocator = std.mem.Allocator;
const log = std.log;

fn unifiedSolution() anyerror!void {}

fn part1(allocator: Allocator) anyerror!void {
_ = allocator;
var row_it = std.mem.tokenizeSequence(u8, @embedFile("puzzle-01"), "\n");
const max = 100;
var i: u32 = 0;
var dial: i32 = 50;
var result: u32 = 0;
while (row_it.next()) |row| : (i += 1) {
// std.debug.print("{d}\n", .{dial});
const sign: i32 = if (row[0] == 'L') -1 else 1;
const number = try std.fmt.parseInt(i32, row[1..], 10);
dial += sign * number;
dial = @mod(dial, max);
if (dial == 0) result += 1;
}
std.debug.print("\nResult: {d}\n", .{result});
}

fn part2(allocator: Allocator) anyerror!void {
_ = allocator;
var row_it = std.mem.tokenizeSequence(u8, @embedFile("puzzle-01"), "\n");
const max = 100;
var dial: i32 = 50;
var result: u32 = 0;
while (row_it.next()) |row| {
const sign: i32 = if (row[0] == 'L') -1 else 1;
const number = try std.fmt.parseInt(i32, row[1..], 10);
var change = sign * number;
while (change != 0) : (change += -1 * sign) {
dial += sign;
dial = @mod(dial, max);
if (dial == 0) result += 1;
}
}
std.debug.print("\nResult: {d}", .{result});
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

try aoc.runPart(allocator, part1);
try aoc.runPart(allocator, part2);
}
95 changes: 95 additions & 0 deletions 2025/src/day02.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const std = @import("std");
const aoc = @import("aoc");

const YEAR: u12 = 2025;
const DAY: u5 = 2;

const Allocator = std.mem.Allocator;
const log = std.log;

fn countDigits(number: usize) usize {
var r: usize = 0;
var n = number;
while (n > 0) : (r += 1) {
n /= 10;
}
return r;
}

fn part1(allocator: Allocator) anyerror!void {
const input_embed = @embedFile("puzzle-02");
std.debug.print("--- INPUT---\n{s}\n------------\n", .{input_embed});

var result: usize = 0;

var reader: std.Io.Reader = .fixed(std.mem.trimEnd(u8, input_embed, "\n"));
while (try reader.takeDelimiter(',')) |line| {
var ranges = std.mem.splitSequence(u8, line, "-");
const lhs = ranges.next().?;
const rhs = ranges.next().?;
const lower = try std.fmt.parseInt(u64, lhs, 10);
const upper = try std.fmt.parseInt(u64, rhs, 10);
for (lower..upper + 1) |id| {
const id_str = try std.fmt.allocPrint(allocator, "{d}", .{id});
if (try std.math.rem(usize, countDigits(id), 2) == 0) {
const left = id_str[0 .. id_str.len / 2];
const right = id_str[id_str.len / 2 ..];
defer allocator.free(id_str);
if (std.mem.eql(u8, left, right)) result += id;
}
}
}

std.debug.print("Result: {d}\n", .{result});
}

fn part2(allocator: Allocator) anyerror!void {
const input_embed = @embedFile("puzzle-02");
std.debug.print("--- INPUT---\n{s}\n------------\n", .{input_embed});

var result: usize = 0;

var reader: std.Io.Reader = .fixed(std.mem.trimEnd(u8, input_embed, "\n"));
while (try reader.takeDelimiter(',')) |line| {
var ranges = std.mem.splitSequence(u8, line, "-");
const lhs = ranges.next().?;
const rhs = ranges.next().?;
const lower = try std.fmt.parseInt(u64, lhs, 10);
const upper = try std.fmt.parseInt(u64, rhs, 10);
for (lower..upper + 1) |id| {
const id_str = try std.fmt.allocPrint(allocator, "{d}", .{id});
defer allocator.free(id_str);

var invalid = false;

const digit_count = countDigits(id);
check: for (1..digit_count) |x| {
const w = digit_count - x;
const remainder = try std.math.rem(usize, digit_count, w);
if (remainder > 0) continue;

var window_it = std.mem.window(u8, id_str, w, w);
const search = window_it.next().?;
while (window_it.next()) |seq| {
if (!std.mem.eql(u8, search, seq)) {
continue :check;
}
}
invalid = true;
break :check;
}
if (invalid) result += id;
}
}

std.debug.print("Result: {d}\n", .{result});
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

// try aoc.runPart(allocator, part1);
try aoc.runPart(allocator, part2);
}
119 changes: 119 additions & 0 deletions 2025/src/day03.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
const std = @import("std");
const aoc = @import("aoc");

const expect = std.testing.expect;

const YEAR: u12 = 2025;
const DAY: u5 = 3;

const Allocator = std.mem.Allocator;
const log = std.log;

fn part1(allocator: Allocator) anyerror!void {
_ = allocator;
const input_embed = @embedFile("puzzle-03");
var sum: u32 = 0;

var reader: std.Io.Reader = .fixed(input_embed);
while (try reader.takeDelimiter('\n')) |line| {
var largest: u8 = 0;

for (0..line.len) |i| {
const start_digit = try std.fmt.charToDigit(line[i], 10);
for (i + 1..line.len) |j| {
const end_digit = try std.fmt.charToDigit(line[j], 10);
const combination = start_digit * 10 + end_digit;
if (combination > largest) largest = combination;
}
}
sum += largest;
}
std.debug.print("Result: {d}\n", .{sum});
}

fn part2(allocator: Allocator) anyerror!void {
_ = allocator;
var total_joltage: u128 = 0;

const input = @embedFile("puzzle-03");
var reader: std.Io.Reader = .fixed(input);

const battery_count = 12;
while (try reader.takeDelimiter('\n')) |line| {
const contained_number = try findLargestContainedNumber(
@TypeOf(total_joltage),
line,
battery_count,
);
total_joltage += contained_number;
}

std.debug.print("Result: {d}\n", .{total_joltage});
}

fn findLargestContainedNumber(comptime T: type, line: []const u8, battery_count: usize) !T {
var largest_contained_number: T = 0;
var start_idx: usize = 0;
var search_space = line[start_idx .. line.len - (battery_count - 1)];
var found_digit_count: usize = 0;
for (0..battery_count) |e| {
var max: u8 = try std.fmt.charToDigit(search_space[0], 10);
var max_idx: usize = 0;
for (search_space[0..], 0..) |c, i| {
if (try std.fmt.charToDigit(c, 10) > max) {
max = c - '0';
max_idx = i;
}
}

largest_contained_number += max * std.math.pow(T, 10, (battery_count - 1) - e);

found_digit_count += 1;
start_idx += max_idx + 1;
const upper_bound = @min(
line.len,
@max(
(line.len - (battery_count -| 1 -| found_digit_count)),
start_idx + 1,
),
);
search_space = line[start_idx..upper_bound];
// std.debug.print(" > max: {d} [{d}]\n", .{ max, max_idx });
}
return largest_contained_number;
}

pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();

try aoc.runPart(allocator, part1);
try aoc.runPart(allocator, part2);
}

test "example-part2" {
try expect(987654321111 == try findLargestContainedNumber(u32, "987654321111111", 12));
try expect(811111111119 == try findLargestContainedNumber(u32, "811111111111119", 12));
try expect(434234234278 == try findLargestContainedNumber(u32, "234234234234278", 12));
try expect(888911112111 == try findLargestContainedNumber(u32, "818181911112111", 12));

try expect(919 == try findLargestContainedNumber(u32, "9119", 3));
try expect(123 == try findLargestContainedNumber(u32, "111123", 3));
try expect(923 == try findLargestContainedNumber(u32, "234789123", 3));
try expect(11145 == try findLargestContainedNumber(u32, "1111145", 5));
try expect(99919 == try findLargestContainedNumber(u32, "19191919", 5));

try expect(99919 == try findLargestContainedNumber(u32, "19191919", 5));

const input_example = @embedFile("example-03");
var result: u128 = 0;
var reader: std.Io.Reader = .fixed(input_example);
while (try reader.takeDelimiter('\n')) |line| {
const number = try findLargestContainedNumber(u32, line, 12);
result += number;
}
try expect(result == 3121910778619);

_ = try findLargestContainedNumber(u128, "2753445676625843555534776876555247667428557664243735457776754553427876646616644267454232337424744677", 12);
}
Loading