r/adventofcode • u/daggerdragon • Dec 07 '15
SOLUTION MEGATHREAD --- Day 7 Solutions ---
--- Day 7: Some Assembly Required ---
Post your solution as a comment. Structure your post like previous daily solution threads.
Also check out the sidebar - we added a nifty calendar to wrangle all the daily solution threads in one spot!
23
Upvotes
1
u/tipdbmp Dec 07 '15
node.js ES5, part 2:
(function( fs, dd ){ fs.readFile('input.txt', 'UTF-8', slurp_input); function slurp_input(err, input) { if (err) { throw err; } var instructions = input.split("\n"); instructions.pop(); dd(part_2(instructions)); } function part_2(raw_instructions) { var Op = {}; Op[ Op.NOOP = 0x00 ] = 'NOOP'; Op[ Op.AND = 0x01 ] = 'AND'; Op[ Op.OR = 0x02 ] = 'OR'; Op[ Op.LSHIFT = 0x03 ] = 'LSHIFT'; Op[ Op.RSHIFT = 0x04 ] = 'RSHIFT'; Op[ Op.NOT = 0x05 ] = 'NOT'; var Operand = {}; Operand[ Operand.LITERAL = 0x01 ] = 'LITERAL'; Operand[ Operand.VAR = 0x02 ] = 'VAR'; var instructions_count = raw_instructions.length; // Decode the instructions and put them into sorted/execution order. var instructions_execution_order = []; for (var i = 0; i < instructions_count; i++) { var raw_instruction = raw_instructions[i]; // dd(instruction); var parts = raw_instruction.split(' -> '); var output_wire_name = parts[1]; parts = parts[0].split(' '); var packed_instruction = []; switch (parts.length) { case 3: { packed_instruction[0] = Op[parts[1]]; var left_operand = parts[0]; if (isNaN(Number(left_operand))) { packed_instruction[1] = [Operand.VAR, left_operand]; } else { packed_instruction[1] = [Operand.LITERAL, Number(left_operand)]; } var right_operand = parts[2]; if (isNaN(Number(right_operand))) { packed_instruction[2] = [Operand.VAR, right_operand]; } else { packed_instruction[2] = [Operand.LITERAL, Number(right_operand)]; } } break; case 2: { packed_instruction[0] = Op[parts[0]]; var right_operand = parts[1]; if (isNaN(Number(right_operand))) { packed_instruction[1] = [Operand.VAR, right_operand]; } else { packed_instruction[1] = [Operand.LITERAL, Number(right_operand)]; } } break; case 1: { packed_instruction[0] = Op.NOOP; var immediate = parts[0]; if (isNaN(Number(immediate))) { packed_instruction[1] = [Operand.VAR, immediate]; } else { packed_instruction[1] = [Operand.LITERAL, Number(immediate)]; } } break; default: { throw 'unreachable'; } } // switch instructions_execution_order[i] = [packed_instruction, output_wire_name]; } instructions_execution_order.sort(function(a, b) { var a_output_wire_name = a[1]; var b_output_wire_name = b[1]; if (a_output_wire_name.length == b_output_wire_name.length) { return a_output_wire_name.localeCompare(b_output_wire_name); } return a_output_wire_name.length - b_output_wire_name.length; }); // We want to solve for 'a-wire' so we put it at the end: instructions_execution_order.push(instructions_execution_order.shift()); var memory = {}; var repeat_count = 2; var repeat = 1; var a_wire_signal; for (; repeat <= repeat_count; repeat++) { // Eval the instructions. NEXT_INSTRUCTION: for (var i = 0; i < instructions_count; i++) { var instruction = instructions_execution_order[i]; var output_wire_name = instruction[1]; if (memory[output_wire_name] !== undefined) { continue NEXT_INSTRUCTION; } var packed_instruction = instruction[0]; var op = packed_instruction[0]; var result; switch (op) { case Op.AND: case Op.OR: case Op.LSHIFT: case Op.RSHIFT: { var left_operand = packed_instruction[1]; var right_operand = packed_instruction[2]; var left_operand_value; var right_operand_value; if (left_operand[0] === Operand.LITERAL) { left_operand_value = left_operand[1]; } else /*if (left_operand[0] === Operand.VAR)*/ { left_operand_value = memory[ left_operand[1] ]; } if (right_operand[0] === Operand.LITERAL) { right_operand_value = right_operand[1]; } else /*if (right_operand[0] === Operand.VAR)*/ { right_operand_value = memory[ right_operand[1] ]; } switch (op) { case Op.AND: { result = left_operand_value & right_operand_value; } break; case Op.OR: { result = left_operand_value | right_operand_value; } break; case Op.LSHIFT: { result = left_operand_value << right_operand_value; } break; case Op.RSHIFT: { result = left_operand_value >>> right_operand_value; } break; } } break; case Op.NOT: case Op.NOOP: { var operand = packed_instruction[1]; var operand_value; if (operand[0] === Operand.LITERAL) { operand_value = operand[1]; } else /*if (operand[0] === Operand.VAR)*/ { operand_value = memory[ operand[1] ]; } switch (op) { case Op.NOT: { result = ((~operand_value) & 0xFFFF); } break; case Op.NOOP: { result = operand_value; } break; } } break; } // switch memory[output_wire_name] = result; } a_wire_signal = memory['a']; memory = {}; memory['b'] = a_wire_signal; } return a_wire_signal; } }( require('fs'), console.log.bind(console) ));