Skip to content

Commit

Permalink
2024 day 4
Browse files Browse the repository at this point in the history
  • Loading branch information
agagniere committed Dec 4, 2024
1 parent 5e0a963 commit eeaeb53
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 3 deletions.
41 changes: 41 additions & 0 deletions 2024/04/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const std = @import("std");

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

const utils = b.dependency("utils", .{ .target = target, .optimize = optimize }).module("utils");

const exe = b.addExecutable(.{
.name = "day4",
.root_source_file = b.path("solve.zig"),
.target = target,
.optimize = optimize,
});

exe.root_module.addImport("utils", utils);
b.installArtifact(exe);

{ // Run
const run_step = b.step("run", "Run the app");
const run_cmd = b.addRunArtifact(exe);

run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
run_step.dependOn(&run_cmd.step);
}
{ // Test
const test_step = b.step("test", "Run unit tests");
const unit_tests = b.addTest(.{
.root_source_file = b.path("solve.zig"),
.target = target,
.optimize = optimize,
});
const run_unit_tests = b.addRunArtifact(unit_tests);

unit_tests.root_module.addImport("utils", utils);
test_step.dependOn(&run_unit_tests.step);
}
}
11 changes: 11 additions & 0 deletions 2024/04/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.{
.name = "day04",
.version = "0.1.0",
.dependencies = .{
.utils = .{
.url = "../utils/",
.hash = "122059863bba3b73097c2905eacfa772e5c9ad7cd6616270b08dfdf41e3d81900420",
},
},
.paths = .{ "build.zig", "build.zig.zon", "solve.zig" },
}
160 changes: 160 additions & 0 deletions 2024/04/solve.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
const std = @import("std");
const utils = @import("utils");

const PositionedLetter = std.AutoHashMap(Point, u8);
const Allocator = std.mem.Allocator;

const Point = struct {
x: i32,
y: i32,

pub fn add(self: Point, other: Point) Point {
return .{ .x = self.x + other.x, .y = self.y + other.y };
}

pub fn corners(self: Point) CornerIterator {
return .{ .center = self };
}
};

/// Loop over the 8 possible directions
const directions: [8]Point = blk: {
var result: [8]Point = undefined;

for (0..9) |i| {
result[i - (if (i > 4) 1 else 0)] = .{ .x = (@as(i32, i) % 3) - 1, .y = @as(i32, i) / 3 - 1 };
}
break :blk result;
};

/// Infinite iteration from a point in a given direction
const RayIterator = struct {
current: Point,
move: Point,

pub fn next(self: *RayIterator) ?Point {
self.current = self.current.add(self.move);
return self.current;
}
};

/// Iterate over the 4 corners of a given point
const CornerIterator = struct {
center: Point,
index: u8 = 0,

const corners: [4]Point = .{
.{ .x = -1, .y = -1 },
.{ .x = 1, .y = -1 },
.{ .x = 1, .y = 1 },
.{ .x = -1, .y = 1 },
};

pub fn next(self: *CornerIterator) ?Point {
if (self.index == 4)
return null;
const current = self.center.add(corners[self.index]);
self.index += 1;
return current;
}
};

/// Build the hashmap from an iterator of lines
pub fn parse(allocator: Allocator, input: anytype) !PositionedLetter {
var result = PositionedLetter.init(allocator);
var lines = utils.lineIterator(input);
var y: i32 = 0;

while (lines.next()) |line| {
for (line, 0..line.len) |c, x| {
try result.put(.{ .x = @intCast(x), .y = y }, c);
}
y += 1;
}
return result;
}

pub fn part1(input: PositionedLetter) u32 {
var iter = input.iterator();
var result: u32 = 0;

while (iter.next()) |letter| {
if (letter.value_ptr.* == 'X') {
for (directions) |direction| {
var ray: RayIterator = .{ .current = letter.key_ptr.*, .move = direction };
var i: u32 = 0;

while (ray.next()) |p| {
if (input.get(p) orelse break != "MAS"[i])
break;
i += 1;
if (i > 2) {
result += 1;
break;
}
}
}
}
}
return result;
}

pub fn part2(input: PositionedLetter) u32 {
var iter = input.iterator();
var result: u32 = 0;

outer: while (iter.next()) |letter| {
if (letter.value_ptr.* == 'A') {
var corners = letter.key_ptr.corners();
var surroundings: [4]u8 = undefined;
var i: u32 = 0;

while (corners.next()) |corner| {
const c = input.get(corner) orelse continue :outer;
surroundings[i] = c;
i += 1;
}
if (std.mem.indexOf(u8, "MSSMMSS", &surroundings) != null) {
result += 1;
}
}
}
return result;
}

pub fn main() !void {
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .{};
defer _ = gpa.deinit();
const allocator = gpa.allocator();

var stdin = std.io.bufferedReader(std.io.getStdIn().reader());

var input = try parse(allocator, stdin.reader());
defer input.deinit();

std.debug.print("Number of 'XMAS' : {:5}\n", .{part1(input)});
std.debug.print("Number of X 'MAS': {:5}\n", .{part2(input)});
}

// -------------------- Tests --------------------

test part1 {
const sample =
\\MMMSXXMASM
\\MSAMXMSMSA
\\AMXSXMAAMM
\\MSAMASMSMX
\\XMASAMXAMM
\\XXAMMXXAMA
\\SMSMSASXSS
\\SAXAMASAAA
\\MAMMMXMMMM
\\MXMXAXMASX
;
var stream = std.io.fixedBufferStream(sample);
var input = try parse(std.testing.allocator, stream.reader());
defer input.deinit();

try std.testing.expectEqual(18, part1(input));
try std.testing.expectEqual(9, part2(input));
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ My solutions for the [Advent of Code](https://adventofcode.com), a challenge sta
| 01 |:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:
| 02 |:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:
| 03 |:star::star:|:star::star:||:star::star:|:star::star:|:star::star:|:star::star:|:star::star:|:star::star:
| 04 |:star::star:|:star::star:|||:star::star:|:star::star:|:star::star:|:star::star:|
| 04 |:star::star:|:star::star:|||:star::star:|:star::star:|:star::star:|:star::star:|:star::star:
| 05 |:star::star:|:star::star:|||:star::star:|:star::star:|:star::star:|:star::star:|
| 06 ||:star::star:|||:star::star:|:star::star:|:star::star:|:star::star:|
| 07 ||:star::star:|||:star::star:|:star::star:|:star::star:|:star::star:|
Expand All @@ -30,6 +30,6 @@ My solutions for the [Advent of Code](https://adventofcode.com), a challenge sta
| 23 |||||||:star::star:|:star:|
| 24 ||||||:star::star:|:star::star:|:star:|
| 25 |||||:star:|:star:|:star::star:||
| Total | 10 | 14 | 4 | 6 | 42 | 44 | 50 | 44 | 6
| Total | 10 | 14 | 4 | 6 | 42 | 44 | 50 | 44 | 8

Total stars: 220
Total stars: 222

0 comments on commit eeaeb53

Please sign in to comment.