package main import "core:bytes" import "core:fmt" import "core:io" import "core:os" import "core:slice" Rucksack :: struct { items: []u8, } parse_input_file :: proc(filepath: string) -> [dynamic]Rucksack { data, ok := os.read_entire_file_from_filename(filepath) if !ok { panic("oh no, could not read file") } buf: bytes.Buffer bytes.buffer_init(&buf, data) defer bytes.buffer_destroy(&buf) rucksacks := make([dynamic]Rucksack, 0, 100) line: []u8 err: io.Error for ; err != .EOF; line, err = bytes.buffer_read_bytes(&buf, '\n') { if len(line) == 0 { continue } append(&rucksacks, Rucksack{items = slice.clone(line[:len(line) - 1])}) } return rucksacks } char_to_score :: proc(char: u8) -> int { score: int if char <= 'Z' { score = int(char - 'A') + 27 } else { score = int(char - 'a') + 1 } return score } task1 :: proc(rucksacks: []Rucksack) -> int { score: int for rucksack in rucksacks { first := make(map[u8]int) defer delete(first) last := make(map[u8]int) defer delete(last) half := len(rucksack.items) / 2 for i := 0; i < half; i += 1 { first[rucksack.items[i]] = 1 last[rucksack.items[half + i]] = 1 } for item in first { if item in last { score += char_to_score(item) } } } return score } task2 :: proc(rucksacks: []Rucksack) -> int { score: int for i := 0; i < len(rucksacks); i += 3 { items := make(map[u8]int) defer delete(items) for rucksack in rucksacks[i:i + 3] { unique_items := make(map[u8]int) defer delete(unique_items) for item in rucksack.items { unique_items[item] += 1 } for item in unique_items { items[item] += 1 } } for item, amount in items { if amount >= 3 { score += char_to_score(item) } } } return score } main :: proc() { rucksacks := parse_input_file("input.txt") defer delete(rucksacks) result1 := task1(rucksacks[:]) fmt.printf("Task 1 result: %v\n", result1) result2 := task2(rucksacks[:]) fmt.printf("Task 2 result: %v\n", result2) }