-
Notifications
You must be signed in to change notification settings - Fork 0
/
07.js
131 lines (127 loc) · 2.7 KB
/
07.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'use strict';
class bagNode {
/**
* @param {[string, [*]]} bag
*/
constructor(bag) {
/** @type {string} */
this.name = bag[0];
/** @type {[bagNode]} */
this.parents = [];
/** @type {[bagNode]} */
this.children = [];
/** @type {[*]} */
this.unprocessedChildren = bag[1]; // Not all children have made their nodes yet when this is called
}
/**
* @param {Map} bags
*/
processChildren(bags) {
if (this.unprocessedChildren) {
this.unprocessedChildren.forEach(e=> {
const bag = bags.get(e[0]);
bag.parents.push(this);
this.children.push([e[1], bag]);
});
}
}
}
/**
* @param {string} d
*/
const part1 = async d => {
const bags = new Map();
const bagsThatHasOurs = new Set();
const bagsChecked = new Set();
const bagsToCheck = [];
let ourBag = null;
d.split('\n')
.map(e => e.replace(/(no other bags)?\./g, '').replace(/bags/g, 'bag').split(' contain '))
.map(e => {
if (e[1]) {
const split = /(\d+) (.*)/;
e[1] = e[1].split(/, /g).map(e=> {
const match = split.exec(e);
return [match[2], +match[1]];
});
}
else {
e[1] = null;
}
bags.set(e[0], new bagNode(e));
if (e[0] == 'shiny gold bag') {
ourBag = bags.get(e[0]);
}
return e;
});
bags.forEach(e => e.processChildren(bags));
ourBag.parents.forEach(e => {
bagsThatHasOurs.add(e);
bagsChecked.add(e);
bagsToCheck.push(e);
});
while (bagsToCheck.length) {
const bag = bagsToCheck.shift();
bag.parents.forEach(e => {
if (bagsChecked.has(e)) {
// We checked this bag already in another path
return;
}
bagsThatHasOurs.add(e);
bagsChecked.add(e);
bagsToCheck.push(e);
});
}
return bagsThatHasOurs.size;
};
/**
* @param {string} d
*/
const part2 = async d => {
const bags = new Map();
const bagsToCheck = [];
let bagsInside = 0;
let ourBag = null;
d.split('\n')
.map(e => e.replace(/(no other bags)?\./g, '').replace(/bags/g, 'bag').split(' contain '))
.map(e => {
if (e[1]) {
const split = /(\d+) (.*)/;
e[1] = e[1].split(/, /g).map(e=> {
const match = split.exec(e);
return [match[2], +match[1]];
});
}
else {
e[1] = null;
}
bags.set(e[0], new bagNode(e));
if (e[0] == 'shiny gold bag') {
ourBag = bags.get(e[0]);
}
return e;
});
bags.forEach(e => e.processChildren(bags));
ourBag.children.forEach(e => {
bagsInside += e[0];
for (let i = 0; i < e[0]; i++) {
bagsToCheck.push(e[1]);
}
});
while (bagsToCheck.length) {
const bag = bagsToCheck.shift();
if (bag.children) {
bag.children.forEach(e => {
bagsInside += e[0];
for (let i = 0; i < e[0]; i++) {
bagsToCheck.push(e[1]);
}
});
}
}
return bagsInside;
};
module.exports = {
part1,
part2
};