Repo for my Advent of Code solutions.
package main

import "core:os"
import "core:fmt"
import "core:strings"
import "core:strconv"

PassportFields :: enum {
    byr, iyr, eyr, hgt, hcl, ecl, pid, cid
}

Passport :: bit_set[PassportFields];
FullPassport :: bit_set[PassportFields] { .byr, .iyr, .eyr, .hgt, .hcl, .ecl, .pid, .cid };
NorthPoleCredentials :: bit_set[PassportFields] { .byr, .iyr, .eyr, .hgt, .hcl, .ecl, .pid };

main :: proc() {
    input, err := os.read_entire_file("input.txt");
	inputStr := string(input);

    lines := strings.split(inputStr, "\n");
    
    passportIndex := 0;
    currentPassport := Passport {};
    numValid := 0;
    for line in lines {
        line := strings.trim_space(line);

        if line == "" {
            // Check if valid
            if FullPassport &~ currentPassport == {} || FullPassport &~ currentPassport == { .cid } {
                numValid += 1;
            }

            passportIndex += 1;
            currentPassport = {};
        } else {
            fields := strings.split(line, " ");

            for field in fields {
                parts := strings.split(field, ":");
                kind := parts[0];
                value := parts[1];

                if kind == "byr" {
                    num, ok := strconv.parse_int(value);

                    if ok && num >= 1920 && num <= 2002 {
                        currentPassport |= { .byr };
                    }
                } else if kind == "iyr" {
                    num, ok := strconv.parse_int(value);

                    if ok && num >= 2010 && num <= 2020 {
                        currentPassport |= { .iyr };
                    }
                } else if kind == "eyr" {
                    num, ok := strconv.parse_int(value);

                    if ok && num >= 2020 && num <= 2030 {
                        currentPassport |= { .eyr };
                    }
                } else if kind == "hgt" {
                    num, ok := strconv.parse_int(value[0:len(value) - 2]);

                    if ok && strings.has_suffix(value, "cm") && num >= 150 && num <= 193 {
                        currentPassport |= { .hgt };
                    } else if ok && strings.has_suffix(value, "in") && num >= 59 && num <= 76 {
                        currentPassport |= { .hgt };
                    }
                } else if kind == "hcl" {
                    if strings.has_prefix(value, "#") && len(value) - 1 == 6 {
                        currentPassport |= { .hcl };
                    }
                } else if kind == "ecl" {
                    if value == "amb" || value == "blu" || value == "brn" || value == "gry" || value == "grn" || value == "hzl" || value == "oth" {
                        currentPassport |= { .ecl };
                    }
                } else if kind == "pid" {
                    num, ok := strconv.parse_int(value);

                    if ok && len(value) == 9 {
                        currentPassport |= { .pid };
                    }
                } else if kind == "cid" {
                    currentPassport |= { .cid };
                }
            }
        }
    }

    fmt.printf("Valid: %d\n", numValid);
}