1 Commits

Author SHA1 Message Date
fc73788989 Messy initial solution. 2022-12-06 17:03:21 +01:00
4 changed files with 133 additions and 64 deletions

View File

@@ -1,9 +1,13 @@
# Advent of Code 2022 - Assignment 4 - javascript # Advent of Code 2022 - Assignment5 javascript
## Description This repository contains answers to the assignments of Advent of Coding 2022
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_includes.asp
- https://stackoverflow.com/questions/10261986/how-to-detect-string-which-contains-only-spaces
- https://www.w3schools.com/jsref/jsref_indexof.asp - https://www.w3schools.com/jsref/jsref_indexof.asp
- 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/8073673/how-can-i-add-new-array-elements-at-the-beginning-of-an-array-in-javascript
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring - https://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript
- https://medium.com/@raihan_tazdid/overlapping-numbers-in-ranges-5d0f2efc294e - https://www.w3schools.com/jsref/jsref_ceil.asp
- https://stackoverflow.com/questions/30561056/console-log-a-multi-dimensional-array
- https://teamtreehouse.com/community/removing-more-than-1-element-using-pop-and-shift-method
- https://stackoverflow.com/questions/14723848/push-multiple-elements-to-array

View File

@@ -9,7 +9,7 @@
<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"/> <input type="checkbox" id="algorithm"/>
<label for="algorithm">Full overlap</label> <label for="algorithm">All containers at once?</label>
<p>Answer:</p> <p>Answer:</p>
<div id="answer">Provide input first</div> <div id="answer">Provide input first</div>

177
script.js
View File

@@ -1,10 +1,11 @@
const ASSIGNMENT = 'assignment'; const ASSIGNMENT = 'assignment';
const ANSWER = 'answer'; const ANSWER = 'answer';
const ALGORITHM_CHECKBOX = 'algorithm'; const ALGORITHM_CHECKBOX = 'algorithm';
const ERROR_MESSAGE_INVALID_RANGE = "Invalid range, "; const CONTAINER_NULL_CHARACTER=0;
const COMMA_CHARACTER = ','; const INSTRUCTION_FROM='from';
const INSTRUCTION_MOVE='move';
const INSTRUCTION_TO='to';
const NEWLINE_CHARACTER = '\n'; const NEWLINE_CHARACTER = '\n';
const RANGE_CHARACTER = '-';
/** /**
* Main function * Main function
@@ -21,8 +22,8 @@ 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 assignment = document.getElementById(ASSIGNMENT).value;
let fullOverlap = document.getElementById(ALGORITHM_CHECKBOX).checked; let allAtOnce = document.getElementById(ALGORITHM_CHECKBOX).checked;
let answer = algorithm(assignment, fullOverlap); let answer = algorithm(assignment, allAtOnce);
document.getElementById(ANSWER).innerText = answer; document.getElementById(ANSWER).innerText = answer;
} }
@@ -30,73 +31,137 @@ 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. * @param allAtOnce should all containers be moved at once.
* @return string the answer * @return string the answer
*/ */
function algorithm(assignment, fullOverlap) { function algorithm(assignment, allAtOnce) {
let lines = assignment.trim().split(NEWLINE_CHARACTER); let lines = assignment.split(NEWLINE_CHARACTER);
let containerPlan = Array.from({length:(lines[0].length+1)/4}, () => [])
console.info("Linecount:" + lines.length); console.info("Linecount:" + lines.length);
let containedPairs = 0; let parsec = true;
for(let i=0; i<lines.length; i++) { for(let i=0; i<lines.length; i++) {
let error = false; if(parsec) {
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 // Parse containers
let range1LowerString = ranges.substring(0,range1CharacterIndex); let containerLine = lines[i];
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 // Skip numbers
let range1Lower = parseInt(range1LowerString); if(containerLine[1] == '1') {
let range1Higher = parseInt(range1HigherString); parsec = false;
let range2Lower = parseInt(range2LowerString); i+=1;
let range2Higher = parseInt(range2HigherString); console.table(containerPlan);
continue;
}
// Validation let containers = parseContainers(containerLine);
if(range1Lower > range1Higher) { if(containers == -1) {
console.error(ERROR_MESSAGE_INVALID_RANGE + range1Lower + "-" + range1Higher + " on line:" + i + " for range1"); // invalid containerline
error = true; // TODO: error
} console.error("Container parse failure.");
if(range2Lower > range2Higher) { continue;
console.error(ERROR_MESSAGE_INVALID_RANGE + range2Lower + "-" + range2Higher + " on line:" + i + " for range2"); }
error = true;
}
if(error) { // Add containers
continue; //console.debug(containers);
} for(let j=0; j<containers.length; j++) {
let container = containers[j];
//console.debug(container);
if(container != CONTAINER_NULL_CHARACTER) {
//console.debug(j);
//console.debug(containerPlan);
containerPlan[j].push(container);
}
}
//console.table(containerPlan);
} else {
// Parse instructions
let instructionLine = lines[i];
let instruction = parseInstruction(instructionLine);
// Check for overlap console.debug(instruction);
if(fullOverlap && doesRangeFullyOverlap(range1Lower, range1Higher, range2Lower, range2Higher) if(instruction == -1) {
|| !fullOverlap && doesRangeOverlap(range1Lower, range1Higher, range2Lower, range2Higher)) { // invalid instructionline
console.debug("Found overlapping range:" + range1Lower + "-" + range1Higher + "," + range2Lower + "-" + range2Higher); // TODO: error
containedPairs++; console.error("Instruction parse failure.");
continue;
}
// Execute instruction
let movecount=0;
if(allAtOnce) {
while(instruction.move > 0) {
let container = containerPlan[instruction.from].shift();
containerPlan[instruction.to].unshift(container);
instruction.move--;
movecount++;
}
console.debug("moved:" + movecount);
} else {
let splicedContainers = containerPlan[instruction.from].splice(0, instruction.move);
containerPlan[instruction.to].unshift(...splicedContainers);
}
//console.table(containerPlan);
} }
} }
return "Fully overlapping timeslot counts: " + containedPairs; let result="";
for(let k=0; k<containerPlan.length; k++) {
result += containerPlan[k][0];
}
return "Top containers on the stack are: " + result;
} }
function doesRangeFullyOverlap(lower, higher, lower2, higher2) { function parseInstruction(instructionLine) {
console.debug("Compare range: " + lower + "-" + higher + " with " + lower2 + "-" + higher2); let instruction={
if(lower > higher || lower2 > higher2) { move:0,
return false; from:0,
} to:0,
return ((lower <= lower2 && higher >= higher2) || (lower2 <= lower && higher2 >= higher)); }
instructionLine.replace(/\s/g, ''); // Remove whitespace
let fromIndex = instructionLine.indexOf(INSTRUCTION_FROM);
let moveIndex = instructionLine.indexOf(INSTRUCTION_MOVE);
let toIndex = instructionLine.indexOf(INSTRUCTION_TO);
// Validate
if(fromIndex < 0 || moveIndex < 0 || toIndex < 0) {
// Error
return -1;
}
// TODO validate check for numbers after indices.
// Parse
instruction.move = parseInt(instructionLine.substring(moveIndex + INSTRUCTION_MOVE.length + 1, fromIndex));
instruction.from = parseInt(instructionLine.substring(fromIndex + INSTRUCTION_FROM.length + 1, toIndex)) -1;
instruction.to = parseInt(instructionLine.substring(toIndex + INSTRUCTION_TO.length + 1)) -1;
return instruction;
} }
function doesRangeOverlap(lower, higher, lower2, higher2) { function parseContainers(containerLine) {
console.debug("Compare range: " + lower + "-" + higher + " with " + lower2 + "-" + higher2); let containerLineLength = (containerLine.length+1);
if(lower > higher || lower2 > higher2) { //console.debug("Parse ContainerLine, length: " + containerLineLength);
return false;
}
return higher2 >= lower && lower2 <= higher; if(!containerLine.includes('[') || !containerLine.includes(']') || containerLineLength % 4 != 0) {
return -1;
}
let containers = [];
for(let i=0; i<containerLineLength; i+=4) {
let containerLineSubString = containerLine.substring(i, i+4).trim();
let character = containerLineSubString[1];
if(containerLineSubString[0] != '[' || containerLineSubString[2] != ']') {
// Warning invalid container format
// TODO: warning
}
containers.push((!character)? CONTAINER_NULL_CHARACTER: character);
}
//console.debug(containers);
return containers;
} }

View File

@@ -9,7 +9,7 @@ body {
textarea { textarea {
display: block; display: block;
} }
#answer { #answer {
color: purple color: purple
} }