2016-12-11 23:54:03 +00:00
|
|
|
var initialFloors = [];
|
|
|
|
var initialLift = 0;
|
|
|
|
var minFloor = 0;
|
|
|
|
var _ = require("underscore");
|
|
|
|
var previous = [];
|
2016-12-13 23:09:27 +00:00
|
|
|
var p = require("pararr");
|
2016-12-11 23:54:03 +00:00
|
|
|
|
|
|
|
var scenarios = [
|
|
|
|
{
|
|
|
|
floors: initialFloors,
|
|
|
|
lift: initialLift
|
|
|
|
}
|
|
|
|
];
|
|
|
|
|
2016-12-13 23:09:27 +00:00
|
|
|
var input = require("fs").readFileSync("input_2.txt").toString().replace(/\r/g, "");
|
2016-12-11 23:54:03 +00:00
|
|
|
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] = [];
|
|
|
|
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].push(["generator", itemParts[1]])
|
|
|
|
}
|
|
|
|
else if(item.indexOf("microchip") != -1){
|
|
|
|
var itemParts = item.match(/a ([^ ]+)-compatible microchip/);
|
|
|
|
initialFloors[floorNum].push(["microchip", itemParts[1]])
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
function checkFloors(floors){
|
|
|
|
for(var floor of 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
function getMinFloors(floors){
|
|
|
|
return floors.map((a)=>(Boolean(a.length))).indexOf(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function possibleScenarios(scenario){
|
2016-12-13 23:09:27 +00:00
|
|
|
var combinatorics = require("js-combinatorics");
|
2016-12-11 23:54:03 +00:00
|
|
|
|
2016-12-13 23:09:27 +00:00
|
|
|
var newScenarios = [];
|
2016-12-11 23:54:03 +00:00
|
|
|
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 + 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});
|
|
|
|
}
|
2016-12-13 23:09:27 +00:00
|
|
|
if((scenario.lift > 0)){
|
2016-12-11 23:54:03 +00:00
|
|
|
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});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return newScenarios;
|
|
|
|
}
|
|
|
|
|
2016-12-13 23:09:27 +00:00
|
|
|
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)=>{
|
2016-12-15 10:39:48 +00:00
|
|
|
scenario.floors = scenario.floors.map((a)=>(a.sort()));
|
2016-12-13 23:09:27 +00:00
|
|
|
return scenario;
|
|
|
|
}
|
2016-12-15 10:39:48 +00:00
|
|
|
scenarioToJson = (scenario)=>{
|
|
|
|
return scenario
|
|
|
|
};
|
|
|
|
scenarioFromJson = (scenario)=>(scenario);
|
2016-12-13 23:49:17 +00:00
|
|
|
scenarioDuplicate = (scenario, i, scenarios)=>{
|
2016-12-15 10:39:48 +00:00
|
|
|
//console.log(scenario[2].findIndex((item)=>(console.log("item", item))), i);
|
|
|
|
var scenarioStr = JSON.stringify(scenario);
|
|
|
|
return (scenarios.findIndex((item)=>(JSON.stringify(item) == scenarioStr)) == i);
|
2016-12-13 23:49:17 +00:00
|
|
|
};
|
2016-12-15 10:39:48 +00:00
|
|
|
scenarioPrevious = (scenario)=>{
|
|
|
|
//console.log(previous.indexOf(JSON.stringify(scenario)));
|
|
|
|
return (previous.indexOf(JSON.stringify(scenario)) == -1);
|
|
|
|
};
|
|
|
|
scenarioAddToPrevious = (scenario)=>{
|
|
|
|
previous.push(JSON.stringify(scenario));
|
|
|
|
}
|
2016-12-13 23:09:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
console.log("start", scenarios.length);
|
|
|
|
p.map(scenarios, possibleScenarios, (err, scenarios)=>{
|
2016-12-13 23:18:11 +00:00
|
|
|
var allscenarios = [];
|
|
|
|
for(var scenarioSet of scenarios){
|
|
|
|
for(var scenario of scenarioSet){
|
|
|
|
allscenarios.push(scenario);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
scenarios = allscenarios;
|
2016-12-13 23:09:27 +00:00
|
|
|
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);
|
2016-12-15 10:39:48 +00:00
|
|
|
|
|
|
|
console.log("to JSON", scenarios.length);
|
|
|
|
scenarios = scenarios.map((scenario)=>(JSON.stringify(scenario)));
|
|
|
|
console.log("dedupe", scenarios.length);
|
|
|
|
scenarios = _.uniq(scenarios, (scenario)=>(JSON.stringify(scenario)));
|
|
|
|
console.log("removing previous", scenarios.length);
|
|
|
|
scenarios = _.difference(scenarios, previous);
|
|
|
|
console.log("adding to previous", scenarios.length);
|
|
|
|
scenarios.forEach((scenario)=>(previous.push(scenario)));
|
|
|
|
console.log("from JSON", scenarios.length);
|
|
|
|
scenarios = scenarios.map((scenario)=>(JSON.parse(scenario)));
|
|
|
|
callback(scenarios);
|
|
|
|
|
|
|
|
/*
|
2016-12-13 23:49:17 +00:00
|
|
|
p.map(scenarios, scenarioToJson, (err, scenarios)=>{
|
|
|
|
console.log("inJSON", scenarios.length);
|
2016-12-15 10:39:48 +00:00
|
|
|
//console.log(scenarios[0]);
|
2016-12-13 23:56:11 +00:00
|
|
|
scenarios = scenarios.map((scenario)=>([false, scenario]));
|
2016-12-13 23:49:17 +00:00
|
|
|
p.map(scenarios, scenarioDuplicate, (err, scenarios)=>{
|
|
|
|
scenarios = scenarios.filter((scenario)=>(scenario[0]));
|
|
|
|
scenarios = scenarios.map((scenario)=>(scenario[1]));
|
|
|
|
console.log("deduped", scenarios.length);
|
|
|
|
p.map(scenarios, scenarioFromJson, (err, scenarios)=>{
|
|
|
|
console.log("fromJSON", scenarios.length);
|
|
|
|
callback(scenarios);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2016-12-15 10:39:48 +00:00
|
|
|
*/
|
2016-12-13 23:09:27 +00:00
|
|
|
});
|
|
|
|
});
|
2016-12-13 23:49:17 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
/*
|
|
|
|
Standard code to copy
|
|
|
|
p.map(scenarios, scenarioSort, (err, scenarios)=>{
|
|
|
|
callback(scenarios);
|
|
|
|
});
|
|
|
|
|
|
|
|
*/
|
2016-12-13 23:09:27 +00:00
|
|
|
|
|
|
|
//p.map(possibleScenarios).reduce(merge).spawn(forceMerge).then(callback);
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2016-12-11 23:54:03 +00:00
|
|
|
for(var scenario of scenarios){
|
2016-12-15 10:39:48 +00:00
|
|
|
scenarios = newScenarios.concat(possibleScenarios(scenario));
|
2016-12-11 23:54:03 +00:00
|
|
|
}
|
2016-12-13 23:09:27 +00:00
|
|
|
|
|
|
|
console.log("removing invalid");
|
2016-12-11 23:54:03 +00:00
|
|
|
newScenarios = newScenarios.filter((scenario)=>(checkFloors(scenario.floors)));
|
|
|
|
console.log("newLength", newScenarios.length);
|
2016-12-13 23:09:27 +00:00
|
|
|
console.log("calc min");
|
2016-12-11 23:54:03 +00:00
|
|
|
localMinFloor = newScenarios.map((scenario)=>(getMinFloors(scenario.floors))).reduce((a, b)=>(Math.max(a, b)))
|
2016-12-13 23:09:27 +00:00
|
|
|
console.log("sorting");
|
2016-12-11 23:54:03 +00:00
|
|
|
newScenarios.forEach((scenario)=>{scenario.floors.forEach((a)=>(a.sort()));})
|
2016-12-13 23:09:27 +00:00
|
|
|
console.log("to JSON");
|
|
|
|
newScenarios = newScenarios.map((scenario)=>(JSON.stringify(scenario)));
|
|
|
|
console.log("dedupe");
|
2016-12-11 23:54:03 +00:00
|
|
|
newScenarios = _.uniq(newScenarios, (scenario)=>(JSON.stringify(scenario)));
|
2016-12-13 23:09:27 +00:00
|
|
|
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)));
|
|
|
|
|
2016-12-11 23:54:03 +00:00
|
|
|
console.log("MIN", localMinFloor);
|
|
|
|
if(localMinFloor == 3){
|
|
|
|
console.log("SOLVED");
|
|
|
|
}
|
|
|
|
scenarios = newScenarios;
|
2016-12-13 23:09:27 +00:00
|
|
|
*/
|
2016-12-11 23:54:03 +00:00
|
|
|
}
|
2016-12-13 23:09:27 +00:00
|
|
|
/*
|
2016-12-11 23:54:03 +00:00
|
|
|
var i = 0;
|
|
|
|
|
|
|
|
while(minFloor < 3){
|
|
|
|
i++;
|
|
|
|
nextSetOfScenarios();
|
2016-12-13 23:09:27 +00:00
|
|
|
console.log("it", i);
|
2016-12-11 23:54:03 +00:00
|
|
|
console.log(scenarios.length);
|
|
|
|
}
|
|
|
|
console.log(i);
|
2016-12-13 23:09:27 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
var i = 0;
|
|
|
|
|
|
|
|
var callback = (scenarios)=>{
|
2016-12-13 23:10:07 +00:00
|
|
|
i++;
|
2016-12-15 10:39:48 +00:00
|
|
|
console.log(i, scenarios.length);
|
2016-12-20 15:16:24 +00:00
|
|
|
if(scenarios.map((scenario)=>(scenario.floors)).filter((floors)=>(floors[0].length == 0)).filter((floors)=>(floors[1].length == 0)).filter((floors)=>(floors[2].length == 0)).length == 0){
|
2016-12-13 23:09:27 +00:00
|
|
|
nextSetOfScenarios(scenarios, callback);
|
|
|
|
}
|
|
|
|
else{
|
2016-12-20 15:16:24 +00:00
|
|
|
console.log("SOLVED", i);
|
2016-12-13 23:09:27 +00:00
|
|
|
p.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nextSetOfScenarios(scenarios, callback);
|