mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(curriculum): daily challenges 110-119 (#63852)
Co-authored-by: majestic-owl448 <26656284+majestic-owl448@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efb
|
||||
title: "Challenge 110: Word Guesser"
|
||||
challengeType: 28
|
||||
dashedName: challenge-110
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two strings of the same length, a secret word and a guess, compare the guess to the secret word using the following rules:
|
||||
|
||||
- The secret word and guess will only consist of uppercase letters (`"A"` to `"Z"`);
|
||||
- For each letter in the guess, replace it with a number according to how it matches the secret word:
|
||||
- `"2"` if the letter is in the secret word and in the correct position.
|
||||
- `"1"` if the letter is in the secret word but in the wrong position.
|
||||
- `"0"` if the letter is not in the secret word.
|
||||
- Each letter in the secret word can be used at most once.
|
||||
- Exact matches (`"2"`) are assigned first, then partial matches (`"1"`) are assigned from left to right for remaining letters.
|
||||
- If a letter occurs multiple times in the guess, it can only match as many times as it appears in the secret word.
|
||||
|
||||
For example, given a secret word of `"APPLE"` and a guess of `"POPPA"`, return `"10201"`:
|
||||
|
||||
The first `"P"` is not in the correct location (`"1"`), the `"O"` isn't in the secret word (`"0"`), the second `"P"` is in the correct location (`"2"`), the third `"P"` is a zero (`"0"`) because the two `"P"`'s in the secret word have been used, and the `"A"` is not in the correct location (`"1"`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`compare("APPLE", "POPPA")` should return `"10201"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("APPLE", "POPPA"), "10201");
|
||||
```
|
||||
|
||||
`compare("REACT", "TRACE")` should return `"11221"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("REACT", "TRACE"), "11221");
|
||||
```
|
||||
|
||||
`compare("DEBUGS", "PYTHON")` should return `"000000"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("DEBUGS", "PYTHON"), "000000");
|
||||
```
|
||||
|
||||
`compare("JAVASCRIPT", "TYPESCRIPT")` should return `"0000222222"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("JAVASCRIPT", "TYPESCRIPT"), "0000222222");
|
||||
```
|
||||
|
||||
`compare("ORANGE", "ROUNDS")` should return `"110200"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("ORANGE", "ROUNDS"), "110200");
|
||||
```
|
||||
|
||||
`compare("WIRELESS", "ETHERNET")` should return `"10021000"`.
|
||||
|
||||
```js
|
||||
assert.equal(compare("WIRELESS", "ETHERNET"), "10021000");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function compare(word, guess) {
|
||||
|
||||
return word;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function compare(word, guess) {
|
||||
const n = word.length;
|
||||
let result = Array(n).fill("0");
|
||||
let used = Array(n).fill(false);
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
if (guess[i] === word[i]) {
|
||||
result[i] = "2";
|
||||
used[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < n; i++) {
|
||||
if (result[i] === "0") {
|
||||
for (let j = 0; j < n; j++) {
|
||||
if (!used[j] && guess[i] === word[j]) {
|
||||
result[i] = "1";
|
||||
used[j] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.join("");
|
||||
}
|
||||
```
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efc
|
||||
title: "Challenge 111: Ball Trajectory"
|
||||
challengeType: 28
|
||||
dashedName: challenge-111
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Today's challenge is inspired by the video game Pong, which was released November 29, 1972.
|
||||
|
||||
Given a matrix (array of arrays) that includes the location of the ball (`2`), and the previous location of the ball (`1`), return the matrix indices for the next location of the ball.
|
||||
|
||||
- The ball always moves in a straight line.
|
||||
- The movement direction is determined by how the ball moved from `1` to `2`.
|
||||
- The edges of the matrix are considered walls. If the balls hits a:
|
||||
- top or bottom wall, it bounces by reversing its vertical direction.
|
||||
- left or right wall, it bounces by reversing its horizontal direction.
|
||||
- corner, it bounces by reversing both directions.
|
||||
|
||||
# --hints--
|
||||
|
||||
`getNextLocation([[0,0,0,0], [0,0,0,0], [0,1,2,0], [0,0,0,0]])` should return `[2, 3]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getNextLocation([[0,0,0,0], [0,0,0,0], [0,1,2,0], [0,0,0,0]]), [2, 3]);
|
||||
```
|
||||
|
||||
`getNextLocation([[0,0,0,0], [0,0,1,0], [0,2,0,0], [0,0,0,0]])` should return `[3, 0]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getNextLocation([[0,0,0,0], [0,0,1,0], [0,2,0,0], [0,0,0,0]]), [3, 0]);
|
||||
```
|
||||
|
||||
`getNextLocation([[0,2,0,0], [1,0,0,0], [0,0,0,0], [0,0,0,0]])` should return `[1, 2]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getNextLocation([[0,2,0,0], [1,0,0,0], [0,0,0,0], [0,0,0,0]]), [1, 2]);
|
||||
```
|
||||
|
||||
`getNextLocation([[0,0,0,0], [0,0,0,0], [2,0,0,0], [0,1,0,0]])` should return `[1, 1]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getNextLocation([[0,0,0,0], [0,0,0,0], [2,0,0,0], [0,1,0,0]]), [1, 1]);
|
||||
```
|
||||
|
||||
`getNextLocation([[0,0,0,0], [0,0,0,0], [0,0,1,0], [0,0,0,2]])` should return `[2, 2]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(getNextLocation([[0,0,0,0], [0,0,0,0], [0,0,1,0], [0,0,0,2]]), [2, 2]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function getNextLocation(matrix) {
|
||||
|
||||
return matrix;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function getNextLocation(matrix) {
|
||||
let prev = null;
|
||||
let curr = null;
|
||||
|
||||
for (let row = 0; row < matrix.length; row++) {
|
||||
for (let col = 0; col < matrix[0].length; col++) {
|
||||
if (matrix[row][col] === 1) prev = [row, col];
|
||||
if (matrix[row][col] === 2) curr = [row, col];
|
||||
}
|
||||
}
|
||||
|
||||
const [prevRow, prevCol] = prev;
|
||||
const [currRow, currCol] = curr;
|
||||
|
||||
let dirX = currCol - prevCol;
|
||||
let dirY = currRow - prevRow;
|
||||
|
||||
let nextRow = currRow + dirY;
|
||||
let nextCol = currCol + dirX;
|
||||
|
||||
const maxRow = matrix.length - 1;
|
||||
const maxCol = matrix[0].length - 1;
|
||||
|
||||
|
||||
if (nextCol < 0 || nextCol > maxCol) dirX *= -1;
|
||||
if (nextRow < 0 || nextRow > maxRow) dirY *= -1;
|
||||
|
||||
nextRow = currRow + dirY;
|
||||
nextCol = currCol + dirX;
|
||||
|
||||
return [nextRow, nextCol];
|
||||
}
|
||||
```
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efd
|
||||
title: "Challenge 112: AI Detector"
|
||||
challengeType: 28
|
||||
dashedName: challenge-112
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Today's challenge is inspired by the release of ChatGPT on November 30, 2022.
|
||||
|
||||
Given a string of one or more sentences, determine if it was likely generated by AI using the following rules:
|
||||
|
||||
- It contains two or more dashes (`-`).
|
||||
- It contains two or more sets of parenthesis (`()`). Text can be within the parenthesis.
|
||||
- It contains three or more words with 7 or more letters.
|
||||
|
||||
- Words are separated by a single space and only consist of letters (`A-Z`). Don't include punctuation or other non-letters as part of a word.
|
||||
|
||||
If the given sentence meets any of the rules above, return `"AI"`, otherwise, return `"Human"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`detectAI("The quick brown fox jumped over the lazy dog.")` should return `"Human"`.
|
||||
|
||||
```js
|
||||
assert.equal(detectAI("The quick brown fox jumped over the lazy dog."), "Human");
|
||||
```
|
||||
|
||||
`detectAI("The hypersonic brown fox - jumped (over) the lazy dog.")` should return `"Human"`.
|
||||
|
||||
```js
|
||||
assert.equal(detectAI("The hypersonic brown fox - jumped (over) the lazy dog."), "Human");
|
||||
```
|
||||
|
||||
`detectAI("Yes - you're right! I made a mistake there - let me try again.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
assert.equal(detectAI("Yes - you're right! I made a mistake there - let me try again."), "AI");
|
||||
```
|
||||
|
||||
`detectAI("The extraordinary students were studying vivaciously.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
assert.equal(detectAI("The extraordinary students were studying vivaciously."), "AI");
|
||||
```
|
||||
|
||||
`detectAI("The (excited) student was (coding) in the library.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
assert.equal(detectAI("The (excited) student was (coding) in the library."), "AI");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function detectAI(text) {
|
||||
|
||||
return text;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function detectAI(text) {
|
||||
const dashCount = (text.match(/-/g) || []).length;
|
||||
if (dashCount >= 2) return "AI";
|
||||
|
||||
const parenCount = (text.match(/\([^)]*\)/g) || []).length;
|
||||
if (parenCount >= 2) return "AI";
|
||||
|
||||
const words = text.split(" ");
|
||||
const longWordCount = words.filter(w => w.replace(/[^A-Za-z]/g, "").length >= 7).length;
|
||||
if (longWordCount >= 3) return "AI";
|
||||
|
||||
return "Human";
|
||||
}
|
||||
```
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efe
|
||||
title: "Challenge 113: Miles to Kilometers"
|
||||
challengeType: 28
|
||||
dashedName: challenge-113
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a distance in miles as a number, return the equivalent distance in kilometers.
|
||||
|
||||
- The input will always be a non-negative number.
|
||||
- 1 mile equals 1.60934 kilometers.
|
||||
- Round the result to two decimal places.
|
||||
|
||||
# --hints--
|
||||
|
||||
`convertToKm(1)` should return `1.61`.
|
||||
|
||||
```js
|
||||
assert.equal(convertToKm(1), 1.61);
|
||||
```
|
||||
|
||||
`convertToKm(21)` should return `33.8`.
|
||||
|
||||
```js
|
||||
assert.equal(convertToKm(21), 33.8);
|
||||
```
|
||||
|
||||
`convertToKm(3.5)` should return `5.63`.
|
||||
|
||||
```js
|
||||
assert.equal(convertToKm(3.5), 5.63);
|
||||
```
|
||||
|
||||
`convertToKm(0)` should return `0`.
|
||||
|
||||
```js
|
||||
assert.equal(convertToKm(0), 0);
|
||||
```
|
||||
|
||||
`convertToKm(0.621371)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(convertToKm(0.621371), 1);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function convertToKm(miles) {
|
||||
|
||||
return miles;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function convertToKm(miles) {
|
||||
const km = miles * 1.60934;
|
||||
return Math.round(km * 100) / 100;
|
||||
}
|
||||
```
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629eff
|
||||
title: "Challenge 114: Camel to Snake"
|
||||
challengeType: 28
|
||||
dashedName: challenge-114
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string in camel case, return the snake case version of the string using the following rules:
|
||||
|
||||
- The input string will contain only letters (`A-Z` and `a-z`) and will always start with a lowercase letter.
|
||||
- Every uppercase letter in the camel case string starts a new word.
|
||||
- Convert all letters to lowercase.
|
||||
- Separate words with an underscore (`_`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`toSnake("helloWorld")` should return `"hello_world"`.
|
||||
|
||||
```js
|
||||
assert.equal(toSnake("helloWorld"), "hello_world");
|
||||
```
|
||||
|
||||
`toSnake("myVariableName")` should return `"my_variable_name"`.
|
||||
|
||||
```js
|
||||
assert.equal(toSnake("myVariableName"), "my_variable_name");
|
||||
```
|
||||
|
||||
`toSnake("freecodecampDailyChallenges")` should return `"freecodecamp_daily_challenges"`.
|
||||
|
||||
```js
|
||||
assert.equal(toSnake("freecodecampDailyChallenges"), "freecodecamp_daily_challenges");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function toSnake(camel) {
|
||||
|
||||
return camel;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function toSnake(camel) {
|
||||
return camel
|
||||
.replace(/([A-Z])/g, "_$1")
|
||||
.toLowerCase();
|
||||
}
|
||||
```
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f00
|
||||
title: "Challenge 115: Markdown Ordered List Item Converter"
|
||||
challengeType: 28
|
||||
dashedName: challenge-115
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing an ordered list item in Markdown, return the equivalent HTML string.
|
||||
|
||||
A valid ordered list item in Markdown must:
|
||||
|
||||
- Start with zero or more spaces, followed by
|
||||
- A number (1 or greater) and a period (`.`), followed by
|
||||
- At least one space, and then
|
||||
- The list item text.
|
||||
|
||||
If the string doesn't have the exact format above, return `"Invalid format"`. Otherwise, wrap the list item text in `li` tags and return the string.
|
||||
|
||||
For example, given `"1. My item"`, return `"<li>My item</li>"`
|
||||
|
||||
Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included.
|
||||
|
||||
# --hints--
|
||||
|
||||
`convertListItem("1. My item")` should return `"<li>My item</li>"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem("1. My item"), "<li>My item</li>");
|
||||
```
|
||||
|
||||
`convertListItem(" 1. Another item")` should return `"<li>Another item</li>"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem(" 1. Another item"), "<li>Another item</li>");
|
||||
```
|
||||
|
||||
`convertListItem("1 . invalid item")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem("1 . invalid item"), "Invalid format");
|
||||
```
|
||||
|
||||
`convertListItem("2. list item text")` should return `"<li>list item text</li>"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem("2. list item text"), "<li>list item text</li>");
|
||||
```
|
||||
|
||||
`convertListItem(". invalid again")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem(". invalid again"), "Invalid format");
|
||||
```
|
||||
|
||||
`convertListItem("A. last invalid")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
assert.equal(convertListItem("A. last invalid"), "Invalid format");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function convertListItem(markdown) {
|
||||
|
||||
return markdown;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function convertListItem(markdown) {
|
||||
const match = markdown.match(/^\s*(\d+)\.\s+(.+)$/);
|
||||
if (!match) return "Invalid format";
|
||||
|
||||
const text = match[2];
|
||||
return `<li>${text}</li>`;
|
||||
}
|
||||
```
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f01
|
||||
title: "Challenge 116: Permutation Count"
|
||||
challengeType: 28
|
||||
dashedName: challenge-116
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string, return the number of distinct permutations that can be formed from its characters.
|
||||
|
||||
- A permutation is any reordering of the characters in the string.
|
||||
- Do not count duplicate permutations.
|
||||
- If the string contains repeated characters, repeated arrangements should only be counted once.
|
||||
- The string will contain only letters (`A-Z`, `a-z`).
|
||||
|
||||
For example, given `"abb"`, return `3` because there's three unique ways to arrange the letters: `"abb"`, `"bab"`, and `"bba"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`countPermutations("abb")` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(countPermutations("abb"), 3);
|
||||
```
|
||||
|
||||
`countPermutations("abc")` should return `6`.
|
||||
|
||||
```js
|
||||
assert.equal(countPermutations("abc"), 6);
|
||||
```
|
||||
|
||||
`countPermutations("racecar")` should return `630`.
|
||||
|
||||
```js
|
||||
assert.equal(countPermutations("racecar"), 630);
|
||||
```
|
||||
|
||||
`countPermutations("freecodecamp")` should return `39916800`.
|
||||
|
||||
```js
|
||||
assert.equal(countPermutations("freecodecamp"), 39916800);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function countPermutations(str) {
|
||||
|
||||
return str;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function countPermutations(str) {
|
||||
const freq = {};
|
||||
for (const ch of str) {
|
||||
freq[ch] = (freq[ch] || 0) + 1;
|
||||
}
|
||||
|
||||
function factorial(n) {
|
||||
let result = 1;
|
||||
for (let i = 2; i <= n; i++) result *= i;
|
||||
return result;
|
||||
}
|
||||
|
||||
const n = str.length;
|
||||
let result = factorial(n);
|
||||
|
||||
for (const ch in freq) {
|
||||
result /= factorial(freq[ch]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f02
|
||||
title: "Challenge 117: Symmetric Difference"
|
||||
challengeType: 28
|
||||
dashedName: challenge-117
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two arrays, return a new array containing the symmetric difference of them.
|
||||
|
||||
- The symmetric difference between two sets is the set of values that appear in either set, but not both.
|
||||
- Return the values in the order they first appear in the input arrays.
|
||||
|
||||
# --hints--
|
||||
|
||||
`difference([1, 2, 3], [3, 4, 5])` should return `[1, 2, 4, 5]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(difference([1, 2, 3], [3, 4, 5]), [1, 2, 4, 5]);
|
||||
```
|
||||
|
||||
`difference(["a", "b"], ["c", "b"])` should return `["a", "c"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(difference(["a", "b"], ["c", "b"]), ["a", "c"]);
|
||||
```
|
||||
|
||||
`difference([1, "a", 2], [2, "b", "a"])` should return `[1, "b"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(difference([1, "a", 2], [2, "b", "a"]), [1, "b"]);
|
||||
```
|
||||
|
||||
`difference([1, 3, 5, 7, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9])` should return `[2, 4, 6, 8]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(difference([1, 3, 5, 7, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9]), [2, 4, 6, 8]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function difference(arr1, arr2) {
|
||||
|
||||
return arr1;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function difference(arr1, arr2) {
|
||||
const diff = [];
|
||||
|
||||
for (const v of arr1) {
|
||||
|
||||
if (!diff.includes(v) && !arr2.includes(v)) diff.push(v)
|
||||
}
|
||||
|
||||
for (const v of arr2) {
|
||||
if (!diff.includes(v) && !arr1.includes(v)) diff.push(v)
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
```
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f03
|
||||
title: "Challenge 118: Date Formatter"
|
||||
challengeType: 28
|
||||
dashedName: challenge-118
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a date in the format `"Month day, year"`, return the date in the format `"YYYY-MM-DD"`.
|
||||
|
||||
- The given month will be the full English month name. For example: `"January"`, `"February"`, etc.
|
||||
- In the return value, pad the month and day with leading zeros if necessary to ensure two digits.
|
||||
|
||||
For example, given `"December 6, 2025"`, return `"2025-12-06"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`formatDate("December 6, 2025")` should return `"2025-12-06"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("December 6, 2025"), "2025-12-06");
|
||||
```
|
||||
|
||||
`formatDate("January 1, 2000")` should return `"2000-01-01"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("January 1, 2000"), "2000-01-01");
|
||||
```
|
||||
|
||||
`formatDate("November 11, 1111")` should return `"1111-11-11"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("November 11, 1111"), "1111-11-11");
|
||||
```
|
||||
|
||||
`formatDate("September 7, 512")` should return `"512-09-07"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("September 7, 512"), "512-09-07");
|
||||
```
|
||||
|
||||
`formatDate("May 4, 1950")` should return `"1950-05-04"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("May 4, 1950"), "1950-05-04");
|
||||
```
|
||||
|
||||
`formatDate("February 29, 1992")` should return `"1992-02-29"`.
|
||||
|
||||
```js
|
||||
assert.equal(formatDate("February 29, 1992"), "1992-02-29");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function formatDate(dateString) {
|
||||
|
||||
return dateString;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function formatDate(dateString) {
|
||||
const months = {
|
||||
January: "01",
|
||||
February: "02",
|
||||
March: "03",
|
||||
April: "04",
|
||||
May: "05",
|
||||
June: "06",
|
||||
July: "07",
|
||||
August: "08",
|
||||
September: "09",
|
||||
October: "10",
|
||||
November: "11",
|
||||
December: "12"
|
||||
};
|
||||
|
||||
const [month, day, year] = dateString.replace(",", "").split(" ");
|
||||
|
||||
return `${year}-${months[month]}-${day.padStart(2, "0")}`;
|
||||
}
|
||||
```
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f04
|
||||
title: "Challenge 119: String Compression"
|
||||
challengeType: 28
|
||||
dashedName: challenge-119
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string sentence, return a compressed version of the sentence where consecutive duplicate words are replaced by the word followed with the number of times it repeats in parentheses.
|
||||
|
||||
- Only consecutive duplicates are compressed.
|
||||
- Words are separated by single spaces.
|
||||
|
||||
For example, given `"yes yes yes please"`, return `"yes(3) please"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`compressString("yes yes yes please")` should return `"yes(3) please"`.
|
||||
|
||||
```js
|
||||
assert.equal(compressString("yes yes yes please"), "yes(3) please");
|
||||
```
|
||||
|
||||
`compressString("I have have have apples")` should return `"I have(3) apples"`.
|
||||
|
||||
```js
|
||||
assert.equal(compressString("I have have have apples"), "I have(3) apples");
|
||||
```
|
||||
|
||||
`compressString("one one three and to the the the the")` should return `"one(2) three and to the(4)"`.
|
||||
|
||||
```js
|
||||
assert.equal(compressString("one one three and to the the the the"), "one(2) three and to the(4)");
|
||||
```
|
||||
|
||||
`compressString("route route route route route route tee tee tee tee tee tee")` should return `"route(6) tee(6)"`.
|
||||
|
||||
```js
|
||||
assert.equal(compressString("route route route route route route tee tee tee tee tee tee"), "route(6) tee(6)");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function compressString(sentence) {
|
||||
|
||||
return sentence;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function compressString(sentence) {
|
||||
const words = sentence.split(" ");
|
||||
const result = [];
|
||||
let count = 1;
|
||||
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
if (words[i] === words[i + 1]) {
|
||||
count++;
|
||||
} else {
|
||||
if (count > 1) {
|
||||
result.push(`${words[i]}(${count})`);
|
||||
} else {
|
||||
result.push(words[i]);
|
||||
}
|
||||
count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result.join(" ");
|
||||
}
|
||||
```
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efb
|
||||
title: "Challenge 110: Word Guesser"
|
||||
challengeType: 29
|
||||
dashedName: challenge-110
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two strings of the same length, a secret word and a guess, compare the guess to the secret word using the following rules:
|
||||
|
||||
- The secret word and guess will only consist of uppercase letters (`"A"` to `"Z"`);
|
||||
- For each letter in the guess, replace it with a number according to how it matches the secret word:
|
||||
- `"2"` if the letter is in the secret word and in the correct position.
|
||||
- `"1"` if the letter is in the secret word but in the wrong position.
|
||||
- `"0"` if the letter is not in the secret word.
|
||||
- Each letter in the secret word can be used at most once.
|
||||
- Exact matches (`"2"`) are assigned first, then partial matches (`"1"`) are assigned from left to right for remaining letters.
|
||||
- If a letter occurs multiple times in the guess, it can only match as many times as it appears in the secret word.
|
||||
|
||||
For example, given a secret word of `"APPLE"` and a guess of `"POPPA"`, return `"10201"`:
|
||||
|
||||
The first `"P"` is not in the correct location (`"1"`), the `"O"` isn't in the secret word (`"0"`), the second `"P"` is in the correct location (`"2"`), the third `"P"` is a zero (`"0"`) because the two `"P"`'s in the secret word have been used, and the `"A"` is not in the correct location (`"1"`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`compare("APPLE", "POPPA")` should return `"10201"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("APPLE", "POPPA"), "10201")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compare("REACT", "TRACE")` should return `"11221"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("REACT", "TRACE"), "11221")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compare("DEBUGS", "PYTHON")` should return `"000000"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("DEBUGS", "PYTHON"), "000000")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compare("JAVASCRIPT", "TYPESCRIPT")` should return `"0000222222"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("JAVASCRIPT", "TYPESCRIPT"), "0000222222")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compare("ORANGE", "ROUNDS")` should return `"110200"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("ORANGE", "ROUNDS"), "110200")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compare("WIRELESS", "ETHERNET")` should return `"10021000"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compare("WIRELESS", "ETHERNET"), "10021000")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def compare(word, guess):
|
||||
|
||||
return word
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def compare(word, guess):
|
||||
n = len(word)
|
||||
result = ["0"] * n
|
||||
used_secret = [False] * n
|
||||
|
||||
for i in range(n):
|
||||
if guess[i] == word[i]:
|
||||
result[i] = "2"
|
||||
used_secret[i] = True
|
||||
|
||||
for i in range(n):
|
||||
if result[i] == "0":
|
||||
for j in range(n):
|
||||
if not used_secret[j] and guess[i] == word[j]:
|
||||
result[i] = "1"
|
||||
used_secret[j] = True
|
||||
break
|
||||
|
||||
return "".join(result)
|
||||
```
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efc
|
||||
title: "Challenge 111: Ball Trajectory"
|
||||
challengeType: 29
|
||||
dashedName: challenge-111
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Today's challenge is inspired by the video game Pong, which was released November 29, 1972.
|
||||
|
||||
Given a matrix (array of arrays) that includes the location of the ball (`2`), and the previous location of the ball (`1`), return the matrix indices for the next location of the ball.
|
||||
|
||||
- The ball always moves in a straight line.
|
||||
- The movement direction is determined by how the ball moved from `1` to `2`.
|
||||
- The edges of the matrix are considered walls. If the balls hits a:
|
||||
- top or bottom wall, it bounces by reversing its vertical direction.
|
||||
- left or right wall, it bounces by reversing its horizontal direction.
|
||||
- corner, it bounces by reversing both directions.
|
||||
|
||||
# --hints--
|
||||
|
||||
`get_next_location([[0,0,0,0], [0,0,0,0], [0,1,2,0], [0,0,0,0]])` should return `[2, 3]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(get_next_location([[0,0,0,0], [0,0,0,0], [0,1,2,0], [0,0,0,0]]), [2, 3])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`get_next_location([[0,0,0,0], [0,0,1,0], [0,2,0,0], [0,0,0,0]])` should return `[3, 0]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(get_next_location([[0,0,0,0], [0,0,1,0], [0,2,0,0], [0,0,0,0]]), [3, 0])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`get_next_location([[0,2,0,0], [1,0,0,0], [0,0,0,0], [0,0,0,0]])` should return `[1, 2]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(get_next_location([[0,2,0,0], [1,0,0,0], [0,0,0,0], [0,0,0,0]]), [1, 2])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`get_next_location([[0,0,0,0], [0,0,0,0], [2,0,0,0], [0,1,0,0]])` should return `[1, 1]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(get_next_location([[0,0,0,0], [0,0,0,0], [2,0,0,0], [0,1,0,0]]), [1, 1])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`get_next_location([[0,0,0,0], [0,0,0,0], [0,0,1,0], [0,0,0,2]])` should return `[2, 2]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(get_next_location([[0,0,0,0], [0,0,0,0], [0,0,1,0], [0,0,0,2]]), [2, 2])`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def get_next_location(matrix):
|
||||
|
||||
return matrix
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def get_next_location(matrix):
|
||||
prev = None
|
||||
curr = None
|
||||
|
||||
for r in range(len(matrix)):
|
||||
for c in range(len(matrix[0])):
|
||||
if matrix[r][c] == 1:
|
||||
prev = (r, c)
|
||||
if matrix[r][c] == 2:
|
||||
curr = (r, c)
|
||||
|
||||
prev_row, prev_col = prev
|
||||
curr_row, curr_col = curr
|
||||
|
||||
dir_x = curr_col - prev_col
|
||||
dir_y = curr_row - prev_row
|
||||
|
||||
next_row = curr_row + dir_y
|
||||
next_col = curr_col + dir_x
|
||||
|
||||
max_row = len(matrix) - 1
|
||||
max_col = len(matrix[0]) - 1
|
||||
|
||||
if next_col < 0 or next_col > max_col:
|
||||
dir_x *= -1
|
||||
if next_row < 0 or next_row > max_row:
|
||||
dir_y *= -1
|
||||
|
||||
next_row = curr_row + dir_y
|
||||
next_col = curr_col + dir_x
|
||||
|
||||
return [next_row, next_col]
|
||||
```
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efd
|
||||
title: "Challenge 112: AI Detector"
|
||||
challengeType: 29
|
||||
dashedName: challenge-112
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Today's challenge is inspired by the release of ChatGPT on November 30, 2022.
|
||||
|
||||
Given a string of one or more sentences, determine if it was likely generated by AI using the following rules:
|
||||
|
||||
- It contains two or more dashes (`-`).
|
||||
- It contains two or more sets of parenthesis (`()`). Text can be within the parenthesis.
|
||||
- It contains three or more words with 7 or more letters.
|
||||
|
||||
- Words are separated by a single space and only consist of letters (`A-Z`). Don't include punctuation or other non-letters as part of a word.
|
||||
|
||||
If the given sentence meets any of the rules above, return `"AI"`, otherwise, return `"Human"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`detect_ai("The quick brown fox jumped over the lazy dog.")` should return `"Human"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(detect_ai("The quick brown fox jumped over the lazy dog."), "Human")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`detect_ai("The hypersonic brown fox - jumped (over) the lazy dog.")` should return `"Human"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(detect_ai("The hypersonic brown fox - jumped (over) the lazy dog."), "Human")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`detect_ai("Yes - you're right! I made a mistake there - let me try again.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(detect_ai("Yes - you're right! I made a mistake there - let me try again."), "AI")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`detect_ai("The extraordinary students were studying vivaciously.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(detect_ai("The extraordinary students were studying vivaciously."), "AI")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`detect_ai("The (excited) student was (coding) in the library.")` should return `"AI"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(detect_ai("The (excited) student was (coding) in the library."), "AI")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def detect_ai(text):
|
||||
|
||||
return text
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def detect_ai(text):
|
||||
if len(re.findall(r'-', text)) >= 2:
|
||||
return "AI"
|
||||
|
||||
if len(re.findall(r'\([^)]*\)', text)) >= 2:
|
||||
return "AI"
|
||||
|
||||
words = text.split()
|
||||
long_word_count = sum(1 for w in words if len(re.sub(r'[^A-Za-z]', '', w)) >= 7)
|
||||
if long_word_count >= 3:
|
||||
return "AI"
|
||||
|
||||
return "Human"
|
||||
```
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629efe
|
||||
title: "Challenge 113: Miles to Kilometers"
|
||||
challengeType: 29
|
||||
dashedName: challenge-113
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a distance in miles as a number, return the equivalent distance in kilometers.
|
||||
|
||||
- The input will always be a non-negative number.
|
||||
- 1 mile equals 1.60934 kilometers.
|
||||
- Round the result to two decimal places.
|
||||
|
||||
# --hints--
|
||||
|
||||
`convert_to_km(1)` should return `1.61`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_to_km(1), 1.61)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_to_km(21)` should return `33.8`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_to_km(21), 33.8)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_to_km(3.5)` should return `5.63`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_to_km(3.5), 5.63)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_to_km(0)` should return `0`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_to_km(0), 0)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_to_km(0.621371)` should return `1`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_to_km(0.621371), 1)`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def convert_to_km(miles):
|
||||
|
||||
return miles
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def convert_to_km(miles):
|
||||
km = miles * 1.60934
|
||||
return round(km, 2)
|
||||
```
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629eff
|
||||
title: "Challenge 114: Camel to Snake"
|
||||
challengeType: 29
|
||||
dashedName: challenge-114
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string in camel case, return the snake case version of the string using the following rules:
|
||||
|
||||
- The input string will contain only letters (`A-Z` and `a-z`) and will always start with a lowercase letter.
|
||||
- Every uppercase letter in the camel case string starts a new word.
|
||||
- Convert all letters to lowercase.
|
||||
- Separate words with an underscore (`_`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`to_snake("helloWorld")` should return `"hello_world"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_snake("helloWorld"), "hello_world")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_snake("myVariableName")` should return `"my_variable_name"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_snake("myVariableName"), "my_variable_name")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_snake("freecodecampDailyChallenges")` should return `"freecodecamp_daily_challenges"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_snake("freecodecampDailyChallenges"), "freecodecamp_daily_challenges")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def to_snake(camel):
|
||||
|
||||
return camel
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def to_snake(camel):
|
||||
return re.sub(r'([A-Z])', r'_\1', camel).lower()
|
||||
```
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f00
|
||||
title: "Challenge 115: Markdown Ordered List Item Converter"
|
||||
challengeType: 29
|
||||
dashedName: challenge-115
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing an ordered list item in Markdown, return the equivalent HTML string.
|
||||
|
||||
A valid ordered list item in Markdown must:
|
||||
|
||||
- Start with zero or more spaces, followed by
|
||||
- A number (1 or greater) and a period (`.`), followed by
|
||||
- At least one space, and then
|
||||
- The list item text.
|
||||
|
||||
If the string doesn't have the exact format above, return `"Invalid format"`. Otherwise, wrap the list item text in `li` tags and return the string.
|
||||
|
||||
For example, given `"1. My item"`, return `"<li>My item</li>"`
|
||||
|
||||
Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included.
|
||||
|
||||
# --hints--
|
||||
|
||||
`convert_list_item("1. My item")` should return `"<li>My item</li>"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item("1. My item"), "<li>My item</li>")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_list_item(" 1. Another item")` should return `"<li>Another item</li>"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item(" 1. Another item"), "<li>Another item</li>")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_list_item("1 . invalid item")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item("1 . invalid item"), "Invalid format")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_list_item("2. list item text")` should return `"<li>list item text</li>"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item("2. list item text"), "<li>list item text</li>")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_list_item(". invalid again")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item(". invalid again"), "Invalid format")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`convert_list_item("A. last invalid")` should return `"Invalid format"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(convert_list_item("A. last invalid"), "Invalid format")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def convert_list_item(markdown):
|
||||
|
||||
return markdown
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def convert_list_item(markdown):
|
||||
match = re.match(r'^\s*(\d+)\.\s+(.+)$', markdown)
|
||||
if not match:
|
||||
return "Invalid format"
|
||||
text = match.group(2)
|
||||
return f"<li>{text}</li>"
|
||||
```
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f01
|
||||
title: "Challenge 116: Permutation Count"
|
||||
challengeType: 29
|
||||
dashedName: challenge-116
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string, return the number of distinct permutations that can be formed from its characters.
|
||||
|
||||
- A permutation is any reordering of the characters in the string.
|
||||
- Do not count duplicate permutations.
|
||||
- If the string contains repeated characters, repeated arrangements should only be counted once.
|
||||
- The string will contain only letters (`A-Z`, `a-z`).
|
||||
|
||||
For example, given `"abb"`, return `3` because there's three unique ways to arrange the letters: `"abb"`, `"bab"`, and `"bba"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`count_permutations("abb")` should return `3`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count_permutations("abb"), 3)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count_permutations("abc")` should return `6`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count_permutations("abc"), 6)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count_permutations("racecar")` should return `630`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count_permutations("racecar"), 630)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count_permutations("freecodecamp")` should return `39916800`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count_permutations("freecodecamp"), 39916800)`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def count_permutations(s):
|
||||
|
||||
return s
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
from math import factorial
|
||||
from collections import Counter
|
||||
def count_permutations(s):
|
||||
freq = Counter(s)
|
||||
n = len(s)
|
||||
|
||||
result = factorial(n)
|
||||
for count in freq.values():
|
||||
result //= factorial(count)
|
||||
|
||||
return result
|
||||
```
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f02
|
||||
title: "Challenge 117: Symmetric Difference"
|
||||
challengeType: 29
|
||||
dashedName: challenge-117
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two arrays, return a new array containing the symmetric difference of them.
|
||||
|
||||
- The symmetric difference between two sets is the set of values that appear in either set, but not both.
|
||||
- Return the values in the order they first appear in the input arrays.
|
||||
|
||||
# --hints--
|
||||
|
||||
`difference([1, 2, 3], [3, 4, 5])` should return `[1, 2, 4, 5]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(difference([1, 2, 3], [3, 4, 5]), [1, 2, 4, 5])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`difference(["a", "b"], ["c", "b"])` should return `["a", "c"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(difference(["a", "b"], ["c", "b"]), ["a", "c"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`difference([1, "a", 2], [2, "b", "a"])` should return `[1, "b"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(difference([1, "a", 2], [2, "b", "a"]), [1, "b"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`difference([1, 3, 5, 7, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9])` should return `[2, 4, 6, 8]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(difference([1, 3, 5, 7, 9], [1, 2, 3, 4, 5, 6, 7, 8, 9]), [2, 4, 6, 8])`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def difference(arr1, arr2):
|
||||
|
||||
return diff
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def difference(arr1, arr2):
|
||||
diff = []
|
||||
|
||||
for v in arr1:
|
||||
if v not in arr2 and v not in diff:
|
||||
diff.append(v)
|
||||
|
||||
for v in arr2:
|
||||
if v not in arr1 and v not in diff:
|
||||
diff.append(v)
|
||||
|
||||
return diff
|
||||
```
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f03
|
||||
title: "Challenge 118: Date Formatter"
|
||||
challengeType: 29
|
||||
dashedName: challenge-118
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a date in the format `"Month day, year"`, return the date in the format `"YYYY-MM-DD"`.
|
||||
|
||||
- The given month will be the full English month name. For example: `"January"`, `"February"`, etc.
|
||||
- In the return value, pad the month and day with leading zeros if necessary to ensure two digits.
|
||||
|
||||
For example, given `"December 6, 2025"`, return `"2025-12-06"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`format_date("December 6, 2025")` should return `"2025-12-06"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("December 6, 2025"), "2025-12-06")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format_date("January 1, 2000")` should return `"2000-01-01"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("January 1, 2000"), "2000-01-01")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format_date("November 11, 1111")` should return `"1111-11-11"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("November 11, 1111"), "1111-11-11")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format_date("September 7, 512")` should return `"512-09-07"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("September 7, 512"), "512-09-07")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format_date("May 4, 1950")` should return `"1950-05-04"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("May 4, 1950"), "1950-05-04")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format_date("February 29, 1992")` should return `"1992-02-29"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format_date("February 29, 1992"), "1992-02-29")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def format_date(date_string):
|
||||
|
||||
return date_string
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def format_date(date_string):
|
||||
months = {
|
||||
"January": "01",
|
||||
"February": "02",
|
||||
"March": "03",
|
||||
"April": "04",
|
||||
"May": "05",
|
||||
"June": "06",
|
||||
"July": "07",
|
||||
"August": "08",
|
||||
"September": "09",
|
||||
"October": "10",
|
||||
"November": "11",
|
||||
"December": "12"
|
||||
}
|
||||
|
||||
month, day, year = date_string.replace(",", "").split(" ")
|
||||
day = day.zfill(2)
|
||||
|
||||
return f"{year}-{months[month]}-{day}"
|
||||
```
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 69162d64f96574d9bb629f04
|
||||
title: "Challenge 119: String Compression"
|
||||
challengeType: 29
|
||||
dashedName: challenge-119
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string sentence, return a compressed version of the sentence where consecutive duplicate words are replaced by the word followed with the number of times it repeats in parentheses.
|
||||
|
||||
- Only consecutive duplicates are compressed.
|
||||
- Words are separated by single spaces.
|
||||
|
||||
For example, given `"yes yes yes please"`, return `"yes(3) please"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`compress_string("yes yes yes please")` should return `"yes(3) please"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compress_string("yes yes yes please"), "yes(3) please")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compress_string("I have have have apples")` should return `"I have(3) apples"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compress_string("I have have have apples"), "I have(3) apples")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compress_string("one one three and to the the the the")` should return `"one(2) three and to the(4)"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compress_string("one one three and to the the the the"), "one(2) three and to the(4)")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`compress_string("route route route route route route tee tee tee tee tee tee")` should return `"route(6) tee(6)"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(compress_string("route route route route route route tee tee tee tee tee tee"), "route(6) tee(6)")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def compress_string(sentence):
|
||||
|
||||
return sentence
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def compress_string(sentence):
|
||||
words = sentence.split(" ")
|
||||
result = []
|
||||
count = 1
|
||||
|
||||
for i in range(len(words)):
|
||||
if i < len(words) - 1 and words[i] == words[i + 1]:
|
||||
count += 1
|
||||
else:
|
||||
if count > 1:
|
||||
result.append(f"{words[i]}({count})")
|
||||
else:
|
||||
result.append(words[i])
|
||||
count = 1
|
||||
|
||||
return " ".join(result)
|
||||
```
|
||||
@@ -442,6 +442,46 @@
|
||||
{
|
||||
"id": "68ffb91507a5b645769328cc",
|
||||
"title": "Challenge 109: What's My Age Again?"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efb",
|
||||
"title": "Challenge 110: Word Guesser"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efc",
|
||||
"title": "Challenge 111: Ball Trajectory"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efd",
|
||||
"title": "Challenge 112: AI Detector"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efe",
|
||||
"title": "Challenge 113: Miles to Kilometers"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629eff",
|
||||
"title": "Challenge 114: Camel to Snake"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f00",
|
||||
"title": "Challenge 115: Markdown Ordered List Item Converter"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f01",
|
||||
"title": "Challenge 116: Permutation Count"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f02",
|
||||
"title": "Challenge 117: Symmetric Difference"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f03",
|
||||
"title": "Challenge 118: Date Formatter"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f04",
|
||||
"title": "Challenge 119: String Compression"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -441,6 +441,46 @@
|
||||
{
|
||||
"id": "68ffb91507a5b645769328cc",
|
||||
"title": "Challenge 109: What's My Age Again?"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efb",
|
||||
"title": "Challenge 110: Word Guesser"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efc",
|
||||
"title": "Challenge 111: Ball Trajectory"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efd",
|
||||
"title": "Challenge 112: AI Detector"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629efe",
|
||||
"title": "Challenge 113: Miles to Kilometers"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629eff",
|
||||
"title": "Challenge 114: Camel to Snake"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f00",
|
||||
"title": "Challenge 115: Markdown Ordered List Item Converter"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f01",
|
||||
"title": "Challenge 116: Permutation Count"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f02",
|
||||
"title": "Challenge 117: Symmetric Difference"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f03",
|
||||
"title": "Challenge 118: Date Formatter"
|
||||
},
|
||||
{
|
||||
"id": "69162d64f96574d9bb629f04",
|
||||
"title": "Challenge 119: String Compression"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const { MONGOHQ_URL } = process.env;
|
||||
|
||||
// Number challenges in the dev-playground blocks
|
||||
// Update this if the number of challenges changes
|
||||
const EXPECTED_CHALLENGE_COUNT = 109;
|
||||
const EXPECTED_CHALLENGE_COUNT = 119;
|
||||
|
||||
// Date to set for the first challenge, second challenge will be one day later, etc...
|
||||
// **DO NOT CHANGE THIS AFTER RELEASE (if seeding production - okay for local dev)**
|
||||
|
||||
Reference in New Issue
Block a user