From b3b1e40b4e480bf5e92e94f98097d699f2735ab2 Mon Sep 17 00:00:00 2001 From: wieerwill Date: Fri, 15 Dec 2023 22:46:01 +0100 Subject: [PATCH] lint and analysis --- Analytics.md | 199 ++++++++++++++++++++++++++++++++++++-- Day04/js/solution.js | 98 ++++++++++--------- Day04/ts/solution.ts | 150 ++++++++++++++-------------- Day13/python/solution1.py | 11 ++- Day13/python/solution2.py | 21 +++- Day14/python/solution1.py | 29 ++++-- Day14/python/solution2.py | 62 +++++++----- Day15/js/solution.js | 2 +- Day15/python/solution1.py | 10 +- Day15/python/solution2.py | 13 ++- Day15/rust/src/main.rs | 23 +++-- README.md | 4 +- 12 files changed, 441 insertions(+), 181 deletions(-) diff --git a/Analytics.md b/Analytics.md index effade0..97707f4 100644 --- a/Analytics.md +++ b/Analytics.md @@ -3,14 +3,199 @@ ## Day01 | Language | Status | Real Time | User Time | Sys Time | | --- | --- | --- | --- | --- | -| Python | Success | 0m0,090s | 0m0,065s | 0m0,025s | -| Rust | Success | 0m0,111s | 0m0,062s | 0m0,048s | -| JavaScript | Success | 0m0,079s | 0m0,073s | 0m0,013s | -| TypeScript | Success | 0m1,300s | 0m2,668s | 0m0,201s | +| Python | Success | 0m0,088s | 0m0,068s | 0m0,012s | +| Rust | Success | 0m0,132s | 0m0,070s | 0m0,044s | +| JavaScript | Success | 0m0,098s | 0m0,068s | 0m0,037s | +| TypeScript | Success | 0m1,220s | 0m2,742s | 0m0,120s | ## Day02 | Language | Status | Real Time | User Time | Sys Time | | --- | --- | --- | --- | --- | -| Python | Success | 0m0,048s | 0m0,033s | 0m0,012s | -| Rust | Success | 0m0,097s | 0m0,062s | 0m0,035s | -| JavaScript | Success | 0m0,045s | 0m0,041s | 0m0,004s | +| Python | Success | 0m0,088s | 0m0,047s | 0m0,012s | +| Rust | Success | 0m0,152s | 0m0,061s | 0m0,055s | +| JavaScript | Success | 0m0,064s | 0m0,049s | 0m0,016s | +| TypeScript | Success | 0m1,234s | 0m2,621s | 0m0,187s | + +## Day03 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,083s | 0m0,051s | 0m0,008s | +| Rust | Success | 0m0,138s | 0m0,065s | 0m0,045s | +| JavaScript | Success | 0m0,077s | 0m0,055s | 0m0,023s | +| TypeScript | Success | 0m1,256s | 0m2,881s | 0m0,200s | + +## Day04 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m3,181s | 0m3,169s | 0m0,012s | +| Rust | Success | 0m0,199s | 0m0,122s | 0m0,043s | +| JavaScript | Success | 0m0,049s | 0m0,036s | 0m0,014s | +| TypeScript | Success | 0m1,274s | 0m2,790s | 0m0,255s | + +## Day05 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,078s | 0m0,038s | 0m0,017s | +| Rust | Success | 6m9,770s | 3m44,200s | 2m25,858s | +| JavaScript | Success | 0m0,064s | 0m0,050s | 0m0,017s | +| TypeScript | Success | 0m1,215s | 0m2,595s | 0m0,215s | + +## Day06 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m1,611s | 0m1,227s | 0m0,012s | +| Rust | Success | 0m0,387s | 0m0,356s | 0m0,147s | +| JavaScript | Success | 0m0,078s | 0m0,059s | 0m0,020s | +| TypeScript | Success | 0m1,226s | 0m2,733s | 0m0,261s | + +## Day07 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,069s | 0m0,035s | 0m0,013s | +| Rust | Failed | - | - | - | +| JavaScript | Success | 0m0,062s | 0m0,046s | 0m0,016s | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day08 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,341s | 0m0,185s | 0m0,059s | +| Rust | Success | 0m0,880s | 0m1,046s | 0m0,274s | +| JavaScript | Success | 0m0,332s | 0m0,304s | 0m0,058s | +| TypeScript | Success | 0m1,499s | 0m3,073s | 0m0,268s | + +## Day09 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,065s | 0m0,050s | 0m0,004s | +| Rust | Success | 0m0,510s | 0m0,552s | 0m0,202s | +| JavaScript | Success | 0m0,050s | 0m0,036s | 0m0,020s | +| TypeScript | Success | 0m1,215s | 0m2,581s | 0m0,208s | + +## Day10 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,113s | 0m0,087s | 0m0,008s | +| Rust | Success | 0m0,149s | 0m0,077s | 0m0,056s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day11 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Not Found or Not Executable | - | - | - | +| Rust | Success | 0m0,135s | 0m0,063s | 0m0,060s | +| JavaScript | Failed | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day12 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m1,659s | 0m1,596s | 0m0,048s | +| Rust | Success | 0m0,847s | 0m1,098s | 0m0,250s | +| JavaScript | Success | 0m1,235s | 0m1,173s | 0m0,119s | +| TypeScript | Success | 0m2,416s | 0m4,062s | 0m0,329s | + +## Day13 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,062s | 0m0,045s | 0m0,016s | +| Rust | Success | 0m0,111s | 0m0,045s | 0m0,055s | +| JavaScript | Success | 0m0,166s | 0m0,161s | 0m0,012s | +| TypeScript | Success | 0m1,150s | 0m2,744s | 0m0,198s | + +## Day14 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,032s | 0m0,028s | 0m0,004s | +| Rust | Success | 0m0,110s | 0m0,051s | 0m0,042s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day15 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,076s | 0m0,038s | 0m0,038s | +| Rust | Success | 0m0,547s | 0m0,820s | 0m0,218s | +| JavaScript | Success | 0m0,118s | 0m0,138s | 0m0,020s | +| TypeScript | Success | 0m1,336s | 0m2,927s | 0m0,237s | + +## Day16 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,030s | 0m0,030s | 0m0,000s | +| Rust | Success | 0m0,108s | 0m0,049s | 0m0,051s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day17 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,031s | 0m0,019s | 0m0,011s | +| Rust | Success | 0m0,129s | 0m0,051s | 0m0,064s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day18 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,029s | 0m0,018s | 0m0,011s | +| Rust | Success | 0m0,127s | 0m0,059s | 0m0,053s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day19 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,050s | 0m0,042s | 0m0,008s | +| Rust | Success | 0m0,108s | 0m0,055s | 0m0,046s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day20 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,049s | 0m0,041s | 0m0,008s | +| Rust | Success | 0m0,139s | 0m0,043s | 0m0,080s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day21 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,052s | 0m0,032s | 0m0,020s | +| Rust | Success | 0m0,180s | 0m0,083s | 0m0,057s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day22 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,051s | 0m0,047s | 0m0,004s | +| Rust | Success | 0m0,140s | 0m0,078s | 0m0,054s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day23 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,033s | 0m0,016s | 0m0,017s | +| Rust | Success | 0m0,139s | 0m0,047s | 0m0,079s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day24 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,030s | 0m0,019s | 0m0,011s | +| Rust | Success | 0m0,138s | 0m0,065s | 0m0,064s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | + +## Day25 +| Language | Status | Real Time | User Time | Sys Time | +| --- | --- | --- | --- | --- | +| Python | Success | 0m0,030s | 0m0,023s | 0m0,007s | +| Rust | Success | 0m0,127s | 0m0,054s | 0m0,061s | +| JavaScript | Not Found or Not Executable | - | - | - | +| TypeScript | Not Found or Not Executable | - | - | - | diff --git a/Day04/js/solution.js b/Day04/js/solution.js index 8898ed7..2ae1200 100644 --- a/Day04/js/solution.js +++ b/Day04/js/solution.js @@ -1,68 +1,76 @@ const fs = require('fs'); +const path = require('path'); -// Parses a line of card data and returns the card number, winning numbers, and own numbers -function parseCardData(line) { - const [cardInfo, numberParts] = line.split(':'); - const [winningPart, ownPart] = numberParts.split('|'); - const cardNumber = parseInt(cardInfo.match(/\d+/)[0], 10); - const winningNumbers = new Set(winningPart.trim().split(/\s+/).map(Number)); - const ownNumbers = ownPart.trim().split(/\s+/).map(Number); - return { cardNumber, winningNumbers, ownNumbers }; +function main() { + try { + // Run tests + const testCards = parseInput(path.join(__dirname, '../test.txt')); + assert(partA(testCards) === 13, 'Part A test failed'); + assert(partB(testCards) === 30, 'Part B test failed'); + console.log('All tests passed.'); + + // Process main input + const mainCards = parseInput(path.join(__dirname, '../input.txt')); + const result = partA(mainCards) + partB(mainCards); + console.log(`Puzzle result: ${result}`); + } catch (error) { + console.error(`Error: ${error.message}`); + } } -// Calculates the number of matches for a card -function calculateMatches(winningNumbers, ownNumbers) { - return ownNumbers.reduce((count, number) => count + winningNumbers.has(number), 0); +function partA(cards) { + // Calculate the sum of scores for each card in part A + return cards.reduce((sum, card) => { + return sum + (card.wins > 0 ? Math.pow(2, card.wins - 1) : 0); + }, 0); } -// Processes the cards and returns the total number of cards including copies -function processCards(cards) { - let totalCards = cards.length; - const queue = cards.slice(); // Clone the original array to avoid modifying it +function partB(cards) { + // Calculate the count for part B logic + let queue = [...Array(cards.length).keys()]; + let visited = 0; - while (queue.length > 0) { - const currentCard = queue.shift(); - const matches = calculateMatches(currentCard.winningNumbers, currentCard.ownNumbers); - for (let i = 1; i <= matches; i++) { - if (currentCard.cardNumber + i < cards.length) { - totalCards++; - queue.push(cards[currentCard.cardNumber + i - 1]); + while (queue.length) { + const i = queue.pop(); + visited++; + + const card = cards[i]; + if (card.wins === 0) continue; + + for (let j = 0; j < card.wins; j++) { + if (j + i + 1 < cards.length) { + queue.push(j + i + 1); } } } - return totalCards; + return visited; } -// Reads the file and processes the cards -function processFile(filePath) { +function parseInput(filePath) { + // Read and parse input file into an array of card objects try { - const data = fs.readFileSync(filePath, 'utf-8'); - const lines = data.trim().split('\n'); - const cards = lines.map(parseCardData); - return processCards(cards); + const data = fs.readFileSync(filePath, 'utf8'); + return data.trim().split('\n').map(parseCard); } catch (error) { - console.error(`Error processing file ${filePath}: ${error.message}`); - return null; + throw new Error(`Failed to read file at ${filePath}: ${error.message}`); } } -// Test function -function test() { - const expectedResult = 30; - const result = processFile('../test.txt'); - console.assert(result === expectedResult, `Test failed: Expected ${expectedResult}, got ${result}`); - console.log(`Test passed: ${result} cards`); +function parseCard(line) { + // Parse a single line into a card object + const [, cardInfo] = line.split(': '); + const [winning, scratch] = cardInfo.split(' | ').map(s => s.split(' ').map(Number)); + const winningSet = new Set(winning); + const wins = scratch.reduce((count, num) => count + (winningSet.has(num) ? 1 : 0), 0); + + return { wins }; } -// Main function -function main() { - try { - test(); - const totalCards = processFile('../input.txt'); - console.log(`Total cards from input.txt: ${totalCards}`); - } catch (error) { - console.error(`An error occurred: ${error.message}`); +function assert(condition, message) { + // Simple assertion function + if (!condition) { + throw new Error(message); } } diff --git a/Day04/ts/solution.ts b/Day04/ts/solution.ts index 2dca5d5..3b0e0da 100644 --- a/Day04/ts/solution.ts +++ b/Day04/ts/solution.ts @@ -1,83 +1,85 @@ -import * as fs from 'fs'; +import { readFileSync } from "fs"; -interface Card { - cardNumber: number; - winningNumbers: Set; - ownNumbers: number[]; -} - -// Parses a line of card data and returns the card number, winning numbers, and own numbers -function parseCardData(line: string): Card { - const [cardInfo, numberParts] = line.split(':'); - const [winningPart, ownPart] = numberParts.split('|'); - const cardNumber = parseInt(cardInfo.match(/\d+/)![0], 10); - const winningNumbers = new Set(winningPart.trim().split(/\s+/).map(Number)); - const ownNumbers = ownPart.trim().split(/\s+/).map(Number); - return { cardNumber, winningNumbers, ownNumbers }; -} - -// Calculates the number of matches for a card -function calculateMatches(winningNumbers: Set, ownNumbers: number[]): number { - return ownNumbers.reduce((count, number) => count + (winningNumbers.has(number) ? 1 : 0), 0); -} - -// Processes the cards and returns the total number of cards including copies -function processCards(cards: Card[]): number { - let totalCards = cards.length; - const queue: Card[] = cards.slice(); // Clone the original array to avoid modifying it - - while (queue.length > 0) { - const currentCard = queue.shift()!; - const matches = calculateMatches(currentCard.winningNumbers, currentCard.ownNumbers); - for (let i = 1; i <= matches; i++) { - if (currentCard.cardNumber + i < cards.length) { - totalCards++; - queue.push(cards[currentCard.cardNumber + i - 1]); - } - } - } - - return totalCards; -} - -// Reads the file and processes the cards -function processFile(filePath: string): number | null { - try { - const data = fs.readFileSync(filePath, 'utf-8'); - const lines = data.trim().split('\n'); - const cards = lines.map(parseCardData); - return processCards(cards); - } catch (error) { - if (error instanceof Error) { - console.error(`Error processing file ${filePath}: ${error.message}`); - return null; - } else { - console.error(`An unknown error occurred`); - } - } -} - -// Test function -function test() { - const expectedResult = 30; - const result = processFile('../test.txt'); - console.assert(result === expectedResult, `Test failed: Expected ${expectedResult}, got ${result}`); - console.log(`Test passed: ${result} cards`); -} - -// Main function function main() { try { - test(); - const totalCards = processFile('../input.txt'); - console.log(`Total cards from input.txt: ${totalCards}`); + console.log("Running tests..."); + runTest("../test.txt"); + console.log("Tests passed."); + + console.log("Processing main input..."); + const result = processInput("../input.txt"); + console.log(`Puzzle result: ${result}`); } catch (error) { - if (error instanceof Error) { - console.error(`An error occurred: ${error.message}`); - } else { - console.error(`An unknown error occurred`); + console.error(`Error: ${error}`); + } +} + +function runTest(filename: string) { + const input = readFile(filename); + const cards = parse(input); + + const partAResult = partA(cards); + const partBResult = partB(cards); + + console.assert(partAResult === 13, `Part A Test failed: Expected 13, got ${partAResult}`); + console.assert(partBResult === 30, `Part B Test failed: Expected 30, got ${partBResult}`); +} + +function processInput(filename: string): number { + const input = readFile(filename); + const cards = parse(input); + + return partA(cards) + partB(cards); +} + +function partA(cards: Card[]): number { + return cards + .filter(card => card.wins > 0) + .map(card => Math.pow(2, card.wins - 1)) + .reduce((a, b) => a + b, 0); +} + +function partB(cards: Card[]): number { + const queue = Array.from(Array(cards.length).keys()); + let visited = 0; + + while (queue.length > 0) { + const i = queue.pop()!; + visited++; + + const card = cards[i]; + if (card.wins === 0) continue; + + for (let j = 0; j < card.wins; j++) { + queue.push(j + i + 1); } } + + return visited; +} + +function readFile(filename: string): string { + try { + return readFileSync(filename, 'utf-8'); + } catch (error) { + throw new Error(`Failed to read file '${filename}': ${error}`); + } +} + +function parse(input: string): Card[] { + return input.split('\n').map(line => { + const [winning, scratch] = line.split(': ')[1].split(' | ').map(parseNumbers); + const wins = scratch.filter(x => winning.includes(x)).length; + return new Card(wins); + }); +} + +function parseNumbers(input: string): number[] { + return input.split(' ').map(Number); +} + +class Card { + constructor(public wins: number) {} } main(); diff --git a/Day13/python/solution1.py b/Day13/python/solution1.py index fc5d6ec..708db63 100644 --- a/Day13/python/solution1.py +++ b/Day13/python/solution1.py @@ -1,5 +1,6 @@ from itertools import groupby + def find_mirror(group): """ Find the line of symmetry in the pattern. @@ -14,6 +15,7 @@ def find_mirror(group): return i return 0 + def process_file(filename): """ Process the given file to find the sum of mirror lines. @@ -23,7 +25,9 @@ def process_file(filename): with open(filename) as f: lines = f.read().splitlines() - groups = [tuple(group) for not_empty, group in groupby(lines, bool) if not_empty] + groups = [ + tuple(group) for not_empty, group in groupby(lines, bool) if not_empty + ] res = 0 for group in groups: @@ -31,13 +35,14 @@ def process_file(filename): res += find_mirror(group) * 100 # Horizontal reflection res += find_mirror(tuple(zip(*group))) - + return res except Exception as e: print(f"Error processing file {filename}: {e}") raise + def test(): """ Test function to verify the algorithm with test data. @@ -52,6 +57,7 @@ def test(): except Exception as e: print(f"Test error: {e}") + def main(): """ Main function to run the test and then process the actual input file. @@ -63,5 +69,6 @@ def main(): final_result = process_file("../input.txt") print(f"Final result: {final_result}") + if __name__ == "__main__": main() diff --git a/Day13/python/solution2.py b/Day13/python/solution2.py index c68cd10..136ab1e 100644 --- a/Day13/python/solution2.py +++ b/Day13/python/solution2.py @@ -1,5 +1,6 @@ from itertools import groupby + def find_mirror(group): """ Find the line of symmetry in the pattern, considering there may be one smudge. @@ -12,6 +13,7 @@ def find_mirror(group): return i return 0 + def process_file(filename): """ Process the given file to find the sum of mirror lines considering smudges. @@ -20,7 +22,9 @@ def process_file(filename): with open(filename) as f: lines = f.read().splitlines() - groups = [tuple(group) for not_empty, group in groupby(lines, bool) if not_empty] + groups = [ + tuple(group) for not_empty, group in groupby(lines, bool) if not_empty + ] res = 0 for group in groups: @@ -28,13 +32,14 @@ def process_file(filename): res += find_mirror(group) * 100 # Horizontal reflection res += find_mirror(tuple(zip(*group))) - + return res except Exception as e: print(f"Error processing file {filename}: {e}") raise + def test(): """ Test function to verify the algorithm with test data. @@ -42,26 +47,32 @@ def test(): try: test_result = process_file("../test.txt") print(f"Test result: {test_result}") - expected_result = 400 # Adjust this based on the expected outcome of the test data - assert test_result == expected_result, f"Test failed. Expected result is {expected_result}." + expected_result = ( + 400 # Adjust this based on the expected outcome of the test data + ) + assert ( + test_result == expected_result + ), f"Test failed. Expected result is {expected_result}." print("Test passed.") except AssertionError as ae: print(ae) except Exception as e: print(f"Test error: {e}") + def main(): """ Main function to process the actual input file. """ print("Starting tests...") test() - + try: final_result = process_file("../input.txt") print(f"Final result: {final_result}") except Exception as e: print(f"An error occurred: {e}") + if __name__ == "__main__": main() diff --git a/Day14/python/solution1.py b/Day14/python/solution1.py index 3f5ae68..d34cef2 100644 --- a/Day14/python/solution1.py +++ b/Day14/python/solution1.py @@ -1,13 +1,14 @@ def read_grid(file_path): """Reads the grid from a file and returns it as a 2D list.""" try: - with open(file_path, 'r') as file: + with open(file_path, "r") as file: grid = [list(line.strip()) for line in file] return grid except Exception as e: print(f"Error reading file {file_path}: {e}") raise + def move_rocks_north(grid): """Moves all rounded rocks 'O' north as far as possible.""" rows = len(grid) @@ -15,12 +16,16 @@ def move_rocks_north(grid): for col in range(cols): for row in range(1, rows): # Start from second row - if grid[row][col] == 'O': + if grid[row][col] == "O": target_row = row - while target_row > 0 and grid[target_row-1][col] == '.': + while target_row > 0 and grid[target_row - 1][col] == ".": target_row -= 1 if target_row != row: - grid[target_row][col], grid[row][col] = grid[row][col], grid[target_row][col] + grid[target_row][col], grid[row][col] = ( + grid[row][col], + grid[target_row][col], + ) + def calculate_load(grid): """Calculates the total load on the north support beams.""" @@ -29,24 +34,25 @@ def calculate_load(grid): for row in range(rows): for cell in grid[row]: - if cell == 'O': - total_load += (rows - row) + if cell == "O": + total_load += rows - row return total_load + def run_simulation(file_path): """Runs the rock-moving simulation and returns the total load.""" try: grid = read_grid(file_path) print(f"Initial Grid from {file_path}:") for row in grid: - print(''.join(row)) + print("".join(row)) move_rocks_north(grid) print(f"Grid after moving rocks north from {file_path}:") for row in grid: - print(''.join(row)) + print("".join(row)) total_load = calculate_load(grid) return total_load @@ -54,6 +60,7 @@ def run_simulation(file_path): print(f"Error during simulation for file {file_path}: {e}") raise + def test_simulation(): """Runs test simulation and asserts the expected output.""" test_file = "../test.txt" @@ -63,9 +70,12 @@ def test_simulation(): actual_load = run_simulation(test_file) print(f"Test simulation load: {actual_load}") - assert actual_load == expected_load, f"Test failed: expected {expected_load}, got {actual_load}" + assert ( + actual_load == expected_load + ), f"Test failed: expected {expected_load}, got {actual_load}" print("Test passed successfully.") + def main(): """Main function to run the test and then the actual simulation.""" try: @@ -78,6 +88,7 @@ def main(): except Exception as e: print(f"Error in main function: {e}") + # Run the main function if __name__ == "__main__": main() diff --git a/Day14/python/solution2.py b/Day14/python/solution2.py index 52ec29f..9a1efaf 100644 --- a/Day14/python/solution2.py +++ b/Day14/python/solution2.py @@ -1,13 +1,14 @@ def read_grid(file_path): """Reads the grid from a file and returns it as a 2D list.""" try: - with open(file_path, 'r') as file: + with open(file_path, "r") as file: grid = [list(line.strip()) for line in file] return grid except Exception as e: print(f"Error reading file {file_path}: {e}") raise + def tilt_grid(grid, direction): """Tilts the grid in the specified direction and moves the rounded rocks.""" rows, cols = len(grid), len(grid[0]) @@ -16,45 +17,57 @@ def tilt_grid(grid, direction): if direction == "north": for col in range(cols): for row in range(1, rows): - if grid[row][col] == 'O': + if grid[row][col] == "O": target_row = row - while target_row > 0 and grid[target_row-1][col] == '.': + while target_row > 0 and grid[target_row - 1][col] == ".": target_row -= 1 if target_row != row: - grid[target_row][col], grid[row][col] = grid[row][col], grid[target_row][col] - + grid[target_row][col], grid[row][col] = ( + grid[row][col], + grid[target_row][col], + ) + # West: Move rocks to the left elif direction == "west": for row in range(rows): for col in range(1, cols): - if grid[row][col] == 'O': + if grid[row][col] == "O": target_col = col - while target_col > 0 and grid[row][target_col-1] == '.': + while target_col > 0 and grid[row][target_col - 1] == ".": target_col -= 1 if target_col != col: - grid[row][target_col], grid[row][col] = grid[row][col], grid[row][target_col] + grid[row][target_col], grid[row][col] = ( + grid[row][col], + grid[row][target_col], + ) # South: Move rocks downwards elif direction == "south": for col in range(cols): for row in range(rows - 2, -1, -1): # Start from the second last row - if grid[row][col] == 'O': + if grid[row][col] == "O": target_row = row - while target_row < rows - 1 and grid[target_row + 1][col] == '.': + while target_row < rows - 1 and grid[target_row + 1][col] == ".": target_row += 1 if target_row != row: - grid[target_row][col], grid[row][col] = grid[row][col], grid[target_row][col] + grid[target_row][col], grid[row][col] = ( + grid[row][col], + grid[target_row][col], + ) # East: Move rocks to the right elif direction == "east": for row in range(rows): for col in range(cols - 2, -1, -1): # Start from the second last column - if grid[row][col] == 'O': + if grid[row][col] == "O": target_col = col - while target_col < cols - 1 and grid[row][target_col + 1] == '.': + while target_col < cols - 1 and grid[row][target_col + 1] == ".": target_col += 1 if target_col != col: - grid[row][target_col], grid[row][col] = grid[row][col], grid[row][target_col] + grid[row][target_col], grid[row][col] = ( + grid[row][col], + grid[row][target_col], + ) def run_spin_cycles(grid, cycles): @@ -64,20 +77,23 @@ def run_spin_cycles(grid, cycles): tilt_grid(grid, direction) # Implement pattern detection or optimization here if needed + def run_simulation_with_cycles(file_path, cycles): """Runs the simulation with spin cycles and returns the total load.""" try: grid = read_grid(file_path) - run_spin_cycles(grid, cycles) + actual_cycles = run_spin_cycles_with_optimization(grid, cycles) total_load = calculate_load(grid) return total_load except Exception as e: print(f"Error during simulation for file {file_path}: {e}") raise + def grid_to_string(grid): """Converts the grid to a string for easy comparison.""" - return '\n'.join(''.join(row) for row in grid) + return "\n".join("".join(row) for row in grid) + def run_spin_cycles_with_optimization(grid, max_cycles): """Runs spin cycles on the grid with optimizations for large cycle numbers.""" @@ -106,30 +122,28 @@ def test_simulation_with_cycles(): actual_load = run_simulation_with_cycles(test_file, 1000000000) print(f"Test simulation load after cycles: {actual_load}") - assert actual_load == expected_load_after_cycles, f"Test failed: expected {expected_load_after_cycles}, got {actual_load}" + assert ( + actual_load == expected_load_after_cycles + ), f"Test failed: expected {expected_load_after_cycles}, got {actual_load}" print("Test passed successfully.") + def main(): """Main function to run the test and then the actual simulation with cycles.""" try: test_simulation_with_cycles() - input_file = "../input.txt" cycles = 1000000000 print("\nRunning actual simulation with cycles...") grid = read_grid(input_file) actual_cycles = run_spin_cycles_with_optimization(grid, cycles) total_load = calculate_load(grid) - #total_load = run_simulation_with_cycles(input_file, cycles) + # total_load = run_simulation_with_cycles(input_file, cycles) print(f"Total load from actual simulation with cycles: {total_load}") except Exception as e: print(f"Error in main function: {e}") + # Run the main function if __name__ == "__main__": main() - -# Note: The actual implementation of tilt logic for 'west', 'south', and 'east' directions -# and any optimization techniques for handling a large number of cycles are not included here -# due to complexity and are left as an exercise. This code provides a framework for how -# the algorithm could be structured. diff --git a/Day15/js/solution.js b/Day15/js/solution.js index b96308c..6e299e5 100644 --- a/Day15/js/solution.js +++ b/Day15/js/solution.js @@ -11,7 +11,7 @@ function processSteps(steps) { const focalLengths = new Map(); steps.forEach(step => { - const [_, label, operation, focalLength] = step.match(/([a-z]+)([=-])(\d)?/); + const [, label, operation, focalLength] = step.match(/([a-z]+)([=-])(\d)?/); const hashed = hashLabel(label); const destination = boxes[hashed]; diff --git a/Day15/python/solution1.py b/Day15/python/solution1.py index ebcf719..b0db5eb 100644 --- a/Day15/python/solution1.py +++ b/Day15/python/solution1.py @@ -7,12 +7,13 @@ def hash_algorithm(step): current_value %= 256 # Modulo 256 return current_value + def process_file(file_path): """Process each step in the file and return the sum of HASH values.""" try: - with open(file_path, 'r') as file: - data = file.read().replace('\n', '') # Remove newline characters - steps = data.split(',') # Split steps by comma + with open(file_path, "r") as file: + data = file.read().replace("\n", "") # Remove newline characters + steps = data.split(",") # Split steps by comma print(f"Processing {len(steps)} steps from {file_path}") total_sum = 0 @@ -27,12 +28,14 @@ def process_file(file_path): except Exception as e: print(f"Unexpected error occurred: {e}") + def test_algorithm(): """Test the algorithm with the test file.""" test_result = process_file("../test.txt") print(f"Test Result: {test_result}") assert test_result == 1320, "Test failed. Expected result is 1320." + def main(): """Main function to run the HASH algorithm on the input file.""" try: @@ -48,5 +51,6 @@ def main(): except Exception as e: print(f"An error occurred in main: {e}") + if __name__ == "__main__": main() diff --git a/Day15/python/solution2.py b/Day15/python/solution2.py index 969c9a7..c1cec64 100644 --- a/Day15/python/solution2.py +++ b/Day15/python/solution2.py @@ -1,6 +1,7 @@ import re from collections import defaultdict + def hash_label(label): """Compute hash value for a given label.""" value = 0 @@ -8,11 +9,12 @@ def hash_label(label): value = (value + ord(char)) * 17 % 256 return value + def process_file(file_path): """Process the file and return the total focusing power.""" try: - with open(file_path, 'r') as file: - line = file.read().replace('\n', '') + with open(file_path, "r") as file: + line = file.read().replace("\n", "") boxes = defaultdict(list) focal_lengths = {} @@ -44,11 +46,15 @@ def process_file(file_path): except Exception as e: print(f"Unexpected error occurred: {e}") + def test_algorithm(): """Test the algorithm with the test file.""" test_result = process_file("../test.txt") print(f"Test Result: {test_result}") - assert test_result == 145, f"Test failed. Expected result is 145, got {test_result}." + assert ( + test_result == 145 + ), f"Test failed. Expected result is 145, got {test_result}." + def main(): """Main function to run the algorithm on the input file.""" @@ -65,5 +71,6 @@ def main(): except Exception as e: print(f"An error occurred in main: {e}") + if __name__ == "__main__": main() diff --git a/Day15/rust/src/main.rs b/Day15/rust/src/main.rs index 2038de1..e2cf3cc 100644 --- a/Day15/rust/src/main.rs +++ b/Day15/rust/src/main.rs @@ -2,7 +2,9 @@ use std::collections::HashMap; use std::fs; fn hash_label(label: &str) -> usize { - label.chars().fold(0, |acc, c| (acc + (c as usize)) * 17 % 256) + label + .chars() + .fold(0, |acc, c| (acc + (c as usize)) * 17 % 256) } fn process_steps(steps: Vec<&str>) -> usize { @@ -22,11 +24,11 @@ fn process_steps(steps: Vec<&str>) -> usize { boxes[hashed].push(label.to_string()); } focal_lengths.insert(label.to_string(), focal_length); - }, + } '-' => { boxes[hashed].retain(|l| l != label); focal_lengths.remove(label); - }, + } _ => panic!("Invalid operation character: {}", operation), } } @@ -39,9 +41,14 @@ fn process_steps(steps: Vec<&str>) -> usize { } fn parse_step(step: &str) -> (&str, char, &str) { - let operation_index = step.find(|c: char| c == '=' || c == '-').expect("Invalid step format"); + let operation_index = step + .find(|c: char| c == '=' || c == '-') + .expect("Invalid step format"); let label = &step[..operation_index]; - let operation = step.chars().nth(operation_index).expect("Invalid step format"); + let operation = step + .chars() + .nth(operation_index) + .expect("Invalid step format"); let value = &step[operation_index + 1..]; (label, operation, value) @@ -57,7 +64,11 @@ fn test_algorithm() { let test_result = process_steps(test_steps); println!("Test Result: {}", test_result); - assert_eq!(test_result, 145, "Test failed. Expected result is 145, got {}.", test_result); + assert_eq!( + test_result, 145, + "Test failed. Expected result is 145, got {}.", + test_result + ); } fn main() { diff --git a/README.md b/README.md index 84b7a90..fa9f141 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ![Build Status](https://github.com/wieerwill/advent_of_code_2023/actions/workflows/lint.yml/badge.svg) ![Completed](https://img.shields.io/badge/days%20completed-15-red) -![Stars](https://img.shields.io/badge/stars%20⭐-27-yellow) +![Stars](https://img.shields.io/badge/stars%20⭐-29-yellow) ![License](https://img.shields.io/github/license/wieerwill/advent_of_code_2023.svg) Welcome to my repository where I share my solutions for the [Advent of Code 2023](https://adventofcode.com/2023). Advent of Code is an annual online event where participants solve a series of programming puzzles released daily from December 1st until December 25th. Each puzzle is a fun and unique challenge designed to test problem-solving skills. @@ -46,7 +46,7 @@ I aim to complete each day's puzzle on the same day, but as with any challenge, | 10 | ✅ | ✅ | [Day10 README](/Day10/README.md) | | 11 | ✅ | ✅ | [Day11 README](/Day11/README.md) | | 12 | ✅ | ✅ | [Day12 README](/Day12/README.md) | -| 13 | ❓ | ❓ | [Day13 README](/Day13/README.md) | +| 13 | ✅ | ✅ | [Day13 README](/Day13/README.md) | | 14 | ✅ | ❓ | [Day14 README](/Day14/README.md) | | 15 | ✅ | ✅ | [Day15 README](/Day15/README.md) | | 16 | ❓ | ❓ | [Day16 README](/Day16/README.md) |