diff --git a/.vscode/settings.json b/.vscode/settings.json index 507bb42..3c99ce2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,13 @@ { - "java.project.sourcePaths": ["java"] + "java.project.sourcePaths": ["java"], + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "euler/node_modules": true, + "euler/python_archive": true + } } diff --git a/euler/package.json b/euler/package.json index d8ec871..f567dd5 100644 --- a/euler/package.json +++ b/euler/package.json @@ -2,7 +2,7 @@ "name": "project-euler", "scripts": { "build": "gulp build", - "start": "node run" + "start": "node run.js" }, "devDependencies": { "@types/node": "^16.11.6", diff --git a/euler/run.js b/euler/run.js index a18e860..85ca159 100644 --- a/euler/run.js +++ b/euler/run.js @@ -1,8 +1,10 @@ const fs = require('fs'); const chalk = require('chalk'); -const { spawnSync } = require('child_process'); +const { spawnSync, spawn } = require('child_process'); const perf = require('execution-time')(); +// todo: move to ts-node + const run = (file, puzzleName) => { // Calculate the length of the divider for the puzzle let divider = '--'; @@ -26,33 +28,49 @@ const run = (file, puzzleName) => { console.log(chalk.bold(chalk.yellow(`Executed in ${results.words}`))); }; -// Get files -const tsFiles = fs - .readdirSync('src') - .filter(f => f.endsWith('.ts')) - .filter(f => f !== 'utils.ts'); -const jsFiles = fs - .readdirSync('build') - .filter(f => f.endsWith('.js')) - .filter(f => f !== 'utils.js'); +new Promise(async resolve => { + // Rebuild the files + const gulp = spawn('npx', ['gulp-cli', 'build'], { shell: true, stdio: 'pipe' }); -try { - // Extract the puzzle number - const puzzleNumber = process.argv[2]; - if (isNaN(puzzleNumber)) throw Error(); + gulp.stdout.on('data', data => { + const message = data.toString(); + const match = message.match(/Starting '(.*)'/)?.[1]; + if (match) console.log(chalk.red(`[gulp] Running '${match}' task`)); + }); - // Find the associated puzzle - const tsFile = tsFiles.filter(f => f.startsWith(puzzleNumber))[0]; - const puzzleName = tsFile.split('.ts')[0]; + gulp.on('close', () => { + console.log(); + resolve(); + }); +}).then(() => { + // Get files + const tsFiles = fs + .readdirSync('src') + .filter(f => f.endsWith('.ts')) + .filter(f => f !== 'utils.ts'); + const jsFiles = fs + .readdirSync('build') + .filter(f => f.endsWith('.js')) + .filter(f => f !== 'utils.js'); - run(`${puzzleNumber}.js`, puzzleName); -} catch (error) { - for (let i = 0; i < jsFiles.length; i++) { - const file = jsFiles[i]; - const tsFile = tsFiles[i]; + try { + // Extract the puzzle number + const puzzleNumber = process.argv[2]; + if (isNaN(puzzleNumber)) throw Error(); + + // Find the associated puzzle + const tsFile = tsFiles.filter(f => f.startsWith(puzzleNumber))[0]; const puzzleName = tsFile.split('.ts')[0]; - run(file, puzzleName); - console.log(); + run(`${puzzleNumber}.js`, puzzleName); + } catch (error) { + for (let i = 0; i < jsFiles.length; i++) { + const file = jsFiles[i]; + const tsFile = tsFiles[i]; + const puzzleName = tsFile.split('.ts')[0]; + + run(file, puzzleName); + console.log(); + } } -} +}); diff --git a/euler/src/14 - Longest Collatz sequence.ts b/euler/src/14 - Longest Collatz sequence.ts new file mode 100644 index 0000000..77451ee --- /dev/null +++ b/euler/src/14 - Longest Collatz sequence.ts @@ -0,0 +1,40 @@ +// n -> n/2 (if n is even) +// n -> 3n + 1 (if n is odd) +// Start at a number, iterate until 1 +// Which starting number under one million has the longest chain? + +export {}; + +const isEven = (n: number) => n % 2 === 0; + +const collatzSequence = (startNumber: number) => { + let currentNumber = startNumber; + let sequence = [startNumber]; + + while (currentNumber > 1) { + if (isEven(currentNumber)) currentNumber = currentNumber / 2; + else currentNumber = currentNumber * 3 + 1; + + sequence.push(currentNumber); + } + + return sequence; +}; + +const longestCollatzUnderLimit = (limit: number) => { + let longestStartingNumber = -1; + let longestStartingNumberLength = -1; + + for (let i = 1; i < limit; i++) { + const sequence = collatzSequence(i); + + if (sequence.length > longestStartingNumberLength) { + longestStartingNumber = i; + longestStartingNumberLength = sequence.length; + } + } + + return longestStartingNumberLength; +}; + +console.log(longestCollatzUnderLimit(1000000));