From a6aaafb7ffd81d62ff6c75436b4fa68ab41d2408 Mon Sep 17 00:00:00 2001 From: Tim Stallard Date: Tue, 13 Dec 2016 23:09:27 +0000 Subject: [PATCH] Started day 11 parallel rewrite --- day11/input_2.txt | 2 +- day11/input_test.txt | 4 + day11/old/part1.js | 151 ++++++++++++++++ day11/{ => old}/part1_new.js | 0 day11/{ => old}/part1_new3.js | 0 day11/{ => old}/part1_new4_unopt.js | 0 day11/{ => old}/part1_new5_unopt.js | 0 day11/package.json | 2 + day11/{part1_new2.js => parallel_rewrite.js} | 87 ++++++++-- day11/part1.js | 170 ++++++++----------- day11/test.js | 10 ++ 11 files changed, 316 insertions(+), 110 deletions(-) create mode 100644 day11/input_test.txt create mode 100644 day11/old/part1.js rename day11/{ => old}/part1_new.js (100%) rename day11/{ => old}/part1_new3.js (100%) rename day11/{ => old}/part1_new4_unopt.js (100%) rename day11/{ => old}/part1_new5_unopt.js (100%) rename day11/{part1_new2.js => parallel_rewrite.js} (63%) create mode 100644 day11/test.js diff --git a/day11/input_2.txt b/day11/input_2.txt index e82fca5..6bcf006 100644 --- a/day11/input_2.txt +++ b/day11/input_2.txt @@ -1,4 +1,4 @@ -The first floor contains a polonium generator, a thulium generator, a thulium-compatible microchip, a promethium generator, a ruthenium generator, a ruthenium-compatible microchip, a cobalt generator, and a cobalt-compatible microchip. +The first floor contains a polonium generator, a thulium generator, a thulium-compatible microchip, a promethium generator, a ruthenium generator, a ruthenium-compatible microchip, a cobalt generator, a elerium generator, a elerium-compatible microchip, a dilithium generator, a dilithium-compatible microchip, and a cobalt-compatible microchip. The second floor contains a polonium-compatible microchip and a promethium-compatible microchip. The third floor contains nothing relevant. The fourth floor contains nothing relevant. diff --git a/day11/input_test.txt b/day11/input_test.txt new file mode 100644 index 0000000..cc94eaa --- /dev/null +++ b/day11/input_test.txt @@ -0,0 +1,4 @@ +The first floor contains a thulium-compatible microchip. +The second floor contains nothing relevant. +The third floor contains nothing relevant. +The fourth floor contains nothing relevant. diff --git a/day11/old/part1.js b/day11/old/part1.js new file mode 100644 index 0000000..7bc3a4d --- /dev/null +++ b/day11/old/part1.js @@ -0,0 +1,151 @@ +var initialFloors = []; +var initialLift = 0; +var minFloor = 0; +var _ = require("underscore"); + +var scenarios = [ + { + floors: initialFloors, + lift: initialLift + } +]; + +var input = require("fs").readFileSync("input.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] = {chips: [], generators: []}; + 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(itemParts[1]); + } + else if(item.indexOf("microchip") != -1){ + var itemParts = item.match(/a ([^ ]+)-compatible microchip/); + initialFloors[floorNum].chips.push(itemParts[1]); + } + }); +}); + +function checkFloors(floors){ + for(var floor of floors){ + if(floor.generators.length > 0){ + for(var elem of floor.chips){ + if(floor.generators.indexOf(elem) == -1){ + return false; + } + } + } + } + return true; +} + +function possibleMoves(scenario){ + var newScenarios = []; + for(var chip of scenario.floors[scenario.lift].chips){ + if(scenario.lift > minFloor){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); + floors[scenario.lift - 1].chips.push(chip); + newScenarios.push({lift: scenario.lift - 1, floors: floors}); + } + if(scenario.lift < 3){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); + floors[scenario.lift + 1].chips.push(chip); + newScenarios.push({lift: scenario.lift + 1, floors: floors}); + } + + for(var generator of scenario.floors[scenario.lift].generators){ + /* + if(scenario.lift > 0){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); + floors[scenario.lift].generators = floors[scenario.lift].generators.filter((a)=>(a != generator)); + floors[scenario.lift - 1].chips.push(chip); + floors[scenario.lift - 1].generators.push(generator); + newScenarios.push({lift: scenario.lift - 1, floors: floors}); + } + */ + if(scenario.lift < 3){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); + floors[scenario.lift].generators = floors[scenario.lift].generators.filter((a)=>(a != generator)); + floors[scenario.lift + 1].chips.push(chip); + floors[scenario.lift + 1].generators.push(generator); + newScenarios.push({lift: scenario.lift + 1, floors: floors}); + } + } + for(var chip2 of scenario.floors[scenario.lift].chips.filter((a)=>(a != chip))){ + if(scenario.lift > minFloor){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)).filter((a)=>(a != chip2)); + floors[scenario.lift - 1].chips.push(chip); + floors[scenario.lift - 1].chips.push(chip2); + newScenarios.push({lift: scenario.lift - 1, floors: floors}); + } + if(scenario.lift < 3){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)).filter((a)=>(a != chip2)); + floors[scenario.lift + 1].chips.push(chip); + floors[scenario.lift + 1].chips.push(chip2); + newScenarios.push({lift: scenario.lift + 1, floors: floors}); + } + } + } + return newScenarios; +} + +function newPossibleScenarios(){ + allNewScenarios = []; + scenarios.forEach((scenario)=>{ + allNewScenarios = allNewScenarios.concat(possibleMoves(scenario).filter((a)=>(checkFloors(a.floors)))); + }); + return allNewScenarios; +} + +var i = 1; + +var solved = false; +/* +while(!solved){ + scenarios = newPossibleScenarios(); + console.log(JSON.stringify(scenarios)); + i++ + console.log(i); + minFloor = getMinFloor(); + console.log(minFloor); + if(minFloor == 3){ + console.log("SOLVED"); + solved = true; + } +} +*/ +function getMinFloor(){ + var min = 0; + for(var scenario of scenarios){ + var scenarioMin = 5; + for(var i in scenario.floors){ + if((scenario.floors[i].chips.length > 0) || (scenario.floors[i].generators.length > 0)){ + if(i < scenarioMin){ + scenarioMin = i; + } + } + } + if((scenarioMin > min) && (scenarioMin != 5)){ + min = scenarioMin + } + } + return min; +} + + +//console.log(JSON.stringify(possibleMoves(scenarios[0]))); +for(var i = 0; i < 8; i++){ + scenarios = newPossibleScenarios(); + console.log(JSON.stringify(scenarios)); + minFloor = getMinFloor() + console.log(minFloor); +} diff --git a/day11/part1_new.js b/day11/old/part1_new.js similarity index 100% rename from day11/part1_new.js rename to day11/old/part1_new.js diff --git a/day11/part1_new3.js b/day11/old/part1_new3.js similarity index 100% rename from day11/part1_new3.js rename to day11/old/part1_new3.js diff --git a/day11/part1_new4_unopt.js b/day11/old/part1_new4_unopt.js similarity index 100% rename from day11/part1_new4_unopt.js rename to day11/old/part1_new4_unopt.js diff --git a/day11/part1_new5_unopt.js b/day11/old/part1_new5_unopt.js similarity index 100% rename from day11/part1_new5_unopt.js rename to day11/old/part1_new5_unopt.js diff --git a/day11/package.json b/day11/package.json index 28410f3..d223e69 100644 --- a/day11/package.json +++ b/day11/package.json @@ -10,6 +10,8 @@ "license": "UNLICENSED", "dependencies": { "js-combinatorics": "^0.5.2", + "paralleljs": "^0.2.1", + "pararr": "0.0.3", "underscore": "^1.8.3" } } diff --git a/day11/part1_new2.js b/day11/parallel_rewrite.js similarity index 63% rename from day11/part1_new2.js rename to day11/parallel_rewrite.js index 8281a9c..92fd212 100644 --- a/day11/part1_new2.js +++ b/day11/parallel_rewrite.js @@ -2,8 +2,8 @@ var initialFloors = []; var initialLift = 0; var minFloor = 0; var _ = require("underscore"); -var combinatorics = require("js-combinatorics"); var previous = []; +var p = require("pararr"); var scenarios = [ { @@ -12,7 +12,7 @@ var scenarios = [ } ]; -var input = require("fs").readFileSync("input.txt").toString().replace(/\r/g, ""); +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 (.*)./); @@ -49,8 +49,9 @@ function getMinFloors(floors){ } function possibleScenarios(scenario){ - var newScenarios = []; + var combinatorics = require("js-combinatorics"); + var newScenarios = []; var ids = scenario.floors[scenario.lift].map((a, i)=>(i)); var arrangements = []; if(ids.length >= 1){ @@ -71,7 +72,7 @@ function possibleScenarios(scenario){ floors[scenario.lift] = floors[scenario.lift].filter((a)=>(a)); newScenarios.push({lift: scenario.lift + 1, floors: floors}); } - if((scenario.lift > minFloor)){ + if((scenario.lift > 0)){ var floors = JSON.parse(JSON.stringify(scenario.floors)); floors[scenario.lift - 1].push(floors[scenario.lift][arrangement[0]]); delete floors[scenario.lift][arrangement[0]]; @@ -86,33 +87,95 @@ function possibleScenarios(scenario){ return newScenarios; } -function nextSetOfScenarios(){ - var newScenarios = []; +function nextSetOfScenarios(scenarios, callback){ + scenarioCheckFloors = (scenario)=>{ + for(var floor of scenario.floors){ + if(floor.filter((a)=>(a[0] == "generator")).length > 0){ + for(var element of floor.filter((a)=>(a[0] == "microchip")).map((a)=>(a[1]))){ + if(floor.filter((a)=>(a[0] == "generator")).map((a)=>(a[1])).indexOf(element) == -1){ + return false; + } + } + } + } + return true; + }; + + scenarioSort = (scenario)=>{ + scenario.floors.forEach((a)=>(a.sort())); + return scenario; + } + + + + console.log("start", scenarios.length); + p.map(scenarios, possibleScenarios, (err, scenarios)=>{ + scenarios = scenarios.reduce((a, b)=>(a.concat(b)), []); + console.log("possibilities", scenarios.length); + p.filter(scenarios, scenarioCheckFloors, (err, scenarios)=>{ + console.log("valid", scenarios.length); + p.map(scenarios, scenarioSort, (err, scenarios)=>{ + console.log("sorted", scenarios.length); + callback(scenarios); + }); + }); + }) + + //p.map(possibleScenarios).reduce(merge).spawn(forceMerge).then(callback); + + + /* for(var scenario of scenarios){ newScenarios = newScenarios.concat(possibleScenarios(scenario)); } + + console.log("removing invalid"); newScenarios = newScenarios.filter((scenario)=>(checkFloors(scenario.floors))); console.log("newLength", newScenarios.length); + console.log("calc min"); localMinFloor = newScenarios.map((scenario)=>(getMinFloors(scenario.floors))).reduce((a, b)=>(Math.max(a, b))) - //console.log(newScenarios); - //newScenarios = newScenarios.filter((scenario)=>(getMinFloors(scenario.floors) == localMinFloor)); + console.log("sorting"); newScenarios.forEach((scenario)=>{scenario.floors.forEach((a)=>(a.sort()));}) + console.log("to JSON"); + newScenarios = newScenarios.map((scenario)=>(JSON.stringify(scenario))); + console.log("dedupe"); newScenarios = _.uniq(newScenarios, (scenario)=>(JSON.stringify(scenario))); - newScenarios = newScenarios.filter((scenario)=>(previous.indexOf(JSON.stringify(scenario)) == -1)); - //previous = []; - newScenarios.map((scenario)=>(previous.push(JSON.stringify(scenario)))); + console.log("removing previous"); + newScenarios = _.difference(newScenarios, previous); + console.log("adding to previous"); + newScenarios.forEach((scenario)=>(previous.push(scenario))); + console.log("from JSON"); + newScenarios = newScenarios.map((scenario)=>(JSON.parse(scenario))); + console.log("MIN", localMinFloor); if(localMinFloor == 3){ console.log("SOLVED"); } scenarios = newScenarios; + */ } - +/* var i = 0; while(minFloor < 3){ i++; nextSetOfScenarios(); + console.log("it", i); console.log(scenarios.length); } console.log(i); +*/ + +var i = 0; + +var callback = (scenarios)=>{ + if(i < 10){ + nextSetOfScenarios(scenarios, callback); + } + else{ + console.log(possibilities); + p.destroy(); + } +} + +nextSetOfScenarios(scenarios, callback); diff --git a/day11/part1.js b/day11/part1.js index 7bc3a4d..e4c6906 100644 --- a/day11/part1.js +++ b/day11/part1.js @@ -2,6 +2,8 @@ var initialFloors = []; var initialLift = 0; var minFloor = 0; var _ = require("underscore"); +var combinatorics = require("js-combinatorics"); +var previous = []; var scenarios = [ { @@ -15,25 +17,25 @@ 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] = {chips: [], generators: []}; + initialFloors[floorNum] = []; 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(itemParts[1]); + initialFloors[floorNum].push(["generator", itemParts[1]]) } else if(item.indexOf("microchip") != -1){ var itemParts = item.match(/a ([^ ]+)-compatible microchip/); - initialFloors[floorNum].chips.push(itemParts[1]); + initialFloors[floorNum].push(["microchip", itemParts[1]]) } }); }); function checkFloors(floors){ for(var floor of floors){ - if(floor.generators.length > 0){ - for(var elem of floor.chips){ - if(floor.generators.indexOf(elem) == -1){ + if(floor.filter((a)=>(a[0] == "generator")).length > 0){ + for(var element of floor.filter((a)=>(a[0] == "microchip")).map((a)=>(a[1]))){ + if(floor.filter((a)=>(a[0] == "generator")).map((a)=>(a[1])).indexOf(element) == -1){ return false; } } @@ -42,110 +44,84 @@ function checkFloors(floors){ return true; } -function possibleMoves(scenario){ +function getMinFloors(floors){ + return floors.map((a)=>(Boolean(a.length))).indexOf(true); +} + +function possibleScenarios(scenario){ var newScenarios = []; - for(var chip of scenario.floors[scenario.lift].chips){ - if(scenario.lift > minFloor){ - var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); - floors[scenario.lift - 1].chips.push(chip); - newScenarios.push({lift: scenario.lift - 1, floors: floors}); - } + + var ids = scenario.floors[scenario.lift].map((a, i)=>(i)); + var arrangements = []; + if(ids.length >= 1){ + arrangements = arrangements.concat(combinatorics.combination(ids, 1).toArray()); + } + if(ids.length >= 2){ + arrangements = arrangements.concat(combinatorics.combination(ids, 2).toArray()); + } + arrangements.forEach((arrangement)=>{ if(scenario.lift < 3){ var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); - floors[scenario.lift + 1].chips.push(chip); + floors[scenario.lift + 1].push(floors[scenario.lift][arrangement[0]]); + delete floors[scenario.lift][arrangement[0]]; + if(arrangement.length == 2){ + floors[scenario.lift + 1].push(floors[scenario.lift][arrangement[1]]); + delete floors[scenario.lift][arrangement[1]]; + } + floors[scenario.lift] = floors[scenario.lift].filter((a)=>(a)); newScenarios.push({lift: scenario.lift + 1, floors: floors}); } - - for(var generator of scenario.floors[scenario.lift].generators){ - /* - if(scenario.lift > 0){ - var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); - floors[scenario.lift].generators = floors[scenario.lift].generators.filter((a)=>(a != generator)); - floors[scenario.lift - 1].chips.push(chip); - floors[scenario.lift - 1].generators.push(generator); - newScenarios.push({lift: scenario.lift - 1, floors: floors}); - } - */ - if(scenario.lift < 3){ - var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)); - floors[scenario.lift].generators = floors[scenario.lift].generators.filter((a)=>(a != generator)); - floors[scenario.lift + 1].chips.push(chip); - floors[scenario.lift + 1].generators.push(generator); - newScenarios.push({lift: scenario.lift + 1, floors: floors}); + if((scenario.lift > minFloor)){ + var floors = JSON.parse(JSON.stringify(scenario.floors)); + floors[scenario.lift - 1].push(floors[scenario.lift][arrangement[0]]); + delete floors[scenario.lift][arrangement[0]]; + if(arrangement.length == 2){ + floors[scenario.lift - 1].push(floors[scenario.lift][arrangement[1]]); + delete floors[scenario.lift][arrangement[1]]; } + floors[scenario.lift] = floors[scenario.lift].filter((a)=>(a)); + newScenarios.push({lift: scenario.lift - 1, floors: floors}); } - for(var chip2 of scenario.floors[scenario.lift].chips.filter((a)=>(a != chip))){ - if(scenario.lift > minFloor){ - var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)).filter((a)=>(a != chip2)); - floors[scenario.lift - 1].chips.push(chip); - floors[scenario.lift - 1].chips.push(chip2); - newScenarios.push({lift: scenario.lift - 1, floors: floors}); - } - if(scenario.lift < 3){ - var floors = JSON.parse(JSON.stringify(scenario.floors)); - floors[scenario.lift].chips = floors[scenario.lift].chips.filter((a)=>(a != chip)).filter((a)=>(a != chip2)); - floors[scenario.lift + 1].chips.push(chip); - floors[scenario.lift + 1].chips.push(chip2); - newScenarios.push({lift: scenario.lift + 1, floors: floors}); - } - } - } + }); return newScenarios; } -function newPossibleScenarios(){ - allNewScenarios = []; - scenarios.forEach((scenario)=>{ - allNewScenarios = allNewScenarios.concat(possibleMoves(scenario).filter((a)=>(checkFloors(a.floors)))); - }); - return allNewScenarios; -} - -var i = 1; - -var solved = false; -/* -while(!solved){ - scenarios = newPossibleScenarios(); - console.log(JSON.stringify(scenarios)); - i++ - console.log(i); - minFloor = getMinFloor(); - console.log(minFloor); - if(minFloor == 3){ - console.log("SOLVED"); - solved = true; - } -} -*/ -function getMinFloor(){ - var min = 0; +function nextSetOfScenarios(){ + var newScenarios = []; for(var scenario of scenarios){ - var scenarioMin = 5; - for(var i in scenario.floors){ - if((scenario.floors[i].chips.length > 0) || (scenario.floors[i].generators.length > 0)){ - if(i < scenarioMin){ - scenarioMin = i; - } - } - } - if((scenarioMin > min) && (scenarioMin != 5)){ - min = scenarioMin - } + newScenarios = newScenarios.concat(possibleScenarios(scenario)); } - return min; + console.log("removing invalid"); + newScenarios = newScenarios.filter((scenario)=>(checkFloors(scenario.floors))); + console.log("newLength", 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.sort()));}) + console.log("to JSON"); + newScenarios = newScenarios.map((scenario)=>(JSON.stringify(scenario))); + console.log("dedupe"); + newScenarios = _.uniq(newScenarios, (scenario)=>(JSON.stringify(scenario))); + console.log("removing previous"); + newScenarios = _.difference(newScenarios, previous); + console.log("adding to previous"); + newScenarios.forEach((scenario)=>(previous.push(scenario))); + console.log("from JSON"); + newScenarios = newScenarios.map((scenario)=>(JSON.parse(scenario))); + + console.log("MIN", localMinFloor); + if(localMinFloor == 3){ + console.log("SOLVED"); + } + scenarios = newScenarios; } +var i = 0; -//console.log(JSON.stringify(possibleMoves(scenarios[0]))); -for(var i = 0; i < 8; i++){ - scenarios = newPossibleScenarios(); - console.log(JSON.stringify(scenarios)); - minFloor = getMinFloor() - console.log(minFloor); +while(minFloor < 3){ + i++; + nextSetOfScenarios(); + console.log("it", i); + console.log(scenarios.length); } +console.log(i); diff --git a/day11/test.js b/day11/test.js new file mode 100644 index 0000000..705d70a --- /dev/null +++ b/day11/test.js @@ -0,0 +1,10 @@ +var p = require("pararr"); +//var p = new Parallel([1, 2]); + +square = (num)=>([1, Math.pow(num, 2)]); +merge = ([a, b])=>(a.concat(b)); + +p.map([1, 2, 3], square, (err, data)=>{ + console.log(data); + p.destroy(); +});