var initialFloors = []; var initialLift = 0; var minFloor = 0; var _ = require("underscore"); var combinatorics = require("js-combinatorics"); var previous = []; var mapNumsToTypes = []; var stringify = (scenario) => { return scenario.lift + "x" + scenario.floors.map((floor)=>(floor.generators.join(",") + ":" + floor.chips.join(","))).join("-"); } var scenarioify = (str) => { return { floors: str.split("x")[1].split("-").map((floor)=>(floor.split(":").map((set)=>(set.split(",").map((a)=>(parseInt(a))).filter((a)=>(!isNaN(a))))))).map((group)=>({generators: group[0], chips: group[1]})), lift: parseInt(str.split("x")[0]) } } numFromType = (str) => { if(mapNumsToTypes.indexOf(str) > -1){ return mapNumsToTypes.indexOf(str); } else{ mapNumsToTypes.push(str); return (mapNumsToTypes.length - 1); } } var scenarios = [ { floors: initialFloors, lift: initialLift } ]; var input = require("fs").readFileSync("input_2.txt").toString().replace(/\r/g, ""); input.split("\n").filter((a)=>(a)).forEach((line)=>{ var floorNums = ["first", "second", "third", "fourth"]; var lineParts = line.match(/The ([^ ]+) floor contains (.*)./); var floorNum = floorNums.indexOf(lineParts[1]); initialFloors[floorNum] = {generators: [], chips: []}; var items = lineParts[2].replace("and ", ", ").split(", ").filter((a)=>(a)); items.forEach((item)=>{ if(item.indexOf("generator") != -1){ var itemParts = item.match(/a ([^ ]+) generator/); initialFloors[floorNum].generators.push(numFromType(itemParts[1])); } else if(item.indexOf("microchip") != -1){ var itemParts = item.match(/a ([^ ]+)-compatible microchip/); initialFloors[floorNum].chips.push(numFromType(itemParts[1])); } }); }); checkFloors = (floors) => { for(var floor of floors){ if(floor.generators.length > 0){ for(var chip of floor.chips){ if(floor.generators.indexOf(chip) == -1){ return false; } } } } return true; }; possibleScenarios = (scenario)=>{ var newScenarios = []; var items = scenario.floors[scenario.lift].generators.map((i)=>(["generators", i])).concat(scenario.floors[scenario.lift].chips.map((i)=>(["chips", i]))); var arrangements = []; if(items.length >= 1){ arrangements = arrangements.concat(combinatorics.combination(items, 1).toArray()); } if(items.length >= 2){ arrangements = arrangements.concat(combinatorics.combination(items, 2).toArray()); } var moves = []; if(scenario.lift < 3){ moves.push(1); } if(scenario.lift > 0){ moves.push(-1); } moves.forEach((move)=>{ arrangements.forEach((arrangement)=>{ var floors = JSON.parse(JSON.stringify(scenario.floors)); arrangement.forEach((item)=>{ floors[scenario.lift][item[0]] = floors[scenario.lift][item[0]].filter((a)=>(a != item[1])); floors[scenario.lift + move][item[0]].push(item[1]); }); newScenarios.push({ floors: floors, lift: scenario.lift + move }) }); }); return newScenarios; } function getMinFloors(floors){ return floors.map((a)=>(Boolean(a.generators.concat(a.chips).length))).indexOf(true); } var solved = false; function nextSetOfScenarios(){ var newScenarios = []; for(var scenario of scenarios){ newScenarios = newScenarios.concat(possibleScenarios(scenario)); } console.log("possible", newScenarios.length); console.log("removing invalid"); newScenarios = newScenarios.filter((scenario)=>(checkFloors(scenario.floors))); console.log("removed invalid", newScenarios.length); console.log("calc min"); localMinFloor = newScenarios.map((scenario)=>(getMinFloors(scenario.floors))).reduce((a, b)=>(Math.max(a, b))) console.log("sorting"); newScenarios.forEach((scenario)=>{scenario.floors.forEach((a)=>{a.chips.sort(); a.generators.sort()});}) console.log("to strings"); newScenarios = newScenarios.map((scenario)=>(stringify(scenario))); console.log("dedupe"); newScenarios = _.uniq(newScenarios); console.log("deduped", newScenarios.length); console.log("removing previous"); newScenarios = _.difference(newScenarios, previous); console.log("removed previous", newScenarios.length); console.log("adding to previous"); newScenarios.forEach((scenario)=>(previous.push(scenario))); console.log("from strings"); newScenarios = newScenarios.map((scenario)=>(scenarioify(scenario))); console.log("MIN", localMinFloor); if(localMinFloor == 3){ solved = true; console.log("SOLVED"); } scenarios = newScenarios; } var i = 0; console.log(scenarios.map(stringify)); while(!solved){ i++; nextSetOfScenarios(); console.log("it", i); } console.log(i); /* console.log(JSON.stringify(scenarios)); console.log(scenarios.map(stringify)); nextSetOfScenarios(); console.log(scenarios.map(stringify)); console.log("possible", possibleScenarios(scenarios[0]).map(stringify)); nextSetOfScenarios(); console.log(scenarios.map(stringify)); nextSetOfScenarios(); console.log(scenarios.map(stringify)); */ //console.log(JSON.stringify(scenarios));