1 Commits

Author SHA1 Message Date
df5b34216c Solution for assignment3. 2022-12-04 23:34:33 +01:00
4 changed files with 125 additions and 102 deletions

View File

@@ -1,8 +1,12 @@
# Advent of Code 2022 - Assignment8 javascript
## Description
This problem is all about walking through a grid. In this solution, we look through an entire column and row until we find a node with height <= height.
# Advent of Code 2022 - Assignment3 javascript solution
This problem is all about searching for duplicates in strings. The solution is implemented using slice to split the string in half.
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
- https://www.w3schools.com/jsref/jsref_charat.asp
- https://stackabuse.com/javascript-check-if-variable-is-a-number/
- https://www.w3schools.com/jsref/jsref_abs.asp
- https://stackoverflow.com/questions/94037/convert-character-to-ascii-code-in-javascript
- https://stackoverflow.com/questions/20474257/split-string-into-two-parts
- https://www.folkstalk.com/2022/10/find-common-characters-in-two-strings-javascript-with-code-examples.html
- https://stackoverflow.com/questions/351409/how-to-append-something-to-an-array
- https://stackoverflow.com/questions/9862761/how-to-check-if-character-is-a-letter-in-javascript
- https://stackoverflow.com/questions/1966476/how-can-i-process-each-letter-of-text-using-javascript
- https://www.w3schools.com/js/js_arrays.asp

View File

@@ -8,8 +8,8 @@
<body>
<p>Assignment:</p>
<textarea rows="15" cols="50" id="assignment"></textarea>
<input type="checkbox" id="algorithm" />
<label for="algorithm">Highest scenic score?</label>
<input type="checkbox" id="algorithm"/>
<label for="algorithm">Solution by compartiment.</label>
<p>Answer:</p>
<div id="answer">Provide input first</div>

205
script.js
View File

@@ -1,14 +1,18 @@
const ASSIGNMENT = 'assignment';
const ANSWER = 'answer';
const ALGORITHM_CHECKBOX = 'algorithm';
const CHARCODE_START=64;
const CHARCODE_UPPER_CORRECTION=6;
const ERROR_MESSAGE_INVALID_INPUT_SIZE = "Invalid input size, should be higher than 2 for: ";
const ERROR_MESSAGE_INVALID_ITEM_CHARACTER = "Invalid item character found: ";
const NEWLINE_CHARACTER = '\n';
/**
* Main function
*/
window.onload = function () {
document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer);
document.getElementById(ALGORITHM_CHECKBOX).addEventListener("click", calculateAnswer);
window.onload = function() {
document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer);
document.getElementById(ALGORITHM_CHECKBOX).addEventListener("click", calculateAnswer);
}
/**
@@ -18,8 +22,8 @@ window.onload = function () {
function calculateAnswer(event) {
console.info("Calculating answer for input...");
let assignment = document.getElementById(ASSIGNMENT).value;
let getHighestScenicScore = document.getElementById(ALGORITHM_CHECKBOX).checked;
let answer = algorithm(assignment, getHighestScenicScore);
let byCompartiments = document.getElementById(ALGORITHM_CHECKBOX).checked;
let answer = algorithm(assignment, byCompartiments);
document.getElementById(ANSWER).innerText = answer;
}
@@ -29,106 +33,121 @@ function calculateAnswer(event) {
* @param assignment the input from the assignment.
* @return string the answer
*/
function algorithm(assignment, getHighestScenicScore) {
let lines = assignment.trim().split(NEWLINE_CHARACTER);
console.info("Linecount:" + lines.length);
function algorithm(assignment, byCompartiments) {
let priorityScoreSum = 0;
let lines = assignment.trim().split(NEWLINE_CHARACTER);
console.info("Linecount:" + lines.length);
let visibleTreeCount = 0;
let highestScenicScore = 0;
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
for (let i = 0; i < lines.length; i++) {
let row = lines[i].trim();
for (let j = 0; j < row.length; j++) {
if (i <= 0 || i >= lines.length - 1 || j <= 0 || j >= row.length - 1) { // Edge node
//console.debug("Edge node found.");
visibleTreeCount++;
continue;
}
let height = parseInt(lines[i].charAt(j));
if (!walkRowVisible(height, j, row) && !walkColumnVisible(height, i, j, lines)) {
console.log("Found invisible tree, height:" + height + ", i:" + i + ", j:" + j);
visibleTreeCount--;
}
if (getHighestScenicScore) {
let scenicScore = walkRowCount(height, j, row) * walkColumnCount(height, i, j, lines);
if (scenicScore > highestScenicScore) {
console.debug("Found new highest scenic score: " + scenicScore);
highestScenicScore = scenicScore;
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, '')];
}
}
// Tree is on edge.
visibleTreeCount++;
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;
}
}
if (getHighestScenicScore) {
return "Highest scenic score: " + highestScenicScore;
}
return "Amount of visible trees in the grid: " + visibleTreeCount;
return "SUM priorityscore: " + priorityScoreSum;
}
function walkColumnCount(height, index, rowIndex, column) {
return walkCount(height, index, column, false, rowIndex);
/**
* 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);
for(let i=0; i<lines.length; i++) {
let rucksack = lines[i].replace(/\s/g, ''); // Remove whitespace
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);
for(item of compartiment2) {
if(compartiment1.includes(item)) {
console.debug("Found duplicate: " + item + " in rucksack" + i);
let priorityScore = getPriorityScore(item);
if(priorityScore < 0) {
console.error(ERROR_MESSAGE_INVALID_ITEM_CHARACTER + item + " on line: " + i);
continue;
}
priorityScoreSum += priorityScore;
break;
}
}
}
return "SUM priorityscore: " + priorityScoreSum;
}
function walkRowCount(height, index, row) {
return walkCount(height, index, row, true, -1);
/**
* Find duplicate character in inputs.
* @param string[] inputs the inputs to find duplicates in.
* @return char the duplicate character
*/
function getDuplicateCharacter(inputs) {
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;
}
}
}
function walkColumnVisible(height, index, rowIndex, column) {
return walkVisible(height, index, column, false, rowIndex);
}
/**
* 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 {
character = uppercase;
}
function walkRowVisible(height, index, row) {
return walkVisible(height, index, row, true, -1);
}
result += character.charCodeAt() - CHARCODE_START;
function walkCount(height, index, line, isRow, rowIndex) {
let visibleLeftCount = __walkHelper(height, index, line, isRow, -1, rowIndex, 0);
let visibleRightCount = __walkHelper(height, index, line, isRow, 1, rowIndex, 0);
return visibleLeftCount * visibleRightCount;
}
function walkVisible(height, index, line, isRow, rowIndex) {
let visibleLeft = __walkHelper(height, index, line, isRow, -1, rowIndex);
let visibleRight = __walkHelper(height, index, line, isRow, 1, rowIndex);
return visibleLeft || visibleRight;
}
function __walkHelper(height, index, line, isRow, direction, rowIndex, count) {
if (direction == 0) {
console.error("Invalid direction 0 in __walkhelper");
return -1;
}
direction = direction / Math.abs(direction);
// Edge reached
if ((direction < 0 && index <= 0) || (direction > 0 && index >= line.length - 1)) {
return (count == undefined) ? true : count;
}
let nextIndex = index + direction;
let nextHeightCharacter = (isRow) ? line.charAt(nextIndex) : line[nextIndex].trim().charAt(rowIndex);
let nextHeight = parseInt(nextHeightCharacter);
if (isNaN(height) || isNaN(nextHeightCharacter)) {
console.error("Invalid height found, height:" + height + ", nextHeight: " + nextHeightCharacter);
return -1;
}
if (height <= nextHeight) {
if (count == undefined)
return false;
return count + 1;
}
return __walkHelper(height, nextIndex, line, isRow, direction, rowIndex, (count !=undefined)? count + 1 : undefined);
return result;
}

View File

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