package day_10 //import "core:container/queue" import "core:log" import "core:os" import "core:strconv" import "core:strings" Machine :: struct { lights: int `fmt:"10b"`, combinations: []int, buttons: [][]int, joltages: []int, } Input :: struct { machines: []Machine, } Result1 :: int Result2 :: int // --- Input --- // print_input :: proc(input: Input) { log.infof("%v", input) } 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") } defer delete(raw_data) lines, err := strings.split_lines(strings.trim_space(string(raw_data))) if err != .None { panic("oh no, failed splitting into lines") } defer delete(lines) input.machines = make([]Machine, len(lines)) for line, i in lines { chunks := strings.split(line, " ") defer delete(chunks) machine: Machine for l, l_i in chunks[0][1:len(chunks[0]) - 1] { machine.lights |= (1 if l == '#' else 0) << uint(l_i) } machine.buttons = make([][]int, len(chunks) - 2) machine.combinations = make([]int, len(chunks) - 2) for c, c_i in chunks[1:len(chunks) - 1] { num_splits := strings.count(c, ",") machine.buttons[c_i] = make([]int, len(c) - 2 - num_splits) val: int s_i: int for s in c[1:len(c) - 1] { if s == ',' { continue } b := s - '0' val |= 1 << uint(b) machine.buttons[c_i][s_i] = int(b) s_i += 1 } machine.combinations[c_i] = val log.debugf("%s -> %10b [%d]", c, val, val) log.debugf("%s -> %v", c, machine.buttons[c_i]) } joltages := strings.split(chunks[len(chunks) - 1][1:len(chunks[len(chunks) - 1]) - 1], ",") log.debugf("%v", joltages) defer delete(joltages) machine.joltages = make([]int, len(joltages)) for j, j_i in joltages { machine.joltages[j_i] = strconv.parse_int(j) or_else 0 } input.machines[i] = machine } log.debugf("%v", input.machines) return input } free_input :: proc(input: ^Input) { for machine in input.machines { for button in machine.buttons { delete(button) } delete(machine.buttons) delete(machine.combinations) delete(machine.joltages) } delete(input.machines) } // --- Input --- // // --- Helpers --- // bit_count := proc(x: int) -> int { x := x count: int for x != 0 { count += int(x & 1) x >>= 1 } return count } // --- Helpers --- // // --- Task 1 --- // run_task1 :: proc(input: Input) -> Result1 { result: Result1 for machine in input.machines { m := uint(len(machine.combinations)) best := 9999 total_subsets := 1 << m for subset in 0 ..< total_subsets { presses := bit_count(subset) if presses >= best { continue } state: int for i in 0 ..< m { if ((subset >> i) & 1) != 0 { state ~= machine.combinations[i] } } if state == machine.lights { best = presses } } log.debugf("%10b -> %d", machine.lights, best) result += best } return result } print_result1 :: proc(result: Result1) { log.infof("Task 1: %d", result) } // --- Task 1 --- // // --- Task 2 --- // State :: struct { counters: [10]int, } run_task2 :: proc(input: Input) -> Result2 { result: Result2 /*q: queue.Queue(State) queue.init(&q, 128) defer queue.destroy(&q) next: for machine, m_i in input.machines { log.debugf("machine %v", m_i) queue.clear(&q) start: State queue.push_back(&q, start) dist := make(map[[10]int]int) defer delete(dist) visited := make(map[[10]int]bool) defer delete(visited) for queue.len(q) > 0 { current := queue.pop_front(&q) done := true for j, j_i in machine.joltages { if current.counters[j_i] != j { done = false break } } if done { log.infof("FOUND %d", dist[current.counters]) result += dist[current.counters] continue next } for button in machine.buttons { next: [10]int copy(next[:], current.counters[:]) for b in button { next[b] += 1 } exceeds: bool for j, j_i in machine.joltages { if next[j_i] > j { exceeds = true break } } if exceeds { continue } if _, ok := visited[next]; !ok { visited[next] = true dist[next] = dist[current.counters] + 1 queue.push_back(&q, State{counters = next}) } } } }*/ return result } print_result2 :: proc(result: Result2) { log.infof("Task 2: %d", result) } // --- Task 2 --- // run :: proc() { input := parse_input_file("input/day_10.txt") defer free_input(&input) result1 := run_task1(input) print_result1(result1) result2 := run_task2(input) print_result2(result2) }