diff --git a/README.md b/README.md index da57339..6e8d790 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ -This repository contains answers to the assignments of Advent of Coding 2022 +# 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. + +## 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 \ No newline at end of file diff --git a/index.html b/index.html index 5cf1ba4..b89c9ad 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,8 @@

Assignment:

+ +

Answer:

Provide input first
diff --git a/script.js b/script.js index a6e2848..5df2cdc 100644 --- a/script.js +++ b/script.js @@ -1,12 +1,14 @@ const ASSIGNMENT = 'assignment'; const ANSWER = 'answer'; +const ALGORITHM_CHECKBOX = 'algorithm'; const NEWLINE_CHARACTER = '\n'; /** * Main function */ -window.onload = function() { - document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer); +window.onload = function () { + document.getElementById(ASSIGNMENT).addEventListener("input", calculateAnswer); + document.getElementById(ALGORITHM_CHECKBOX).addEventListener("click", calculateAnswer); } /** @@ -15,7 +17,9 @@ window.onload = function() { */ function calculateAnswer(event) { console.info("Calculating answer for input..."); - let answer = algorithm(event.target.value); + let assignment = document.getElementById(ASSIGNMENT).value; + let getHighestScenicScore = document.getElementById(ALGORITHM_CHECKBOX).checked; + let answer = algorithm(assignment, getHighestScenicScore); document.getElementById(ANSWER).innerText = answer; } @@ -25,9 +29,106 @@ function calculateAnswer(event) { * @param assignment the input from the assignment. * @return string the answer */ -function algorithm(assignment) { - let lines = assignment.trim().split(NEWLINE_CHARACTER); - console.info("Linecount:" + lines.length); +function algorithm(assignment, getHighestScenicScore) { + let lines = assignment.trim().split(NEWLINE_CHARACTER); + console.info("Linecount:" + lines.length); - // TODO: implement assignment + let visibleTreeCount = 0; + let highestScenicScore = 0; + + 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; + } + } + + // Tree is on edge. + visibleTreeCount++; + } + } + + if (getHighestScenicScore) { + return "Highest scenic score: " + highestScenicScore; + } + + return "Amount of visible trees in the grid: " + visibleTreeCount; +} + +function walkColumnCount(height, index, rowIndex, column) { + return walkCount(height, index, column, false, rowIndex); +} + +function walkRowCount(height, index, row) { + return walkCount(height, index, row, true, -1); +} + +function walkColumnVisible(height, index, rowIndex, column) { + return walkVisible(height, index, column, false, rowIndex); +} + +function walkRowVisible(height, index, row) { + return walkVisible(height, index, row, true, -1); +} + +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); } \ No newline at end of file diff --git a/style.css b/style.css index f39a6bd..861cba6 100644 --- a/style.css +++ b/style.css @@ -6,6 +6,10 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } + textarea { + display: block; + } + #answer { color: purple }