mirror of
https://github.com/theoludwig/programming-challenges.git
synced 2025-05-18 12:02:53 +02:00
Compare commits
9 Commits
c807aeaf3f
...
master
Author | SHA1 | Date | |
---|---|---|---|
773f381f9f
|
|||
070ac30ec3
|
|||
643989cc44
|
|||
2b6669bf4a
|
|||
db15155137
|
|||
9b925eea92
|
|||
f28d1b816d
|
|||
8cda0ed622
|
|||
9a187deaef
|
@ -1 +0,0 @@
|
|||||||
{ "extends": ["@commitlint/config-conventional"] }
|
|
@ -10,7 +10,7 @@ charset = utf-8
|
|||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.{py,cs,rs,java}]
|
[*.{py,cs,rs,java,md}]
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
[*.txt]
|
[*.txt]
|
||||||
|
@ -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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
4
.github/ISSUE_TEMPLATE/BUG.md
vendored
4
.github/ISSUE_TEMPLATE/BUG.md
vendored
@ -6,8 +6,8 @@ labels: "bug"
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please provide a clear and concise description of what the bug is. Include
|
Please provide a clear and concise description of what the bug is. Include
|
||||||
screenshots if needed. Please make sure your issue has not already been fixed.
|
screenshots if needed. Please make sure your issue has not already been fixed.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
## Steps To Reproduce
|
## Steps To Reproduce
|
||||||
|
4
.github/workflows/challenges.yml
vendored
4
.github/workflows/challenges.yml
vendored
@ -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.4.0"
|
||||||
with:
|
with:
|
||||||
node-version: "lts/*"
|
node-version: "lts/*"
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
16
.github/workflows/cli.yml
vendored
16
.github/workflows/cli.yml
vendored
@ -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.4.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.4.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.4.0"
|
||||||
with:
|
with:
|
||||||
node-version: "lts/*"
|
node-version: "lts/*"
|
||||||
cache: "npm"
|
cache: "npm"
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -28,3 +28,6 @@ coverage
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
temp
|
temp
|
||||||
tmp
|
tmp
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"config": {
|
|
||||||
"extends": "markdownlint/style/prettier",
|
|
||||||
"default": true,
|
|
||||||
"relative-links": true,
|
|
||||||
"no-duplicate-heading": false,
|
|
||||||
"no-inline-html": false,
|
|
||||||
},
|
|
||||||
"globs": ["**/*.md"],
|
|
||||||
"ignores": ["**/node_modules"],
|
|
||||||
"customRules": ["markdownlint-rule-relative-links"],
|
|
||||||
}
|
|
19
.markdownlint-cli2.mjs
Normal file
19
.markdownlint-cli2.mjs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import relativeLinksRule, { markdownIt } from "markdownlint-rule-relative-links"
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
config: {
|
||||||
|
extends: "markdownlint/style/prettier",
|
||||||
|
default: true,
|
||||||
|
"relative-links": true,
|
||||||
|
"no-duplicate-heading": false,
|
||||||
|
"no-inline-html": false,
|
||||||
|
},
|
||||||
|
globs: ["**/*.md"],
|
||||||
|
ignores: ["**/node_modules"],
|
||||||
|
customRules: [relativeLinksRule],
|
||||||
|
markdownItFactory: () => {
|
||||||
|
return markdownIt
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default config
|
3
.prettierrc.json
Normal file
3
.prettierrc.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"semi": false
|
||||||
|
}
|
@ -20,21 +20,16 @@ community include:
|
|||||||
- Demonstrating empathy and kindness toward other people
|
- Demonstrating empathy and kindness toward other people
|
||||||
- Being respectful of differing opinions, viewpoints, and experiences
|
- Being respectful of differing opinions, viewpoints, and experiences
|
||||||
- Giving and gracefully accepting constructive feedback
|
- Giving and gracefully accepting constructive feedback
|
||||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
||||||
and learning from the experience
|
- Focusing on what is best not just for us as individuals, but for the overall community
|
||||||
- Focusing on what is best not just for us as individuals, but for the
|
|
||||||
overall community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
Examples of unacceptable behavior include:
|
||||||
|
|
||||||
- The use of sexualized language or imagery, and sexual attention or
|
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
||||||
advances of any kind
|
|
||||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||||
- Public or private harassment
|
- Public or private harassment
|
||||||
- Publishing others' private information, such as a physical or email
|
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
||||||
address, without their explicit permission
|
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||||
- Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
## Enforcement Responsibilities
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ You can add support for a new language, so you can solve the challenges with eve
|
|||||||
- Create a new template inside `templates/solution` folder with the file extension of the new programming language, with the basic boilerplate to read from `stdin` and print to `stdout` the result
|
- Create a new template inside `templates/solution` folder with the file extension of the new programming language, with the basic boilerplate to read from `stdin` and print to `stdout` the result
|
||||||
- Every programming language should have at least one working solution for `challenges/hello-world`.
|
- Every programming language should have at least one working solution for `challenges/hello-world`.
|
||||||
|
|
||||||
To generate the solution for the `hello-world` challenge with your new language, run the command `programming-challenges generate solution --challenge="hello-world" --github-user="<your-github-user>" --language="<your-new-language>" --solution="function"`
|
To generate the solution for the `hello-world` challenge with your new language, run the command `programming-challenges generate solution --challenge="hello-world" --github-user="<your-github-user>" --language="<your-new-language>" --solution="function"`
|
||||||
|
|
||||||
Before submitting the new programming language, make sure it passes all the tests by running `programming-challenges run test --affected`
|
Before submitting the new programming language, make sure it passes all the tests by running `programming-challenges run test --affected`
|
||||||
|
|
||||||
|
39
README.md
39
README.md
@ -1,21 +1,21 @@
|
|||||||
<h1 align="center">programming-challenges</h1>
|
<h1 align="center">programming-challenges</h1>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<strong>Programming exercises and challenges to improve your algorithmic logic.</strong>
|
<strong>Programming exercises and challenges to improve your algorithmic logic.</strong>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="CONTRIBUTING" /></a>
|
<a href="./CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="CONTRIBUTING" /></a>
|
||||||
<a href="./LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue.svg" alt="Licence MIT"/></a>
|
<a href="./LICENSE"><img src="https://img.shields.io/badge/licence-MIT-blue.svg" alt="Licence MIT"/></a>
|
||||||
<a href="./CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Contributor Covenant" /></a>
|
<a href="./CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Contributor Covenant" /></a>
|
||||||
<br />
|
<br />
|
||||||
<a href="https://github.com/theoludwig/programming-challenges/actions/workflows/cli.yml"><img src="https://github.com/theoludwig/programming-challenges/actions/workflows/cli.yml/badge.svg?branch=master" alt="CLI" /></a>
|
<a href="https://github.com/theoludwig/programming-challenges/actions/workflows/cli.yml"><img src="https://github.com/theoludwig/programming-challenges/actions/workflows/cli.yml/badge.svg?branch=master" alt="CLI" /></a>
|
||||||
<a href="https://github.com/theoludwig/programming-challenges/actions/workflows/challenges.yml"><img src="https://github.com/theoludwig/programming-challenges/actions/workflows/challenges.yml/badge.svg?branch=master" alt="Challenges" /></a>
|
<a href="https://github.com/theoludwig/programming-challenges/actions/workflows/challenges.yml"><img src="https://github.com/theoludwig/programming-challenges/actions/workflows/challenges.yml/badge.svg?branch=master" alt="Challenges" /></a>
|
||||||
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg" alt="Conventional Commits" /></a>
|
<a href="https://conventionalcommits.org"><img src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg" alt="Conventional Commits" /></a>
|
||||||
<br/>
|
<br/>
|
||||||
<a href="https://gitpod.io/#https://github.com/theoludwig/programming-challenges"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod" alt="Gitpod ready-to-code"/></a>
|
<a href="https://gitpod.io/#https://github.com/theoludwig/programming-challenges"><img src="https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod" alt="Gitpod ready-to-code"/></a>
|
||||||
<br/> <br/>
|
<br/> <br/>
|
||||||
<img src="./logo.png" width="120" alt="programming-challenges Logo" />
|
<img src="./logo.png" width="120" alt="programming-challenges Logo" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## 📜 About
|
## 📜 About
|
||||||
@ -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/)
|
||||||
|
|
||||||
@ -80,17 +80,20 @@ programming-challenges --help
|
|||||||
# Generate a new challenge
|
# Generate a new challenge
|
||||||
programming-challenges generate challenge --github-user="YourGitHubName" --challenge="hello-world"
|
programming-challenges generate challenge --github-user="YourGitHubName" --challenge="hello-world"
|
||||||
|
|
||||||
|
# Search for a challenge not yet solved in a specific programming language
|
||||||
|
programming-challenges search --language="rust"
|
||||||
|
|
||||||
# Generate a new solution
|
# Generate a new solution
|
||||||
programming-challenges generate solution --github-user="YourGitHubName" --challenge="hello-world" --solution="function" --language="python"
|
programming-challenges generate solution --github-user="YourGitHubName" --challenge="hello-world" --solution="function" --language="python"
|
||||||
|
|
||||||
# Test a solution
|
|
||||||
programming-challenges run test --challenge="hello-world" --solution="function" --language="python"
|
|
||||||
|
|
||||||
# Run a solution with specific `input.txt` file
|
# Run a solution with specific `input.txt` file
|
||||||
programming-challenges run solution --challenge="hello-world" --solution="function" --language="python" --input-path="./challenges/hello-world/test/1/input.txt" --output
|
programming-challenges run solution --challenge="hello-world" --solution="function" --language="python" --input-path="./challenges/hello-world/test/1/input.txt" --output
|
||||||
|
|
||||||
# Search for a challenge not yet solved in a specific programming language
|
# Test a solution
|
||||||
programming-challenges search --language="rust"
|
programming-challenges run test --challenge="hello-world" --solution="function" --language="python"
|
||||||
|
|
||||||
|
# Test all the solutions in all the challenges
|
||||||
|
programming-challenges run test --all
|
||||||
```
|
```
|
||||||
|
|
||||||
## 💡 Contributing
|
## 💡 Contributing
|
||||||
|
25
challenges/a-phone-code/README.md
Normal file
25
challenges/a-phone-code/README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# a-phone-code
|
||||||
|
|
||||||
|
Created by [@theoludwig](https://github.com/theoludwig) on 13 May 2025.
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
Polycarpus has n friends in Tarasov city. Polycarpus knows phone numbers of all his friends: they are strings s1, s2, ..., sn. All these strings consist only of digits and have the same length.
|
||||||
|
|
||||||
|
Once Polycarpus needed to figure out Tarasov city phone code. He assumed that the phone code of the city is the longest common prefix of all phone numbers of his friends. In other words, it is the longest string c which is a prefix (the beginning) of each si for all i. Help Polycarpus determine the length of the city phone code.
|
||||||
|
|
||||||
|
### Input
|
||||||
|
|
||||||
|
The first line of the input contains an integer n — the number of Polycarpus's friends. The following n lines contain strings — the phone numbers of Polycarpus's friends. It is guaranteed that all strings consist only of digits and have the same length from 1 to 20, inclusive. It is also guaranteed that all strings are different.
|
||||||
|
|
||||||
|
### Output
|
||||||
|
|
||||||
|
Print the number of digits in the city phone code.
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
[Codeforces - A. Phone Code](https://codeforces.com/problemset/problem/172/A)
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
See the `test` folder for examples of input/output.
|
0
challenges/a-phone-code/solutions/.gitkeep
Normal file
0
challenges/a-phone-code/solutions/.gitkeep
Normal file
3
challenges/a-phone-code/solutions/c/function/README.md
Normal file
3
challenges/a-phone-code/solutions/c/function/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# a-phone-code/c/function
|
||||||
|
|
||||||
|
Created by [@theoludwig](https://github.com/theoludwig) on 13 May 2025.
|
7
challenges/a-phone-code/solutions/c/function/character.c
Normal file
7
challenges/a-phone-code/solutions/c/function/character.c
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include "character.h"
|
||||||
|
|
||||||
|
void character_append(char* string, char character) {
|
||||||
|
size_t length = strlen(string);
|
||||||
|
string[length] = character;
|
||||||
|
string[length + 1] = '\0';
|
||||||
|
}
|
16
challenges/a-phone-code/solutions/c/function/character.h
Normal file
16
challenges/a-phone-code/solutions/c/function/character.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __CHARACTER__
|
||||||
|
#define __CHARACTER__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Append a character to a string, assuming string points to an array
|
||||||
|
* with enough space.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* @param character
|
||||||
|
*/
|
||||||
|
void character_append(char* string, char character);
|
||||||
|
|
||||||
|
#endif
|
14
challenges/a-phone-code/solutions/c/function/input.c
Normal file
14
challenges/a-phone-code/solutions/c/function/input.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
char* input() {
|
||||||
|
char character;
|
||||||
|
size_t length = 1;
|
||||||
|
char* string = malloc(length * sizeof(char));
|
||||||
|
*string = '\0';
|
||||||
|
while ((character = getchar()) != '\n' && character != EOF) {
|
||||||
|
length++;
|
||||||
|
string = realloc(string, length * sizeof(char));
|
||||||
|
character_append(string, character);
|
||||||
|
}
|
||||||
|
return string;
|
||||||
|
}
|
16
challenges/a-phone-code/solutions/c/function/input.h
Normal file
16
challenges/a-phone-code/solutions/c/function/input.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __INPUT__
|
||||||
|
#define __INPUT__
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "character.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a line from stdin.
|
||||||
|
*
|
||||||
|
* @return char*
|
||||||
|
*/
|
||||||
|
char* input();
|
||||||
|
|
||||||
|
#endif
|
40
challenges/a-phone-code/solutions/c/function/solution.c
Normal file
40
challenges/a-phone-code/solutions/c/function/solution.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
size_t count = (size_t)atoi(input());
|
||||||
|
size_t prefix_length = 0;
|
||||||
|
|
||||||
|
char* last = NULL;
|
||||||
|
for (size_t i = 1; i < count; i++) {
|
||||||
|
if (last == NULL) {
|
||||||
|
last = input();
|
||||||
|
}
|
||||||
|
char* current = input();
|
||||||
|
|
||||||
|
size_t prefix_current_length = 0;
|
||||||
|
for (size_t j = 0; j < strlen(current); j++) {
|
||||||
|
if (current[j] == last[j]) {
|
||||||
|
prefix_current_length += 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix_length > prefix_current_length) {
|
||||||
|
prefix_length = prefix_current_length;
|
||||||
|
} else if (prefix_length == 0) {
|
||||||
|
prefix_length = prefix_current_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = current;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%ld\n", prefix_length);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
5
challenges/a-phone-code/test/1/input.txt
Normal file
5
challenges/a-phone-code/test/1/input.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
4
|
||||||
|
00209
|
||||||
|
00219
|
||||||
|
00999
|
||||||
|
00909
|
1
challenges/a-phone-code/test/1/output.txt
Normal file
1
challenges/a-phone-code/test/1/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
2
|
3
challenges/a-phone-code/test/2/input.txt
Normal file
3
challenges/a-phone-code/test/2/input.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
2
|
||||||
|
1
|
||||||
|
2
|
1
challenges/a-phone-code/test/2/output.txt
Normal file
1
challenges/a-phone-code/test/2/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
0
|
4
challenges/a-phone-code/test/3/input.txt
Normal file
4
challenges/a-phone-code/test/3/input.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
3
|
||||||
|
77012345678999999999
|
||||||
|
77012345678901234567
|
||||||
|
77012345678998765432
|
1
challenges/a-phone-code/test/3/output.txt
Normal file
1
challenges/a-phone-code/test/3/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
12
|
@ -16,9 +16,7 @@ make?
|
|||||||
### Input
|
### Input
|
||||||
|
|
||||||
- **Line 1:** Single integer `N` for the number of ingredients.
|
- **Line 1:** Single integer `N` for the number of ingredients.
|
||||||
- **`N` next lines:** One for each ingredient. Each of these lines contains two positive integers:
|
- **`N` next lines:** One for each ingredient. Each of these lines contains two positive integers: the first one is the required quantity of this ingredient per cake, the second one is the quantity of this ingredient you have in your kitchen.
|
||||||
the first one is the required quantity of this ingredient per cake, the second one is the quantity of
|
|
||||||
this ingredient you have in your kitchen.
|
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
||||||
@ -32,7 +30,7 @@ available ingredients.
|
|||||||
|
|
||||||
## Source
|
## Source
|
||||||
|
|
||||||
[SWERC 2020–2021 - Problem E: Cake](https://swerc.eu/2020/problems/)
|
[SWERC 2020-2021 - Problem E: Cake](https://swerc.eu/2020/problems/)
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ This data is comprised of lines, each of which represents a defibrillator. Each
|
|||||||
- Contact Phone number
|
- Contact Phone number
|
||||||
- Longitude (degrees)
|
- Longitude (degrees)
|
||||||
- Latitude (degrees)
|
- Latitude (degrees)
|
||||||
These fields are separated by a semicolon (`;`).
|
|
||||||
|
These fields are separated by a semicolon (`;`).
|
||||||
|
|
||||||
**Beware:** the decimal numbers use the comma (,) as decimal separator. Remember to turn the comma (,) into dot (.) if necessary in order to use the data in your program.
|
**Beware:** the decimal numbers use the comma (,) as decimal separator. Remember to turn the comma (,) into dot (.) if necessary in order to use the data in your program.
|
||||||
|
|
||||||
|
@ -14,37 +14,3 @@ Display a pyramid of stars (`*`) whose height is given and in the right order (`
|
|||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
See the `test` folder for examples of input/output.
|
See the `test` folder for examples of input/output.
|
||||||
|
|
||||||
### Example 1
|
|
||||||
|
|
||||||
#### Input
|
|
||||||
|
|
||||||
```txt
|
|
||||||
normal
|
|
||||||
3
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Output
|
|
||||||
|
|
||||||
```txt
|
|
||||||
*
|
|
||||||
***
|
|
||||||
*****
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2
|
|
||||||
|
|
||||||
#### Input
|
|
||||||
|
|
||||||
```txt
|
|
||||||
reverse
|
|
||||||
3
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Output
|
|
||||||
|
|
||||||
```txt
|
|
||||||
*****
|
|
||||||
***
|
|
||||||
*
|
|
||||||
```
|
|
||||||
|
@ -22,9 +22,9 @@ Here are the rules for building a Roman numeral:
|
|||||||
- Subtractions of values are limited to 2 letters only. For example we **cannot** write `8` while doing `IIX`. We must use the addition of letters like this `VIII`.
|
- Subtractions of values are limited to 2 letters only. For example we **cannot** write `8` while doing `IIX`. We must use the addition of letters like this `VIII`.
|
||||||
- Therefore, the first ten numbers are written as `I`, `II`, `III`, `IV`, `V`, `VI`, `VII`, `VIII`, `IX`, `X` . Larger numbers follow the same pattern.
|
- Therefore, the first ten numbers are written as `I`, `II`, `III`, `IV`, `V`, `VI`, `VII`, `VIII`, `IX`, `X` . Larger numbers follow the same pattern.
|
||||||
- You can associate as many symbols as you want to write larger numbers, for example:
|
- You can associate as many symbols as you want to write larger numbers, for example:
|
||||||
- `36` is written as `XXXVI`
|
- `36` is written as `XXXVI`
|
||||||
- `42` is written as `XLII`
|
- `42` is written as `XLII`
|
||||||
- `2448` is written as `MMCDXLVIII`.
|
- `2448` is written as `MMCDXLVIII`.
|
||||||
|
|
||||||
| Symbol | I | V | X | L | C | D | M |
|
| Symbol | I | V | X | L | C | D | M |
|
||||||
| ------ | --- | --- | --- | --- | --- | --- | ---- |
|
| ------ | --- | --- | --- | --- | --- | --- | ---- |
|
||||||
|
49
challenges/valid-parentheses/README.md
Normal file
49
challenges/valid-parentheses/README.md
Normal 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
|
||||||
|
```
|
0
challenges/valid-parentheses/solutions/.gitkeep
Normal file
0
challenges/valid-parentheses/solutions/.gitkeep
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# valid-parentheses/javascript/function
|
||||||
|
|
||||||
|
Created by [@theoludwig](https://github.com/theoludwig) on 18 November 2024.
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"type": "module"
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
1
challenges/valid-parentheses/test/1/input.txt
Normal file
1
challenges/valid-parentheses/test/1/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
()
|
1
challenges/valid-parentheses/test/1/output.txt
Normal file
1
challenges/valid-parentheses/test/1/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
1
challenges/valid-parentheses/test/2/input.txt
Normal file
1
challenges/valid-parentheses/test/2/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
()[]{}
|
1
challenges/valid-parentheses/test/2/output.txt
Normal file
1
challenges/valid-parentheses/test/2/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
1
challenges/valid-parentheses/test/3/input.txt
Normal file
1
challenges/valid-parentheses/test/3/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
(]
|
1
challenges/valid-parentheses/test/3/output.txt
Normal file
1
challenges/valid-parentheses/test/3/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
false
|
1
challenges/valid-parentheses/test/4/input.txt
Normal file
1
challenges/valid-parentheses/test/4/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
([])
|
1
challenges/valid-parentheses/test/4/output.txt
Normal file
1
challenges/valid-parentheses/test/4/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
1
challenges/valid-parentheses/test/5/input.txt
Normal file
1
challenges/valid-parentheses/test/5/input.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
(abc[def])
|
1
challenges/valid-parentheses/test/5/output.txt
Normal file
1
challenges/valid-parentheses/test/5/output.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
true
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
@ -19,7 +19,7 @@ export class Challenge implements ChallengeOptions {
|
|||||||
public name: string
|
public name: string
|
||||||
public path: string
|
public path: string
|
||||||
|
|
||||||
constructor(options: ChallengeOptions) {
|
public constructor(options: ChallengeOptions) {
|
||||||
const { name } = options
|
const { name } = options
|
||||||
this.name = name
|
this.name = name
|
||||||
this.path = fileURLToPath(new URL(`./${name}`, Challenge.BASE_URL))
|
this.path = fileURLToPath(new URL(`./${name}`, Challenge.BASE_URL))
|
||||||
|
@ -20,7 +20,7 @@ export interface GitAffectedOptions {
|
|||||||
export class GitAffected implements GitAffectedOptions {
|
export class GitAffected implements GitAffectedOptions {
|
||||||
public base?: string
|
public base?: string
|
||||||
|
|
||||||
constructor(options: GitAffectedOptions = {}) {
|
public constructor(options: GitAffectedOptions = {}) {
|
||||||
this.base = options.base
|
this.base = options.base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export class Solution implements SolutionOptions {
|
|||||||
public path: string
|
public path: string
|
||||||
public temporaryFolder: TemporaryFolder
|
public temporaryFolder: TemporaryFolder
|
||||||
|
|
||||||
constructor(options: SolutionOptions) {
|
public constructor(options: SolutionOptions) {
|
||||||
const { programmingLanguageName, challenge, name } = options
|
const { programmingLanguageName, challenge, name } = options
|
||||||
this.programmingLanguageName = programmingLanguageName
|
this.programmingLanguageName = programmingLanguageName
|
||||||
this.challenge = challenge
|
this.challenge = challenge
|
||||||
@ -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) {
|
||||||
@ -92,7 +92,9 @@ export class Solution implements SolutionOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async generate(options: GenerateSolutionOptions): Promise<Solution> {
|
public static async generate(
|
||||||
|
options: GenerateSolutionOptions,
|
||||||
|
): Promise<Solution> {
|
||||||
const { name, challengeName, programmingLanguageName, githubUser } = options
|
const { name, challengeName, programmingLanguageName, githubUser } = options
|
||||||
const challenge = new Challenge({ name: challengeName })
|
const challenge = new Challenge({ name: challengeName })
|
||||||
if (!(await isExistingPath(challenge.path))) {
|
if (!(await isExistingPath(challenge.path))) {
|
||||||
@ -116,7 +118,7 @@ export class Solution implements SolutionOptions {
|
|||||||
return solution
|
return solution
|
||||||
}
|
}
|
||||||
|
|
||||||
static async get(options: GetSolutionOptions): Promise<Solution> {
|
public static async get(options: GetSolutionOptions): Promise<Solution> {
|
||||||
const { name, challengeName, programmingLanguageName } = options
|
const { name, challengeName, programmingLanguageName } = options
|
||||||
const challenge = new Challenge({
|
const challenge = new Challenge({
|
||||||
name: challengeName,
|
name: challengeName,
|
||||||
@ -132,7 +134,9 @@ export class Solution implements SolutionOptions {
|
|||||||
return solution
|
return solution
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getManyByChallenge(challenge: Challenge): Promise<Solution[]> {
|
public static async getManyByChallenge(
|
||||||
|
challenge: Challenge,
|
||||||
|
): Promise<Solution[]> {
|
||||||
const solutionsPath = path.join(challenge.path, "solutions")
|
const solutionsPath = path.join(challenge.path, "solutions")
|
||||||
const languagesSolution = (await fs.promises.readdir(solutionsPath)).filter(
|
const languagesSolution = (await fs.promises.readdir(solutionsPath)).filter(
|
||||||
(name) => {
|
(name) => {
|
||||||
@ -151,7 +155,7 @@ export class Solution implements SolutionOptions {
|
|||||||
return await Solution.getManyByPaths(paths)
|
return await Solution.getManyByPaths(paths)
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getManyByProgrammingLanguages(
|
public static async getManyByProgrammingLanguages(
|
||||||
programmingLanguages?: string[],
|
programmingLanguages?: string[],
|
||||||
): Promise<Solution[]> {
|
): Promise<Solution[]> {
|
||||||
const languages =
|
const languages =
|
||||||
@ -185,7 +189,7 @@ export class Solution implements SolutionOptions {
|
|||||||
* @param paths relative to `challenges` (e.g: `challenges/hello-world/solutions/c/function`)
|
* @param paths relative to `challenges` (e.g: `challenges/hello-world/solutions/c/function`)
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
static async getManyByPaths(paths: string[]): Promise<Solution[]> {
|
public static async getManyByPaths(paths: string[]): Promise<Solution[]> {
|
||||||
const solutions: string[] = []
|
const solutions: string[] = []
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
if (await isExistingPath(path)) {
|
if (await isExistingPath(path)) {
|
||||||
|
@ -25,7 +25,7 @@ export class SolutionTestsResult implements SolutionTestsResultOptions {
|
|||||||
"Success:",
|
"Success:",
|
||||||
)} Tests passed! 🎉`
|
)} Tests passed! 🎉`
|
||||||
|
|
||||||
constructor(options: SolutionTestsResultOptions) {
|
public constructor(options: SolutionTestsResultOptions) {
|
||||||
this.tests = options.tests.sort((a, b) => {
|
this.tests = options.tests.sort((a, b) => {
|
||||||
return a.testNumber - b.testNumber
|
return a.testNumber - b.testNumber
|
||||||
})
|
})
|
||||||
|
@ -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")
|
||||||
|
@ -35,7 +35,7 @@ export class Test implements TestOptions {
|
|||||||
public output: string
|
public output: string
|
||||||
public stdout: string
|
public stdout: string
|
||||||
|
|
||||||
constructor(options: TestOptions) {
|
public constructor(options: TestOptions) {
|
||||||
this.testNumber = options.testNumber
|
this.testNumber = options.testNumber
|
||||||
this.path = options.path
|
this.path = options.path
|
||||||
this.isSuccess = options.isSuccess
|
this.isSuccess = options.isSuccess
|
||||||
@ -44,7 +44,7 @@ export class Test implements TestOptions {
|
|||||||
this.stdout = options.stdout
|
this.stdout = options.stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
static async runAll(solution: Solution): Promise<SolutionTestsResult> {
|
public static async runAll(solution: Solution): Promise<SolutionTestsResult> {
|
||||||
const testsPath = path.join(solution.challenge.path, "test")
|
const testsPath = path.join(solution.challenge.path, "test")
|
||||||
const testsFolders = await fs.promises.readdir(testsPath)
|
const testsFolders = await fs.promises.readdir(testsPath)
|
||||||
const testsNumbers = testsFolders.map((test) => {
|
const testsNumbers = testsFolders.map((test) => {
|
||||||
@ -62,7 +62,7 @@ export class Test implements TestOptions {
|
|||||||
return new SolutionTestsResult({ solution, tests, elapsedTimeMilliseconds })
|
return new SolutionTestsResult({ solution, tests, elapsedTimeMilliseconds })
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getInputOutput(testPath: string): Promise<InputOutput> {
|
public static async getInputOutput(testPath: string): Promise<InputOutput> {
|
||||||
const inputPath = path.join(testPath, "input.txt")
|
const inputPath = path.join(testPath, "input.txt")
|
||||||
const outputPath = path.join(testPath, "output.txt")
|
const outputPath = path.join(testPath, "output.txt")
|
||||||
const input = await fs.promises.readFile(inputPath, { encoding: "utf-8" })
|
const input = await fs.promises.readFile(inputPath, { encoding: "utf-8" })
|
||||||
@ -72,7 +72,9 @@ export class Test implements TestOptions {
|
|||||||
return { input, output }
|
return { input, output }
|
||||||
}
|
}
|
||||||
|
|
||||||
static async runManyWithSolutions(solutions: Solution[]): Promise<number> {
|
public static async runManyWithSolutions(
|
||||||
|
solutions: Solution[],
|
||||||
|
): Promise<number> {
|
||||||
const solutionTestsResultsPromises: Array<Promise<SolutionTestsResult>> = []
|
const solutionTestsResultsPromises: Array<Promise<SolutionTestsResult>> = []
|
||||||
let isSolutionSuccess = true
|
let isSolutionSuccess = true
|
||||||
for (const solution of solutions) {
|
for (const solution of solutions) {
|
||||||
@ -85,7 +87,9 @@ export class Test implements TestOptions {
|
|||||||
isSolutionSuccess = false
|
isSolutionSuccess = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
.catch(() => {
|
||||||
|
isSolutionSuccess = false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
await Promise.all(solutionTestsResultsPromises)
|
await Promise.all(solutionTestsResultsPromises)
|
||||||
await TemporaryFolder.cleanAll()
|
await TemporaryFolder.cleanAll()
|
||||||
@ -96,7 +100,7 @@ export class Test implements TestOptions {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
static async run(options: TestRunOptions): Promise<Test> {
|
public static async run(options: TestRunOptions): Promise<Test> {
|
||||||
const { input, output } = await Test.getInputOutput(options.path)
|
const { input, output } = await Test.getInputOutput(options.path)
|
||||||
try {
|
try {
|
||||||
const { stdout } = await docker.run(
|
const { stdout } = await docker.run(
|
||||||
|
19
eslint.config.js
Normal file
19
eslint.config.js
Normal 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
8977
package-lock.json
generated
8977
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
68
package.json
68
package.json
@ -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,49 @@
|
|||||||
"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.4.1",
|
||||||
"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.3",
|
||||||
"log-symbols": "6.0.0",
|
"log-symbols": "7.0.0",
|
||||||
"ora": "8.0.1",
|
"ora": "8.2.0",
|
||||||
"replace-in-file": "7.1.0",
|
"replace-in-file": "8.3.0",
|
||||||
"table": "6.8.1",
|
"table": "6.9.0",
|
||||||
"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.7.7",
|
||||||
"@commitlint/config-conventional": "18.6.0",
|
"@swc/core": "1.11.24",
|
||||||
"@swc/cli": "0.3.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": "2.1.0",
|
||||||
"@types/node": "20.11.10",
|
"@types/node": "22.15.17",
|
||||||
"@types/sinon": "17.0.3",
|
"@types/sinon": "17.0.4",
|
||||||
"@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.1",
|
||||||
"eslint": "8.56.0",
|
"eslint": "9.26.0",
|
||||||
"eslint-config-conventions": "13.1.0",
|
"eslint-config-conventions": "19.2.0",
|
||||||
"eslint-plugin-import": "2.29.1",
|
"eslint-plugin-import-x": "4.11.1",
|
||||||
"eslint-plugin-promise": "6.1.1",
|
"eslint-plugin-promise": "7.2.1",
|
||||||
"eslint-plugin-unicorn": "50.0.1",
|
"eslint-plugin-unicorn": "59.0.1",
|
||||||
"get-stream": "8.0.1",
|
"get-stream": "9.0.1",
|
||||||
"markdownlint-cli2": "0.12.1",
|
"globals": "16.1.0",
|
||||||
"markdownlint-rule-relative-links": "2.2.0",
|
"markdownlint-cli2": "0.18.0",
|
||||||
"mock-fs": "5.2.0",
|
"markdownlint-rule-relative-links": "4.1.0",
|
||||||
|
"mock-fs": "5.5.0",
|
||||||
"ms": "2.1.3",
|
"ms": "2.1.3",
|
||||||
"sinon": "17.0.1",
|
"prettier": "3.5.3",
|
||||||
"typescript": "5.3.3"
|
"sinon": "20.0.0",
|
||||||
|
"typescript": "5.8.3",
|
||||||
|
"typescript-eslint": "8.32.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM dart:3.2.5 AS builder
|
FROM dart:3.7.3 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
|
||||||
|
@ -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"]
|
||||||
|
@ -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"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM pypy:3.10
|
FROM pypy:3.11-bookworm
|
||||||
WORKDIR /usr/src/application
|
WORKDIR /usr/src/application
|
||||||
COPY ./ ./
|
COPY ./ ./
|
||||||
CMD ["python", "solution.py"]
|
CMD ["python", "solution.py"]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM rust:1.75.0 AS builder
|
FROM rust:1.86.0 AS builder
|
||||||
WORKDIR /usr/src/rust_application
|
WORKDIR /usr/src/rust_application
|
||||||
|
|
||||||
# Cache dependencies
|
# Cache dependencies
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
FROM node:20.11.0 AS builder-dependencies
|
FROM node:22.15.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.15.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
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@
|
|||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noUncheckedIndexedAccess": true,
|
"noUncheckedIndexedAccess": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,37 @@
|
|||||||
{
|
{
|
||||||
"extends": "@tsconfig/strictest/tsconfig.json",
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ESNext",
|
|
||||||
"module": "NodeNext",
|
|
||||||
"lib": ["ESNext"],
|
"lib": ["ESNext"],
|
||||||
"moduleResolution": "NodeNext",
|
|
||||||
"outDir": "./build",
|
"outDir": "./build",
|
||||||
"rootDir": "./cli",
|
"rootDir": "./cli",
|
||||||
"noEmit": true,
|
|
||||||
"checkJs": false,
|
"checkJs": false,
|
||||||
"exactOptionalPropertyTypes": false,
|
"exactOptionalPropertyTypes": false,
|
||||||
|
|
||||||
|
"strict": true,
|
||||||
|
"allowUnusedLabels": false,
|
||||||
|
"allowUnreachableCode": false,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"erasableSyntaxOnly": true,
|
||||||
|
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowImportingTsExtensions": false,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"resolveJsonModule": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "challenges", "templates", "temp", "tmp"],
|
"exclude": ["node_modules", "challenges", "templates", "temp", "tmp"]
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user