├── .gitattributes ├── .github ├── CODEOWNERS └── workflows │ ├── check-formatting.yml │ ├── deploy-github-pages.yml │ ├── generate-health-report.yml │ ├── lint.yml │ ├── post-leetcode-potd-to-discord.yml │ ├── run-tests.yml │ ├── set-up-everything │ └── action.yml │ ├── typecheck.yml │ └── update-leetcode-problem-data.yml ├── .gitignore ├── .husky └── pre-commit ├── .prettierignore ├── .vscode ├── extensions.json └── settings.json ├── .yarn ├── patches │ ├── @types-chrome-npm-0.0.280-34ee4ba05a.patch │ ├── graphql-npm-16.9.0-a36f71845f.patch │ ├── immutability-helper-npm-3.1.1-482f1f8f58.patch │ └── nullthrows-npm-1.1.1-3d1f817134.patch └── releases │ ├── code-chronicles.patch │ └── yarn-4.5.1-git.20241025.hash-f59bbf9-code-chronicles-patch.cjs ├── .yarnrc.yml ├── AUTHORS ├── CONTRIBUTING.md ├── DEVELOPMENT.md ├── LICENSE ├── README.md ├── eslint.config.js ├── lint-staged.config.mjs ├── package.json ├── tsconfig-base.json ├── workspaces ├── adventure-pack │ ├── .gitignore │ ├── .prettierignore │ ├── README.md │ ├── css │ │ └── style.css │ ├── eslint.config.js │ ├── goodies │ │ ├── java │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ ├── gradle │ │ │ │ ├── libs.versions.toml │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ ├── settings.gradle.kts │ │ │ └── src │ │ │ │ ├── digits_int │ │ │ │ ├── AP.java │ │ │ │ ├── Test.java │ │ │ │ └── goody.json │ │ │ │ ├── gcd_int_int │ │ │ │ ├── AP.java │ │ │ │ ├── Test.java │ │ │ │ └── goody.json │ │ │ │ ├── iterable_double_stream │ │ │ │ ├── IterableDoubleStream.java │ │ │ │ └── goody.json │ │ │ │ ├── iterable_int_stream │ │ │ │ ├── IterableIntStream.java │ │ │ │ └── goody.json │ │ │ │ ├── iterable_long_stream │ │ │ │ ├── IterableLongStream.java │ │ │ │ └── goody.json │ │ │ │ ├── iterable_stream │ │ │ │ ├── IterableStream.java │ │ │ │ └── goody.json │ │ │ │ ├── lcm_int_int │ │ │ │ ├── AP.java │ │ │ │ ├── Test.java │ │ │ │ └── goody.json │ │ │ │ ├── pair │ │ │ │ ├── Pair.java │ │ │ │ └── goody.json │ │ │ │ ├── primes │ │ │ │ ├── AP.java │ │ │ │ ├── Test.java │ │ │ │ └── goody.json │ │ │ │ ├── simple_iterator │ │ │ │ ├── SimpleIterator.java │ │ │ │ └── goody.json │ │ │ │ ├── traverse_in_order │ │ │ │ ├── AP.java │ │ │ │ └── goody.json │ │ │ │ ├── traverse_post_order │ │ │ │ ├── AP.java │ │ │ │ └── goody.json │ │ │ │ ├── traverse_pre_order │ │ │ │ ├── AP.java │ │ │ │ └── goody.json │ │ │ │ ├── union_find │ │ │ │ ├── Test.java │ │ │ │ ├── UnionFind.java │ │ │ │ └── goody.json │ │ │ │ └── virtual_list │ │ │ │ ├── VirtualList.java │ │ │ │ └── goody.json │ │ ├── kotlin │ │ │ ├── .gitattributes │ │ │ ├── .gitignore │ │ │ ├── build.gradle.kts │ │ │ ├── gradle.properties │ │ │ ├── gradle │ │ │ │ ├── libs.versions.toml │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradlew │ │ │ ├── gradlew.bat │ │ │ ├── settings.gradle.kts │ │ │ └── src │ │ │ │ ├── gcd_int_int │ │ │ │ ├── Main.kt │ │ │ │ ├── Test.kt │ │ │ │ └── goody.json │ │ │ │ ├── lcm_int_int │ │ │ │ ├── Main.kt │ │ │ │ ├── Test.kt │ │ │ │ └── goody.json │ │ │ │ └── traverse_level_order │ │ │ │ ├── Main.kt │ │ │ │ ├── Test.kt │ │ │ │ └── goody.json │ │ ├── python3 │ │ │ ├── .gitignore │ │ │ ├── format.sh │ │ │ ├── install.sh │ │ │ ├── pytest.ini │ │ │ ├── requirements.txt │ │ │ ├── run_python.sh │ │ │ ├── src │ │ │ │ ├── flatten │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── int_digits │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── is_palindrome │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── transpose_matrix │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── traverse_inorder │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── traverse_level_order │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── traverse_postorder │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── traverse_postorder_n_ary │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ ├── traverse_preorder │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ │ └── union_find │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── goody.json │ │ │ │ │ └── test.py │ │ │ └── test.sh │ │ └── typescript │ │ │ ├── Array.prototype.slidingWindows │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Array.prototype.swap │ │ │ └── index.ts │ │ │ ├── ArraySlice │ │ │ └── index.ts │ │ │ ├── BinaryHeap │ │ │ └── index.ts │ │ │ ├── Function.returnThis │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.from │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.drop │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.every │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.filter │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.find │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.flatMap │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.forEach │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.map │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.max │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.min │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.product │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.reduce │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.some │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.sum │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.take │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.tally │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.toArray │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.toIterable │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.toMap │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.toObject │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype.toSet │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Iterator.prototype │ │ │ └── index.ts │ │ │ ├── Map.groupBy │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Math.gcd │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Math.lcm │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Math.primes │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Number.prototype.chr │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Number.prototype.digits │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Number.prototype.positiveMod │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── Object.getUnsafe │ │ │ └── index.ts │ │ │ ├── Object.prototype.entries │ │ │ └── index.ts │ │ │ ├── Object.prototype.keys │ │ │ └── index.ts │ │ │ ├── Object.prototype.values │ │ │ └── index.ts │ │ │ ├── Object.setUnsafe │ │ │ └── index.ts │ │ │ ├── String.prototype.caesar │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── String.prototype.chars │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── String.prototype.ord │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── compareNatural │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── console.meow │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── invariant │ │ │ └── index.ts │ │ │ ├── invariantViolation │ │ │ └── index.ts │ │ │ ├── isNonNullish │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── newArray │ │ │ ├── index.test.ts │ │ │ └── index.ts │ │ │ ├── nullthrows │ │ │ └── index.ts │ │ │ ├── traverseInOrder │ │ │ └── index.ts │ │ │ ├── traverseLevelOrder │ │ │ └── index.ts │ │ │ ├── traversePostOrder │ │ │ └── index.ts │ │ │ ├── traversePostOrderNAry │ │ │ └── index.ts │ │ │ └── traversePreOrder │ │ │ └── index.ts │ ├── jest.config.ts │ ├── package.json │ ├── prettier.config.mjs │ ├── src │ │ ├── app │ │ │ ├── Goody.ts │ │ │ ├── Language.ts │ │ │ ├── __tests__ │ │ │ │ ├── __snapshots__ │ │ │ │ │ ├── equip-test.ts.snap │ │ │ │ │ └── render-test.ts.snap │ │ │ │ ├── equip-test.ts │ │ │ │ └── render-test.ts │ │ │ ├── centerTextInComment.ts │ │ │ ├── components │ │ │ │ ├── App.tsx │ │ │ │ ├── Checkbox.tsx │ │ │ │ ├── CopyButton.tsx │ │ │ │ ├── GoodyCard.tsx │ │ │ │ ├── HighlightedCode.tsx │ │ │ │ └── LanguageSelector.tsx │ │ │ ├── constants.ts │ │ │ ├── fetchGoodies.ts │ │ │ ├── main.tsx │ │ │ ├── mergeCode.ts │ │ │ ├── mergeJavaCode.ts │ │ │ ├── sortTypeScriptModuleAndInterfaceDeclarations.ts │ │ │ ├── stringifyGoody.ts │ │ │ ├── stringifyTypeScriptInterfaceDeclarations.ts │ │ │ ├── stringifyTypeScriptModuleDeclarations.ts │ │ │ ├── useAppState.ts │ │ │ ├── useMergedCode.ts │ │ │ └── zod-types │ │ │ │ ├── goodyBaseZodType.ts │ │ │ │ ├── javaGoodyZodType.ts │ │ │ │ ├── javaScriptGoodyZodType.ts │ │ │ │ ├── kotlinGoodyZodType.ts │ │ │ │ ├── python3GoodyZodType.ts │ │ │ │ └── typeScriptGoodyZodType.ts │ │ └── scripts │ │ │ ├── build │ │ │ ├── WriteGoodiesJsonWebpackPlugin.tsx │ │ │ ├── WriteIndexHtmlWebpackPlugin.tsx │ │ │ ├── buildChromeExtension.ts │ │ │ └── constants.ts │ │ │ └── package-goodies │ │ │ ├── extractJavaesqueImports.ts │ │ │ ├── fillOutImportedByAndSortImports.ts │ │ │ ├── java │ │ │ ├── constants.ts │ │ │ ├── readBaseGoody.ts │ │ │ ├── readCode.ts │ │ │ ├── readGoodies.ts │ │ │ ├── readMetadata.ts │ │ │ └── splitCodeIntoClasses.ts │ │ │ ├── kotlin │ │ │ ├── constants.ts │ │ │ ├── readBaseGoody.ts │ │ │ ├── readCode.ts │ │ │ ├── readGoodies.ts │ │ │ └── readMetadata.ts │ │ │ ├── normalizeGoodyNameToPackageOrModuleName.ts │ │ │ ├── python3 │ │ │ ├── constants.ts │ │ │ ├── readBaseGoody.ts │ │ │ ├── readCode.ts │ │ │ ├── readGoodies.ts │ │ │ └── readMetadata.ts │ │ │ ├── readAllGoodies.ts │ │ │ └── typescript │ │ │ ├── createSourceFile.ts │ │ │ ├── extractImports.ts │ │ │ ├── extractModuleDeclarations.ts │ │ │ ├── formatCode.ts │ │ │ ├── getCodeAt.ts │ │ │ ├── getLeadingTriviaRange.ts │ │ │ ├── getTrailingTriviaRange.ts │ │ │ ├── getTrivia.ts │ │ │ ├── readBaseGoody.ts │ │ │ ├── readGoodies.ts │ │ │ ├── removeNode.ts │ │ │ ├── removeUninitializedPropertyDeclarations.ts │ │ │ └── transpile.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── archive │ ├── .gitattributes │ ├── README.md │ ├── difference-between-element-sum-and-digit-sum-of-an-array.md │ ├── general-code-review.md │ ├── number-of-good-pairs.md │ ├── package.json │ ├── problem-list.md │ ├── problems.jsonl │ ├── ransom-note.md │ ├── smallest-even-multiple.md │ ├── solutions │ │ ├── check-straight-line-solution.js │ │ ├── checkStraightLines.cpp │ │ └── straight_line.py │ └── to-lower-case.md ├── download-leetcode-submissions │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── secrets_TEMPLATE.json │ ├── src │ │ ├── constants.ts │ │ ├── getDirnameForSubmission.ts │ │ ├── getFilenameForSubmission.ts │ │ ├── main.ts │ │ ├── readPriorSubmissions.ts │ │ ├── readSecrets.ts │ │ ├── transformSubmission.ts │ │ └── writeSubmissionsMetadataAndHashes.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── eslint-config │ ├── README.md │ ├── eslint.config.js │ └── package.json ├── fetch-leetcode-problem-list │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ └── main.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── fetch-recent-accepted-leetcode-submissions │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ └── main.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── generate-health-report │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ └── main.ts │ └── tsconfig.json ├── javascript-leetcode-month │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── problems │ │ ├── 2618-check-if-object-instance-of-class │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2619-array-prototype-last │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2620-counter │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2621-sleep │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2622-cache-with-time-limit │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2623-memoize │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2624-snail-traversal │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2625-flatten-deeply-nested-array │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2626-array-reduce-transformation │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── iterative │ │ │ │ ├── destructive-using-while.ts │ │ │ │ ├── using-for-each.ts │ │ │ │ └── using-for-of.ts │ │ │ │ ├── recursive │ │ │ │ ├── elegant-but-quadratic.ts │ │ │ │ ├── inner-function.ts │ │ │ │ ├── linear-through-own-reduce-right.ts │ │ │ │ └── single-function-width-default-argument.ts │ │ │ │ ├── using-built-in-reduce-right │ │ │ │ ├── using-reverse.ts │ │ │ │ └── using-to-reversed.ts │ │ │ │ └── using-built-in-reduce │ │ │ │ ├── binding.js │ │ │ │ ├── delegating.js │ │ │ │ └── delegating.ts │ │ ├── 2627-debounce │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2629-function-composition │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2630-memoize-ii │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2631-group-by │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2634-filter-elements-from-array │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── iterative-loops │ │ │ │ ├── using-classic-for.ts │ │ │ │ ├── using-for-each.ts │ │ │ │ ├── using-for-of-entries.ts │ │ │ │ └── using-generators.ts │ │ │ │ ├── recursive │ │ │ │ ├── inner-function.ts │ │ │ │ └── single-function-with-default-arguments.ts │ │ │ │ ├── using-built-in-filter │ │ │ │ ├── binding.js │ │ │ │ └── delegating.ts │ │ │ │ ├── using-flat-map │ │ │ │ └── delegating.ts │ │ │ │ └── using-reduce │ │ │ │ ├── elegant-but-quadratic.ts │ │ │ │ ├── linear-contrarian.ts │ │ │ │ ├── linear-with-comma-operator.ts │ │ │ │ └── linear.ts │ │ ├── 2635-apply-transform-over-each-element-in-array │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── iterative-loops │ │ │ │ ├── using-classic-for-mutating-input.ts │ │ │ │ ├── using-classic-for.ts │ │ │ │ ├── using-for-each.ts │ │ │ │ ├── using-for-of-entries.ts │ │ │ │ └── using-generators.ts │ │ │ │ ├── recursive │ │ │ │ ├── inner-function-with-index-argument.ts │ │ │ │ ├── inner-function-without-index-argument.ts │ │ │ │ └── single-function-with-default-argument.ts │ │ │ │ ├── using-built-in-map │ │ │ │ ├── binding.js │ │ │ │ └── delegating.ts │ │ │ │ ├── using-other-mapping-built-ins │ │ │ │ ├── aliasing-array-from.js │ │ │ │ ├── delegating-to-array-from.ts │ │ │ │ ├── delegating-to-flat-map-safe.ts │ │ │ │ └── delegating-to-flat-map-sloppy.ts │ │ │ │ └── using-reduce │ │ │ │ ├── elegant-but-quadratic.ts │ │ │ │ ├── linear-contrarian.ts │ │ │ │ ├── linear-with-comma-operator.ts │ │ │ │ └── linear.ts │ │ ├── 2637-promise-time-limit │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2648-generate-fibonacci-sequence │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2649-nested-array-generator │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2650-design-cancellable-function │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2665-counter-ii │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2666-allow-one-function-call │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2667-create-hello-world-function │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2677-chunk-array │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── grabbing-slices │ │ │ │ ├── using-built-in-slice.ts │ │ │ │ ├── using-generators.ts │ │ │ │ ├── using-hand-rolled-slice-with-start-and-end.ts │ │ │ │ └── using-hand-rolled-slice-with-start-and-size.ts │ │ │ │ ├── processing-individual-elements │ │ │ │ ├── iterating-by-index.ts │ │ │ │ ├── iterating-over-elements.ts │ │ │ │ ├── iterating-over-index-element-pairss.ts │ │ │ │ ├── iterating-with-foreach-method.ts │ │ │ │ └── special-casing-last-chunk.ts │ │ │ │ └── using-lodash │ │ │ │ ├── delegating.js │ │ │ │ ├── delegating.ts │ │ │ │ └── destructuring.js │ │ ├── 2693-call-function-with-custom-context │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2694-event-emitter │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2695-array-wrapper │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2703-return-length-of-arguments-passed │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── using-arguments-object │ │ │ │ ├── anonymous-function.js │ │ │ │ ├── anonymous-function.ts │ │ │ │ ├── named-function-with-empty-destructure.ts │ │ │ │ ├── named-function.js │ │ │ │ └── named-function.ts │ │ │ │ └── using-rest-parameters │ │ │ │ ├── arrow-function-without-return-annotation.ts │ │ │ │ ├── arrow-function.ts │ │ │ │ ├── named-function.js │ │ │ │ └── named-function.ts │ │ ├── 2704-to-be-or-not-to-be │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2705-compact-object │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2715-timeout-cancellation │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2721-execute-asynchronous-functions-in-parallel │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2722-join-two-arrays-by-id │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2723-add-two-promises │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2724-sort-by │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ │ ├── minimizing-calls-to-fn │ │ │ │ ├── caching-in-map.ts │ │ │ │ ├── mapping-to-records.ts │ │ │ │ ├── mapping-to-tuples.ts │ │ │ │ └── using-lodash-memoize.js │ │ │ │ ├── refusing-to-specify-custom-comparator │ │ │ │ └── adding-an-offset-to-sort-key-for-padding.ts │ │ │ │ ├── using-built-in-sort │ │ │ │ ├── delegating-without-modifying-input.ts │ │ │ │ ├── delegating.js │ │ │ │ └── delegating.ts │ │ │ │ ├── using-own-sort-implementation │ │ │ │ └── merge-sort.ts │ │ │ │ └── using-to-sorted │ │ │ │ ├── delegating.js │ │ │ │ └── delegating.ts │ │ ├── 2725-interval-cancellation │ │ │ ├── README.md │ │ │ └── solution.md │ │ ├── 2726-calculator-with-method-chaining │ │ │ ├── README.md │ │ │ └── solution.md │ │ └── 2727-is-object-empty │ │ │ ├── README.md │ │ │ ├── solution.md │ │ │ └── solutions │ │ │ ├── using-for-in │ │ │ ├── array-check-via-if-and-property-ownership-check.js │ │ │ ├── array-check-via-ternary-and-property-ownership-check.ts │ │ │ └── no-checks.ts │ │ │ ├── using-json-stringify │ │ │ ├── array-check-via-if.js │ │ │ ├── array-check-via-ternary-and-json-length.ts │ │ │ ├── array-check-via-ternary.ts │ │ │ └── no-array-check.ts │ │ │ └── using-object-keys │ │ │ ├── array-check-via-if.js │ │ │ ├── array-check-via-if.ts │ │ │ ├── array-check-via-ternary-subexpression.ts │ │ │ ├── array-check-via-ternary.ts │ │ │ └── no-array-check.ts │ ├── scripts │ │ ├── prep-write-up-for-leetcode.ts │ │ └── processWriteUpForLeetCode.ts │ └── tsconfig.json ├── leetcode-api │ ├── .gitattributes │ ├── README.md │ ├── eslint.config.js │ ├── graphql-codegen.config.ts │ ├── jest.config.ts │ ├── package.json │ ├── schema-original.graphql │ ├── schema-patched.graphql │ ├── src │ │ ├── __tests__ │ │ │ └── validSchema-test.ts │ │ ├── api │ │ │ ├── active-daily-coding-challenge-question │ │ │ │ ├── fetchGraphQL.generated.ts │ │ │ │ ├── main.ts │ │ │ │ └── query.graphql │ │ │ ├── daily-coding-challenge-v2 │ │ │ │ ├── fetchGraphQL.generated.ts │ │ │ │ ├── main.ts │ │ │ │ └── query.graphql │ │ │ ├── question-list │ │ │ │ ├── fetchGraphQL.generated.ts │ │ │ │ ├── main.ts │ │ │ │ └── query.graphql │ │ │ ├── recent-ac-submission-list │ │ │ │ ├── fetchGraphQL.generated.ts │ │ │ │ ├── main.ts │ │ │ │ └── query.graphql │ │ │ ├── submission-list-non-graphql │ │ │ │ └── main.ts │ │ │ └── topic │ │ │ │ ├── fetchGraphQL.generated.ts │ │ │ │ ├── main.ts │ │ │ │ └── query.graphql │ │ ├── fetchGraphQLTypeInformation.ts │ │ ├── getGraphQLClient.ts │ │ ├── graphqlTypes.generated.ts │ │ ├── normalizeGraphQLDescription.ts │ │ ├── scripts │ │ │ ├── codegen │ │ │ │ ├── graphqlCodegenPlugin.ts │ │ │ │ └── graphqlToZod.ts │ │ │ ├── patch-graphql-schema │ │ │ │ ├── addDirectiveToField.ts │ │ │ │ ├── addEnumDirectiveToField.ts │ │ │ │ ├── assertSingleASTNode.ts │ │ │ │ ├── astNodeBuilders.ts │ │ │ │ ├── constants.ts │ │ │ │ ├── main.ts │ │ │ │ ├── markFieldNonNull.ts │ │ │ │ ├── modifications.ts │ │ │ │ └── visitor.ts │ │ │ └── scrape-graphql-schema │ │ │ │ ├── constants.ts │ │ │ │ ├── encodeValue.ts │ │ │ │ ├── getFakeScalarType.ts │ │ │ │ ├── main.ts │ │ │ │ ├── parseEncodedValues.ts │ │ │ │ ├── readSeedGraphQLTypeNames.ts │ │ │ │ └── stringifyGraphQLSchema.ts │ │ ├── sortByName.ts │ │ └── zod-types │ │ │ ├── questionDifficultyZodType.ts │ │ │ ├── slugZodType.ts │ │ │ └── yyyymmddDateZodType.ts │ └── tsconfig.json ├── leetcode-prettier-extension │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── isMonaco.ts │ │ └── main.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── leetcode-zen-mode │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── extension │ │ │ ├── constants.ts │ │ │ ├── content-script-isolated │ │ │ │ └── main.ts │ │ │ ├── content-script-non-isolated │ │ │ │ ├── isArrayOfDataByDifficulty.ts │ │ │ │ ├── main.ts │ │ │ │ ├── patchJsxFactory.ts │ │ │ │ ├── patchLeetCodeModule.ts │ │ │ │ ├── rewriteLeetCodeAggregateDataForDifficulty.ts │ │ │ │ ├── rewriteLeetCodeGraphQLData.ts │ │ │ │ └── stringCase.ts │ │ │ ├── options-ui │ │ │ │ ├── components │ │ │ │ │ └── App.tsx │ │ │ │ └── main.tsx │ │ │ ├── useChromeStorage.ts │ │ │ └── usePreferredDifficulty.ts │ │ └── scripts │ │ │ └── build │ │ │ └── WriteOptionsHtmlWebpackPlugin.tsx │ ├── tsconfig.json │ └── webpack.config.ts ├── post-leetcode-potd-to-discord │ ├── .gitignore │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── secrets_TEMPLATE.json │ ├── src │ │ ├── formatTimestampForDiscord.ts │ │ ├── getPotdMessage.ts │ │ ├── main.ts │ │ ├── readScriptData.ts │ │ ├── readSecrets.ts │ │ ├── sendDiscordMessage.ts │ │ └── writeScriptData.ts │ ├── tsconfig.json │ └── webpack.config.ts ├── repository-scripts │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── bin │ │ │ ├── lint.js │ │ │ └── typecheck.js │ │ ├── chalkLevelOrForced.ts │ │ ├── lint.ts │ │ ├── main.ts │ │ ├── reportCommand.ts │ │ ├── reportCommandAndSpawn.ts │ │ ├── runCommands.ts │ │ ├── scripts.ts │ │ └── typecheck.ts │ └── tsconfig.json ├── simon-game │ ├── .gitignore │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── components │ │ │ │ ├── App.tsx │ │ │ │ └── Box.tsx │ │ │ ├── constants.ts │ │ │ ├── main.tsx │ │ │ └── util │ │ │ │ ├── playNote.ts │ │ │ │ └── playSound.ts │ │ └── scripts │ │ │ └── build │ │ │ └── WriteIndexHtmlWebpackPlugin.tsx │ ├── tsconfig.json │ └── webpack.config.ts ├── util │ ├── README.md │ ├── eslint.config.js │ ├── jest.config.ts │ ├── package.json │ ├── src │ │ ├── BinaryHeap.ts │ │ ├── NonEmptyArray.ts │ │ ├── Queue.ts │ │ ├── __tests__ │ │ │ ├── distinctArray-test.ts │ │ │ ├── getConcertPitch-test.ts │ │ │ ├── getLines-test.ts │ │ │ ├── isNonNullish-test.ts │ │ │ ├── squashWhitespace-test.ts │ │ │ ├── stripPrefix-test.ts │ │ │ ├── stripSuffix-test.ts │ │ │ ├── stripSuffixOrThrow-test.ts │ │ │ └── timestampInSecondsToYearMonthDay-test.ts │ │ ├── addAllToSet.ts │ │ ├── and.ts │ │ ├── arpeggiate.ts │ │ ├── assertIsArray.ts │ │ ├── assertIsIntegerString.ts │ │ ├── assertIsObject.ts │ │ ├── assertIsRunningInCI.ts │ │ ├── assertIsRunningInGitHubActions.ts │ │ ├── assertIsString.ts │ │ ├── browser-extensions │ │ │ ├── NullReactElement.ts │ │ │ ├── chrome │ │ │ │ └── getChrome.ts │ │ │ ├── injectJsonParseMiddleware.ts │ │ │ ├── injectJsonScriptMiddleware.ts │ │ │ ├── injectXhrBlobResponseMiddleware.ts │ │ │ ├── isModuleReact.ts │ │ │ ├── isModuleWebCellDomRenderer.ts │ │ │ ├── startRecordingXhrResponseBlobs.ts │ │ │ └── webpackChunkLoading.ts │ │ ├── chdirToCurrentGitRepositoryRoot.ts │ │ ├── chunkBySize.ts │ │ ├── coalesceResults.ts │ │ ├── compareStrings.ts │ │ ├── compareStringsCaseInsensitive.ts │ │ ├── constructJsonBlob.ts │ │ ├── createTemporaryFile.ts │ │ ├── distinctArray.ts │ │ ├── execWithArgs.ts │ │ ├── execWithArgsOrThrowOnNzec.ts │ │ ├── filterMapValues.ts │ │ ├── first.ts │ │ ├── firstOrThrow.ts │ │ ├── getConcertPitch.ts │ │ ├── getCurrentGitRepositoryRoot.ts │ │ ├── getCurrentGitRepositoryStatusPaths.ts │ │ ├── getLines.ts │ │ ├── getMultilineCommentText.ts │ │ ├── getRandomBytes.ts │ │ ├── getResult.ts │ │ ├── getUniqueId.ts │ │ ├── groupBy.ts │ │ ├── identity.ts │ │ ├── invariantViolation.ts │ │ ├── isArrayOfNumbers.ts │ │ ├── isEnvironmentDev.ts │ │ ├── isNonArrayObject.ts │ │ ├── isNonNullish.ts │ │ ├── isNumber.ts │ │ ├── isObject.ts │ │ ├── isRunningInCI.ts │ │ ├── isRunningInGitHubActions.ts │ │ ├── isString.ts │ │ ├── isStringAWayOfSayingFalse.ts │ │ ├── isStringEmptyOrWhitespaceOnly.ts │ │ ├── isStringLowerCase.ts │ │ ├── isStringTitleCase.ts │ │ ├── isStringUpperCase.ts │ │ ├── isSystemError.ts │ │ ├── jsonMimeType.ts │ │ ├── jsonParseSafe.ts │ │ ├── jsonStringifyPrettyInDev.ts │ │ ├── last.ts │ │ ├── lastOrThrow.ts │ │ ├── mapArrayAtIndex.ts │ │ ├── mapJsonBlobData.ts │ │ ├── mapObjectValues.ts │ │ ├── mapObjectValuesAsync.ts │ │ ├── maybeThrow.ts │ │ ├── mergeObjects.ts │ │ ├── object-properties │ │ │ ├── assignFunctionCosmeticProperties.ts │ │ │ ├── isAccessorPropertyDescriptor.ts │ │ │ ├── isDataPropertyDescriptor.ts │ │ │ ├── redefineObjectProperty.ts │ │ │ └── types.ts │ │ ├── objectFromKeys.ts │ │ ├── once.ts │ │ ├── only.ts │ │ ├── or.ts │ │ ├── partition.ts │ │ ├── popMany.ts │ │ ├── promiseAllLimitingConcurrency.ts │ │ ├── promiseAllObject.ts │ │ ├── promiseIdleCallback.ts │ │ ├── readPackageJson.ts │ │ ├── readWorkspaces.ts │ │ ├── removeKeysWithNullishValues.ts │ │ ├── replaceInMap.ts │ │ ├── resultify.ts │ │ ├── runWithLogGroupAsync.ts │ │ ├── setIfNotHasOwnOrThrow.ts │ │ ├── sha512.ts │ │ ├── shiftOctaves.ts │ │ ├── shiftSemitones.ts │ │ ├── sleep.ts │ │ ├── slurpReadable.ts │ │ ├── sortObjectKeys.ts │ │ ├── sortObjectKeysRecursive.ts │ │ ├── spawnWithSafeStdio.ts │ │ ├── spliceString.ts │ │ ├── squashWhitespace.ts │ │ ├── stringToCase.ts │ │ ├── stripPrefix.ts │ │ ├── stripPrefixOrThrow.ts │ │ ├── stripSuffix.ts │ │ ├── stripSuffixOrThrow.ts │ │ ├── sum.ts │ │ ├── swap.ts │ │ ├── timeConstants.ts │ │ ├── timestampInSecondsToYearMonthDay.ts │ │ ├── toTitleCase.ts │ │ ├── whileReturnsTrueAsync.ts │ │ ├── writeToTemporaryFile.ts │ │ ├── yearMonthDayToTimestampInSeconds.ts │ │ └── zod-types │ │ │ ├── graphqlKindTypeZodType.ts │ │ │ ├── nonBlankStringZodType.ts │ │ │ ├── nonNegativeIntOrIntStringZodType.ts │ │ │ ├── numericIdAsNumberZodType.ts │ │ │ ├── numericIdAsStringZodType.ts │ │ │ ├── positiveIntOrIntStringZodType.ts │ │ │ ├── timestampZodType.ts │ │ │ ├── transformToInt.ts │ │ │ └── transformToString.ts │ └── tsconfig.json ├── webpack-chrome-extension-manifest-plugin │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ │ └── main.ts │ └── tsconfig.json └── webpack-make-output-executable-plugin │ ├── README.md │ ├── eslint.config.js │ ├── package.json │ ├── src │ └── main.ts │ └── tsconfig.json ├── yarn.config.cjs └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | 3 | yarn.lock linguist-generated 4 | 5 | tsconfig-base.json linguist-language=jsonc 6 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @miorel 2 | -------------------------------------------------------------------------------- /.github/workflows/check-formatting.yml: -------------------------------------------------------------------------------- 1 | name: Check formatting on PRs 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] 6 | 7 | jobs: 8 | check-formatting: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Check out repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Set up everything 16 | uses: ./.github/workflows/set-up-everything 17 | 18 | - name: Check formatting 19 | run: yarn format 20 | -------------------------------------------------------------------------------- /.github/workflows/generate-health-report.yml: -------------------------------------------------------------------------------- 1 | name: Generate PR Health Report 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] 6 | 7 | env: 8 | NODE_ENV: development 9 | 10 | jobs: 11 | generate-health-report: 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | os: [ubuntu-latest, windows-latest, macos-latest] 16 | runs-on: ${{ matrix.os }} 17 | 18 | steps: 19 | - name: Check out repository 20 | uses: actions/checkout@v4 21 | 22 | - name: Set up everything 23 | uses: ./.github/workflows/set-up-everything 24 | 25 | - name: Run health report script 26 | run: yarn workspace @code-chronicles/generate-health-report start 27 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint PRs 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Check out repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Set up everything 16 | uses: ./.github/workflows/set-up-everything 17 | 18 | - name: Lint 19 | run: yarn lint 20 | # TODO: Annotations of files that fail lint? 21 | # TODO: Maybe write up a job summary per https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary 22 | -------------------------------------------------------------------------------- /.github/workflows/typecheck.yml: -------------------------------------------------------------------------------- 1 | name: Typecheck PRs 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize] 6 | 7 | jobs: 8 | typecheck: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - name: Check out repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Set up everything 16 | uses: ./.github/workflows/set-up-everything 17 | 18 | - name: Typecheck 19 | run: yarn typecheck 20 | # TODO: Annotations of files that fail the typecheck? 21 | # TODO: Maybe write up a job summary per https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log 3 | 4 | .DS_Store 5 | 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/sdks 12 | !.yarn/versions 13 | 14 | .idea 15 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | lint-staged 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore the workspaces directory, it will handle its own formatting. 2 | # See the "format" script in `package.json`. 3 | workspaces/ 4 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["esbenp.prettier-vscode", "mathiasfrohlich.kotlin"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "prettier.prettierPath": "./node_modules/prettier", 4 | "typescript.tsdk": "./node_modules/typescript/lib" 5 | } 6 | -------------------------------------------------------------------------------- /.yarn/patches/@types-chrome-npm-0.0.280-34ee4ba05a.patch: -------------------------------------------------------------------------------- 1 | diff --git a/index.d.ts b/index.d.ts 2 | index e0bdd370b90c09973074493e8ecaf3ae250b562d..a8981b34374e54d9beb588a2eeaaac43803cbe45 100644 3 | --- a/index.d.ts 4 | +++ b/index.d.ts 5 | @@ -5,9 +5,7 @@ 6 | //////////////////// 7 | // Global object 8 | //////////////////// 9 | -interface Window { 10 | - chrome: typeof chrome; 11 | -} 12 | +export type Chrome = typeof chrome; 13 | 14 | //////////////////// 15 | // Accessibility Features 16 | -------------------------------------------------------------------------------- /.yarn/patches/immutability-helper-npm-3.1.1-482f1f8f58.patch: -------------------------------------------------------------------------------- 1 | diff --git a/index.d.ts b/index.d.ts 2 | index 77c12444ac3adf293518e92c07e1680f7d954cb2..8b8da3a4fe0405d81e14998045f8047b1822ac12 100644 3 | --- a/index.d.ts 4 | +++ b/index.d.ts 5 | @@ -11,6 +11,7 @@ export declare const isEquals: any; 6 | export declare const extend: (directive: string, fn: (param: any, old: T) => T) => void; 7 | declare const _default: = never>(object: T, $spec: Spec) => T; 8 | export default _default; 9 | +export = _default; 10 | export declare type CustomCommands = T & { 11 | __noInferenceCustomCommandsBrand: any; 12 | }; 13 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | defaultSemverRangePrefix: "" 2 | enableColors: true 3 | enableConstraintsChecks: true 4 | enableInlineBuilds: true 5 | enableTelemetry: false 6 | nodeLinker: node-modules 7 | tsEnableAutoTypes: true 8 | yarnPath: .yarn/releases/yarn-4.5.1-git.20241025.hash-f59bbf9-code-chronicles-patch.cjs 9 | # TODO: patch Yarn to not add extra newlines to this file 10 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Eli Manzo (github.com/elimanzo) 2 | Elijah Kramer (github.com/BitCrusader) 3 | Ethan Bleier (github.com/ethanbleier) 4 | Jorge A. Martinez (github.com/jmartinez159) 5 | Joshua Lum (github.com/josh-lum) 6 | Michael Volk (github.com/volkmchl) 7 | Miorel-Lucian Palii (github.com/miorel) 8 | Rafael L.S Reis (github.com/Sirraff) 9 | Vighnesh Prabhu (github.com/Kratosmsn11) 10 | Utsav Tayde (github.com/utsavatwork) 11 | Yulianna Khorolich (github.com/yulianka) 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Code Chronicles LeetCode ecosystem 2 | 3 | A collection of packages for LeetCode fun and profit! 4 | 5 | > [!TIP] 6 | > Check out the new [Adventure Pack](https://code-chronicles-code.github.io/leetcode-curriculum/) for some fun goodies you can add to your LeetCode solutions! 7 | 8 | ## Contributing 9 | 10 | It would be wonderful to get to work with you! Learn more in the [Contributing](CONTRIBUTING.md) guide or jump right into the list of [good first issues](../../issues?q=is%3Aopen+is%3Aissue+label%3A"good+first+issue"+no%3Aassignee). 11 | 12 | ## License 13 | 14 | Except where otherwise specified, the contents of this repository is distributed under [the MIT license](LICENSE). 15 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [ 4 | ...config, 5 | { 6 | ignores: [ 7 | // Ignore the workspaces directory, it will handle its own linting. 8 | // See the "lint" script in `package.json`. 9 | "workspaces/", 10 | 11 | // Minified Yarn code! 12 | ".yarn/releases/", 13 | ], 14 | }, 15 | ]; 16 | -------------------------------------------------------------------------------- /lint-staged.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | // TODO: this doesn't quite work, because the `workspaces` directory is 3 | // ignored by Prettier at the top-level... 4 | "*.{graphql,json,md,js,jsx,mjs,ts,tsx,mts}": "prettier --write", 5 | }; 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/.prettierignore: -------------------------------------------------------------------------------- 1 | goodies/java/.gradle/ 2 | goodies/java/build/ 3 | 4 | goodies/kotlin/.gradle/ 5 | goodies/kotlin/.kotlin/ 6 | goodies/kotlin/build/ 7 | 8 | goodies/python3/.pytest_cache/ 9 | goodies/python3/.venv/ 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/README.md: -------------------------------------------------------------------------------- 1 | # Adventure Pack 2 | 3 | ## Pre-requisites: 4 | 5 | - **node**: if you do not have node installed on your machine, you can start by getting [nvm](https://nvm.sh/). 6 | - once you have `nvm`, install `node` with the following command: `nvm install node`. 7 | - **yarn**: execute `corepack enable`, `corepack` comes as part of the `node` installation. 8 | 9 | ## Useful commands: 10 | 11 | Prepare language-specific environment: `yarn goodies::install`. 12 | 13 | Currently available languages: 14 | 15 | - java 16 | - kotlin 17 | - python3 18 | - typescript 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [ 4 | ...config, 5 | { 6 | ignores: ["dist/", "goodies/java/build/", "goodies/kotlin/build/"], 7 | }, 8 | ]; 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle/ 3 | 4 | # Ignore Gradle build output directory 5 | build/ 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/gradle.properties: -------------------------------------------------------------------------------- 1 | # This file was generated by the Gradle 'init' task. 2 | # https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties 3 | 4 | org.gradle.parallel=true 5 | org.gradle.caching=true 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | # This file was generated by the Gradle 'init' task. 2 | # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format 3 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-chronicles-code/leetcode-curriculum/f661d198912879608ba66aa0848efcea04ce6896/workspaces/adventure-pack/goodies/java/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.8/userguide/multi_project_builds.html in the Gradle documentation. 6 | * This project uses @Incubating APIs which are subject to change. 7 | */ 8 | 9 | rootProject.name = "adventure-pack" 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/digits_int/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "digits(int)" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/gcd_int_int/AP.java: -------------------------------------------------------------------------------- 1 | package gcd_int_int; 2 | 3 | public final class AP { 4 | 5 | public static int gcd(int a, int b) { 6 | if (a < 0 || b < 0) { 7 | throw new IllegalArgumentException( 8 | "Can only find the GCD of non-negative integers!" 9 | ); 10 | } 11 | 12 | while (b != 0) { 13 | int tmp = b; 14 | b = a % b; 15 | a = tmp; 16 | } 17 | 18 | return a; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/gcd_int_int/Test.java: -------------------------------------------------------------------------------- 1 | package gcd_int_int; 2 | 3 | import static gcd_int_int.AP.gcd; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | class GcdTest { 9 | 10 | @Test 11 | public void findsTheGcd() { 12 | assertEquals(3, gcd(9, 12)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/gcd_int_int/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gcd(int,int)" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/iterable_double_stream/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IterableDoubleStream" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/iterable_int_stream/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IterableIntStream" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/iterable_long_stream/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IterableLongStream" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/iterable_stream/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "IterableStream" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/lcm_int_int/AP.java: -------------------------------------------------------------------------------- 1 | package lcm_int_int; 2 | 3 | import static gcd_int_int.AP.*; 4 | 5 | public final class AP { 6 | 7 | public static int lcm(int a, int b) { 8 | return (a / gcd(a, b)) * b; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/lcm_int_int/Test.java: -------------------------------------------------------------------------------- 1 | package lcm_int_int; 2 | 3 | import static lcm_int_int.AP.lcm; 4 | import static org.junit.jupiter.api.Assertions.assertEquals; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | class LcmTest { 9 | 10 | @Test 11 | public void findsTheLcm() { 12 | assertEquals(12, lcm(6, 4)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/lcm_int_int/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lcm(int,int)" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/pair/Pair.java: -------------------------------------------------------------------------------- 1 | package pair; 2 | 3 | public record Pair(TFirst first, TSecond second) {} 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/pair/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Pair" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/primes/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "primes()" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/simple_iterator/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SimpleIterator" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/traverse_in_order/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverseInOrder()" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/traverse_post_order/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traversePostOrder()" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/traverse_pre_order/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traversePreOrder()" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/union_find/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UnionFind" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/virtual_list/VirtualList.java: -------------------------------------------------------------------------------- 1 | package virtual_list; 2 | 3 | import java.util.AbstractList; 4 | import java.util.function.IntFunction; 5 | 6 | public final class VirtualList extends AbstractList { 7 | 8 | private final int size; 9 | private final IntFunction getter; 10 | 11 | public VirtualList(int size, IntFunction getter) { 12 | this.getter = getter; 13 | this.size = size; 14 | } 15 | 16 | public T get(int index) { 17 | if (index < 0 || index >= this.size) { 18 | throw new IndexOutOfBoundsException(); 19 | } 20 | return this.getter.apply(index); 21 | } 22 | 23 | public int size() { 24 | return this.size; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/java/src/virtual_list/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "VirtualList" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore Gradle project-specific cache directory 2 | .gradle/ 3 | 4 | # Ignore Gradle build output directory 5 | build/ 6 | 7 | # Ignore Kotlin Gradle plugin persistent project-specific data 8 | # See: https://kotlinlang.org/docs/gradle-configure-project.html#kotlin-gradle-plugin-data-in-a-project 9 | .kotlin/ 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/gradle.properties: -------------------------------------------------------------------------------- 1 | # This file was generated by the Gradle 'init' task. 2 | # https://docs.gradle.org/current/userguide/build_environment.html#sec:gradle_configuration_properties 3 | 4 | org.gradle.parallel=true 5 | org.gradle.caching=true 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | # This file was generated by the Gradle 'init' task. 2 | # https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format 3 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/code-chronicles-code/leetcode-curriculum/f661d198912879608ba66aa0848efcea04ce6896/workspaces/adventure-pack/goodies/kotlin/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * For more detailed information on multi-project builds, please refer to https://docs.gradle.org/8.8/userguide/multi_project_builds.html in the Gradle documentation. 6 | * This project uses @Incubating APIs which are subject to change. 7 | */ 8 | 9 | rootProject.name = "adventure-pack" 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/gcd_int_int/Main.kt: -------------------------------------------------------------------------------- 1 | package gcd_int_int 2 | 3 | public fun gcd(a: Int, b: Int): Int { 4 | var mutableA = a 5 | var mutableB = b 6 | 7 | while (mutableB != 0) { 8 | mutableB = (mutableA % mutableB).also { mutableA = mutableB } 9 | } 10 | 11 | return mutableA 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/gcd_int_int/Test.kt: -------------------------------------------------------------------------------- 1 | package gcd_int_int 2 | 3 | import kotlin.test.* 4 | 5 | internal class GcdTest { 6 | @Test 7 | fun findsTheGcd() { 8 | assertEquals(3, gcd(9, 12), "gcd(9, 12) == 3") 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/gcd_int_int/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gcd(Int,Int)" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/lcm_int_int/Main.kt: -------------------------------------------------------------------------------- 1 | package lcm_int_int 2 | 3 | import gcd_int_int.gcd 4 | 5 | public fun lcm(a: Int, b: Int): Int = a / gcd(a, b) * b 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/lcm_int_int/Test.kt: -------------------------------------------------------------------------------- 1 | package lcm_int_int 2 | 3 | import kotlin.test.* 4 | 5 | internal class LcmTest { 6 | @Test 7 | fun findsTheLcm() { 8 | assertEquals(12, lcm(6, 4), "lcm(6, 4) == 12") 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/lcm_int_int/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lcm(Int,Int)" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/traverse_level_order/Main.kt: -------------------------------------------------------------------------------- 1 | package traverse_level_order 2 | 3 | public data class TreeNode(val `val`: Int, var left: TreeNode? = null, var right: TreeNode? = null) 4 | 5 | public fun TreeNode?.traverseLevelOrder(): Sequence> { 6 | if (this == null) { 7 | return sequenceOf() 8 | } 9 | 10 | var nodesAtLevel = listOf(this) 11 | 12 | return sequence { 13 | do { 14 | yield(nodesAtLevel) 15 | 16 | nodesAtLevel = nodesAtLevel.flatMap { listOf(it.left, it.right) }.filterNotNull() 17 | } while (nodesAtLevel.isNotEmpty()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/kotlin/src/traverse_level_order/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverseLevelOrder()" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/.gitignore: -------------------------------------------------------------------------------- 1 | **/__pycache__/ 2 | .pytest_cache/ 3 | .venv/ 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/format.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Change directory to the directory of the script. 6 | cd "$(dirname "$0")" 7 | 8 | # Activate Python virtual environment. 9 | if [ -f .venv/bin/activate ]; then 10 | source .venv/bin/activate 11 | elif [ -f .venv/Scripts/activate ]; then 12 | source .venv/Scripts/activate 13 | else 14 | echo "Error: Could not activate the Python virtual environment." >&2 15 | exit 1 16 | fi 17 | 18 | bash run_python.sh -m black --color --line-length=80 . 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Change directory to the directory of the script. 6 | cd "$(dirname "$0")" 7 | 8 | # Prepare Python virtual environment. 9 | bash run_python.sh -m venv .venv 10 | 11 | # Activate Python virtual environment. 12 | if [ -f .venv/bin/activate ]; then 13 | source .venv/bin/activate 14 | elif [ -f .venv/Scripts/activate ]; then 15 | source .venv/Scripts/activate 16 | else 17 | echo "Error: Could not activate the Python virtual environment." >&2 18 | exit 1 19 | fi 20 | 21 | bash run_python.sh -m pip install -r requirements.txt 22 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | python_files = test.py 3 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/requirements.txt: -------------------------------------------------------------------------------- 1 | black==24.4.2 2 | pytest==8.2.2 3 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/run_python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | check_if_python3() { 6 | local python_cmd="$1" 7 | command -v "$python_cmd" >& /dev/null && "$python_cmd" -c 'import sys; sys.exit(0 if tuple(sys.version_info) >= (3,) else 1)' 8 | } 9 | 10 | if check_if_python3 python3; then 11 | python3 "$@" 12 | elif check_if_python3 python; then 13 | python "$@" 14 | else 15 | echo "Error: Did not find a \`python3\` or \`python\` command that's Python 3." >&2 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/flatten/__init__.py: -------------------------------------------------------------------------------- 1 | from typing import Generator, TypeVar 2 | 3 | T = TypeVar("T") 4 | NestedList = T | list["NestedList"] 5 | 6 | 7 | def flatten(self: NestedList) -> Generator[T, None, None]: 8 | for i in self: 9 | if isinstance(i, list): 10 | yield from flatten(i) 11 | else: 12 | yield i 13 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/flatten/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flatten" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/flatten/test.py: -------------------------------------------------------------------------------- 1 | from . import * 2 | 3 | 4 | def test_flatten(): 5 | input_ = [[3, 1, 4, 1], [[5, 9, [2, 6]], [5, 3, 5]], 8, 9] 6 | expected = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9] 7 | flattened = list(flatten(input_)) 8 | assert expected == flattened 9 | 10 | 11 | def test_flatten_random_types(): 12 | dictionary = {"something": "something_else"} 13 | l = [["hi", -80, "c", 0.0], [[(3, 3), dictionary, 6], [5, 4, 3]], 2, 1, 0] 14 | flattened = list(flatten(l)) 15 | expected = ["hi", -80, "c", 0.0, (3, 3), dictionary, 6, 5, 4, 3, 2, 1, 0] 16 | assert flattened == expected 17 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/int_digits/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "int.digits" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/is_palindrome/__init__.py: -------------------------------------------------------------------------------- 1 | def is_palindrome(sequence: list | str) -> bool: 2 | left: int = 0 3 | right: int = len(sequence) - 1 4 | while left < right: 5 | if sequence[left] != sequence[right]: 6 | return False 7 | left += 1 8 | right -= 1 9 | return True 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/is_palindrome/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "is_palindrome" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/transpose_matrix/__init__.py: -------------------------------------------------------------------------------- 1 | from typing import TypeVar 2 | 3 | T = TypeVar("T") 4 | 5 | 6 | def transpose_matrix(input: list[list[T]]) -> list[list[T]]: 7 | r = len(input) 8 | c = len(input[0]) if r != 0 else 0 9 | if r == 0 or c == 0: 10 | raise ValueError("Can't transpose a matrix that has a 0 dimension!") 11 | if any(len(row) != c for row in input): 12 | raise ValueError("Matrix has rows of different lengths!") 13 | 14 | return [list(row) for row in zip(*input)] 15 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/transpose_matrix/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "transpose_matrix" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/traverse_inorder/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverse_inorder" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/traverse_level_order/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverse_level_order" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/traverse_postorder/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverse_postorder" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/traverse_postorder_n_ary/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverse_postorder_n_ary" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/traverse_preorder/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "traverse_preorder" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/src/union_find/goody.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "UnionFind" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/python3/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | 5 | # Change directory to the directory of the script. 6 | cd "$(dirname "$0")" 7 | 8 | # Activate Python virtual environment. 9 | if [ -f .venv/bin/activate ]; then 10 | source .venv/bin/activate 11 | elif [ -f .venv/Scripts/activate ]; then 12 | source .venv/Scripts/activate 13 | else 14 | echo "Error: Could not activate the Python virtual environment." >&2 15 | exit 1 16 | fi 17 | 18 | bash run_python.sh -m pytest --color=yes 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Array.prototype.slidingWindows/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | 3 | import "./index.ts"; 4 | 5 | describe("Array.prototype.slidingWindows", () => { 6 | it("can slide over an array", () => { 7 | const windows = [3, 1, 4, 1, 5, 9].slidingWindows(2); 8 | 9 | expect([...windows.next().value!]).toStrictEqual([3, 1]); 10 | expect([...windows.next().value!]).toStrictEqual([1, 4]); 11 | expect([...windows.next().value!]).toStrictEqual([4, 1]); 12 | expect([...windows.next().value!]).toStrictEqual([1, 5]); 13 | expect([...windows.next().value!]).toStrictEqual([5, 9]); 14 | }); 15 | 16 | // TODO: add more tests! 17 | }); 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Array.prototype.swap/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Array { 3 | swap(this: T[], i: number, j: number): void; 4 | } 5 | } 6 | 7 | Array.prototype.swap = function (this: T[], i: number, j: number): void { 8 | const tmp = this[i]; 9 | this[i] = this[j]; 10 | this[j] = tmp; 11 | }; 12 | 13 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 14 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 15 | export {}; 16 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Function.returnThis/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface FunctionConstructor { 3 | returnThis(this: T): T; 4 | } 5 | } 6 | 7 | Function.returnThis = function (this: T): T { 8 | return this; 9 | }; 10 | 11 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 12 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 13 | export {}; 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.forEach/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | interface Iterator { 6 | forEach( 7 | this: Iterator, 8 | callbackFn: (element: T, index: number) => void, 9 | ): void; 10 | } 11 | } 12 | 13 | iteratorPrototype.forEach ??= function ( 14 | this: Iterator, 15 | callbackFn: (element: T, index: number) => void, 16 | ): void { 17 | let index = 0; 18 | for (const element of this.toIterable()) { 19 | callbackFn(element, index); 20 | ++index; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.product/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 6 | interface Iterator { 7 | product(this: Iterator): number; 8 | } 9 | } 10 | 11 | iteratorPrototype.product = function (this: Iterator): number { 12 | let res = 1; 13 | for (const element of this.toIterable()) { 14 | res *= element; 15 | } 16 | 17 | return res; 18 | }; 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.sum/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 6 | interface Iterator { 7 | sum(this: Iterator): number; 8 | } 9 | } 10 | 11 | iteratorPrototype.sum = function (this: Iterator): number { 12 | let res = 0; 13 | for (const element of this.toIterable()) { 14 | res += element; 15 | } 16 | return res; 17 | }; 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.tally/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | interface Iterator { 6 | tally(this: Iterator): Map; 7 | } 8 | } 9 | 10 | iteratorPrototype.tally = function (this: Iterator): Map { 11 | const tally = new Map(); 12 | 13 | for (const element of this.toIterable()) { 14 | tally.set(element, (tally.get(element) ?? 0) + 1); 15 | } 16 | 17 | return tally; 18 | }; 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.toArray/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | interface Iterator { 6 | toArray(this: Iterator): T[]; 7 | } 8 | } 9 | 10 | iteratorPrototype.toArray ??= function (this: Iterator): T[] { 11 | return [...this.toIterable()]; 12 | }; 13 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.toIterable/index.ts: -------------------------------------------------------------------------------- 1 | import "../Function.returnThis/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | interface Iterator { 6 | toIterable(this: Iterator): IterableIterator; 7 | } 8 | } 9 | 10 | iteratorPrototype.toIterable = function ( 11 | this: Iterator, 12 | ): IterableIterator { 13 | (this as unknown as Record)[Symbol.iterator] ??= 14 | Function.returnThis; 15 | return this as unknown as IterableIterator; 16 | }; 17 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype.toSet/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.toIterable/index.ts"; 2 | import { iteratorPrototype } from "../Iterator.prototype/index.ts"; 3 | 4 | declare global { 5 | interface Iterator { 6 | toSet(this: Iterator): Set; 7 | } 8 | } 9 | 10 | iteratorPrototype.toSet ??= function (this: Iterator): Set { 11 | return new Set(this.toIterable()); 12 | }; 13 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Iterator.prototype/index.ts: -------------------------------------------------------------------------------- 1 | export const iteratorPrototype = Object.getPrototypeOf( 2 | Object.getPrototypeOf([].values()), 3 | ) as Iterator; 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Math.gcd/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | 3 | import "./index.ts"; 4 | 5 | describe("Math.gcd", () => { 6 | it.each([ 7 | [48, 18, 6], 8 | [17, 13, 1], 9 | [36, 60, 12], 10 | [5, 0, 5], 11 | [0, 5, 5], 12 | [-5, 10, 5], 13 | [-7, 3, 1], 14 | [-8, -12, 4], 15 | [0, 0, 0], 16 | [1000000007, 1000000009, 1], 17 | [1000000007, 2, 1], 18 | [2000000014, 1000000007, 1000000007], 19 | [1000000007, 7000000049, 1000000007], 20 | [1000000007, 2, 1], 21 | ])("Math.gcd(%p, %p) === %p", (a, b, expected) => { 22 | expect(Math.gcd(a, b)).toBe(expected); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Math.gcd/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Math { 3 | gcd(a: number, b: number): number; 4 | } 5 | } 6 | 7 | Math.gcd = function (a: number, b: number): number { 8 | a = Math.abs(a); 9 | b = Math.abs(b); 10 | 11 | while (b !== 0) { 12 | const temp = b; 13 | b = a % b; 14 | a = temp; 15 | } 16 | return a; 17 | }; 18 | 19 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 20 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 21 | export {}; 22 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Math.lcm/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | 3 | import "./index.ts"; 4 | 5 | describe("Math.lcm", () => { 6 | it.each([ 7 | [4, 5, 20], 8 | [6, 8, 24], 9 | [21, 6, 42], 10 | [13, 17, 221], 11 | [0, 5, 0], 12 | [5, 0, 0], 13 | [0, 0, 0], 14 | [-5, 15, 15], 15 | [7, -3, 21], 16 | [-6, -8, 24], 17 | [2, 1000000007, 2000000014], 18 | [9999991, 99999959, 999998690000369], 19 | [123456, 789012, 8117355456], 20 | [15, 25, 75], 21 | ])("Math.lcm(%p, %p) === %p", (a, b, expected) => { 22 | expect(Math.lcm(a, b)).toBe(expected); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Math.lcm/index.ts: -------------------------------------------------------------------------------- 1 | import "../Math.gcd/index.ts"; 2 | 3 | declare global { 4 | interface Math { 5 | lcm(a: number, b: number): number; 6 | } 7 | } 8 | 9 | Math.lcm = function (a: number, b: number): number { 10 | if (a === 0 || b === 0) { 11 | return 0; 12 | } 13 | 14 | a = Math.abs(a); 15 | b = Math.abs(b); 16 | return (a / Math.gcd(a, b)) * b; 17 | }; 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Number.prototype.chr/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Number { 3 | chr(this: Number): string; 4 | } 5 | } 6 | 7 | Number.prototype.chr = function (this: Number): string { 8 | return String.fromCodePoint(Number(this)); 9 | }; 10 | 11 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 12 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 13 | export {}; 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Number.prototype.positiveMod/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Number { 3 | positiveMod(this: Number, modulo: number): number; 4 | } 5 | } 6 | 7 | Number.prototype.positiveMod = function (this: Number, modulo: number): number { 8 | return ((Number(this) % modulo) + Math.abs(modulo)) % modulo; 9 | }; 10 | 11 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 12 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 13 | export {}; 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Object.prototype.entries/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.map/index.ts"; 2 | import "../Object.prototype.keys/index.ts"; 3 | 4 | declare global { 5 | interface Object { 6 | entries( 7 | this: T, 8 | ): Generator<{ [K in keyof T]: [K, T[K]] }[keyof T], void, void>; 9 | } 10 | } 11 | 12 | Object.prototype.entries = function ( 13 | this: T, 14 | ): Generator<{ [K in keyof T]: [K, T[K]] }[keyof T], void, void> { 15 | return this.keys().map((k) => [k, this[k]]); 16 | }; 17 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/Object.prototype.values/index.ts: -------------------------------------------------------------------------------- 1 | import "../Iterator.prototype.map/index.ts"; 2 | import "../Object.prototype.keys/index.ts"; 3 | 4 | declare global { 5 | interface Object { 6 | values(this: T): Generator; 7 | } 8 | } 9 | 10 | Object.prototype.values = function ( 11 | this: T, 12 | ): Generator { 13 | return this.keys().map((k) => this[k]); 14 | }; 15 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/String.prototype.caesar/index.ts: -------------------------------------------------------------------------------- 1 | import "../Number.prototype.chr/index.ts"; 2 | import "../Number.prototype.positiveMod/index.ts"; 3 | import "../String.prototype.ord/index.ts"; 4 | 5 | declare global { 6 | interface String { 7 | caesar(this: String): string; 8 | caesar(this: String, delta: number): string; 9 | } 10 | } 11 | 12 | String.prototype.caesar = function (this: String, delta: number = 1): string { 13 | return this.replaceAll(/[a-z]/gi, (letter: string) => { 14 | const offset = (letter >= "A" && letter <= "Z" ? "A" : "a").ord(); 15 | return ((letter.ord() - offset + delta).positiveMod(26) + offset).chr(); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/String.prototype.chars/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from "@jest/globals"; 2 | 3 | import "./index.ts"; 4 | 5 | describe("String.prototype.chars", () => { 6 | it("can iterate over a string's characters", () => { 7 | const iterator = "bonjour".chars(); 8 | 9 | expect(iterator.next().value).toBe("b"); 10 | expect(iterator.next().value).toBe("o"); 11 | expect(iterator.next().value).toBe("n"); 12 | expect(iterator.next().value).toBe("j"); 13 | expect(iterator.next().value).toBe("o"); 14 | expect(iterator.next().value).toBe("u"); 15 | expect(iterator.next().value).toBe("r"); 16 | expect(iterator.next().done).toBe(true); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/String.prototype.chars/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface String { 3 | chars(this: String): IterableIterator; 4 | } 5 | } 6 | 7 | String.prototype.chars = String.prototype[Symbol.iterator]; 8 | 9 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 10 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 11 | export {}; 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/String.prototype.ord/index.ts: -------------------------------------------------------------------------------- 1 | import { nullthrows } from "../nullthrows/index.ts"; 2 | 3 | declare global { 4 | interface String { 5 | ord(this: String): number; 6 | } 7 | } 8 | 9 | String.prototype.ord = function (this: String): number { 10 | return nullthrows(this.codePointAt(0)); 11 | }; 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/console.meow/index.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Console { 3 | meow: Console["log"]; 4 | } 5 | } 6 | 7 | console.meow = function () { 8 | console.log.call(this, "😺", ...arguments); 9 | }; 10 | 11 | // Needed to fix the error "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations. ts(2669)" 12 | // See: https://stackoverflow.com/questions/57132428/augmentations-for-the-global-scope-can-only-be-directly-nested-in-external-modul 13 | export {}; 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/invariant/index.ts: -------------------------------------------------------------------------------- 1 | export function invariant( 2 | condition: boolean, 3 | errorMessage: string = "Invariant violation!", 4 | ): asserts condition { 5 | if (!condition) { 6 | throw new Error(errorMessage); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/invariantViolation/index.ts: -------------------------------------------------------------------------------- 1 | import { invariant } from "../invariant/index.ts"; 2 | 3 | export function invariantViolation(errorMessage?: string): never { 4 | invariant(false, errorMessage); 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/isNonNullish/index.ts: -------------------------------------------------------------------------------- 1 | export function isNonNullish(value: T | null | undefined): value is T { 2 | return value != null; 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/nullthrows/index.ts: -------------------------------------------------------------------------------- 1 | export function nullthrows( 2 | value: T | null | undefined, 3 | errorMessage: string = "Unexpected nullish value!", 4 | ): NonNullable { 5 | if (value == null) { 6 | throw new Error(errorMessage); 7 | } 8 | return value; 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/traverseInOrder/index.ts: -------------------------------------------------------------------------------- 1 | export function* traverseInOrder< 2 | T extends { left?: T | null | undefined; right?: T | null | undefined }, 3 | >(root: T | null | undefined): Generator { 4 | const stack: [T | null | undefined, boolean][] = [[root, false]]; 5 | 6 | do { 7 | const [node, didTraverseLeftChild] = stack.pop()!; 8 | if (node == null) { 9 | continue; 10 | } 11 | 12 | if (didTraverseLeftChild) { 13 | yield node; 14 | continue; 15 | } 16 | 17 | stack.push([node.right, false], [node, true], [node.left, false]); 18 | } while (stack.length > 0); 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/traverseLevelOrder/index.ts: -------------------------------------------------------------------------------- 1 | import { isNonNullish } from "../isNonNullish/index.ts"; 2 | 3 | export function* traverseLevelOrder< 4 | T extends { left?: T | null | undefined; right?: T | null | undefined }, 5 | >(root: T | null | undefined): Generator { 6 | if (root == null) { 7 | return; 8 | } 9 | 10 | let level = [root]; 11 | do { 12 | yield level; 13 | 14 | level = level 15 | .flatMap((node) => [node.left, node.right]) 16 | .filter(isNonNullish); 17 | } while (level.length > 0); 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/traversePostOrder/index.ts: -------------------------------------------------------------------------------- 1 | export function* traversePostOrder< 2 | T extends { left?: T | null | undefined; right?: T | null | undefined }, 3 | >(root: T | null | undefined): Generator { 4 | const stack: [T | null | undefined, boolean][] = [[root, false]]; 5 | 6 | do { 7 | const [node, didTraverseChildren] = stack.pop()!; 8 | if (node == null) { 9 | continue; 10 | } 11 | 12 | if (didTraverseChildren) { 13 | yield node; 14 | continue; 15 | } 16 | 17 | stack.push([node, true], [node.right, false], [node.left, false]); 18 | } while (stack.length > 0); 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/goodies/typescript/traversePreOrder/index.ts: -------------------------------------------------------------------------------- 1 | export function* traversePreOrder< 2 | T extends { left?: T | null | undefined; right?: T | null | undefined }, 3 | >(root: T | null | undefined): Generator { 4 | const stack = [root]; 5 | 6 | do { 7 | const node = stack.pop(); 8 | 9 | if (node != null) { 10 | yield node; 11 | stack.push(node.right, node.left); 12 | } 13 | } while (stack.length > 0); 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/prettier.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: ["prettier-plugin-java"], 3 | }; 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/Goody.ts: -------------------------------------------------------------------------------- 1 | import type { JavaGoody } from "./zod-types/javaGoodyZodType.ts"; 2 | import type { JavaScriptGoody } from "./zod-types/javaScriptGoodyZodType.ts"; 3 | import type { KotlinGoody } from "./zod-types/kotlinGoodyZodType.ts"; 4 | import type { Python3Goody } from "./zod-types/python3GoodyZodType.ts"; 5 | import type { TypeScriptGoody } from "./zod-types/typeScriptGoodyZodType.ts"; 6 | 7 | export type Goody = 8 | | JavaGoody 9 | | JavaScriptGoody 10 | | KotlinGoody 11 | | Python3Goody 12 | | TypeScriptGoody; 13 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/Language.ts: -------------------------------------------------------------------------------- 1 | import type { Goody } from "./Goody.ts"; 2 | 3 | export type Language = Goody["language"]; 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/components/Checkbox.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export function Checkbox({ 4 | children, 5 | isChecked, 6 | onChange, 7 | }: { 8 | children: React.ReactNode; 9 | isChecked: boolean; 10 | onChange: () => void; 11 | }) { 12 | return ( 13 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/components/GoodyCard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import type { Goody } from "../Goody.ts"; 4 | import { stringifyGoody } from "../stringifyGoody.ts"; 5 | import { HighlightedCode } from "./HighlightedCode.tsx"; 6 | 7 | type Props = { 8 | goody: Goody; 9 | }; 10 | 11 | export function GoodyCard({ goody }: Props) { 12 | return ( 13 |
14 |

{goody.name}

15 | 16 | {stringifyGoody(goody)} 17 | 18 |
19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/constants.ts: -------------------------------------------------------------------------------- 1 | import type { Language } from "./Language.ts"; 2 | 3 | export const GOODIES_FILENAME = "goodies.json"; 4 | 5 | export const LANGUAGE_NAMES: Record = { 6 | java: "Java", 7 | javascript: "JavaScript", 8 | kotlin: "Kotlin", 9 | python3: "Python 3", 10 | typescript: "TypeScript", 11 | }; 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/main.tsx: -------------------------------------------------------------------------------- 1 | import nullthrows from "nullthrows"; 2 | import React from "react"; 3 | import ReactDOM from "react-dom/client"; 4 | 5 | import { App } from "./components/App.tsx"; 6 | 7 | declare const ADVENTURE_PACK_COMMIT_HASH: string; 8 | 9 | window.addEventListener( 10 | "load", 11 | () => { 12 | ReactDOM.createRoot( 13 | nullthrows( 14 | document.getElementById("main"), 15 | 'No element with id "main" in the DOM!', 16 | ), 17 | ).render(); 18 | }, 19 | { once: true }, 20 | ); 21 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/stringifyTypeScriptInterfaceDeclarations.ts: -------------------------------------------------------------------------------- 1 | import type { ReadonlyDeep } from "type-fest"; 2 | 3 | export function stringifyTypeScriptInterfaceDeclarations( 4 | interfaceDeclarations: ReadonlyDeep>, 5 | { indent = "" }: { indent?: string } = {}, 6 | ): string { 7 | return Object.entries(interfaceDeclarations) 8 | .map( 9 | ([interfaceName, codeSections]) => 10 | `${indent}interface ${interfaceName} {\n${codeSections.join("\n\n")}\n${indent}}`, 11 | ) 12 | .join("\n\n"); 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/zod-types/goodyBaseZodType.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | import { nonBlankStringZodType } from "@code-chronicles/util/zod-types/nonBlankStringZodType"; 4 | 5 | export const goodyBaseZodType = z.object({ 6 | importedBy: z.array(nonBlankStringZodType), 7 | imports: z.array(nonBlankStringZodType), 8 | name: nonBlankStringZodType, 9 | }); 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/zod-types/javaScriptGoodyZodType.ts: -------------------------------------------------------------------------------- 1 | import type { ReadonlyDeep } from "type-fest"; 2 | import { z } from "zod"; 3 | 4 | import { nonBlankStringZodType } from "@code-chronicles/util/zod-types/nonBlankStringZodType"; 5 | 6 | import { goodyBaseZodType } from "./goodyBaseZodType.ts"; 7 | 8 | export const javaScriptGoodyZodType = goodyBaseZodType 9 | .extend({ 10 | code: nonBlankStringZodType, 11 | language: z.literal("javascript"), 12 | }) 13 | .strict(); 14 | 15 | export type JavaScriptGoody = ReadonlyDeep< 16 | z.infer 17 | >; 18 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/app/zod-types/python3GoodyZodType.ts: -------------------------------------------------------------------------------- 1 | import type { ReadonlyDeep } from "type-fest"; 2 | import { z } from "zod"; 3 | 4 | import { nonBlankStringZodType } from "@code-chronicles/util/zod-types/nonBlankStringZodType"; 5 | 6 | import { goodyBaseZodType } from "./goodyBaseZodType.ts"; 7 | 8 | export const python3GoodyZodType = goodyBaseZodType 9 | .extend({ 10 | code: nonBlankStringZodType, 11 | language: z.literal("python3"), 12 | }) 13 | .strict(); 14 | 15 | export type Python3Goody = ReadonlyDeep>; 16 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/build/constants.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | export const CHROME_EXTENSION_DIST = path.resolve("dist", "chrome-extension"); 4 | export const WEB_APP_DIST = path.resolve("dist", "web-app"); 5 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/java/constants.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | export const GOODIES_DIRECTORY = path.join("goodies", "java", "src"); 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/java/readMetadata.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | import path from "node:path"; 3 | 4 | import { z } from "zod"; 5 | 6 | import { GOODIES_DIRECTORY } from "./constants.ts"; 7 | 8 | const metadataZodType = z 9 | .object({ 10 | name: z.string().regex(/^\S/).regex(/\S$/), 11 | }) 12 | .strict(); 13 | 14 | type Metadata = z.infer; 15 | 16 | export async function readMetadata(packageName: string): Promise { 17 | const text = await fsPromises.readFile( 18 | path.join(GOODIES_DIRECTORY, packageName, "goody.json"), 19 | "utf8", 20 | ); 21 | 22 | return metadataZodType.parse(JSON.parse(text)); 23 | } 24 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/kotlin/constants.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | export const GOODIES_DIRECTORY = path.join("goodies", "kotlin", "src"); 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/kotlin/readCode.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | import path from "node:path"; 3 | 4 | import { GOODIES_DIRECTORY } from "./constants.ts"; 5 | 6 | export function readCode(packageName: string): Promise { 7 | return fsPromises.readFile( 8 | path.join(GOODIES_DIRECTORY, packageName, "Main.kt"), 9 | "utf8", 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/kotlin/readMetadata.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | import path from "node:path"; 3 | 4 | import { z } from "zod"; 5 | 6 | import { GOODIES_DIRECTORY } from "./constants.ts"; 7 | 8 | const metadataZodType = z 9 | .object({ 10 | name: z.string().regex(/^\S/).regex(/\S$/), 11 | }) 12 | .strict(); 13 | 14 | type Metadata = z.infer; 15 | 16 | export async function readMetadata(packageName: string): Promise { 17 | const text = await fsPromises.readFile( 18 | path.join(GOODIES_DIRECTORY, packageName, "goody.json"), 19 | "utf8", 20 | ); 21 | 22 | return metadataZodType.parse(JSON.parse(text)); 23 | } 24 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/normalizeGoodyNameToPackageOrModuleName.ts: -------------------------------------------------------------------------------- 1 | export function normalizeGoodyNameToPackageOrModuleName( 2 | goodyName: string, 3 | ): string { 4 | return goodyName 5 | .replace(/[A-Z]+/g, ([upper]) => "_" + upper.toLowerCase()) 6 | .replace(/[^a-z0-9]+/gi, "_") 7 | .replace(/_$/, "") 8 | .replace(/^_/, ""); 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/python3/constants.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | export const GOODIES_DIRECTORY = path.join("goodies", "python3", "src"); 4 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/python3/readCode.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | import path from "node:path"; 3 | 4 | import { GOODIES_DIRECTORY } from "./constants.ts"; 5 | 6 | export function readCode(moduleName: string): Promise { 7 | return fsPromises.readFile( 8 | path.join(GOODIES_DIRECTORY, moduleName, "__init__.py"), 9 | "utf8", 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/python3/readMetadata.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | import path from "node:path"; 3 | 4 | import { z } from "zod"; 5 | 6 | import { GOODIES_DIRECTORY } from "./constants.ts"; 7 | 8 | const metadataZodType = z 9 | .object({ 10 | name: z.string().regex(/^\S/).regex(/\S$/), 11 | }) 12 | .strict(); 13 | 14 | type Metadata = z.infer; 15 | 16 | export async function readMetadata(packageName: string): Promise { 17 | const text = await fsPromises.readFile( 18 | path.join(GOODIES_DIRECTORY, packageName, "goody.json"), 19 | "utf8", 20 | ); 21 | 22 | return metadataZodType.parse(JSON.parse(text)); 23 | } 24 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/createSourceFile.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Project as TSProject, 3 | type SourceFile as TSSourceFile, 4 | } from "ts-morph"; 5 | 6 | export function createSourceFile(code: string): TSSourceFile { 7 | return new TSProject({ useInMemoryFileSystem: true }).createSourceFile( 8 | "not/a/real/file", 9 | code, 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/extractImports.ts: -------------------------------------------------------------------------------- 1 | import type { SourceFile as TSSourceFile } from "ts-morph"; 2 | 3 | import { removeNode } from "./removeNode.ts"; 4 | 5 | export function extractImports(sourceFile: TSSourceFile): Set { 6 | const imports = new Set(); 7 | for (const decl of sourceFile.getImportDeclarations()) { 8 | imports.add(decl.getModuleSpecifierValue()); 9 | removeNode(decl, { preserveTrivia: true }); 10 | } 11 | 12 | return imports; 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/formatCode.ts: -------------------------------------------------------------------------------- 1 | import prettier from "prettier"; 2 | 3 | export function formatCode(code: string): Promise { 4 | return prettier.format(code, { parser: "typescript" }); 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/getCodeAt.ts: -------------------------------------------------------------------------------- 1 | import type { SourceFile as TSSourceFile } from "ts-morph"; 2 | 3 | export function getCodeAt( 4 | sourceFile: TSSourceFile, 5 | range: readonly [number, number], 6 | ): string { 7 | return sourceFile.getFullText().slice(...range); 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/getLeadingTriviaRange.ts: -------------------------------------------------------------------------------- 1 | import type { Node as TSNode } from "ts-morph"; 2 | 3 | export function getLeadingTriviaRange(node: TSNode): [number, number] { 4 | return [node.getPos(), node.getPos() + node.getLeadingTriviaWidth()]; 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/getTrailingTriviaRange.ts: -------------------------------------------------------------------------------- 1 | import type { Node as TSNode } from "ts-morph"; 2 | 3 | export function getTrailingTriviaRange(node: TSNode): [number, number] { 4 | return [ 5 | node.getPos() + node.getFullWidth(), 6 | node.getPos() + node.getFullWidth() + node.getTrailingTriviaWidth(), 7 | ]; 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/src/scripts/package-goodies/typescript/removeNode.ts: -------------------------------------------------------------------------------- 1 | import type { Node as TSNode } from "ts-morph"; 2 | 3 | import { stripSuffixOrThrow } from "@code-chronicles/util/stripSuffixOrThrow"; 4 | 5 | export function removeNode( 6 | node: TSNode, 7 | { preserveTrivia = true }: { preserveTrivia?: boolean } = {}, 8 | ): void { 9 | if (preserveTrivia) { 10 | node.replaceWithText( 11 | stripSuffixOrThrow(node.getText(true), node.getText(false)), 12 | ); 13 | } else { 14 | node 15 | .getSourceFile() 16 | .replaceText([node.getPos(), node.getPos() + node.getFullWidth()], ""); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/adventure-pack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/archive/.gitattributes: -------------------------------------------------------------------------------- 1 | problems.jsonl linguist-generated 2 | -------------------------------------------------------------------------------- /workspaces/archive/general-code-review.md: -------------------------------------------------------------------------------- 1 | # General Code Review 2 | 3 | * Variables / Operations 4 | * Clear and concise variable names 5 | * Using `let` instead of `const` when variable isn't reassigned 6 | * Extra variables that could be inlined (variables only used once) 7 | * Using strict equality (For JS and TS) 8 | * Use [tenary operators](https://en.wikipedia.org/wiki/Ternary_conditional_operator) to be more concise 9 | * Other 10 | * See if other languages allow [foreach](https://en.wikipedia.org/wiki/Foreach_loop) if the problem requires you to iterate through input without needing the index 11 | -------------------------------------------------------------------------------- /workspaces/archive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@code-chronicles/archive", 3 | "private": true, 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/code-chronicles-code/leetcode-curriculum.git", 7 | "directory": "workspaces/archive" 8 | }, 9 | "type": "module" 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/archive/solutions/checkStraightLines.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool checkStraightLine(vector>& coordinates) { 4 | int n = coordinates.size(); 5 | if (n <= 2) return true; 6 | 7 | int dx1 = coordinates[1][0] - coordinates[0][0]; 8 | int dy1 = coordinates[1][1] - coordinates[0][1]; 9 | 10 | 11 | for (int i = 2; i < n; ++i) { 12 | int dx2 = coordinates[i][0] - coordinates[i - 1][0]; 13 | int dy2 = coordinates[i][1] - coordinates[i - 1][1]; 14 | 15 | if (y1 * x2 != x1 * y2) return false; 16 | } 17 | return true; 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /workspaces/archive/solutions/straight_line.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def checkStraightLine(self, coordinates: List[List[int]]) -> bool: 3 | x1, y1 = coordinates[0] 4 | x2, y2 = coordinates[1] 5 | dx = x2 - x1 6 | dy = y2 - y1 7 | 8 | prev = dy * x1 - dx * y1 9 | for x, y in coordinates: 10 | if dy * x - dx * y != prev: 11 | return False 12 | 13 | return True 14 | -------------------------------------------------------------------------------- /workspaces/download-leetcode-submissions/.gitignore: -------------------------------------------------------------------------------- 1 | secrets_DO_NOT_COMMIT_OR_SHARE.json 2 | 3 | submissions/ 4 | submissions.jsonl 5 | submissions.sha512 6 | 7 | dist/ 8 | -------------------------------------------------------------------------------- /workspaces/download-leetcode-submissions/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/", "submissions/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/download-leetcode-submissions/secrets_TEMPLATE.json: -------------------------------------------------------------------------------- 1 | { 2 | "leetcodeSessionCookie": "REPLACE WITH A LEETCODE_SESSION COOKIE FOR YOUR LEETCODE USER, IT SHOULD BE SAVED IN YOUR BROWSER IF YOU'RE LOGGED IN TO LEETCODE" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/download-leetcode-submissions/src/readSecrets.ts: -------------------------------------------------------------------------------- 1 | import fsPromises from "node:fs/promises"; 2 | 3 | import { z } from "zod"; 4 | 5 | const SECRETS_FILE = "secrets_DO_NOT_COMMIT_OR_SHARE.json"; 6 | 7 | const secretsZodType = z.object({ 8 | leetcodeSessionCookie: z.string().min(1), 9 | }); 10 | 11 | export type Secrets = z.infer; 12 | 13 | export async function readSecrets(): Promise { 14 | return secretsZodType.parse( 15 | JSON.parse(await fsPromises.readFile(SECRETS_FILE, "utf8")), 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /workspaces/download-leetcode-submissions/tsconfig.json: -------------------------------------------------------------------------------- 1 | // TODO: ignore submissions directory 2 | 3 | { 4 | "extends": "../../tsconfig-base.json" 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/fetch-leetcode-problem-list/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/fetch-leetcode-problem-list/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/fetch-leetcode-problem-list/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/fetch-recent-accepted-leetcode-submissions/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/fetch-recent-accepted-leetcode-submissions/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/fetch-recent-accepted-leetcode-submissions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/generate-health-report/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/generate-health-report/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | // TODO: get to the point where we can use the lint 4 | export default [...config, { ignores: ["problems/"] }]; 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2618-check-if-object-instance-of-class/README.md: -------------------------------------------------------------------------------- 1 | # 2618. Check if Object Instance of Class 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/check-if-object-instance-of-class/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2619-array-prototype-last/README.md: -------------------------------------------------------------------------------- 1 | # 2619. Array Prototype Last 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/array-prototype-last/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2619-array-prototype-last/solution.md: -------------------------------------------------------------------------------- 1 | # 2619. Array Prototype Last 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/array-prototype-last/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/array-prototype-last/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/array-prototype-last/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2620-counter/README.md: -------------------------------------------------------------------------------- 1 | # 2620. Counter 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/counter/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2620-counter/solution.md: -------------------------------------------------------------------------------- 1 | # 2620. Counter 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/counter/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/counter/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/counter/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2621-sleep/README.md: -------------------------------------------------------------------------------- 1 | # 2621. Sleep 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/sleep/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2621-sleep/solution.md: -------------------------------------------------------------------------------- 1 | # 2621. Sleep 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/sleep/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/sleep/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/sleep/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2622-cache-with-time-limit/README.md: -------------------------------------------------------------------------------- 1 | # 2622. Cache With Time Limit 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/cache-with-time-limit/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2623-memoize/README.md: -------------------------------------------------------------------------------- 1 | # 2623. Memoize 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/memoize/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2623-memoize/solution.md: -------------------------------------------------------------------------------- 1 | # 2623. Memoize 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/memoize/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/memoize/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/memoize/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2624-snail-traversal/README.md: -------------------------------------------------------------------------------- 1 | # 2624. Snail Traversal 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/snail-traversal/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2624-snail-traversal/solution.md: -------------------------------------------------------------------------------- 1 | # 2624. Snail Traversal 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/snail-traversal/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/snail-traversal/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/snail-traversal/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2625-flatten-deeply-nested-array/README.md: -------------------------------------------------------------------------------- 1 | # 2625. Flatten Deeply Nested Array 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/flatten-deeply-nested-array/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/iterative/destructive-using-while.ts: -------------------------------------------------------------------------------- 1 | function reduce( 2 | arr: TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult { 6 | let res = init; 7 | 8 | arr.reverse(); 9 | while (arr.length > 0) { 10 | res = fn(res, arr.pop() as TElement); 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/iterative/using-for-each.ts: -------------------------------------------------------------------------------- 1 | function reduce( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult { 6 | let res = init; 7 | 8 | arr.forEach((element) => { 9 | res = fn(res, element); 10 | }); 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/iterative/using-for-of.ts: -------------------------------------------------------------------------------- 1 | function reduce( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult { 6 | let res = init; 7 | 8 | for (const element of arr) { 9 | res = fn(res, element); 10 | } 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/recursive/elegant-but-quadratic.ts: -------------------------------------------------------------------------------- 1 | const reduce = ( 2 | arr: TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult => 6 | arr.length === 0 ? init : reduce(arr, fn, fn(init, arr.shift() as TElement)); 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/recursive/inner-function.ts: -------------------------------------------------------------------------------- 1 | function reduce( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult { 6 | const doReduce = (accumulator: TResult, index: number): TResult => 7 | index === arr.length 8 | ? accumulator 9 | : doReduce(fn(accumulator, arr[index]), index + 1); 10 | 11 | return doReduce(init, 0); 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/recursive/linear-through-own-reduce-right.ts: -------------------------------------------------------------------------------- 1 | const reduceRight = ( 2 | arr: TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult => 6 | arr.length === 0 7 | ? init 8 | : reduceRight(arr, fn, fn(init, arr.pop() as TElement)); 9 | 10 | const reduce = ( 11 | arr: TElement[], 12 | fn: (accumulator: TResult, element: TElement) => TResult, 13 | init: TResult, 14 | ): TResult => reduceRight(arr.reverse(), fn, init); 15 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/recursive/single-function-width-default-argument.ts: -------------------------------------------------------------------------------- 1 | const reduce = ( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | index: number = 0, 6 | ): TResult => 7 | index === arr.length 8 | ? init 9 | : reduce(arr, fn, fn(init, arr[index]), index + 1); 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/using-built-in-reduce-right/using-reverse.ts: -------------------------------------------------------------------------------- 1 | const reduce = ( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult => [...arr].reverse().reduceRight(fn, init); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/using-built-in-reduce-right/using-to-reversed.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Array { 3 | toReversed(this: T[]): T[]; 4 | } 5 | 6 | interface ReadonlyArray { 7 | toReversed(this: readonly T[]): T[]; 8 | } 9 | } 10 | 11 | const reduce = ( 12 | arr: readonly TElement[], 13 | fn: (accumulator: TResult, element: TElement) => TResult, 14 | init: TResult, 15 | ): TResult => arr.toReversed().reduceRight(fn, init); 16 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/using-built-in-reduce/binding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @param {number} init 5 | * @return {number} 6 | */ 7 | const reduce = Function.prototype.call.bind(Array.prototype.reduce); 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/using-built-in-reduce/delegating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @param {number} init 5 | * @return {number} 6 | */ 7 | const reduce = (arr, fn, init) => arr.reduce(fn, init); 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2626-array-reduce-transformation/solutions/using-built-in-reduce/delegating.ts: -------------------------------------------------------------------------------- 1 | const reduce = ( 2 | arr: readonly TElement[], 3 | fn: (accumulator: TResult, element: TElement) => TResult, 4 | init: TResult, 5 | ): TResult => arr.reduce(fn, init); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2627-debounce/README.md: -------------------------------------------------------------------------------- 1 | # 2627. Debounce 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/debounce/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2627-debounce/solution.md: -------------------------------------------------------------------------------- 1 | # 2627. Debounce 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/debounce/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/debounce/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/debounce/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2629-function-composition/README.md: -------------------------------------------------------------------------------- 1 | # 2629. Function Composition 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/function-composition/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2629-function-composition/solution.md: -------------------------------------------------------------------------------- 1 | # 2629. Function Composition 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/function-composition/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/function-composition/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/function-composition/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2630-memoize-ii/README.md: -------------------------------------------------------------------------------- 1 | # 2630. Memoize II 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/memoize-ii/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2630-memoize-ii/solution.md: -------------------------------------------------------------------------------- 1 | # 2630. Memoize II 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/memoize-ii/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/memoize-ii/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/memoize-ii/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2631-group-by/README.md: -------------------------------------------------------------------------------- 1 | # 2631. Group By 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/group-by/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2631-group-by/solution.md: -------------------------------------------------------------------------------- 1 | # 2631. Group By 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/group-by/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/group-by/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/group-by/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/iterative-loops/using-classic-for.ts: -------------------------------------------------------------------------------- 1 | function filter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] { 5 | const res: T[] = []; 6 | 7 | for (let i = 0; i < arr.length; ++i) { 8 | const element = arr[i]; 9 | fn(element, i) && res.push(element); 10 | } 11 | 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/iterative-loops/using-for-each.ts: -------------------------------------------------------------------------------- 1 | function filter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] { 5 | const res: T[] = []; 6 | 7 | arr.forEach((element, index) => { 8 | fn(element, index) && res.push(element); 9 | }); 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/iterative-loops/using-for-of-entries.ts: -------------------------------------------------------------------------------- 1 | function filter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] { 5 | const res: T[] = []; 6 | 7 | for (const [index, element] of arr.entries()) { 8 | fn(element, index) && res.push(element); 9 | } 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/iterative-loops/using-generators.ts: -------------------------------------------------------------------------------- 1 | function* lazyFilter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): Generator { 5 | for (const [index, element] of arr.entries()) { 6 | fn(element, index) && (yield element); 7 | } 8 | } 9 | 10 | const filter = ( 11 | arr: readonly T[], 12 | fn: (element: T, index: number) => unknown, 13 | ): T[] => Array.from(lazyFilter(arr, fn)); 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/recursive/inner-function.ts: -------------------------------------------------------------------------------- 1 | function filter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] { 5 | const res: T[] = []; 6 | 7 | const doFilter = (index: number) => { 8 | if (index === arr.length) { 9 | return; 10 | } 11 | 12 | const element = arr[index]; 13 | fn(element, index) && res.push(element); 14 | doFilter(index + 1); 15 | }; 16 | 17 | doFilter(0); 18 | 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/recursive/single-function-with-default-arguments.ts: -------------------------------------------------------------------------------- 1 | function filter( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | index: number = 0, 5 | res: T[] = [], 6 | ): T[] { 7 | if (index === arr.length) { 8 | return res; 9 | } 10 | 11 | const element = arr[index]; 12 | fn(element, index) && res.push(element); 13 | return filter(arr, fn, index + 1, res); 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-built-in-filter/binding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @return {number[]} 5 | */ 6 | const filter = Function.prototype.call.bind(Array.prototype.filter); 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-built-in-filter/delegating.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => arr.filter(fn); 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-flat-map/delegating.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => 5 | arr.flatMap((element, index) => (fn(element, index) ? [element] : [])); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-reduce/elegant-but-quadratic.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => 5 | arr.reduce( 6 | (res: T[], element, index) => 7 | fn(element, index) ? [...res, element] : res, 8 | [], 9 | ); 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-reduce/linear-contrarian.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => 5 | arr 6 | .reduceRight((res: T[], element, index) => { 7 | fn(element, index) && res.push(element); 8 | return res; 9 | }, []) 10 | .reverse(); 11 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-reduce/linear-with-comma-operator.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => 5 | arr.reduce( 6 | (res: T[], element, index) => ( 7 | fn(element, index) && res.push(element), res 8 | ), 9 | [], 10 | ); 11 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2634-filter-elements-from-array/solutions/using-reduce/linear.ts: -------------------------------------------------------------------------------- 1 | const filter = ( 2 | arr: readonly T[], 3 | fn: (element: T, index: number) => unknown, 4 | ): T[] => 5 | arr.reduce((res: T[], element, index) => { 6 | fn(element, index) && res.push(element); 7 | return res; 8 | }, []); 9 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/iterative-loops/using-classic-for-mutating-input.ts: -------------------------------------------------------------------------------- 1 | function map(arr: TIn[], fn: (element: TIn, index: number) => TIn): TIn[] { 2 | for (let i = 0; i < arr.length; ++i) { 3 | arr[i] = fn(arr[i], i); 4 | } 5 | 6 | return arr; 7 | } 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/iterative-loops/using-classic-for.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] { 5 | const res: TOut[] = []; 6 | 7 | for (let i = 0; i < arr.length; ++i) { 8 | res.push(fn(arr[i], i)); 9 | } 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/iterative-loops/using-for-each.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] { 5 | const res: TOut[] = []; 6 | 7 | arr.forEach((element, index) => { 8 | res.push(fn(element, index)); 9 | }); 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/iterative-loops/using-for-of-entries.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] { 5 | const res: TOut[] = []; 6 | 7 | for (const [index, element] of arr.entries()) { 8 | res.push(fn(element, index)); 9 | } 10 | 11 | return res; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/iterative-loops/using-generators.ts: -------------------------------------------------------------------------------- 1 | function* lazyMap( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): Generator { 5 | for (const [index, element] of arr.entries()) { 6 | yield fn(element, index); 7 | } 8 | } 9 | 10 | const map = ( 11 | arr: readonly TIn[], 12 | fn: (element: TIn, index: number) => TOut, 13 | ): TOut[] => Array.from(lazyMap(arr, fn)); 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/recursive/inner-function-with-index-argument.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] { 5 | const res: TOut[] = []; 6 | 7 | const doMap = (index: number) => { 8 | if (index === arr.length) { 9 | return; 10 | } 11 | 12 | res.push(fn(arr[index], index)); 13 | doMap(index + 1); 14 | }; 15 | 16 | doMap(0); 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/recursive/inner-function-without-index-argument.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] { 5 | const res: TOut[] = []; 6 | 7 | const doMap = () => { 8 | if (res.length === arr.length) { 9 | return; 10 | } 11 | 12 | res.push(fn(arr[res.length], res.length)); 13 | doMap(); 14 | }; 15 | 16 | doMap(); 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/recursive/single-function-with-default-argument.ts: -------------------------------------------------------------------------------- 1 | function map( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | res: TOut[] = [], 5 | ): TOut[] { 6 | if (res.length === arr.length) { 7 | return res; 8 | } 9 | 10 | res.push(fn(arr[res.length], res.length)); 11 | return map(arr, fn, res); 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-built-in-map/binding.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @return {number[]} 5 | */ 6 | const map = Function.prototype.call.bind(Array.prototype.map); 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-built-in-map/delegating.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => arr.map(fn); 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-other-mapping-built-ins/aliasing-array-from.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} arr 3 | * @param {Function} fn 4 | * @return {number[]} 5 | */ 6 | const map = Array.from; 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-other-mapping-built-ins/delegating-to-array-from.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => Array.from(arr, fn); 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-other-mapping-built-ins/delegating-to-flat-map-safe.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => arr.flatMap((element, index) => [fn(element, index)]); 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-other-mapping-built-ins/delegating-to-flat-map-sloppy.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => arr.flatMap(fn); 5 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-reduce/elegant-but-quadratic.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => 5 | arr.reduce((res: TOut[], element, index) => [...res, fn(element, index)], []); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-reduce/linear-contrarian.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => 5 | arr 6 | .reduceRight((res: TOut[], element, index) => { 7 | res.push(fn(element, index)); 8 | return res; 9 | }, []) 10 | .reverse(); 11 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-reduce/linear-with-comma-operator.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => 5 | arr.reduce( 6 | (res: TOut[], element, index) => (res.push(fn(element, index)), res), 7 | [], 8 | ); 9 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2635-apply-transform-over-each-element-in-array/solutions/using-reduce/linear.ts: -------------------------------------------------------------------------------- 1 | const map = ( 2 | arr: readonly TIn[], 3 | fn: (element: TIn, index: number) => TOut, 4 | ): TOut[] => 5 | arr.reduce((res: TOut[], element, index) => { 6 | res.push(fn(element, index)); 7 | return res; 8 | }, []); 9 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2637-promise-time-limit/README.md: -------------------------------------------------------------------------------- 1 | # 2637. Promise Time Limit 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/promise-time-limit/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2637-promise-time-limit/solution.md: -------------------------------------------------------------------------------- 1 | # 2637. Promise Time Limit 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/promise-time-limit/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/promise-time-limit/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/promise-time-limit/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2648-generate-fibonacci-sequence/README.md: -------------------------------------------------------------------------------- 1 | # 2648. Generate Fibonacci Sequence 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/generate-fibonacci-sequence/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2649-nested-array-generator/README.md: -------------------------------------------------------------------------------- 1 | # 2649. Nested Array Generator 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/nested-array-generator/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2650-design-cancellable-function/README.md: -------------------------------------------------------------------------------- 1 | # 2650. Design Cancellable Function 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/design-cancellable-function/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2665-counter-ii/README.md: -------------------------------------------------------------------------------- 1 | # 2665. Counter II 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/counter-ii/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2665-counter-ii/solution.md: -------------------------------------------------------------------------------- 1 | # 2665. Counter II 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/counter-ii/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/counter-ii/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/counter-ii/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2666-allow-one-function-call/README.md: -------------------------------------------------------------------------------- 1 | # 2666. Allow One Function Call 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/allow-one-function-call/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2667-create-hello-world-function/README.md: -------------------------------------------------------------------------------- 1 | # 2667. Create Hello World Function 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/create-hello-world-function/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/README.md: -------------------------------------------------------------------------------- 1 | # 2677. Chunk Array 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/chunk-array/) 4 | 5 | Although the problem asks us not to use [`_.chunk`](https://lodash.com/docs/#chunk), I think there's no harm in using it to get a quick accept, as long as we then follow up with another strategy. 6 | 7 | As far as manual implementations, the choice is likely between traversing the input one element at a time, or grabbing a larger _slice_ of input at once. Both approaches are viable and can result in an efficient solution. 8 | 9 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/grabbing-slices/using-built-in-slice.ts: -------------------------------------------------------------------------------- 1 | function chunk(arr: readonly T[], size: number): T[][] { 2 | const res: T[][] = []; 3 | 4 | for (let i = 0; i < arr.length; i += size) { 5 | res.push(arr.slice(i, i + size)); 6 | } 7 | 8 | return res; 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/grabbing-slices/using-generators.ts: -------------------------------------------------------------------------------- 1 | function* generateSlice( 2 | arr: readonly T[], 3 | start: number, 4 | size: number, 5 | ): Generator { 6 | for (let i = start; size > 0 && i < arr.length; ++i, --size) { 7 | yield arr[i]; 8 | } 9 | } 10 | 11 | function* generateChunks( 12 | arr: readonly T[], 13 | size: number, 14 | ): Generator { 15 | for (let i = 0; i < arr.length; i += size) { 16 | yield Array.from(generateSlice(arr, i, size)); 17 | } 18 | } 19 | 20 | function chunk(arr: readonly T[], size: number): T[][] { 21 | return Array.from(generateChunks(arr, size)); 22 | } 23 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/grabbing-slices/using-hand-rolled-slice-with-start-and-end.ts: -------------------------------------------------------------------------------- 1 | function slice(arr: readonly T[], start: number, end: number): T[] { 2 | const res: T[] = []; 3 | 4 | for (let i = start; i < end && i < arr.length; ++i) { 5 | res.push(arr[i]); 6 | } 7 | 8 | return res; 9 | } 10 | 11 | function chunk(arr: readonly T[], size: number): T[][] { 12 | const res: T[][] = []; 13 | 14 | for (let i = 0; i < arr.length; i += size) { 15 | res.push(slice(arr, i, i + size)); 16 | } 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/grabbing-slices/using-hand-rolled-slice-with-start-and-size.ts: -------------------------------------------------------------------------------- 1 | function slice(arr: readonly T[], start: number, size: number): T[] { 2 | const res: T[] = []; 3 | 4 | for (let i = start; res.length < size && i < arr.length; ++i) { 5 | res.push(arr[i]); 6 | } 7 | 8 | return res; 9 | } 10 | 11 | function chunk(arr: readonly T[], size: number): T[][] { 12 | const res: T[][] = []; 13 | 14 | for (let i = 0; i < arr.length; i += size) { 15 | res.push(slice(arr, i, size)); 16 | } 17 | 18 | return res; 19 | } 20 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/processing-individual-elements/iterating-by-index.ts: -------------------------------------------------------------------------------- 1 | function chunk(arr: readonly T[], size: number): T[][] { 2 | const res: T[][] = []; 3 | 4 | for (let i = 0; i < arr.length; ++i) { 5 | // New chunks start at indexes divisible by `size`. 6 | if (i % size === 0) { 7 | res.push([]); 8 | } 9 | 10 | // We can be certain that `res` is not empty because we'll add something 11 | // to `res` during the very first iteration, when `i` is 0. 12 | const lastChunk = res.at(-1)!; 13 | lastChunk.push(arr[i]); 14 | } 15 | 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/processing-individual-elements/iterating-over-elements.ts: -------------------------------------------------------------------------------- 1 | function chunk(arr: readonly T[], size: number): T[][] { 2 | const res: T[][] = []; 3 | 4 | for (const element of arr) { 5 | // If there's no last chunk, or if the last chunk is full, start a new 6 | // chunk. 7 | if (res.length === 0 || res.at(-1)!.length === size) { 8 | res.push([]); 9 | } 10 | 11 | res.at(-1)!.push(element); 12 | } 13 | 14 | return res; 15 | } 16 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/processing-individual-elements/iterating-over-index-element-pairss.ts: -------------------------------------------------------------------------------- 1 | function chunk(arr: readonly T[], size: number): T[][] { 2 | const res: T[][] = []; 3 | 4 | for (const [index, element] of arr.entries()) { 5 | // New chunks start at indexes divisible by `size`. 6 | if (index % size === 0) { 7 | res.push([]); 8 | } 9 | 10 | res.at(-1)!.push(element); 11 | } 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/processing-individual-elements/iterating-with-foreach-method.ts: -------------------------------------------------------------------------------- 1 | function chunk(arr: readonly T[], size: number): T[][] { 2 | const res: T[][] = []; 3 | 4 | arr.forEach((element, index) => { 5 | // New chunks start at indexes divisible by `size`. 6 | if (index % size === 0) { 7 | res.push([]); 8 | } 9 | 10 | res.at(-1)!.push(element); 11 | }); 12 | 13 | return res; 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/using-lodash/delegating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {number} size 4 | * @return {Array} 5 | */ 6 | function chunk(arr, size) { 7 | return _.chunk(arr, size); 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/using-lodash/delegating.ts: -------------------------------------------------------------------------------- 1 | // TODO: declare Lodash in the tsconfig somehow 2 | declare const _: any; 3 | 4 | function chunk(arr: readonly T[], size: number): T[][] { 5 | return _.chunk(arr, size); 6 | } 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2677-chunk-array/solutions/using-lodash/destructuring.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {number} size 4 | * @return {Array} 5 | */ 6 | const { chunk } = _; 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2693-call-function-with-custom-context/README.md: -------------------------------------------------------------------------------- 1 | # 2693. Call Function with Custom Context 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/call-function-with-custom-context/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2694-event-emitter/README.md: -------------------------------------------------------------------------------- 1 | # 2694. Event Emitter 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/event-emitter/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2694-event-emitter/solution.md: -------------------------------------------------------------------------------- 1 | # 2694. Event Emitter 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/event-emitter/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/event-emitter/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/event-emitter/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2695-array-wrapper/README.md: -------------------------------------------------------------------------------- 1 | # 2695. Array Wrapper 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/array-wrapper/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2695-array-wrapper/solution.md: -------------------------------------------------------------------------------- 1 | # 2695. Array Wrapper 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/array-wrapper/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/array-wrapper/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/array-wrapper/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/README.md: -------------------------------------------------------------------------------- 1 | # 2703. Return Length of Arguments Passed 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/return-length-of-arguments-passed/) 4 | 5 | This problem is essentially testing familiarity with [JavaScript's rest parameters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). However, there is also a solution that doesn't rely on rest parameters. Do you know it? It's hinted at in the documentation link. 6 | 7 | Once you've worked on the problem, check out [the full write-up and solution](solution.md). 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-arguments-object/anonymous-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {number} 3 | */ 4 | const argumentsLength = function () { 5 | return arguments.length; 6 | }; 7 | 8 | /** 9 | * argumentsLength(1, 2, 3); // 3 10 | */ 11 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-arguments-object/anonymous-function.ts: -------------------------------------------------------------------------------- 1 | const argumentsLength = function (..._args: readonly unknown[]): number { 2 | return arguments.length; 3 | }; 4 | 5 | /** 6 | * argumentsLength(1, 2, 3); // 3 7 | */ 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-arguments-object/named-function-with-empty-destructure.ts: -------------------------------------------------------------------------------- 1 | function argumentsLength(...[]: readonly unknown[]): number { 2 | return arguments.length; 3 | } 4 | 5 | /** 6 | * argumentsLength(1, 2, 3); // 3 7 | */ 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-arguments-object/named-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @return {number} 3 | */ 4 | function argumentsLength() { 5 | return arguments.length; 6 | } 7 | 8 | /** 9 | * argumentsLength(1, 2, 3); // 3 10 | */ 11 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-arguments-object/named-function.ts: -------------------------------------------------------------------------------- 1 | function argumentsLength(..._args: readonly unknown[]): number { 2 | return arguments.length; 3 | } 4 | 5 | /** 6 | * argumentsLength(1, 2, 3); // 3 7 | */ 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-rest-parameters/arrow-function-without-return-annotation.ts: -------------------------------------------------------------------------------- 1 | const argumentsLength = (...args: readonly unknown[]) => args.length; 2 | 3 | /** 4 | * argumentsLength(1, 2, 3); // 3 5 | */ 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-rest-parameters/arrow-function.ts: -------------------------------------------------------------------------------- 1 | const argumentsLength = (...args: readonly unknown[]): number => args.length; 2 | 3 | /** 4 | * argumentsLength(1, 2, 3); // 3 5 | */ 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-rest-parameters/named-function.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {...(null|boolean|number|string|Array|Object)} args 3 | * @return {number} 4 | */ 5 | function argumentsLength(...args) { 6 | return args.length; 7 | } 8 | 9 | /** 10 | * argumentsLength(1, 2, 3); // 3 11 | */ 12 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2703-return-length-of-arguments-passed/solutions/using-rest-parameters/named-function.ts: -------------------------------------------------------------------------------- 1 | function argumentsLength(...args: readonly unknown[]): number { 2 | return args.length; 3 | } 4 | 5 | /** 6 | * argumentsLength(1, 2, 3); // 3 7 | */ 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2704-to-be-or-not-to-be/README.md: -------------------------------------------------------------------------------- 1 | # 2704. To Be Or Not To Be 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/to-be-or-not-to-be/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2704-to-be-or-not-to-be/solution.md: -------------------------------------------------------------------------------- 1 | # 2704. To Be Or Not To Be 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/to-be-or-not-to-be/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/to-be-or-not-to-be/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/to-be-or-not-to-be/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2705-compact-object/README.md: -------------------------------------------------------------------------------- 1 | # 2705. Compact Object 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/compact-object/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2705-compact-object/solution.md: -------------------------------------------------------------------------------- 1 | # 2705. Compact Object 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/compact-object/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/compact-object/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/compact-object/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2715-timeout-cancellation/README.md: -------------------------------------------------------------------------------- 1 | # 2715. Timeout Cancellation 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/timeout-cancellation/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2715-timeout-cancellation/solution.md: -------------------------------------------------------------------------------- 1 | # 2715. Timeout Cancellation 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/timeout-cancellation/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/timeout-cancellation/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/timeout-cancellation/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2721-execute-asynchronous-functions-in-parallel/README.md: -------------------------------------------------------------------------------- 1 | # 2721. Execute Asynchronous Functions in Parallel 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/execute-asynchronous-functions-in-parallel/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2722-join-two-arrays-by-id/README.md: -------------------------------------------------------------------------------- 1 | # 2722. Join Two Arrays by ID 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/join-two-arrays-by-id/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2723-add-two-promises/README.md: -------------------------------------------------------------------------------- 1 | # 2723. Add Two Promises 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/add-two-promises/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2723-add-two-promises/solution.md: -------------------------------------------------------------------------------- 1 | # 2723. Add Two Promises 2 | 3 | [View this Write-up on LeetCode TODO](https://leetcode.com/problems/add-two-promises/solutions/) | [View Problem on LeetCode](https://leetcode.com/problems/add-two-promises/) 4 | 5 | > [!WARNING] 6 | > This page includes spoilers. For a spoiler-free introduction to the problem, see [the README file](README.md). 7 | 8 | ## Summary 9 | 10 | ## Background 11 | 12 | ## Solutions 13 | 14 | ## Answers to Bonus Questions 15 | 16 | > [!TIP] 17 | > Thanks for reading! If you enjoyed this write-up, feel free to [up-vote it on LeetCode TODO](https://leetcode.com/problems/add-two-promises/solutions/)! 🙏 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/minimizing-calls-to-fn/caching-in-map.ts: -------------------------------------------------------------------------------- 1 | function sortBy(arr: readonly T[], fn: (value: T) => number): T[] { 2 | const cache = new Map(); 3 | const getSortKey = (value: T): number => { 4 | let res = cache.get(value); 5 | if (res == null) { 6 | res = fn(value); 7 | cache.set(value, res); 8 | } 9 | return res; 10 | }; 11 | 12 | return [...arr].sort((a, b) => getSortKey(a) - getSortKey(b)); 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/minimizing-calls-to-fn/mapping-to-records.ts: -------------------------------------------------------------------------------- 1 | const sortBy = (arr: readonly T[], fn: (value: T) => number): T[] => 2 | arr 3 | .map((element) => ({ element, sortKey: fn(element) })) 4 | .sort((a, b) => a.sortKey - b.sortKey) 5 | .map(({ element }) => element); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/minimizing-calls-to-fn/mapping-to-tuples.ts: -------------------------------------------------------------------------------- 1 | const sortBy = (arr: readonly T[], fn: (value: T) => number): T[] => 2 | arr 3 | .map((element): [T, number] => [element, fn(element)]) 4 | .sort((a, b) => a[1] - b[1]) 5 | .map(([element]) => element); 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/minimizing-calls-to-fn/using-lodash-memoize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {Function} fn 4 | * @return {Array} 5 | */ 6 | function sortBy(arr, fn) { 7 | const memoizedFn = _.memoize(fn); 8 | return arr.toSorted((a, b) => memoizedFn(a) - memoizedFn(b)); 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/refusing-to-specify-custom-comparator/adding-an-offset-to-sort-key-for-padding.ts: -------------------------------------------------------------------------------- 1 | const sortBy = (arr: T[], fn: (value: T) => number): T[] => 2 | arr 3 | .map((element) => `${1.1e10 + fn(element)} ${JSON.stringify(element)}`) 4 | .sort() 5 | .map((sortKeyAndElement) => 6 | JSON.parse(sortKeyAndElement.replace(/^\d+ /, "")), 7 | ); 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/using-built-in-sort/delegating-without-modifying-input.ts: -------------------------------------------------------------------------------- 1 | const sortBy = (arr: readonly T[], fn: (value: T) => number): T[] => 2 | [...arr].sort((a, b) => fn(a) - fn(b)); 3 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/using-built-in-sort/delegating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {Function} fn 4 | * @return {Array} 5 | */ 6 | const sortBy = (arr, fn) => arr.sort((a, b) => fn(a) - fn(b)); 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/using-built-in-sort/delegating.ts: -------------------------------------------------------------------------------- 1 | const sortBy = (arr: T[], fn: (value: T) => number): T[] => 2 | arr.sort((a, b) => fn(a) - fn(b)); 3 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/using-to-sorted/delegating.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Array} arr 3 | * @param {Function} fn 4 | * @return {Array} 5 | */ 6 | const sortBy = (arr, fn) => arr.toSorted((a, b) => fn(a) - fn(b)); 7 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2724-sort-by/solutions/using-to-sorted/delegating.ts: -------------------------------------------------------------------------------- 1 | declare global { 2 | interface Array { 3 | toSorted(this: T[], compareFn: (a: T, b: T) => number): T[]; 4 | } 5 | 6 | interface ReadonlyArray { 7 | toSorted(this: readonly T[], compareFn: (a: T, b: T) => number): T[]; 8 | } 9 | } 10 | 11 | const sortBy = (arr: readonly T[], fn: (value: T) => number): T[] => 12 | arr.toSorted((a, b) => fn(a) - fn(b)); 13 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2725-interval-cancellation/README.md: -------------------------------------------------------------------------------- 1 | # 2725. Interval Cancellation 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/interval-cancellation/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2726-calculator-with-method-chaining/README.md: -------------------------------------------------------------------------------- 1 | # 2726. Calculator with Method Chaining 2 | 3 | [View Problem on LeetCode](https://leetcode.com/problems/calculator-with-method-chaining/) 4 | 5 | Once you've worked on the problem, check out [the full write-up and solution](solution.md)! 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-for-in/array-check-via-if-and-property-ownership-check.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Object|Array} obj 3 | * @return {boolean} 4 | */ 5 | function isEmpty(obj) { 6 | if (Array.isArray(obj)) { 7 | return obj.length === 0; 8 | } 9 | 10 | for (const property in obj) { 11 | if (Object.hasOwn(obj, property)) { 12 | return false; 13 | } 14 | } 15 | 16 | return true; 17 | } 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-for-in/array-check-via-ternary-and-property-ownership-check.ts: -------------------------------------------------------------------------------- 1 | function isEmptyObject(obj: Readonly>): boolean { 2 | for (const property in obj) { 3 | if (Object.hasOwn(obj, property)) { 4 | return false; 5 | } 6 | } 7 | 8 | return true; 9 | } 10 | 11 | function isEmpty( 12 | obj: Readonly> | readonly unknown[], 13 | ): boolean { 14 | return Array.isArray(obj) 15 | ? obj.length === 0 16 | : isEmptyObject(obj as Readonly>); 17 | } 18 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-for-in/no-checks.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | for (const _property in obj) { 5 | return false; 6 | } 7 | 8 | return true; 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-json-stringify/array-check-via-if.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Object|Array} obj 3 | * @return {boolean} 4 | */ 5 | function isEmpty(obj) { 6 | if (Array.isArray(obj)) { 7 | return obj.length === 0; 8 | } else { 9 | return JSON.stringify(obj) === "{}"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-json-stringify/array-check-via-ternary-and-json-length.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | return Array.isArray(obj) 5 | ? obj.length === 0 6 | : JSON.stringify(obj).length === 2; 7 | } 8 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-json-stringify/array-check-via-ternary.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | return Array.isArray(obj) ? obj.length === 0 : JSON.stringify(obj) === "{}"; 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-json-stringify/no-array-check.ts: -------------------------------------------------------------------------------- 1 | const isEmpty = (o: unknown) => JSON.stringify(o).length < 3; 2 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-object-keys/array-check-via-if.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Object|Array} obj 3 | * @return {boolean} 4 | */ 5 | function isEmpty(obj) { 6 | if (Array.isArray(obj)) { 7 | return obj.length === 0; 8 | } else { 9 | return Object.keys(obj).length === 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-object-keys/array-check-via-if.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | if (Array.isArray(obj)) { 5 | return obj.length === 0; 6 | } else { 7 | return Object.keys(obj).length === 0; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-object-keys/array-check-via-ternary-subexpression.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | return (Array.isArray(obj) ? obj : Object.keys(obj)).length === 0; 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-object-keys/array-check-via-ternary.ts: -------------------------------------------------------------------------------- 1 | function isEmpty( 2 | obj: Readonly> | readonly unknown[], 3 | ): boolean { 4 | return Array.isArray(obj) ? obj.length === 0 : Object.keys(obj).length === 0; 5 | } 6 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/problems/2727-is-object-empty/solutions/using-object-keys/no-array-check.ts: -------------------------------------------------------------------------------- 1 | const isEmpty = (o: Readonly>) => 2 | !Object.keys(o).length; 3 | -------------------------------------------------------------------------------- /workspaces/javascript-leetcode-month/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/.gitattributes: -------------------------------------------------------------------------------- 1 | schema-*.graphql linguist-generated 2 | *.generated.ts linguist-generated 3 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/eslint.config.js: -------------------------------------------------------------------------------- 1 | export { default } from "@code-chronicles/eslint-config"; 2 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/__tests__/validSchema-test.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "node:fs/promises"; 2 | 3 | import { describe, expect, it } from "@jest/globals"; 4 | import { buildSchema, validateSchema } from "graphql"; 5 | 6 | import { SCHEMA_FILE_ORIGINAL } from "../scripts/scrape-graphql-schema/constants.ts"; 7 | import { SCHEMA_FILE_PATCHED } from "../scripts/patch-graphql-schema/constants.ts"; 8 | 9 | describe("GraphQL schema", () => { 10 | it.each([SCHEMA_FILE_ORIGINAL, SCHEMA_FILE_PATCHED])( 11 | "validates %s", 12 | async (schemaPath) => { 13 | const schema = buildSchema(await readFile(schemaPath, "utf8")); 14 | expect(validateSchema(schema)).toStrictEqual([]); 15 | }, 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/api/active-daily-coding-challenge-question/query.graphql: -------------------------------------------------------------------------------- 1 | query ActiveDailyCodingChallengeQuestion { 2 | activeDailyCodingChallengeQuestion { 3 | date 4 | question { 5 | difficulty 6 | questionFrontendId 7 | title 8 | titleSlug 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/api/daily-coding-challenge-v2/query.graphql: -------------------------------------------------------------------------------- 1 | query DailyCodingChallengeV2($month: Int!, $year: Int!) { 2 | dailyCodingChallengeV2(month: $month, year: $year) { 3 | challenges { 4 | date 5 | question { 6 | difficulty 7 | questionFrontendId 8 | title 9 | titleSlug 10 | } 11 | } 12 | weeklyChallenges { 13 | date 14 | question { 15 | difficulty 16 | questionFrontendId 17 | title 18 | titleSlug 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/api/question-list/query.graphql: -------------------------------------------------------------------------------- 1 | query QuestionList( 2 | $categorySlug: String! 3 | $limit: Int 4 | $skip: Int 5 | $filters: QuestionListFilterInput! 6 | ) { 7 | questionList( 8 | categorySlug: $categorySlug 9 | limit: $limit 10 | skip: $skip 11 | filters: $filters 12 | ) { 13 | data { 14 | challengeQuestionsV2 { 15 | date 16 | type 17 | } 18 | difficulty 19 | isPaidOnly 20 | questionFrontendId 21 | title 22 | titleSlug 23 | } 24 | totalNum 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/api/recent-ac-submission-list/query.graphql: -------------------------------------------------------------------------------- 1 | query RecentAcSubmissionList($username: String!, $limit: Int!) { 2 | recentAcSubmissionList(username: $username, limit: $limit) { 3 | id 4 | title 5 | titleSlug 6 | timestamp 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/api/topic/query.graphql: -------------------------------------------------------------------------------- 1 | query Topic($topicId: Int!) { 2 | topic(id: $topicId) { 3 | title 4 | solutionTags { 5 | slug 6 | } 7 | post { 8 | content 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/getGraphQLClient.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLClient } from "graphql-request"; 2 | 3 | type ErrorPolicy = NonNullable< 4 | NonNullable[1]>["errorPolicy"] 5 | >; 6 | 7 | export function getGraphQLClient( 8 | errorPolicy: ErrorPolicy = "none", 9 | ): GraphQLClient { 10 | return new GraphQLClient("https://leetcode.com/graphql/", { 11 | method: "POST", 12 | headers: { "Content-Type": "application/json" }, 13 | excludeOperationName: true, 14 | errorPolicy, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/normalizeGraphQLDescription.ts: -------------------------------------------------------------------------------- 1 | import { compareStringsCaseInsensitive } from "@code-chronicles/util/compareStringsCaseInsensitive"; 2 | 3 | export function normalizeGraphQLDescription(desc: string): string { 4 | return desc.replaceAll(/
    ((?:
  • [^<]*<\/li>)*)<\/ul>/g, (_, lisMatch) => { 5 | const items = Array.from( 6 | lisMatch.matchAll(/
  • ([^<]*)<\/li>/g), 7 | ([, liMatch]) => liMatch, 8 | ) 9 | .sort(compareStringsCaseInsensitive) 10 | .map((item) => `
  • ${item}
  • `); 11 | 12 | return `
      ${items.join("")}
    `; 13 | }); 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/patch-graphql-schema/assertSingleASTNode.ts: -------------------------------------------------------------------------------- 1 | import type { ASTNode } from "graphql"; 2 | import invariant from "invariant"; 3 | import nullthrows from "nullthrows"; 4 | 5 | // TODO: consistent casing of AST/ast 6 | 7 | export function assertSingleASTNode( 8 | nodeOrNodes: T | readonly T[] | null | undefined, 9 | ): NonNullable { 10 | invariant(!Array.isArray(nodeOrNodes), "Got an array"); 11 | return nullthrows(nodeOrNodes) as T; 12 | } 13 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/patch-graphql-schema/astNodeBuilders.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Kind, 3 | type ListTypeNode, 4 | type NameNode, 5 | type NonNullTypeNode, 6 | } from "graphql"; 7 | 8 | export function nonNullTypeNode( 9 | type: NonNullTypeNode["type"], 10 | ): NonNullTypeNode { 11 | return { 12 | kind: Kind.NON_NULL_TYPE, 13 | type, 14 | }; 15 | } 16 | 17 | export function listTypeNode(type: ListTypeNode["type"]): ListTypeNode { 18 | return { 19 | kind: Kind.LIST_TYPE, 20 | type, 21 | }; 22 | } 23 | 24 | export function nameNode(name: string): NameNode { 25 | return { 26 | kind: Kind.NAME, 27 | value: name, 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/patch-graphql-schema/constants.ts: -------------------------------------------------------------------------------- 1 | export const SCHEMA_FILE_PATCHED = "schema-patched.graphql"; 2 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/scrape-graphql-schema/constants.ts: -------------------------------------------------------------------------------- 1 | export const SCHEMA_FILE_ORIGINAL = "schema-original.graphql"; 2 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/scrape-graphql-schema/encodeValue.ts: -------------------------------------------------------------------------------- 1 | import { Buffer } from "node:buffer"; 2 | 3 | export function encodeValue( 4 | value: string | undefined, 5 | marker: string, 6 | ): string | undefined { 7 | return value == null 8 | ? undefined 9 | : `${marker}-${Buffer.from(value).toString("hex")}`; 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/scripts/scrape-graphql-schema/parseEncodedValues.ts: -------------------------------------------------------------------------------- 1 | import { Buffer } from "node:buffer"; 2 | 3 | export function parseEncodedValues(text: string, marker: string): string { 4 | return text.replace( 5 | new RegExp('"' + marker + '-([^"]+)"', "g"), 6 | (_match, encodedValue) => Buffer.from(encodedValue, "hex").toString("utf8"), 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/sortByName.ts: -------------------------------------------------------------------------------- 1 | import { compareStringsCaseInsensitive } from "@code-chronicles/util/compareStringsCaseInsensitive"; 2 | 3 | export function sortByName(arr: readonly T[]): T[] { 4 | // TODO: migrate to .toSorted 5 | return [...arr].sort((a, b) => compareStringsCaseInsensitive(a.name, b.name)); 6 | } 7 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/zod-types/questionDifficultyZodType.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const questionDifficultyZodType = z.enum(["Easy", "Medium", "Hard"]); 4 | 5 | export type QuestionDifficulty = z.infer; 6 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/zod-types/slugZodType.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const slugZodType = z 4 | .string() 5 | .trim() 6 | .regex(/^[a-z0-9]+(?:\-[a-z0-9]+)*$/); 7 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/src/zod-types/yyyymmddDateZodType.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const yyyymmddDateZodType = z 4 | .string() 5 | .trim() 6 | .regex(/^\d{4}-\d{2}-\d{2}$/); 7 | -------------------------------------------------------------------------------- /workspaces/leetcode-api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-prettier-extension/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/leetcode-prettier-extension/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-prettier-extension/src/isMonaco.ts: -------------------------------------------------------------------------------- 1 | import type { editor as MonacoEditorNamespace } from "monaco-editor"; 2 | 3 | type Monaco = { editor: typeof MonacoEditorNamespace }; 4 | 5 | type RecursiveObj = { [key: string]: RecursiveObj | undefined }; 6 | 7 | export function isMonaco(obj: unknown): obj is Monaco { 8 | return ( 9 | // The optional chaining should make the cast safe enough. 10 | typeof (obj as RecursiveObj | null | undefined)?.editor 11 | ?.onDidCreateEditor === "function" 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /workspaces/leetcode-prettier-extension/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | export default [...config, { ignores: ["dist/"] }]; 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/src/extension/constants.ts: -------------------------------------------------------------------------------- 1 | export const SETTINGS_ATTRIBUTE = "data-leetcode-zen-mode-settings"; 2 | 3 | export const SETTINGS_STORAGE_KEY = "settings"; 4 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/src/extension/content-script-non-isolated/isArrayOfDataByDifficulty.ts: -------------------------------------------------------------------------------- 1 | import { isNonArrayObject } from "@code-chronicles/util/isNonArrayObject"; 2 | import { isString } from "@code-chronicles/util/isString"; 3 | 4 | export function isArrayOfDataByDifficulty( 5 | arr: unknown[], 6 | ): arr is ({ difficulty: string } & Record)[] { 7 | return arr.every( 8 | (elem) => isNonArrayObject(elem) && isString(elem.difficulty), 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/src/extension/content-script-non-isolated/stringCase.ts: -------------------------------------------------------------------------------- 1 | import { isStringLowerCase } from "@code-chronicles/util/isStringLowerCase"; 2 | import { isStringTitleCase } from "@code-chronicles/util/isStringTitleCase"; 3 | import { isStringUpperCase } from "@code-chronicles/util/isStringUpperCase"; 4 | 5 | // Note: The order is significant, earlier entries will take precedence in our 6 | // checks. 7 | export const STRING_CASE_CHECKERS = [ 8 | ["title", isStringTitleCase], 9 | ["upper", isStringUpperCase], 10 | ["lower", isStringLowerCase], 11 | ] as const; 12 | 13 | export const PREFERRED_STRING_CASE = STRING_CASE_CHECKERS[0][0]; 14 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/src/extension/options-ui/main.tsx: -------------------------------------------------------------------------------- 1 | import nullthrows from "nullthrows"; 2 | import React from "react"; 3 | import ReactDOM from "react-dom/client"; 4 | 5 | import { App } from "./components/App.tsx"; 6 | 7 | window.addEventListener( 8 | "load", 9 | () => { 10 | ReactDOM.createRoot( 11 | nullthrows( 12 | document.getElementById("main"), 13 | 'No element with id "main" in the DOM!', 14 | ), 15 | ).render(); 16 | }, 17 | { once: true }, 18 | ); 19 | -------------------------------------------------------------------------------- /workspaces/leetcode-zen-mode/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | 3 | data.json 4 | secrets_DO_NOT_COMMIT_OR_SHARE.json 5 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | // TODO: maybe read the .gitignore? 4 | export default [...config, { ignores: ["dist/"] }]; 5 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/secrets_TEMPLATE.json: -------------------------------------------------------------------------------- 1 | { 2 | "discordToken": "REPLACE WITH BOT TOKEN FROM DISCORD APP (I GOT MINE FROM https://discord.com/developers/applications/NUMERIC-APP-ID/bot)", 3 | "discordChannelID": "REPLACE WITH CHANNEL ID, THIS IS OBTAINABLE FROM A CHANNEL URL LIKE https://discord.com/channels/SERVER-ID/CHANNEL-ID" 4 | } 5 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/src/formatTimestampForDiscord.ts: -------------------------------------------------------------------------------- 1 | type DateType = "t" | "T" | "d" | "D" | "f" | "F" | "R"; 2 | 3 | export function formatTimestampForDiscord( 4 | timestamp: number, 5 | type?: DateType, 6 | ): string { 7 | return ``; 8 | } 9 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/src/readSecrets.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "node:fs/promises"; 2 | 3 | import { z } from "zod"; 4 | 5 | import { numericIdAsStringZodType } from "@code-chronicles/util/zod-types/numericIdAsStringZodType"; 6 | 7 | const SECRETS_FILE = "secrets_DO_NOT_COMMIT_OR_SHARE.json"; 8 | 9 | const secretsZodType = z.object({ 10 | discordChannelID: numericIdAsStringZodType, 11 | discordToken: z.string().min(1), 12 | }); 13 | 14 | export type Secrets = z.infer; 15 | 16 | export async function readSecrets(): Promise { 17 | return secretsZodType.parse(JSON.parse(await readFile(SECRETS_FILE, "utf8"))); 18 | } 19 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/src/writeScriptData.ts: -------------------------------------------------------------------------------- 1 | import { writeFile } from "node:fs/promises"; 2 | 3 | import { DATA_FILE, type Data } from "./readScriptData.ts"; 4 | 5 | export async function writeScriptData(data: Data): Promise { 6 | await writeFile(DATA_FILE, JSON.stringify(data), { 7 | encoding: "utf8", 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /workspaces/post-leetcode-potd-to-discord/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/eslint.config.js: -------------------------------------------------------------------------------- 1 | export { default } from "@code-chronicles/eslint-config"; 2 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/src/bin/lint.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import "tsx"; 4 | 5 | await import("../lint.ts"); 6 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/src/bin/typecheck.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import "tsx"; 4 | 5 | await import("../typecheck.ts"); 6 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/src/chalkLevelOrForced.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | 3 | export const COLOR_LEVEL = chalk.level || 1; 4 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/src/reportCommandAndSpawn.ts: -------------------------------------------------------------------------------- 1 | import type { SpawnOptions } from "node:child_process"; 2 | 3 | import { spawnWithSafeStdio } from "@code-chronicles/util/spawnWithSafeStdio"; 4 | 5 | import { reportCommand } from "./reportCommand.ts"; 6 | 7 | export function reportCommandAndSpawn( 8 | command: string, 9 | args: readonly string[], 10 | options?: SpawnOptions, 11 | ): Promise { 12 | reportCommand(command, args); 13 | return spawnWithSafeStdio(command, args, options); 14 | } 15 | -------------------------------------------------------------------------------- /workspaces/repository-scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig-base.json" 3 | } 4 | -------------------------------------------------------------------------------- /workspaces/simon-game/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | -------------------------------------------------------------------------------- /workspaces/simon-game/eslint.config.js: -------------------------------------------------------------------------------- 1 | import config from "@code-chronicles/eslint-config"; 2 | 3 | // TODO: maybe read the .gitignore? 4 | export default [...config, { ignores: ["dist/"] }]; 5 | -------------------------------------------------------------------------------- /workspaces/simon-game/src/app/components/Box.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | type Props = { 4 | color?: string; 5 | height?: number; 6 | width?: number; 7 | margin?: number; 8 | onClick: () => void; 9 | }; 10 | 11 | export function Box({ 12 | color = "lightblue", 13 | height = 100, 14 | width = 100, 15 | margin, 16 | onClick, 17 | }: Props) { 18 | return ( 19 |