package main import "core:bytes" import "core:fmt" import "core:io" import "core:os" import "core:strconv" import "core:strings" Card :: struct { winners: []int, numbers: []int, } Input :: struct { cards: [dynamic]Card, } Result1 :: distinct int Result2 :: distinct int // --- Input --- // print_input :: proc(input: ^Input) { for card, i in input.cards { fmt.printf("Card % 3d: ", i + 1) for n in card.winners { fmt.printf("% 3d ", n) } fmt.printf(" |") for n in card.numbers { fmt.printf("% 3d ", n) } fmt.printf("\n") } } parse_numbers :: proc(numbers: string) -> []int { split_numbers := strings.fields(numbers) result := make([]int, len(split_numbers)) for n, i in split_numbers { result[i] = strconv.atoi(n) } return result } parse_input_file :: proc(filepath: string) -> Input { input: Input raw_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, raw_data) defer bytes.buffer_destroy(&buf) input.cards = make([dynamic]Card, 0, 10) line: string err: io.Error for ; err != .EOF; line, err = bytes.buffer_read_string(&buf, '\n') { if line == "" || line == "\n" { continue } line = line[:len(line) - 1] card: Card start := strings.index(line, ":") data := strings.split(line[start + 2:], " | ") card.winners = parse_numbers(data[0]) card.numbers = parse_numbers(data[1]) append(&input.cards, card) } return input } free_input :: proc(input: ^Input) { for card in input.cards { delete(card.winners) delete(card.numbers) } delete(input.cards) } // --- Input --- // // --- Task 1 --- // run_task1 :: proc(input: ^Input, debug: bool) -> Result1 { result: Result1 if debug { print_input(input) } for card in input.cards { count: int for n in card.numbers { for w in card.winners { if n == w { count = count * 2 if count > 0 else 1 break } } } result += Result1(count) } return result } print_result1 :: proc(result: ^Result1) { fmt.printf("Task 1: %d\n", result^) } // --- Task 1 --- // // --- Task 2 --- // run_task2 :: proc(input: ^Input, debug: bool) -> Result2 { result: Result2 if debug { print_input(input) } won_cards := make([]int, len(input.cards)) defer delete(won_cards) for _, i in won_cards { won_cards[i] = 1 } for card, i in input.cards { count: int for n in card.numbers { for w in card.winners { if n == w { count += 1 break } } } if count > 0 { for j := i + 1; j <= i + count && j < len(input.cards); j += 1 { won_cards[j] += won_cards[i] } } } for w in won_cards { result += Result2(w) } return result } print_result2 :: proc(result: ^Result2) { fmt.printf("Task 2: %d\n", result^) } // --- Task 2 --- //