#import "Basic";
#import "File";
#import "String";

solve_day15 :: (test: bool) {
    contents := read_entire_file(ifx test then "inputs/day15_test.txt" else "inputs/day15.txt");

    part1 := 0;
    part2 := 0;

    parts := split(contents, ","[0]);

    boxes := NewArray(256, [..]Lens, initialized = true);

    for token: parts {
        part1 += compute_hash(token);

        i: u32 = 0;
        while token[i] != #char "-" && token[i] != #char "=" {
            i += 1;
        }

        lens_name := slice(token, 0, i);
        hash := compute_hash(lens_name);

        if token[i] == #char "=" {
            i += 1;

            lens_strength := string_to_int(slice(token, i, token.count), 10, u32);

            exists := false;

            for *box: boxes[hash] {
                if box.name == lens_name {
                    box.value = lens_strength;
                    exists = true;
                    break;
                }
            }

            if !exists {
                array_add(*boxes[hash], .{name = lens_name, value = lens_strength});
            }
        } else if token[i] == #char "-" {
            j := -1;

            for box, box_index: boxes[hash] {
                if box.name == lens_name {
                    j = box_index;
                    break;
                }
            }

            if j >= 0 {
                array_ordered_remove_by_index(*boxes[hash], j);
            }
        }
    }

    for box, box_index: boxes {
        for lens, slot: box {
            part2 += (box_index + 1) * lens.value * (slot + 1);
        }
    }

    print("Part 1: %\n", part1);
    print("Part 2: %\n", part2);
} 

compute_hash :: (s: string) -> u8 {
    hash: u64 = 0;

    for 0..s.count - 1 {
        assert(s[it] != #char ",", "Found ',' in '%'", s);

        hash += s[it];
        hash *= 17;
        hash %= 256;
    }

    return xx hash;
}

Lens :: struct {
    name: string;
    value: u32;
}