well part 1 was straightforward... is the solution for part 2 to run it in reverse?
This commit is contained in:
		
							
								
								
									
										117
									
								
								17/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								17/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
				
			|||||||
 | 
					import fs from "node:fs";
 | 
				
			||||||
 | 
					import { printTime, now, toNum } from "../util";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const test = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const data = fs.readFileSync(
 | 
				
			||||||
 | 
					  test ? "./inputs/testinput" : "./inputs/input",
 | 
				
			||||||
 | 
					  "utf8"
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let timer = now.instant();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let computer = data
 | 
				
			||||||
 | 
					  .split("\n")
 | 
				
			||||||
 | 
					  .slice(0, -1)
 | 
				
			||||||
 | 
					  .reduce(
 | 
				
			||||||
 | 
					    (state, line, i) => {
 | 
				
			||||||
 | 
					      switch (i) {
 | 
				
			||||||
 | 
					        case 0:
 | 
				
			||||||
 | 
					          state.A = toNum(line.split(": ")[1]);
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 1:
 | 
				
			||||||
 | 
					          state.B = toNum(line.split(": ")[1]);
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 2:
 | 
				
			||||||
 | 
					          state.C = toNum(line.split(": ")[1]);
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 3:
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        case 4:
 | 
				
			||||||
 | 
					          state.Program = line.split(": ")[1].split(",").map(toNum);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return state;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    { A: 0, B: 0, C: 0, Program: [], Output: [] } as {
 | 
				
			||||||
 | 
					      A: number;
 | 
				
			||||||
 | 
					      B: number;
 | 
				
			||||||
 | 
					      C: number;
 | 
				
			||||||
 | 
					      Program: number[];
 | 
				
			||||||
 | 
					      Output: number[];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const comboOperand = (computer, instructionPointer: number) => {
 | 
				
			||||||
 | 
					  switch (computer.Program[instructionPointer + 1]) {
 | 
				
			||||||
 | 
					    case 0:
 | 
				
			||||||
 | 
					    case 1:
 | 
				
			||||||
 | 
					    case 2:
 | 
				
			||||||
 | 
					    case 3:
 | 
				
			||||||
 | 
					      return computer.Program[instructionPointer + 1];
 | 
				
			||||||
 | 
					    case 4:
 | 
				
			||||||
 | 
					      return computer.A;
 | 
				
			||||||
 | 
					    case 5:
 | 
				
			||||||
 | 
					      return computer.B;
 | 
				
			||||||
 | 
					    case 6:
 | 
				
			||||||
 | 
					      return computer.C;
 | 
				
			||||||
 | 
					    case 7:
 | 
				
			||||||
 | 
					      throw "invalid!";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let instructionPointer = 0;
 | 
				
			||||||
 | 
					while (instructionPointer < computer.Program.length) {
 | 
				
			||||||
 | 
					  let instruction = computer.Program[instructionPointer];
 | 
				
			||||||
 | 
					  switch (instruction) {
 | 
				
			||||||
 | 
					    case 0: // adv: A/(2^combo-operand) => A
 | 
				
			||||||
 | 
					      computer.A = Math.trunc(
 | 
				
			||||||
 | 
					        computer.A / 2 ** comboOperand(computer, instructionPointer)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 1: // bxl: XOR(B, literal=operand) => B
 | 
				
			||||||
 | 
					      computer.B = computer.B ^ computer.Program[instructionPointer + 1];
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 2: // bst: combo-operand % 8 => B
 | 
				
			||||||
 | 
					      computer.B = comboOperand(computer, instructionPointer) % 8;
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 3: // jnz: jump to literal operand if non-zero register A
 | 
				
			||||||
 | 
					      if (computer.A !== 0) {
 | 
				
			||||||
 | 
					        instructionPointer = computer.Program[instructionPointer + 1];
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        instructionPointer += 2;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 4: // bxc: XOR(B, C) => B (consumes and ignores operand)
 | 
				
			||||||
 | 
					      computer.B = computer.B ^ computer.C;
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 5: // out: combo-operand => Output
 | 
				
			||||||
 | 
					      computer.Output.push(comboOperand(computer, instructionPointer) % 8);
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 6: // bdv: A/(2^combo-operand) => B
 | 
				
			||||||
 | 
					      computer.B = Math.trunc(
 | 
				
			||||||
 | 
					        computer.A / 2 ** comboOperand(computer, instructionPointer)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    case 7: // cdv: A/(2^combo-operand) => C
 | 
				
			||||||
 | 
					      computer.C = Math.trunc(
 | 
				
			||||||
 | 
					        computer.A / 2 ** comboOperand(computer, instructionPointer)
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      instructionPointer += 2;
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log(
 | 
				
			||||||
 | 
					  "part one:",
 | 
				
			||||||
 | 
					  computer.Output.join(","),
 | 
				
			||||||
 | 
					  printTime(now.instant().since(timer))
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// timer = now.instant();
 | 
				
			||||||
 | 
					// console.log("part two:", computer, printTime(now.instant().since(timer)));
 | 
				
			||||||
		Reference in New Issue
	
	Block a user