main.c (4257B)
1#include "aoc.h" 2#include "icc.h" 3#include "util.h" 4#include "allocator.h" 5 6#include <assert.h> 7#include <string.h> 8#include <stdlib.h> 9#include <stdio.h> 10#include <stdint.h> 11 12void 13run_amp(struct icc *icc, int phase, int input, int *out) 14{ 15 int in_cnt, out_cnt; 16 17 in_cnt = out_cnt = 0; 18 while (icc->state != ICC_HALT) { 19 icc_step_inst(icc); 20 switch (icc->state) { 21 case ICC_INPUT: 22 assert(in_cnt <= 1); 23 icc->in = (in_cnt == 0) ? phase : input; 24 in_cnt++; 25 break; 26 case ICC_OUTPUT: 27 assert(out_cnt == 0); 28 *out = icc->out; 29 out_cnt++; 30 break; 31 } 32 } 33} 34 35void 36bf_phase(struct icc *icc, struct dvec *inst, size_t *state, 37 size_t max_depth, size_t depth, int in, int *max, size_t *maxstate) 38{ 39 size_t i, k; 40 int out; 41 42 if (depth == max_depth) { 43 aoc_debug("SETTING %i%i%i%i%i -> %i\n", state[0], state[1], 44 state[2], state[3], state[4], in); 45 if (*max == 0 || in > *max) { 46 *max = in; 47 memcpy(maxstate, state, sizeof(int) * max_depth); 48 } 49 return; 50 } 51 52 for (i = 0; i < max_depth; i++) { 53 /* dont reuse phase setting */ 54 for (k = 0; k < depth; k++) 55 if (state[k] == i) break; 56 if (k != depth) continue; 57 58 state[depth] = i; 59 icc_reset(icc, inst); 60 aoc_debug("START AMP %i (%i):\n", depth, i); 61 run_amp(icc, (int) i, in, &out); 62 aoc_debug("END AMP %i (%i): %i -> %i\n", depth, i, in, out); 63 bf_phase(icc, inst, state, max_depth, 64 depth + 1, out, max, maxstate); 65 } 66} 67 68int 69run_phase_loop(struct icc *iccs, struct dvec *inst, size_t *state, size_t n) 70{ 71 size_t i; 72 int passes, done; 73 int *ins, out, in_cnt; 74 75 ins = malloc(n * sizeof(int)); 76 assert(ins != NULL); 77 78 for (i = 0; i < n; i++) 79 icc_reset(&iccs[i], inst); 80 81 ins[0] = 0; 82 passes = done = 0; 83 while (!done) { 84 for (i = 0; i < n; i++) { 85 in_cnt = 0; 86 aoc_debug("START AMP %i (%i):\n", i, state[i]); 87 while (iccs[i].state != ICC_HALT) { 88 icc_step_inst(&iccs[i]); 89 switch (iccs[i].state) { 90 case ICC_INPUT: 91 iccs[i].in = 92 (!passes && !in_cnt 93 ? (int) state[i] : ins[i]); 94 in_cnt++; 95 break; 96 case ICC_OUTPUT: 97 ins[(i+1) % n] = iccs[i].out; 98 break; 99 } 100 if (iccs[i].state == ICC_OUTPUT) 101 break; 102 } 103 if (iccs[i].state == ICC_HALT) 104 done = 1; 105 aoc_debug("END AMP %i (%i): %i -> %i\n", i, 106 state[i], ins[i], ins[(i+1) % n]); 107 } 108 passes += 1; 109 } 110 111 out = ins[0]; 112 free(ins); 113 114 return out; 115} 116 117void 118bf_phase_loop(size_t *state, size_t max_depth, size_t depth, 119 struct icc *iccs, void *inst, int *max, size_t *maxstate) 120{ 121 size_t i, k; 122 int out; 123 124 if (depth == max_depth) { 125 out = run_phase_loop(iccs, inst, state, max_depth); 126 aoc_debug("SETTING %i%i%i%i%i -> %i\n", state[0], state[1], 127 state[2], state[3], state[4], out); 128 if (*max == 0 || out > *max) { 129 *max = out; 130 memcpy(maxstate, state, sizeof(int) * max_depth); 131 } 132 return; 133 } 134 135 for (i = 0; i < max_depth; i++) { 136 for (k = 0; k < depth; k++) 137 if (state[k] - 5 == i) break; 138 if (k != depth) continue; 139 140 state[depth] = i + 5; 141 bf_phase_loop(state, max_depth, depth + 1, iccs, inst, max, maxstate); 142 } 143} 144 145void 146part1(void) 147{ 148 struct icc icc; 149 struct dvec inst; 150 size_t state[5], maxstate[5]; 151 int max; 152 153 icc_init(&icc); 154 icc_parse_inst(&icc, aoc.input, aoc.input_size); 155 156 dvec_init(&inst, sizeof(int), 0, &stdlib_heap_allocator); 157 dvec_copy(&inst, &icc.instructions); 158 159 max = 0; 160 bf_phase(&icc, &inst, state, 5, 0, 0, &max, maxstate); 161 162 aoc_debug("\nMAX SETTING: %i%i%i%i%i\n", maxstate[0], maxstate[1], 163 maxstate[2], maxstate[3], maxstate[4]); 164 165 aoc.answer = aprintf("%i", max); 166 aoc.solution = "24625"; 167 168 dvec_deinit(&inst); 169 icc_deinit(&icc); 170} 171 172void 173part2(void) 174{ 175 size_t state[5], maxstate[5]; 176 struct icc iccs[5]; 177 struct dvec inst; 178 int i, max; 179 180 icc_init(&iccs[0]); 181 icc_parse_inst(&iccs[0], aoc.input, aoc.input_size); 182 183 dvec_init(&inst, sizeof(int), 0, &stdlib_heap_allocator); 184 dvec_copy(&inst, &iccs[0].instructions); 185 186 for (i = 1; i < 5; i++) { 187 icc_init(&iccs[i]); 188 icc_copy(&iccs[i], &iccs[0]); 189 } 190 191 max = 0; 192 bf_phase_loop(state, 5, 0, iccs, &inst, &max, maxstate); 193 194 aoc_debug("\nMAX SETTING: %i%i%i%i%i\n", maxstate[0], maxstate[1], 195 maxstate[2], maxstate[3], maxstate[4]); 196 197 aoc.answer = aprintf("%i", max); 198 aoc.solution = "36497698"; 199 200 dvec_deinit(&inst); 201 for (i = 0; i < 5; i++) 202 icc_deinit(&iccs[i]); 203}