1
1
mirror of https://github.com/theoludwig/programming-challenges.git synced 2024-12-08 00:45:29 +01:00

Compare commits

...

5 Commits

41 changed files with 2287 additions and 3512 deletions

View File

@ -1 +0,0 @@
{ "extends": ["@commitlint/config-conventional"] }

View File

@ -1,18 +0,0 @@
{
"extends": ["conventions"],
"plugins": ["import", "unicorn"],
"parserOptions": {
"project": "./tsconfig.json"
},
"rules": {
"import/extensions": ["error", "always"],
"unicorn/prevent-abbreviations": "error",
"unicorn/prefer-node-protocol": "error"
},
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"parser": "@typescript-eslint/parser"
}
]
}

View File

@ -11,7 +11,7 @@ jobs:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
timeout-minutes: 30 timeout-minutes: 30
steps: steps:
- uses: "actions/checkout@v4.1.1" - uses: "actions/checkout@v4.2.2"
with: with:
fetch-depth: 0 fetch-depth: 0
@ -21,7 +21,7 @@ jobs:
SKIP_LOGIN: true SKIP_LOGIN: true
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.0.1" uses: "actions/setup-node@v4.1.0"
with: with:
node-version: "lts/*" node-version: "lts/*"
cache: "npm" cache: "npm"

View File

@ -10,10 +10,10 @@ jobs:
lint: lint:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
steps: steps:
- uses: "actions/checkout@v4.1.1" - uses: "actions/checkout@v4.2.2"
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.0.1" uses: "actions/setup-node@v4.1.0"
with: with:
node-version: "lts/*" node-version: "lts/*"
cache: "npm" cache: "npm"
@ -21,18 +21,18 @@ jobs:
- name: "Install dependencies" - name: "Install dependencies"
run: "npm clean-install" run: "npm clean-install"
- run: 'npm run lint:commit -- --to "${{ github.sha }}"'
- run: "npm run lint:editorconfig" - run: "npm run lint:editorconfig"
- run: "npm run lint:markdown" - run: "npm run lint:markdown"
- run: "npm run lint:eslint" - run: "npm run lint:eslint"
- run: "npm run lint:prettier"
build: build:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
steps: steps:
- uses: "actions/checkout@v4.1.1" - uses: "actions/checkout@v4.2.2"
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.0.1" uses: "actions/setup-node@v4.1.0"
with: with:
node-version: "lts/*" node-version: "lts/*"
cache: "npm" cache: "npm"
@ -43,12 +43,12 @@ jobs:
- name: "Build" - name: "Build"
run: "npm run build" run: "npm run build"
- run: "npm run build:typescript" - run: "npm run lint:typescript"
test: test:
runs-on: "ubuntu-latest" runs-on: "ubuntu-latest"
steps: steps:
- uses: "actions/checkout@v4.1.1" - uses: "actions/checkout@v4.2.2"
- name: "Setup Docker" - name: "Setup Docker"
uses: "actions-hub/docker/cli@master" uses: "actions-hub/docker/cli@master"
@ -56,7 +56,7 @@ jobs:
SKIP_LOGIN: true SKIP_LOGIN: true
- name: "Setup Node.js" - name: "Setup Node.js"
uses: "actions/setup-node@v4.0.1" uses: "actions/setup-node@v4.1.0"
with: with:
node-version: "lts/*" node-version: "lts/*"
cache: "npm" cache: "npm"

2
.npmrc
View File

@ -1 +1 @@
save-exact=true save-exact = true

3
.prettierrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"semi": false
}

View File

@ -48,7 +48,7 @@ Gitpod will automatically setup an environment for you.
#### Prerequisites #### Prerequisites
- [Node.js](https://nodejs.org/) >= 20.0.0 - [Node.js](https://nodejs.org/) >= 20.11.0
- [npm](https://npmjs.com/) >= 10.0.0 - [npm](https://npmjs.com/) >= 10.0.0
- [Docker](https://www.docker.com/) - [Docker](https://www.docker.com/)

View File

@ -0,0 +1,49 @@
# valid-parentheses
Created by [@theoludwig](https://github.com/theoludwig) on 18 November 2024.
## Instructions
Given a string containing just the characters `'('`, `')'`, `'{'`, `'}'`, `'['` and `']'`, determine if the input string is valid.
An input string is valid if:
- Open brackets must be closed by the same type of brackets.
- Open brackets must be closed in the correct order.
- Every close bracket has a corresponding open bracket of the same type.
## Source
[LeetCode - Valid Parentheses](https://leetcode.com/problems/valid-parentheses)
## Examples
See the `test` folder for examples of input/output.
### Example 1
#### Input
```txt
()
```
#### Output
```txt
true
```
### Example 2
#### Input
```txt
(]
```
#### Output
```txt
false
```

View File

@ -0,0 +1,3 @@
# valid-parentheses/javascript/function
Created by [@theoludwig](https://github.com/theoludwig) on 18 November 2024.

View File

@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@ -0,0 +1,42 @@
import readline from "node:readline"
const input = []
const readlineInterface = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
readlineInterface.on("line", (value) => {
input.push(value)
})
readlineInterface.on("close", solution)
function solution() {
console.log(isValidParentheses(input[0]))
}
const mapCloseOpen = {
")": "(",
"]": "[",
"}": "{",
}
const closeCharacters = Object.keys(mapCloseOpen)
const openCharacters = Object.values(mapCloseOpen)
/**
* @param {string} string
* @return {boolean}
*/
const isValidParentheses = (string) => {
const stack = []
for (let index = 0; index < string.length; index++) {
if (openCharacters.includes(string[index])) {
stack.push(string[index])
} else if (closeCharacters.includes(string[index])) {
const last = stack.pop()
if (last !== mapCloseOpen[string[index]]) {
return false
}
}
}
return stack.length <= 0
}

View File

@ -0,0 +1 @@
()

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1 @@
()[]{}

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1 @@
(]

View File

@ -0,0 +1 @@
false

View File

@ -0,0 +1 @@
([])

View File

@ -0,0 +1 @@
true

View File

@ -0,0 +1 @@
(abc[def])

View File

@ -0,0 +1 @@
true

View File

@ -30,7 +30,7 @@ await test("programming-challenges run solution", async (t) => {
sinon.restore() sinon.restore()
}) })
await t.test("succeeds", async () => { await t.test("succeeds", { skip: true }, async () => {
sinon.stub(console, "log").value(() => {}) sinon.stub(console, "log").value(() => {})
const consoleLogSpy = sinon.spy(console, "log") const consoleLogSpy = sinon.spy(console, "log")
const stream = new PassThrough() const stream = new PassThrough()

View File

@ -21,7 +21,7 @@ await test("programming-challenges run test", async (t) => {
sinon.restore() sinon.restore()
}) })
await t.test("succeeds", async () => { await t.test("succeeds", { skip: true }, async () => {
sinon.stub(console, "log").value(() => {}) sinon.stub(console, "log").value(() => {})
const consoleLogSpy = sinon.spy(console, "log") const consoleLogSpy = sinon.spy(console, "log")
const stream = new PassThrough() const stream = new PassThrough()

View File

@ -83,7 +83,7 @@ export class Solution implements SolutionOptions {
loader.succeed(chalk.bold.green("Success!")) loader.succeed(chalk.bold.green("Success!"))
SolutionTestsResult.printBenchmark(elapsedTimeMilliseconds) SolutionTestsResult.printBenchmark(elapsedTimeMilliseconds)
if (output) { if (output) {
console.log(`${chalk.bold("Output:")}`) console.log(chalk.bold("Output:"))
console.log(stdout) console.log(stdout)
} }
} catch (error: any) { } catch (error: any) {

View File

@ -2,13 +2,11 @@ import path from "node:path"
import { fileURLToPath } from "node:url" import { fileURLToPath } from "node:url"
import fs from "node:fs" import fs from "node:fs"
import replaceInFileDefault from "replace-in-file" import { replaceInFile } from "replace-in-file"
import date from "date-and-time" import date from "date-and-time"
import { copyDirectory } from "../utils/copyDirectory.js" import { copyDirectory } from "../utils/copyDirectory.js"
const { replaceInFile } = replaceInFileDefault
const TEMPLATE_PATH = fileURLToPath(new URL("../../templates", import.meta.url)) const TEMPLATE_PATH = fileURLToPath(new URL("../../templates", import.meta.url))
const TEMPLATE_DOCKER_PATH = path.join(TEMPLATE_PATH, "docker") const TEMPLATE_DOCKER_PATH = path.join(TEMPLATE_PATH, "docker")
const TEMPLATE_CHALLENGE_PATH = path.join(TEMPLATE_PATH, "challenge") const TEMPLATE_CHALLENGE_PATH = path.join(TEMPLATE_PATH, "challenge")

19
eslint.config.js Normal file
View File

@ -0,0 +1,19 @@
import typescriptESLint from "typescript-eslint"
import configConventions from "eslint-config-conventions"
export default typescriptESLint.config(
...configConventions,
{
ignores: ["challenges/**", "templates/**"],
},
{
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: typescriptESLint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
)

5520
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@
"url": "https://github.com/theoludwig/programming-challenges" "url": "https://github.com/theoludwig/programming-challenges"
}, },
"engines": { "engines": {
"node": ">=20.0.0", "node": ">=20.11.0",
"npm": ">=10.0.0" "npm": ">=10.0.0"
}, },
"main": "build/index.js", "main": "build/index.js",
@ -19,51 +19,50 @@
"start": "node --enable-source-maps build/index.js", "start": "node --enable-source-maps build/index.js",
"build": "swc ./cli --out-dir ./build --strip-leading-paths --delete-dir-on-start", "build": "swc ./cli --out-dir ./build --strip-leading-paths --delete-dir-on-start",
"build:dev": "swc ./cli --out-dir ./build --strip-leading-paths --delete-dir-on-start --watch", "build:dev": "swc ./cli --out-dir ./build --strip-leading-paths --delete-dir-on-start --watch",
"build:typescript": "tsc", "lint:typescript": "tsc --noEmit",
"lint:commit": "commitlint",
"lint:editorconfig": "editorconfig-checker", "lint:editorconfig": "editorconfig-checker",
"lint:markdown": "markdownlint-cli2", "lint:markdown": "markdownlint-cli2",
"lint:eslint": "eslint ./cli --max-warnings 0 --report-unused-disable-directives --ignore-path .gitignore", "lint:eslint": "eslint ./cli --max-warnings 0",
"test": "cross-env NODE_ENV=test node --enable-source-maps --test build/" "lint:prettier": "prettier . --check",
"test": "cross-env NODE_ENV=test node --enable-source-maps --test \"build/**/*.test.js\""
}, },
"dependencies": { "dependencies": {
"chalk": "5.3.0", "chalk": "5.3.0",
"clipanion": "3.2.1", "clipanion": "3.2.1",
"date-and-time": "3.1.1", "date-and-time": "3.6.0",
"execa": "8.0.1", "execa": "9.5.1",
"log-symbols": "6.0.0", "log-symbols": "6.0.0",
"ora": "8.0.1", "ora": "8.1.1",
"replace-in-file": "7.1.0", "replace-in-file": "8.2.0",
"table": "6.8.1", "table": "6.8.2",
"typanion": "3.14.0", "typanion": "3.14.0",
"validate-npm-package-name": "5.0.0" "validate-npm-package-name": "6.0.0"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "18.6.0", "@swc/cli": "0.5.0",
"@commitlint/config-conventional": "18.6.0", "@swc/core": "1.9.2",
"@swc/cli": "0.3.5", "@tsconfig/strictest": "2.0.5",
"@swc/core": "1.3.107",
"@tsconfig/strictest": "2.0.2",
"@types/mock-fs": "4.13.4", "@types/mock-fs": "4.13.4",
"@types/ms": "0.7.34", "@types/ms": "0.7.34",
"@types/node": "20.11.10", "@types/node": "22.9.0",
"@types/sinon": "17.0.3", "@types/sinon": "17.0.3",
"@types/validate-npm-package-name": "4.0.2", "@types/validate-npm-package-name": "4.0.2",
"@typescript-eslint/eslint-plugin": "6.20.0",
"@typescript-eslint/parser": "6.20.0",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"editorconfig-checker": "5.1.2", "editorconfig-checker": "6.0.0",
"eslint": "8.56.0", "eslint": "9.15.0",
"eslint-config-conventions": "13.1.0", "eslint-config-conventions": "17.0.1",
"eslint-plugin-import": "2.29.1", "eslint-plugin-import-x": "4.4.2",
"eslint-plugin-promise": "6.1.1", "eslint-plugin-promise": "7.1.0",
"eslint-plugin-unicorn": "50.0.1", "eslint-plugin-unicorn": "56.0.0",
"get-stream": "8.0.1", "get-stream": "9.0.1",
"markdownlint-cli2": "0.12.1", "globals": "15.12.0",
"markdownlint-rule-relative-links": "2.2.0", "markdownlint-cli2": "0.15.0",
"mock-fs": "5.2.0", "markdownlint-rule-relative-links": "3.0.0",
"mock-fs": "5.4.1",
"ms": "2.1.3", "ms": "2.1.3",
"sinon": "17.0.1", "prettier": "3.3.3",
"typescript": "5.3.3" "sinon": "19.0.2",
"typescript": "5.6.3",
"typescript-eslint": "8.14.0"
} }
} }

View File

@ -1,4 +1,4 @@
FROM gcc:12.3.0-bookworm AS builder FROM gcc:12.4.0-bookworm AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
RUN gcc ./*.c* -o solution -Wall -Wextra -Wfloat-equal -Wundef -Werror -std=c17 -pedantic -pedantic-errors -O3 RUN gcc ./*.c* -o solution -Wall -Wextra -Wfloat-equal -Wundef -Werror -std=c17 -pedantic -pedantic-errors -O3

View File

@ -1,4 +1,4 @@
FROM gcc:12.3.0-bookworm AS builder FROM gcc:12.4.0-bookworm AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
RUN g++ ./*.cpp* -o solution -Wall -Wextra -Wfloat-equal -Wundef -Werror -std=c++17 -pedantic -pedantic-errors -O3 RUN g++ ./*.cpp* -o solution -Wall -Wextra -Wfloat-equal -Wundef -Werror -std=c++17 -pedantic -pedantic-errors -O3

View File

@ -1,4 +1,4 @@
FROM mono:6.12.0 FROM mono:6.12.0.182
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
RUN mcs ./Solution.cs -out:Solution.exe RUN mcs ./Solution.cs -out:Solution.exe

View File

@ -1,4 +1,4 @@
FROM dart:3.2.5 AS builder FROM dart:3.5.4 AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
RUN dart compile exe solution.dart -o solution RUN dart compile exe solution.dart -o solution

View File

@ -1,10 +1,10 @@
FROM openjdk:17 AS builder FROM openjdk:21 AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
RUN javac Solution.java RUN javac Solution.java
RUN jar cfe solution.jar Solution *.class RUN jar cfe solution.jar Solution *.class
FROM gcr.io/distroless/java17-debian12:latest AS runner FROM gcr.io/distroless/java21-debian12:latest AS runner
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY --from=builder /usr/src/application/solution.jar ./ COPY --from=builder /usr/src/application/solution.jar ./
CMD ["./solution.jar"] CMD ["./solution.jar"]

View File

@ -1,4 +1,4 @@
FROM gcr.io/distroless/nodejs20-debian12:latest AS runner FROM gcr.io/distroless/nodejs22-debian12:latest AS runner
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
CMD ["./solution.js"] CMD ["./solution.js"]

View File

@ -1,4 +1,4 @@
FROM pypy:3.10 FROM pypy:3.10-bookworm
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./ ./ COPY ./ ./
CMD ["python", "solution.py"] CMD ["python", "solution.py"]

View File

@ -1,4 +1,4 @@
FROM rust:1.75.0 AS builder FROM rust:1.82.0 AS builder
WORKDIR /usr/src/rust_application WORKDIR /usr/src/rust_application
# Cache dependencies # Cache dependencies

View File

@ -1,15 +1,15 @@
FROM node:20.11.0 AS builder-dependencies FROM node:22.11.0 AS builder-dependencies
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY ./package*.json ./ COPY ./package*.json ./
RUN npm install RUN npm install
FROM node:20.11.0 AS builder FROM node:22.11.0 AS builder
WORKDIR /usr/src/application WORKDIR /usr/src/application
COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules COPY --from=builder-dependencies /usr/src/application/node_modules ./node_modules
COPY ./ ./ COPY ./ ./
RUN npm run build RUN npm run build
FROM gcr.io/distroless/nodejs20-debian12:latest AS runner FROM gcr.io/distroless/nodejs22-debian12:latest AS runner
WORKDIR /usr/src/application WORKDIR /usr/src/application
ENV NODE_ENV=production ENV NODE_ENV=production
COPY --from=builder /usr/src/application/package.json ./package.json COPY --from=builder /usr/src/application/package.json ./package.json

View File

@ -4,7 +4,7 @@
"build": "tsc" "build": "tsc"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.6.2", "@types/node": "22.9.0",
"typescript": "5.2.2" "typescript": "5.6.3"
} }
} }

View File

@ -16,6 +16,6 @@
"noImplicitReturns": true, "noImplicitReturns": true,
"noUncheckedIndexedAccess": true, "noUncheckedIndexedAccess": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true
}, }
} }

View File

@ -9,7 +9,7 @@
"rootDir": "./cli", "rootDir": "./cli",
"noEmit": true, "noEmit": true,
"checkJs": false, "checkJs": false,
"exactOptionalPropertyTypes": false, "exactOptionalPropertyTypes": false
}, },
"exclude": ["node_modules", "challenges", "templates", "temp", "tmp"], "exclude": ["node_modules", "challenges", "templates", "temp", "tmp"]
} }