1 Commits

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

View File

@@ -1,9 +1,6 @@
# Advent of Code 2022 - Assignment 4 - javascript # Advent of Code 2022 - Assignment7 javascript
## Description 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.
The problem for assignment4 deals with overlaps and string parsing. The provided solution for this argument uses substring to parse ranges from file. Furthermore it has a checkbox to trigger whether ranges should fully overlap.
## References ## References
- https://www.w3schools.com/jsref/jsref_indexof.asp - https://adrianmejia.com/data-structures-for-beginners-trees-binary-search-tree-tutorial/
- https://www.geeksforgeeks.org/convert-a-string-to-an-integer-in-javascript/#:~:text=In%20JavaScript%20parseInt()%20function,argument%20of%20parseInt()%20function. - https://stackoverflow.com/questions/8376525/get-value-of-a-string-after-last-slash-in-javascript
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring
- https://medium.com/@raihan_tazdid/overlapping-numbers-in-ranges-5d0f2efc294e

View File

@@ -8,8 +8,6 @@
<body> <body>
<p>Assignment:</p> <p>Assignment:</p>
<textarea rows="15" cols="50" id="assignment"></textarea> <textarea rows="15" cols="50" id="assignment"></textarea>
<input type="checkbox" id="algorithm"/>
<label for="algorithm">Full overlap</label>
<p>Answer:</p> <p>Answer:</p>
<div id="answer">Provide input first</div> <div id="answer">Provide input first</div>

179
script.js
View File

@@ -1,17 +1,85 @@
const ASSIGNMENT = 'assignment'; const ASSIGNMENT = 'assignment';
const ANSWER = 'answer'; const ANSWER = 'answer';
const ALGORITHM_CHECKBOX = 'algorithm';
const ERROR_MESSAGE_INVALID_RANGE = "Invalid range, ";
const COMMA_CHARACTER = ',';
const NEWLINE_CHARACTER = '\n'; const NEWLINE_CHARACTER = '\n';
const RANGE_CHARACTER = '-'; const MAX_SIZE = 100000;
const UPDATE_SIZE = 30000000;
const TOTAL_SPACE = 70000000;
/** /**
* Main function * Main function
*/ */
window.onload = function() { window.onload = function() {
document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer); document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer);
document.getElementById(ALGORITHM_CHECKBOX).addEventListener("click", calculateAnswer); }
class TreeNode {
constructor(value, parent) {
console.debug(((!parent)?"Root ":"") + "node created: " + value);
this.parent = parent;
this.value = value;
this.size = 0;
this.descendants = [];
}
getDir = function(path) {
for(let descendant of this.descendants) {
if(descendant.value == path) {
return descendant;
}
}
}
contains = function(path) {
// Recursive case
let subPathIndex = path.indexOf('/');
let subPath = path.substring(0, subPathIndex-1);
let leftOverPath = path.substring(subPathIndex);
// Base case
if(subPath == '') {
return false;
}
for(let descendant of this.descendants) {
if(descendant.value == subPath) {
return descendant.contains(subPath);
}
}
}
findClosestNodeToSize = function(minSize) {
let closest = this;
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;
}
}
return closest;
}
increaseSize = function(size) {
// TODO: Wat doen we met duplicate files?
this.size += size;
if(this.parent) {
this.parent.increaseSize(size);
}
}
getSum = function(maxSize) {
let result = (this.size < maxSize) ? this.size: 0;
for(let descendant of this.descendants) {
result += descendant.getSum(maxSize);
}
return result;
}
} }
/** /**
@@ -20,9 +88,7 @@ window.onload = function() {
*/ */
function calculateAnswer(event) { function calculateAnswer(event) {
console.info("Calculating answer for input..."); console.info("Calculating answer for input...");
let assignment = document.getElementById(ASSIGNMENT).value; let answer = algorithm(event.target.value);
let fullOverlap = document.getElementById(ALGORITHM_CHECKBOX).checked;
let answer = algorithm(assignment, fullOverlap);
document.getElementById(ANSWER).innerText = answer; document.getElementById(ANSWER).innerText = answer;
} }
@@ -30,73 +96,52 @@ function calculateAnswer(event) {
/** /**
* Calculate the answer to assignment. * Calculate the answer to assignment.
* @param assignment the input from the assignment. * @param assignment the input from the assignment.
* @param fullOverlap if input needs to fully overlap.
* @return string the answer * @return string the answer
*/ */
function algorithm(assignment, fullOverlap) { 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 containedPairs = 0; let root = new TreeNode('/');
for(let i=0; i<lines.length; i++) { let currentdir = root;
let error = false;
let ranges = lines[i].trim();
// Search for separation charactes -,-
let range1CharacterIndex = ranges.indexOf(RANGE_CHARACTER);
let range1EndCharacterIndex = ranges.indexOf(COMMA_CHARACTER);
let range2CharacterIndex = ranges.indexOf(RANGE_CHARACTER, range1CharacterIndex+1);
// Get range substrings for(let i=0; i<lines.length; i++) {
let range1LowerString = ranges.substring(0,range1CharacterIndex); let terminalLine = lines[i].trim();
let range1HigherString = ranges.substring(range1CharacterIndex+1, range1EndCharacterIndex);
let range2LowerString = ranges.substring(range1EndCharacterIndex+1, range2CharacterIndex);
let range2HigherString = ranges.substring(range2CharacterIndex+1);
console.debug("Parsed values: " + range1LowerString + "-" + range1HigherString + "," + range2LowerString + "-" + range2HigherString);
// Parse to int if(terminalLine.substring(0, 4) == "$ cd") {
let range1Lower = parseInt(range1LowerString); let changeDirectory = terminalLine.substring(5).trim();
let range1Higher = parseInt(range1HigherString); if(changeDirectory == "..") {
let range2Lower = parseInt(range2LowerString); console.debug("One directory up from: " + currentdir.value);
let range2Higher = parseInt(range2HigherString); currentdir = currentdir.parent;
console.debug("navigates to: " + currentdir.value);
continue;
}
// Validation if(changeDirectory == "/") {
if(range1Lower > range1Higher) { currentdir = root;
console.error(ERROR_MESSAGE_INVALID_RANGE + range1Lower + "-" + range1Higher + " on line:" + i + " for range1"); continue;
error = true; }
}
if(range2Lower > range2Higher) {
console.error(ERROR_MESSAGE_INVALID_RANGE + range2Lower + "-" + range2Higher + " on line:" + i + " for range2");
error = true;
}
if(error) { if(!currentdir.contains(changeDirectory)) {
continue; currentdir.descendants.push(new TreeNode(changeDirectory, currentdir));
} }
// Check for overlap currentdir = currentdir.getDir(changeDirectory);
if(fullOverlap && doesRangeFullyOverlap(range1Lower, range1Higher, range2Lower, range2Higher) } else if(terminalLine.substring(0, 3) != 'dir' && !terminalLine.includes('$')) {
|| !fullOverlap && doesRangeOverlap(range1Lower, range1Higher, range2Lower, range2Higher)) { console.debug(terminalLine);
console.debug("Found overlapping range:" + range1Lower + "-" + range1Higher + "," + range2Lower + "-" + range2Higher); spaceIndex = terminalLine.indexOf(' ');
containedPairs++; size = parseInt(terminalLine.substring(0, spaceIndex));
} currentdir.increaseSize(size);
} }
}
return "Fully overlapping timeslot counts: " + containedPairs; let freeDiskSpace = TOTAL_SPACE - root.size;
} console.debug("Free disk space: " + freeDiskSpace);
function doesRangeFullyOverlap(lower, higher, lower2, higher2) { console.debug("Root size:" + root.size);
console.debug("Compare range: " + lower + "-" + higher + " with " + lower2 + "-" + higher2); console.debug("Value to find: " + (UPDATE_SIZE - freeDiskSpace));
if(lower > higher || lower2 > higher2) { let closestNode = root.findClosestNodeToSize(UPDATE_SIZE - freeDiskSpace);
return false; console.debug("Closest value: " + closestNode.size);
}
return ((lower <= lower2 && higher >= higher2) || (lower2 <= lower && higher2 >= higher)); return "Sum below maxSize " + MAX_SIZE + ": " + root.getSum(MAX_SIZE);
}
function doesRangeOverlap(lower, higher, lower2, higher2) {
console.debug("Compare range: " + lower + "-" + higher + " with " + lower2 + "-" + higher2);
if(lower > higher || lower2 > higher2) {
return false;
}
return higher2 >= lower && lower2 <= higher;
} }

View File

@@ -6,10 +6,6 @@ body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
} }
textarea {
display: block;
}
#answer { #answer {
color: purple color: purple
} }