solve_day3 :: (test: bool) {
    contents := read_entire_file(ifx test then "inputs/day3_test.txt" else "inputs/day3.txt");
    lines := split(contents, cast(u8) #char "\n");

    part1 := 0;
    part2 := 0;

    gamma: u64 = 0;
    
    ones := NewArray(lines[0].count, u16);
    defer array_free(ones);
    memset(ones.data, 0, size_of(u16) * ones.count);

    for line: lines {
        for 0..line.count - 1 {
            if line[it] == #char "1" {
                ones[it] += 1;
            }
        }
    }

    mask: u64 = 0;
    for ones {
        mask = (mask << 1) | 1;
        gamma <<= 1;
        if it * 2 > lines.count {
            gamma |= 1;
        }
    }


    print("Part 1: %\n", gamma * ((~gamma) & mask));
    print("Part 2: %\n", find_rating(lines, 0, true) * find_rating(lines, 0, false));
}

find_rating :: (lines: []string, bit_pos: u16, most: bool) -> s64 {
    if lines.count == 1 {
        return string_to_int(lines[0], 2, s64);
    }

    ones: [..]string;
    zeros: [..]string;

    defer array_free(ones);
    defer array_free(zeros);

    for lines {
        if      it[bit_pos] == #char "0"  array_add(*zeros, it);
        else if it[bit_pos] == #char "1"  array_add(*ones, it);
        else    assert(false);
    }

    most_of, least_of := ones, zeros;

    if most_of.count < least_of.count  most_of, least_of = least_of, most_of;

    return find_rating(ifx most then most_of else least_of, bit_pos + 1, most);
}