Refactor codebase
This commit is contained in:
parent
bb76e3dcc7
commit
bc115462fb
@ -1,5 +1,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
|
||||
<meta charset="utf-8"/>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script src="main.js"></script>
|
||||
<script type="module" src="main.js"></script>
|
||||
</html>
|
||||
|
207
main.js
207
main.js
@ -1,208 +1,55 @@
|
||||
class Resistor {
|
||||
ohmage;
|
||||
constructor(ohmage) {
|
||||
this.ohmage = ohmage;
|
||||
}
|
||||
getOhmage() {
|
||||
return this.ohmage;
|
||||
}
|
||||
equals(other) {
|
||||
return this.getOhmage() === other.getOhmage();
|
||||
}
|
||||
hash() {
|
||||
return this.ohmage;
|
||||
}
|
||||
cost() {
|
||||
return 1;
|
||||
}
|
||||
toString() {
|
||||
return `${this.constructor.name}(${this.getOhmage()})`;
|
||||
}
|
||||
prettyString(depth = 0) {
|
||||
return `${'--'.repeat(depth)}${this.toString()}`
|
||||
}
|
||||
parallel(other) {
|
||||
return new ParallelResistor(this, other);
|
||||
}
|
||||
series(other) {
|
||||
return new SeriesResistor(this, other);
|
||||
}
|
||||
getSVG() {
|
||||
var svg = `<svg width="50" heigh="100"><rect x="0" y="0" width="50" height="100" fill="white" stroke="black"/>
|
||||
<text x="25" y="50" dominant-baseline="middle" text-anchor="middle">${this.getOhmage()}Ω</text></svg>`
|
||||
var [width, height] = [50, 100]
|
||||
return [svg, width, height]
|
||||
}
|
||||
draw() {
|
||||
var [svg, width, height] = this.getSVG();
|
||||
var maxHeight = height + 2*25
|
||||
var maxWidth = width
|
||||
var midPoint = width / 2
|
||||
var thesvg = `<svg width="${maxWidth}" height="${maxHeight}" viewbox="0 0 ${maxWidth} ${maxHeight}">
|
||||
<line x1="${midPoint}" x2="${midPoint}" y1="${0}" y2="${25}" stroke="black"/>
|
||||
<line x1="${midPoint}" x2="${midPoint}" y1="${maxHeight - 25}" y2="${maxHeight}" stroke="black"/>
|
||||
<g transform="translate(0, 25)">
|
||||
${svg}
|
||||
</g>
|
||||
</svg>`
|
||||
document.getElementsByTagName("body")[0].innerHTML = thesvg;
|
||||
}
|
||||
}
|
||||
import { Resistor, SeriesResistor, ParallelResistor } from './modules/resistors.js';
|
||||
|
||||
function sum(list) {
|
||||
var temp = 0;
|
||||
list.forEach(e => temp += e);
|
||||
return temp;
|
||||
}
|
||||
function harm(list) {
|
||||
var temp = 0;
|
||||
list.forEach(e => temp += 1 / e);
|
||||
return 1 / temp;
|
||||
}
|
||||
function flatten(list, flattable) {
|
||||
return list.reduce( (acc, cur) => acc.concat(cur.constructor.name === flattable ? cur.children : [cur]), []);
|
||||
}
|
||||
|
||||
|
||||
class NestedResistor extends Resistor {
|
||||
children = []
|
||||
|
||||
constructor(l, func, instance) {
|
||||
super(func(l.map(e => e.getOhmage())));
|
||||
this.func = func
|
||||
this.children = flatten(l, instance.constructor.name);
|
||||
}
|
||||
cost() {
|
||||
return sum(this.children.map(e => e.cost()));
|
||||
}
|
||||
prettyString(depth = 0) {
|
||||
var childrenStrings = this.children.map(c => c.prettyString(depth + 1)).join("\n")
|
||||
return `${'--'.repeat(depth)}${this.toString()}\n${childrenStrings}`
|
||||
}
|
||||
parallel(other) {
|
||||
return new ParallelResistor(this, other);
|
||||
}
|
||||
series(other) {
|
||||
return new SeriesResistor(this, other);
|
||||
}
|
||||
}
|
||||
|
||||
class SeriesResistor extends NestedResistor {
|
||||
constructor(...l) {
|
||||
super(l, sum, "SeriesResistor");
|
||||
}
|
||||
getSVG() {
|
||||
var svgs = this.children.map(e => e.getSVG()); // triplets [svg, width, height]
|
||||
var n = svgs.length;
|
||||
var maxHeight = sum(svgs.map(([svg, width, height]) => height)) + 25 * (n - 1)
|
||||
var maxWidth = Math.max(...svgs.map(([svg, width, height]) => width))
|
||||
var yOffset = 0; // where to start the next boundin
|
||||
var centerLine = maxWidth / 2;
|
||||
|
||||
var innerSVGs = []
|
||||
var i = 0;
|
||||
svgs.forEach(([svg, width, height]) => {
|
||||
var xStart = (maxWidth - width) / 2
|
||||
|
||||
var partialInnerSVG = `<g transform="translate(${xStart}, ${yOffset})">${svg}</g>`
|
||||
if (i < n - 1)
|
||||
partialInnerSVG += `<line x1="${centerLine}" x2="${centerLine}" y1="${yOffset + height}" y2="${yOffset + height + 25}" stroke="black"/>`
|
||||
// finally
|
||||
yOffset += 25 + height
|
||||
i ++;
|
||||
innerSVGs.push(partialInnerSVG)
|
||||
});
|
||||
var svg = innerSVGs.join("")
|
||||
return [svg, maxWidth, maxHeight]
|
||||
}
|
||||
}
|
||||
|
||||
class ParallelResistor extends NestedResistor {
|
||||
constructor(...l) {
|
||||
super(l, harm, "ParallelResistor");
|
||||
}
|
||||
getSVG() {
|
||||
var svgs = this.children.map(e => e.getSVG()); // triplets [svg, width, height]
|
||||
var n = svgs.length;
|
||||
var maxHeight = Math.max(...svgs.map(([svg, width, height]) => height)) + 2 * 25
|
||||
var maxWidth = sum(svgs.map(([svg, width, height]) => width)) + 25 * (n - 1)
|
||||
var bottomLineStart = svgs[0][1] / 2
|
||||
var bottomLineEnd = maxWidth - svgs[n - 1][1] / 2
|
||||
var xOffset = 0; // where to start the next boundin
|
||||
|
||||
var innerSVGs = []
|
||||
svgs.forEach(([svg, width, height]) => {
|
||||
var antennaX = xOffset + width / 2
|
||||
var antennaLength = (maxHeight - height) / 2
|
||||
var antennaOneStart = 0
|
||||
var antennaOneEnd = antennaLength
|
||||
var antennaTwoStart = antennaLength + height
|
||||
var antennaTwoEnd = maxHeight
|
||||
|
||||
var partialInnerSVG = `<g transform="translate(${xOffset}, ${antennaOneEnd})">${svg}</g>
|
||||
<line x1="${antennaX}" x2="${antennaX}" y1="${antennaOneStart}" y2="${antennaOneEnd}" stroke="black"/>
|
||||
<line x1="${antennaX}" x2="${antennaX}" y1="${antennaTwoStart}" y2="${antennaTwoEnd}" stroke="black"/> `
|
||||
// finally
|
||||
xOffset += 25 + width
|
||||
innerSVGs.push(partialInnerSVG)
|
||||
});
|
||||
var innerSVG = innerSVGs.join("")
|
||||
var svg = `<line x1="${bottomLineStart}" x2="${bottomLineEnd}" y1="0" y2="0" stroke="black"/>
|
||||
<line x1="${bottomLineStart}" x2="${bottomLineEnd}" y1="${maxHeight}" y2="${maxHeight}" stroke="black"/>
|
||||
${innerSVG}`
|
||||
return [svg, maxWidth, maxHeight]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var resistors = [100, 1000]
|
||||
var resistorValues = [100, 1000]
|
||||
var N = 4
|
||||
var maxValue = Math.max(...resistors)
|
||||
var maxValue = Math.max(...resistorValues)
|
||||
|
||||
numberline = new Array(N * maxValue + 1)
|
||||
var numberline = new Array(N * maxValue + 1)
|
||||
numberline.fill(-1)
|
||||
|
||||
set = new Map()
|
||||
var dp = new Map()
|
||||
|
||||
for (i = 0; i < resistors.length; i++) {
|
||||
var value = resistors[i];
|
||||
// Initialize DP array and number line
|
||||
for (var i = 0; i < resistorValues.length; i++) {
|
||||
var value = resistorValues[i];
|
||||
var resistor = new Resistor(value);
|
||||
set.set(value, resistor);
|
||||
dp.set(value, resistor);
|
||||
numberline[value] = resistor;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < N; i++) {
|
||||
iterSet();
|
||||
console.log("After iteration", i, set.size, "entries");
|
||||
}
|
||||
console.log(set)
|
||||
|
||||
function iterSet() {
|
||||
addition = new Set()
|
||||
set.forEach(e1 => {
|
||||
set.forEach(e2 => {
|
||||
r1 = new SeriesResistor(e1, e2);
|
||||
r2 = new ParallelResistor(e1, e2);
|
||||
function bottomUpDP() {
|
||||
var addition = new Set()
|
||||
dp.forEach(e1 => {
|
||||
dp.forEach(e2 => {
|
||||
var r1 = new SeriesResistor(e1, e2);
|
||||
var r2 = new ParallelResistor(e1, e2);
|
||||
addition.add(r1);
|
||||
addition.add(r2);
|
||||
});
|
||||
});
|
||||
addition.forEach( e => {
|
||||
value = Math.round(e.getOhmage());
|
||||
if (!set.has(value)) {
|
||||
set.set(value, e)
|
||||
if (!dp.has(value)) {
|
||||
dp.set(value, e)
|
||||
numberline[value] = e;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Starting Computation of DP array.");
|
||||
console.log(`Parameters: N = ${N}, values = ${resistorValues} `);
|
||||
for (i = 0; i < N; i++)
|
||||
bottomUpDP();
|
||||
console.log("Finished computation of DP array");
|
||||
|
||||
function missings() {
|
||||
missing = new Set()
|
||||
var missing = new Set()
|
||||
for (i = 0; i < N * maxValue + 1; i++) {
|
||||
if (numberline[i] == -1)
|
||||
missing.add(i);
|
||||
}
|
||||
return missing;
|
||||
}
|
||||
console.log(`We found a composite resistor for every value in the range [1, ${N * maxValue + 1}] but for: ${[...missings()].join(",")}`)
|
||||
|
||||
numberline[420].draw() // Draw the Resistor diagram for 420 Ohm as SVG
|
||||
|
144
modules/resistors.js
Normal file
144
modules/resistors.js
Normal file
@ -0,0 +1,144 @@
|
||||
import { sum, harmonicMean as harm, flatten } from './utils.js';
|
||||
|
||||
class Resistor {
|
||||
ohmage;
|
||||
constructor(ohmage) {
|
||||
this.ohmage = ohmage;
|
||||
}
|
||||
getOhmage() {
|
||||
return this.ohmage;
|
||||
}
|
||||
equals(other) {
|
||||
return this.getOhmage() === other.getOhmage();
|
||||
}
|
||||
hash() {
|
||||
return this.ohmage;
|
||||
}
|
||||
cost() {
|
||||
return 1;
|
||||
}
|
||||
toString() {
|
||||
return `${this.constructor.name}(${this.getOhmage()})`;
|
||||
}
|
||||
prettyString(depth = 0) {
|
||||
return `${'--'.repeat(depth)}${this.toString()}`
|
||||
}
|
||||
parallel(other) {
|
||||
return new ParallelResistor(this, other);
|
||||
}
|
||||
series(other) {
|
||||
return new SeriesResistor(this, other);
|
||||
}
|
||||
getSVG() {
|
||||
var svg = `<svg width="50" heigh="100"><rect x="0" y="0" width="50" height="100" fill="white" stroke="black"/>
|
||||
<text x="25" y="50" dominant-baseline="middle" text-anchor="middle">${this.getOhmage()}Ω</text></svg>`
|
||||
var [width, height] = [50, 100]
|
||||
return [svg, width, height]
|
||||
}
|
||||
draw() {
|
||||
var [svg, width, height] = this.getSVG();
|
||||
var maxHeight = height + 2*25
|
||||
var maxWidth = width
|
||||
var midPoint = width / 2
|
||||
var thesvg = `<svg width="${maxWidth}" height="${maxHeight}" viewbox="0 0 ${maxWidth} ${maxHeight}">
|
||||
<line x1="${midPoint}" x2="${midPoint}" y1="${0}" y2="${25}" stroke="black"/>
|
||||
<line x1="${midPoint}" x2="${midPoint}" y1="${maxHeight - 25}" y2="${maxHeight}" stroke="black"/>
|
||||
<g transform="translate(0, 25)">
|
||||
${svg}
|
||||
</g>
|
||||
</svg>`
|
||||
document.getElementsByTagName("body")[0].innerHTML = thesvg;
|
||||
}
|
||||
}
|
||||
|
||||
class NestedResistor extends Resistor {
|
||||
children = []
|
||||
|
||||
constructor(l, func, instance) {
|
||||
super(func(l.map(e => e.getOhmage())));
|
||||
this.func = func
|
||||
this.children = flatten(l, instance.constructor.name);
|
||||
}
|
||||
cost() {
|
||||
return sum(this.children.map(e => e.cost()));
|
||||
}
|
||||
prettyString(depth = 0) {
|
||||
var childrenStrings = this.children.map(c => c.prettyString(depth + 1)).join("\n")
|
||||
return `${'--'.repeat(depth)}${this.toString()}\n${childrenStrings}`
|
||||
}
|
||||
parallel(other) {
|
||||
return new ParallelResistor(this, other);
|
||||
}
|
||||
series(other) {
|
||||
return new SeriesResistor(this, other);
|
||||
}
|
||||
}
|
||||
|
||||
class SeriesResistor extends NestedResistor {
|
||||
constructor(...l) {
|
||||
super(l, sum, "SeriesResistor");
|
||||
}
|
||||
getSVG() {
|
||||
var svgs = this.children.map(e => e.getSVG()); // triplets [svg, width, height]
|
||||
var n = svgs.length;
|
||||
var maxHeight = sum(svgs.map(([svg, width, height]) => height)) + 25 * (n - 1)
|
||||
var maxWidth = Math.max(...svgs.map(([svg, width, height]) => width))
|
||||
var yOffset = 0; // where to start the next boundin
|
||||
var centerLine = maxWidth / 2;
|
||||
|
||||
var innerSVGs = []
|
||||
var i = 0;
|
||||
svgs.forEach(([svg, width, height]) => {
|
||||
var xStart = (maxWidth - width) / 2
|
||||
|
||||
var partialInnerSVG = `<g transform="translate(${xStart}, ${yOffset})">${svg}</g>`
|
||||
if (i < n - 1)
|
||||
partialInnerSVG += `<line x1="${centerLine}" x2="${centerLine}" y1="${yOffset + height}" y2="${yOffset + height + 25}" stroke="black"/>`
|
||||
// finally
|
||||
yOffset += 25 + height
|
||||
i ++;
|
||||
innerSVGs.push(partialInnerSVG)
|
||||
});
|
||||
var svg = innerSVGs.join("")
|
||||
return [svg, maxWidth, maxHeight]
|
||||
}
|
||||
}
|
||||
|
||||
class ParallelResistor extends NestedResistor {
|
||||
constructor(...l) {
|
||||
super(l, harm, "ParallelResistor");
|
||||
}
|
||||
getSVG() {
|
||||
var svgs = this.children.map(e => e.getSVG()); // triplets [svg, width, height]
|
||||
var n = svgs.length;
|
||||
var maxHeight = Math.max(...svgs.map(([svg, width, height]) => height)) + 2 * 25
|
||||
var maxWidth = sum(svgs.map(([svg, width, height]) => width)) + 25 * (n - 1)
|
||||
var bottomLineStart = svgs[0][1] / 2
|
||||
var bottomLineEnd = maxWidth - svgs[n - 1][1] / 2
|
||||
var xOffset = 0; // where to start the next boundin
|
||||
|
||||
var innerSVGs = []
|
||||
svgs.forEach(([svg, width, height]) => {
|
||||
var antennaX = xOffset + width / 2
|
||||
var antennaLength = (maxHeight - height) / 2
|
||||
var antennaOneStart = 0
|
||||
var antennaOneEnd = antennaLength
|
||||
var antennaTwoStart = antennaLength + height
|
||||
var antennaTwoEnd = maxHeight
|
||||
|
||||
var partialInnerSVG = `<g transform="translate(${xOffset}, ${antennaOneEnd})">${svg}</g>
|
||||
<line x1="${antennaX}" x2="${antennaX}" y1="${antennaOneStart}" y2="${antennaOneEnd}" stroke="black"/>
|
||||
<line x1="${antennaX}" x2="${antennaX}" y1="${antennaTwoStart}" y2="${antennaTwoEnd}" stroke="black"/> `
|
||||
// finally
|
||||
xOffset += 25 + width
|
||||
innerSVGs.push(partialInnerSVG)
|
||||
});
|
||||
var innerSVG = innerSVGs.join("")
|
||||
var svg = `<line x1="${bottomLineStart}" x2="${bottomLineEnd}" y1="0" y2="0" stroke="black"/>
|
||||
<line x1="${bottomLineStart}" x2="${bottomLineEnd}" y1="${maxHeight}" y2="${maxHeight}" stroke="black"/>
|
||||
${innerSVG}`
|
||||
return [svg, maxWidth, maxHeight]
|
||||
}
|
||||
}
|
||||
|
||||
export { Resistor, ParallelResistor, SeriesResistor }
|
17
modules/utils.js
Normal file
17
modules/utils.js
Normal file
@ -0,0 +1,17 @@
|
||||
function sum(list) {
|
||||
var temp = 0;
|
||||
list.forEach(e => temp += e);
|
||||
return temp;
|
||||
}
|
||||
|
||||
function harmonicMean(list) {
|
||||
var temp = 0;
|
||||
list.forEach(e => temp += 1 / e);
|
||||
return 1 / temp;
|
||||
}
|
||||
|
||||
function flatten(list, flattable) {
|
||||
return list.reduce( (acc, cur) => acc.concat(cur.constructor.name === flattable ? cur.children : [cur]), []);
|
||||
}
|
||||
|
||||
export {sum, harmonicMean, flatten }
|
Loading…
Reference in New Issue
Block a user