this post was submitted on 01 Dec 2024
49 points (96.2% liked)

Advent Of Code

920 readers
2 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
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

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 1: Historian Hysteria

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://blocks.programming.dev if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] [email protected] 1 points 1 month ago

Zig

const std = @import("std");
const List = std.ArrayList;
const Map = std.AutoHashMap;

const splitSeq = std.mem.splitSequence;
const splitScalar = std.mem.splitScalar;
const parseInt = std.fmt.parseInt;
const print = std.debug.print;
const sort = std.sort.block;

var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const alloc = gpa.allocator();

const Answer = struct {
    distance: u32,
    similarity: u32,
};

fn lessThan(_: void, lhs: []const u8, rhs: []const u8) bool {
    return std.mem.lessThan(u8, lhs, rhs);
}

pub fn solve(input: []const u8) !Answer {
    var rows = splitScalar(u8, input, '\n');
    var left_list = List([]const u8).init(alloc);
    defer left_list.deinit();
    var right_list = List([]const u8).init(alloc);
    defer right_list.deinit();

    // PART 1

    // split the rows into two lists
    while (rows.next()) |row| {
        var sides = splitSeq(u8, row, "   ");
        try left_list.append(sides.next() orelse break);
        try right_list.append(sides.next() orelse break);
    }
    _ = left_list.pop(); // last null

    // sort both lists
    sort([]const u8, left_list.items, {}, lessThan);
    sort([]const u8, right_list.items, {}, lessThan);

    var distance: u32 = 0;
    for (left_list.items, right_list.items) |left, right| {
        distance += @abs(try parseInt(i32, left, 10) - try parseInt(i32, right, 10));
    }

    // PART 2
    var right_scores = Map(i32, u32).init(alloc);
    defer right_scores.deinit();

    // count number of item appearances in the right list
    for (right_list.items) |item| {
        const value = try parseInt(i32, item, 10);
        const result = try right_scores.getOrPut(value);
        if (!result.found_existing) {
            result.value_ptr.* = 1;
        } else {
            result.value_ptr.* += 1;
        }
    }

    // sum up similarity between items in left list and right list scores
    var similarity: u32 = 0;
    for (left_list.items) |item| {
        const value = try parseInt(i32, item, 10);
        const result = right_scores.get(value) orelse 0;
        similarity += @as(u32, @intCast(value)) * result;
    }
    return Answer{ .distance = distance, .similarity = similarity };
}

pub fn main() !void {
    const answer = try solve(@embedFile("input.txt"));
    print("Part 1: {d}\n", .{answer.distance});
    print("Part 2: {d}\n", .{answer.similarity});
}

test "test input" {
    const answer = try solve(@embedFile("test.txt"));
    try std.testing.expectEqual(answer.distance, 11);
    try std.testing.expectEqual(answer.similarity, 31);
}