1 Commits

Author SHA1 Message Date
0af89a72ba Messy solution. 2022-12-08 01:31:18 +01:00
2 changed files with 111 additions and 151 deletions

View File

@@ -1,14 +1,6 @@
# Advent of Code - assignment 9 javascript # Advent of Code 2022 - Assignment7 javascript
This repository contains answers to the assignments of Advent of Coding 2022 Assignment 7 involves parsing linux directory commands/results into a tree. The solution defines a root TreeNode first and sets it as currentdirectory. Whenever a cd command is found a new node is created if it does not exist and set to currentdir. Whenever a cd .. is found currentdirectory is set to parent. Whenever a file is found size is recursively increased for current node and parent nodes.
## References ## References
- https://betterprogramming.pub/tuples-in-javascript-57ede9b1c9d2 - https://adrianmejia.com/data-structures-for-beginners-trees-binary-search-tree-tutorial/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length - https://stackoverflow.com/questions/8376525/get-value-of-a-string-after-last-slash-in-javascript
- https://www.javascripttutorial.net/javascript-multidimensional-array/
- https://flaviocopes.com/how-to-replace-whitespace-javascript/
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt
- https://www.sohamkamani.com/javascript/enums/
- https://www.w3schools.com/js/js_switch.asp
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign
- https://stackoverflow.com/questions/4564414/delete-first-character-of-string-if-it-is-0
- https://stackoverflow.com/questions/1959040/is-it-possible-to-send-a-variable-number-of-arguments-to-a-javascript-function

194
script.js
View File

@@ -1,6 +1,9 @@
const ASSIGNMENT = 'assignment'; const ASSIGNMENT = 'assignment';
const ANSWER = 'answer'; const ANSWER = 'answer';
const NEWLINE_CHARACTER = '\n'; const NEWLINE_CHARACTER = '\n';
const MAX_SIZE = 100000;
const UPDATE_SIZE = 30000000;
const TOTAL_SPACE = 70000000;
/** /**
* Main function * Main function
@@ -9,126 +12,75 @@ window.onload = function() {
document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer); document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer);
} }
const DIRECTIONS = { class TreeNode {
UP: 'U', constructor(value, parent) {
DOWN: 'D', console.debug(((!parent)?"Root ":"") + "node created: " + value);
LEFT: 'L',
RIGHT: 'R'
};
class Knot { this.parent = parent;
constructor(x, y) { this.value = value;
this.x=x; this.size = 0;
this.y=y; this.descendants = [];
}
}
/*class Rope {
constructor(headX, headY, tailX, tailY) {
this.headX = headX;
this.headY = headY;
this.tailX = tailX;
this.tailY = tailY;
console.info("Created Rope with head:" + headX + "," + headY + " and tail: " + tailX + "," + tailY);
} }
step = function (direction) { getDir = function(path) {
let oldHeadX = this.headX; for(let descendant of this.descendants) {
let oldHeadY = this.headY; if(descendant.value == path) {
switch (direction) { return descendant;
case DIRECTIONS.UP: }
this.headY++;
break;
case DIRECTIONS.DOWN:
this.headY--;
break;
case DIRECTIONS.LEFT:
this.headX--;
break;
case DIRECTIONS.RIGHT:
this.headX++;
break;
default:
console.error("Invalid direction given: " + direction);
} }
this.__correctTail(oldHeadX, oldHeadY);
} }
getTailPosition = function () { contains = function(path) {
return "" + this.tailX + "," + this.tailY; // Recursive case
let subPathIndex = path.indexOf('/');
let subPath = path.substring(0, subPathIndex-1);
let leftOverPath = path.substring(subPathIndex);
// Base case
if(subPath == '') {
return false;
} }
__correctTail = function (oldHeadX, oldHeadY) { for(let descendant of this.descendants) {
let absoluteDifferenceX = Math.abs(this.headX - this.tailX); if(descendant.value == subPath) {
let absoluteDifferenceY = Math.abs(this.headY - this.tailY); return descendant.contains(subPath);
if (absoluteDifferenceX > 1 || absoluteDifferenceY > 1) {
this.tailX = oldHeadX;
this.tailY = oldHeadY;
console.debug("Corrected tail Position: (" + this.tailX + ", " + this.tailY + "), head position: (" + this.headX + ", " + this.headY + ")");
} }
} }
};*/
class Rope {
constructor(count) {
if(count < 2) {
console.error("Rope needs at least 2 knots.");
return;
} }
let knots = []; findClosestNodeToSize = function(minSize) {
while(count > 0) { let closest = this;
knots.push(new Knot(0,0));
count--; for(let descendant of this.descendants) {
let closestDescendant = descendant.findClosestNodeToSize(minSize);
if (closestDescendant.size > minSize && closestDescendant.size < closest.size) {
console.debug("New closest:" + closestDescendant.size);
closest = closestDescendant;
}
} }
this.head = knots[0]; return closest;
this.knots = Array.from(knots).slice(1);
this.tail = this.knots[this.knots.length-1];
console.info("Created Rope with " + knots.length + " knots.");
} }
step = function(direction) { increaseSize = function(size) {
let oldHeadX = this.head.x; // TODO: Wat doen we met duplicate files?
let oldHeadY = this.head.y; this.size += size;
switch(direction) { if(this.parent) {
case DIRECTIONS.UP: this.parent.increaseSize(size);
this.head.y++;
break;
case DIRECTIONS.DOWN:
this.head.y--;
break;
case DIRECTIONS.LEFT:
this.head.x--;
break;
case DIRECTIONS.RIGHT:
this.head.x++;
break;
default:
console.error("Invalid direction given: " + direction);
} }
this.__correctTails(oldHeadX, oldHeadY, this.head, this.knots[0], this.knots.slice(1));
} }
getTailPosition = function() { getSum = function(maxSize) {
return "" + this.tail.x + "," + this.tail.y; let result = (this.size < maxSize) ? this.size: 0;
for(let descendant of this.descendants) {
result += descendant.getSum(maxSize);
} }
__correctTails = function(oldHeadX, oldHeadY, head, tail, tails) { return result;
let absoluteDifferenceX = Math.abs(head.x - tail.x);
let absoluteDifferenceY = Math.abs(head.y - tail.y);
let oldTailX = tail.x;
let oldTailY = tail.y;
if(absoluteDifferenceX > 1 || absoluteDifferenceY > 1) {
tail.x = oldHeadX;
tail.y = oldHeadY;
console.debug("Corrected tail Position: (" + this.tail.x + ", " + this.tail.y + "), head position: (" + this.head.x + ", " + this.head.y + ")");
} }
if(tails.length > 0)
this.__correctTails(oldTailX, oldTailY, tail, tails[0], tails.slice(1));
} }
};
/** /**
* Listener function for input in assignment field. * Listener function for input in assignment field.
@@ -150,30 +102,46 @@ function algorithm(assignment) {
let lines = assignment.trim().split(NEWLINE_CHARACTER); let lines = assignment.trim().split(NEWLINE_CHARACTER);
console.info("Linecount:" + lines.length); console.info("Linecount:" + lines.length);
let rope = new Rope(10); let root = new TreeNode('/');
let visitedPositions = [rope.getTailPosition()]; let currentdir = root;
for(let i=0; i<lines.length; i++) { for(let i=0; i<lines.length; i++) {
let line = lines[i].replace(/\s/g, ''); // Remove all whitespace let terminalLine = lines[i].trim();
let direction = line[0];
let count = parseInt(line.substring(1));
if(isNaN(count)) { // Validate count if(terminalLine.substring(0, 4) == "$ cd") {
console.error("Invalid number in line: " + lines[i]); let changeDirectory = terminalLine.substring(5).trim();
if(changeDirectory == "..") {
console.debug("One directory up from: " + currentdir.value);
currentdir = currentdir.parent;
console.debug("navigates to: " + currentdir.value);
continue;
} }
while(count > 0) { if(changeDirectory == "/") {
rope.step(direction); currentdir = root;
let tailPosition = rope.getTailPosition(); continue;
if(!visitedPositions.includes(tailPosition) ) { // Add only unique tailpositions
visitedPositions.push(tailPosition);
} }
count--; if(!currentdir.contains(changeDirectory)) {
currentdir.descendants.push(new TreeNode(changeDirectory, currentdir));
}
currentdir = currentdir.getDir(changeDirectory);
} else if(terminalLine.substring(0, 3) != 'dir' && !terminalLine.includes('$')) {
console.debug(terminalLine);
spaceIndex = terminalLine.indexOf(' ');
size = parseInt(terminalLine.substring(0, spaceIndex));
currentdir.increaseSize(size);
} }
} }
console.log(visitedPositions); let freeDiskSpace = TOTAL_SPACE - root.size;
return "Amount of positions for tail: " + visitedPositions.length; console.debug("Free disk space: " + freeDiskSpace);
console.debug("Root size:" + root.size);
console.debug("Value to find: " + (UPDATE_SIZE - freeDiskSpace));
let closestNode = root.findClosestNodeToSize(UPDATE_SIZE - freeDiskSpace);
console.debug("Closest value: " + closestNode.size);
return "Sum below maxSize " + MAX_SIZE + ": " + root.getSum(MAX_SIZE);
} }