diff --git a/2019/day07/INPUT.txt b/2019/day07/INPUT.txt index ec0423c..0bb12ea 100644 --- a/2019/day07/INPUT.txt +++ b/2019/day07/INPUT.txt @@ -1 +1 @@ -3,225,1,225,6,6,1100,1,238,225,104,0,1101,86,8,225,1101,82,69,225,101,36,65,224,1001,224,-106,224,4,224,1002,223,8,223,1001,224,5,224,1,223,224,223,102,52,148,224,101,-1144,224,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,1102,70,45,225,1002,143,48,224,1001,224,-1344,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1101,69,75,225,1001,18,85,224,1001,224,-154,224,4,224,102,8,223,223,101,2,224,224,1,224,223,223,1101,15,59,225,1102,67,42,224,101,-2814,224,224,4,224,1002,223,8,223,101,3,224,224,1,223,224,223,1101,28,63,225,1101,45,22,225,1101,90,16,225,2,152,92,224,1001,224,-1200,224,4,224,102,8,223,223,101,7,224,224,1,223,224,223,1101,45,28,224,1001,224,-73,224,4,224,1002,223,8,223,101,7,224,224,1,224,223,223,1,14,118,224,101,-67,224,224,4,224,1002,223,8,223,1001,224,2,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,7,677,677,224,102,2,223,223,1005,224,329,1001,223,1,223,1008,226,226,224,1002,223,2,223,1005,224,344,1001,223,1,223,1107,677,226,224,1002,223,2,223,1006,224,359,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,374,101,1,223,223,1108,677,226,224,102,2,223,223,1005,224,389,1001,223,1,223,1007,677,677,224,1002,223,2,223,1005,224,404,101,1,223,223,1008,677,226,224,102,2,223,223,1005,224,419,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,434,1001,223,1,223,8,677,226,224,1002,223,2,223,1005,224,449,101,1,223,223,1008,677,677,224,1002,223,2,223,1006,224,464,1001,223,1,223,1108,226,226,224,1002,223,2,223,1005,224,479,1001,223,1,223,1007,226,677,224,102,2,223,223,1005,224,494,1001,223,1,223,1007,226,226,224,102,2,223,223,1005,224,509,101,1,223,223,107,677,226,224,1002,223,2,223,1006,224,524,1001,223,1,223,108,677,677,224,102,2,223,223,1006,224,539,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,554,1001,223,1,223,1107,226,677,224,102,2,223,223,1005,224,569,101,1,223,223,108,677,226,224,1002,223,2,223,1006,224,584,101,1,223,223,108,226,226,224,102,2,223,223,1006,224,599,1001,223,1,223,1107,226,226,224,102,2,223,223,1006,224,614,1001,223,1,223,8,226,677,224,102,2,223,223,1006,224,629,1001,223,1,223,107,226,226,224,102,2,223,223,1005,224,644,101,1,223,223,8,226,226,224,102,2,223,223,1006,224,659,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,674,101,1,223,223,4,223,99,226 +3,8,1001,8,10,8,105,1,0,0,21,30,39,64,81,102,183,264,345,426,99999,3,9,1001,9,2,9,4,9,99,3,9,1002,9,4,9,4,9,99,3,9,1002,9,5,9,101,2,9,9,102,3,9,9,1001,9,2,9,1002,9,2,9,4,9,99,3,9,1002,9,3,9,1001,9,5,9,1002,9,3,9,4,9,99,3,9,102,4,9,9,1001,9,3,9,102,4,9,9,1001,9,5,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99 diff --git a/2019/day07/README.org b/2019/day07/README.org index 2dd8708..1dd4a32 100644 --- a/2019/day07/README.org +++ b/2019/day07/README.org @@ -93,10 +93,73 @@ Here are some example programs: Try every combination of phase settings on the amplifiers. /What is the highest signal that can be sent to the thrusters?/ -To begin, [[file:7/input][get your puzzle input]]. +Your puzzle answer was =65464=. -Answer: +The first half of this puzzle is complete! It provides one gold star: * -You can also [Shareon -[[https://twitter.com/intent/tweet?text=%22Amplification+Circuit%22+%2D+Day+7+%2D+Advent+of+Code+2019&url=https%3A%2F%2Fadventofcode%2Ecom%2F2019%2Fday%2F7&related=ericwastl&hashtags=AdventOfCode][Twitter]] -[[javascript:void(0);][Mastodon]]] this puzzle. +** --- Part Two --- +It's no good - in this configuration, the amplifiers can't generate a +large enough output signal to produce the thrust you'll need. The Elves +quickly talk you through rewiring the amplifiers into a /feedback loop/: + +#+BEGIN_EXAMPLE + O-------O O-------O O-------O O-------O O-------O + 0 -+->| Amp A |->| Amp B |->| Amp C |->| Amp D |->| Amp E |-. + | O-------O O-------O O-------O O-------O O-------O | + | | + '--------------------------------------------------------+ + | + v + (to thrusters) +#+END_EXAMPLE + +Most of the amplifiers are connected as they were before; amplifier +=A='s output is connected to amplifier =B='s input, and so on. +/However,/ the output from amplifier =E= is now connected into amplifier +=A='s input. This creates the feedback loop: the signal will be sent +through the amplifiers /many times/. + +In feedback loop mode, the amplifiers need /totally different phase +settings/: integers from =5= to =9=, again each used exactly once. These +settings will cause the Amplifier Controller Software to repeatedly take +input and produce output many times before halting. Provide each +amplifier its phase setting at its first input instruction; all further +input/output instructions are for signals. + +Don't restart the Amplifier Controller Software on any amplifier during +this process. Each one should continue receiving and sending signals +until it halts. + +All signals sent or received in this process will be between pairs of +amplifiers except the very first signal and the very last signal. To +start the process, a =0= signal is sent to amplifier =A='s input +/exactly once/. + +Eventually, the software on the amplifiers will halt after they have +processed the final loop. When this happens, the last output signal from +amplifier =E= is sent to the thrusters. Your job is to /find the largest +output signal that can be sent to the thrusters/ using the new phase +settings and feedback loop arrangement. + +Here are some example programs: + +- Max thruster signal /=139629729=/ (from phase setting sequence + =9,8,7,6,5=): + + #+BEGIN_EXAMPLE + 3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26, + 27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5 + #+END_EXAMPLE + +- Max thruster signal /=18216=/ (from phase setting sequence + =9,7,8,5,6=): + + #+BEGIN_EXAMPLE + 3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54, + -5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4, + 53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10 + #+END_EXAMPLE + +Try every combination of the new phase settings on the amplifier +feedback loop. /What is the highest signal that can be sent to the +thrusters?/ diff --git a/2019/day07/aoc-c.c b/2019/day07/aoc-c.c index 9641d90..0bbca6f 100644 --- a/2019/day07/aoc-c.c +++ b/2019/day07/aoc-c.c @@ -41,10 +41,13 @@ typedef struct { char *mnemo; } ops_t; -#define MAXOPS 1024 +#define MAXINPUT 4 +#define MAXOPS 1024 typedef struct { int length; /* total program length */ int cur; /* current position */ + int curinput, lastinput; + int input[MAXINPUT]; /* input */ int mem [MAXOPS]; /* should really be dynamic */ } program_t; @@ -72,7 +75,45 @@ static int _flag_pow10[] = {1, 100, 1000, 10000}; INDIRECT(p, n + i) = val; } \ while (0) -static int run(program_t *p, int in) +/** + * permute - get next permutation of an array of integers + * @len: length of array + * @array: address of array + * + * Algorithm: lexicographic permutations + * https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order + * Before the initial call, the array must be sorted (e.g. 0 2 3 5) + * + * Return: 1 if next permutation was found, 0 if no more permutation. + * + */ +static int permute_next(int len, int *array) +{ + int k, l; + + /* 1. Find the largest index k such that a[k] < a[k + 1] */ + for (k = len - 2; k >= 0 && array[k] >= array[k + 1]; k--) + ; + /* No more permutations */ + if (k < 0) + return 0; + /* 2. Find the largest index l greater than k such that a[k] < a[l] */ + for (l = len - 1; array[l] <= array[k]; l--) + ; + /* 3. Swap the value of a[k] with that of a[l] */ + swap(array[k], array[l]); + /* 4. Reverse sequence from a[k + 1] up to the final element */ + for (l = len - 1, k++; k < l; k++, l--) + swap(array[k], array[l]); + return 1; +} + +static void dup_program(program_t *from, program_t *to) +{ + *to = *from; +} + +static int run(program_t *p) { int out = -1; while (1) { @@ -90,7 +131,7 @@ static int run(program_t *p, int in) poke(p, p->cur, 3, peek(p, p->cur, 1) * peek(p, p->cur, 2)); break; case INP: - poke(p, p->cur, 1, in); + poke(p, p->cur, 1, p->input[p->curinput++]); break; case OUT: out = peek(p, p->cur, 1); @@ -132,15 +173,20 @@ static int usage(char *prg) int main(int ac, char **av) { int opt, part = 1, in = -1; - program_t p = { 0 }; + program_t p = { 0 }, p1; + int phase[] = {0, 1, 2, 3, 4}; - while ((opt = getopt(ac, av, "d:p:i:")) != -1) { + while ((opt = getopt(ac, av, "d:p:i:o:")) != -1) { switch (opt) { case 'd': debug_level_set(atoi(optarg)); break; case 'i': - in = atoi(optarg); + p.input[p.lastinput++] = atoi(optarg); + break; + case 'o': + for (ulong i = 0; i < strlen(optarg); ++i) + phase[i] = optarg[i] - '0'; break; case 'p': /* 1 or 2 */ part = atoi(optarg); @@ -152,11 +198,32 @@ int main(int ac, char **av) } } + for (int i = 0; i < 5; ++i) + printf("phase[%d]=%d\n", i, phase[i]); + parse(&p); + int out, max = 0; + do { + out = 0; + for (int i = 0; i < 5; ++i) { + dup_program(&p, &p1); + p1.input[p1.lastinput++] = phase[i]; + p1.input[p1.lastinput++] = out; + out = run(&p1); + } + if (out > max) { + max = out; + printf("new max: %c%c%c%c%c out=%d max=%d\n", phase[0] + '0', + phase[1] + '0', phase[2] + '0', phase[3] + '0', phase[4] + '0', + out, max); + } + } while (permute_next(5, phase)); + + exit(0); if (optind < ac) return usage(*av); if (in == -1) in = part == 1? 1: 5; parse(&p); - printf("%s : res=%d\n", *av, run(&p, in)); + printf("%s : res=%d\n", *av, run(&p)); exit (0); }