diff --git a/Day04/ts/solution.ts b/Day04/ts/solution.ts new file mode 100644 index 0000000..0d8b54b --- /dev/null +++ b/Day04/ts/solution.ts @@ -0,0 +1,75 @@ +import * as fs 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: any) { + console.error(`Error processing file ${filePath}: ${error.message}`); + return null; + } +} + +// 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}`); + } catch (error: any) { + console.error(`An error occurred: ${error.message}`); + } +} + +main();