aboutsummaryrefslogtreecommitdiffstats
path: root/src/03/main.zig
blob: 2ec8f24a60a87a4a5267aba17ea1223364dbcde3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
const std = @import("std");
const aoc = @import("aoc");

const Entry = []u1;
const Vector = struct { x: u16, y: u16 };

fn freeEntries(allocator: std.mem.Allocator, entries: *const std.ArrayList(Entry)) void {
    for (entries.items) |entry| {
        allocator.free(entry);
    }
    entries.deinit();
}

fn parse(allocator: std.mem.Allocator, input: []u8) !std.ArrayList(Entry) {
    var entries = std.ArrayList(Entry).init(allocator);
    errdefer freeEntries(allocator, &entries);

    var lineit = std.mem.tokenize(u8, input, "\n");
    while (lineit.next()) |line| {
        var linemap: []u1 = try allocator.alloc(u1, line.len);
        errdefer allocator.free(linemap);

        for (line) |c, i| {
            linemap[i] = @boolToInt(c == '#');
        }
        try entries.append(linemap);
    }

    return entries;
}

fn treesHit(map: std.ArrayList(Entry), slope: Vector) u16 {
    var count: u16 = 0;
    var pos = Vector{ .x = 0, .y = 0 };
    while (pos.y < map.items.len - 1) {
        pos.x += slope.x;
        pos.y += slope.y;

        count += map.items[pos.y][pos.x % map.items[0].len];
    }
    return count;
}

fn part1(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
    _ = args;

    const map = try parse(allocator, input);
    defer freeEntries(allocator, &map);

    const answer = treesHit(map, Vector{ .x = 3, .y = 1 });

    return try std.fmt.allocPrint(allocator, "{d}", .{answer});
}

fn part2(allocator: std.mem.Allocator, input: []u8, args: [][]u8) !?[]u8 {
    _ = args;

    const map = try parse(allocator, input);
    defer freeEntries(allocator, &map);

    const slopes = [_]Vector{
        Vector{ .x = 1, .y = 1 },
        Vector{ .x = 3, .y = 1 },
        Vector{ .x = 5, .y = 1 },
        Vector{ .x = 7, .y = 1 },
        Vector{ .x = 1, .y = 2 },
    };

    var answer: u32 = 1;
    for (slopes) |slope| {
        answer *= treesHit(map, slope);
    }

    return try std.fmt.allocPrint(allocator, "{d}", .{answer});
}

pub const main = aoc.main(part1, part2, .{ "282", "958815792" });