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

solve_day4 :: (test: bool) {
    contents := read_entire_file("inputs/day4.txt");
    lines    := split(contents, "\n");
    
    card_count: Table(u64, u64);

    part1 := 0;
    part2 := 0;

    for line, line_index: lines {
        card, added_card := find_or_add(*card_count, cast(u64)line_index);

        index_of_colon := find_index_from_left(line, ": ");
        index_of_pipe  := find_index_from_left(line, "|");

        winning_numbers_slice := slice(line, index_of_colon + 2, index_of_pipe - index_of_colon - 2);
        winning_numbers_split := split(winning_numbers_slice, " ");

        my_numbers_slice := slice(line, index_of_pipe + 2, line.count);
        my_numbers_split := split(my_numbers_slice, " ");

        winning_numbers: Table(string, u32);

        for winning_numbers_split {
            if it.count == 0  continue;
            value := string_to_int(it, 10, u32);
            table_add(*winning_numbers, it, value);
        }

        result       := 0;
        num_winnings := 0;

        for my_numbers_split {
            if it.count <= 0  continue;

            if table_contains(*winning_numbers, it) {
                if result == 0 {
                    result = 1;
                } else {
                    result *= 2;
                }
                num_winnings += 1;
            }
        }

        if added_card {
            (<< card) = 1;
        } else {
            << card += 1;
        }

        for line_index + 1..num_winnings + line_index {
            e, e_added := find_or_add(*card_count, cast(u64)it);

            if e_added {
                (<< e) = << card;
            } else {
                (<< e) += << card;
            }
        }

        part1 += result;

    }

    for v,k: card_count {
        part2 += cast(s64)v;
    }

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