1 Commits

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

View File

@@ -1,12 +1,13 @@
# Advent of Code 2022 - Assignment3 javascript solution # Advent of Code 2022 - Assignment5 javascript
This problem is all about searching for duplicates in strings. The solution is implemented using slice to split the string in half. This repository contains answers to the assignments of Advent of Coding 2022
The priority is retrieved using the ASCII charcode character for convienence. How to retrieve inputs differs between part1 and 2, therefore a checkbox is provided to toggle between different parsing methods.
## References ## References
- https://stackoverflow.com/questions/94037/convert-character-to-ascii-code-in-javascript - https://www.w3schools.com/jsref/jsref_includes.asp
- https://stackoverflow.com/questions/20474257/split-string-into-two-parts - https://stackoverflow.com/questions/10261986/how-to-detect-string-which-contains-only-spaces
- https://www.folkstalk.com/2022/10/find-common-characters-in-two-strings-javascript-with-code-examples.html - https://www.w3schools.com/jsref/jsref_indexof.asp
- https://stackoverflow.com/questions/351409/how-to-append-something-to-an-array - https://stackoverflow.com/questions/8073673/how-can-i-add-new-array-elements-at-the-beginning-of-an-array-in-javascript
- https://stackoverflow.com/questions/9862761/how-to-check-if-character-is-a-letter-in-javascript - https://stackoverflow.com/questions/966225/how-can-i-create-a-two-dimensional-array-in-javascript
- https://stackoverflow.com/questions/1966476/how-can-i-process-each-letter-of-text-using-javascript - https://www.w3schools.com/jsref/jsref_ceil.asp
- https://www.w3schools.com/js/js_arrays.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">Solution by compartiment.</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>

232
script.js
View File

@@ -1,10 +1,10 @@
const ASSIGNMENT = 'assignment'; const ASSIGNMENT = 'assignment';
const ANSWER = 'answer'; const ANSWER = 'answer';
const ALGORITHM_CHECKBOX = 'algorithm'; const ALGORITHM_CHECKBOX = 'algorithm';
const CHARCODE_START=64; const CONTAINER_NULL_CHARACTER=0;
const CHARCODE_UPPER_CORRECTION=6; const INSTRUCTION_FROM='from';
const ERROR_MESSAGE_INVALID_INPUT_SIZE = "Invalid input size, should be higher than 2 for: "; const INSTRUCTION_MOVE='move';
const ERROR_MESSAGE_INVALID_ITEM_CHARACTER = "Invalid item character found: "; const INSTRUCTION_TO='to';
const NEWLINE_CHARACTER = '\n'; const NEWLINE_CHARACTER = '\n';
/** /**
@@ -22,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 byCompartiments = document.getElementById(ALGORITHM_CHECKBOX).checked; let allAtOnce = document.getElementById(ALGORITHM_CHECKBOX).checked;
let answer = algorithm(assignment, byCompartiments); let answer = algorithm(assignment, allAtOnce);
document.getElementById(ANSWER).innerText = answer; document.getElementById(ANSWER).innerText = answer;
} }
@@ -31,123 +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 allAtOnce should all containers be moved at once.
* @return string the answer * @return string the answer
*/ */
function algorithm(assignment, byCompartiments) { function algorithm(assignment, allAtOnce) {
let priorityScoreSum = 0; let lines = assignment.split(NEWLINE_CHARACTER);
let lines = assignment.trim().split(NEWLINE_CHARACTER); let containerPlan = Array.from({length:(lines[0].length+1)/4}, () => [])
console.info("Linecount:" + lines.length);
let increment = (byCompartiments)? 1:3;
for(let i=0; i<lines.length; i+=increment) {
let inputs = [];
let rucksack = lines[i].replace(/\s/g, ''); // Remove whitespace
if(byCompartiments) {
let compartiment1 = rucksack.slice(0, rucksack.length/2);
let compartiment2 = rucksack.slice(rucksack.length/2);
inputs = [compartiment1, compartiment2];
} else {
inputs = [rucksack, lines[i+1].replace(/\s/g, ''), lines[i+2].replace(/\s/g, '')];
}
let duplicate = getDuplicateCharacter(inputs);
if(duplicate < 0) {
console.error(ERROR_MESSAGE_INVALID_INPUT_SIZE + inputs + " on line: " + i);
}
let priorityScore = getPriorityScore(duplicate);
if(priorityScore < 0) {
console.error(ERROR_MESSAGE_INVALID_ITEM_CHARACTER + duplicate + " on line: " + i);
continue;
}
priorityScoreSum += priorityScore;
}
return "SUM priorityscore: " + priorityScoreSum;
}
/**
* Calculate the answer to assignment.
* @param assignment the input from the assignment.
* @return string the answer
*/
function algorithm1(assignment) {
let priorityScoreSum = 0;
let lines = assignment.trim().split(NEWLINE_CHARACTER);
console.info("Linecount:" + lines.length); console.info("Linecount:" + lines.length);
let parsec = true;
for(let i=0; i<lines.length; i++) { for(let i=0; i<lines.length; i++) {
let rucksack = lines[i].replace(/\s/g, ''); // Remove whitespace if(parsec) {
let compartiment1 = rucksack.slice(0, rucksack.length/2);
let compartiment2 = rucksack.slice(rucksack.length/2);
console.debug("Check rucksack" + i, ": " + rucksack + " \n with compartiment1: " + compartiment1 + "\n and compartiment2: " + compartiment2); // Parse containers
let containerLine = lines[i];
for(item of compartiment2) { // Skip numbers
if(compartiment1.includes(item)) { if(containerLine[1] == '1') {
console.debug("Found duplicate: " + item + " in rucksack" + i); parsec = false;
let priorityScore = getPriorityScore(item); i+=1;
if(priorityScore < 0) { console.table(containerPlan);
console.error(ERROR_MESSAGE_INVALID_ITEM_CHARACTER + item + " on line: " + i);
continue; continue;
} }
priorityScoreSum += priorityScore;
break; let containers = parseContainers(containerLine);
} if(containers == -1) {
} // invalid containerline
// TODO: error
console.error("Container parse failure.");
continue;
} }
return "SUM priorityscore: " + priorityScoreSum; // Add containers
} //console.debug(containers);
for(let j=0; j<containers.length; j++) {
/** let container = containers[j];
* Find duplicate character in inputs. //console.debug(container);
* @param string[] inputs the inputs to find duplicates in. if(container != CONTAINER_NULL_CHARACTER) {
* @return char the duplicate character //console.debug(j);
*/ //console.debug(containerPlan);
function getDuplicateCharacter(inputs) { containerPlan[j].push(container);
console.debug("Checking inputs: " + inputs);
if(inputs.length < 2) {
return -1;
}
for(let item of inputs[0]) {
let duplicate = true
for(let j=1; j<inputs.length; j++) {
duplicate = duplicate && inputs[j].includes(item);
}
if(duplicate) {
console.debug("Found duplicate: " + item);
return item;
} }
} }
} //console.table(containerPlan);
/**
* Returns priorityscore for given character.
* @param char character the character
* @return int the priorityscore for character or -1 if invalid
*/
function getPriorityScore(character) {
let result=0;
let uppercase = character.toUpperCase();
let lowercase = character.toLowerCase();
// validate character
if( uppercase == lowercase ) {
return -1;
}
if(character == uppercase) { // Switch results for upper and lowercase characters
result -= CHARCODE_UPPER_CORRECTION;
character = lowercase;
} else { } else {
character = uppercase; // Parse instructions
let instructionLine = lines[i];
let instruction = parseInstruction(instructionLine);
console.debug(instruction);
if(instruction == -1) {
// invalid instructionline
// TODO: error
console.error("Instruction parse failure.");
continue;
} }
result += character.charCodeAt() - CHARCODE_START; // Execute instruction
let movecount=0;
return result; 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);
}
}
let result="";
for(let k=0; k<containerPlan.length; k++) {
result += containerPlan[k][0];
}
return "Top containers on the stack are: " + result;
}
function parseInstruction(instructionLine) {
let instruction={
move:0,
from:0,
to:0,
}
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 parseContainers(containerLine) {
let containerLineLength = (containerLine.length+1);
//console.debug("Parse ContainerLine, length: " + containerLineLength);
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;
} }