feat(curriculum): daily challenges 279-294 (#67227)

This commit is contained in:
Tom
2026-05-11 09:49:57 -05:00
committed by GitHub
parent aa6df83ac1
commit 3e5f5cc938
35 changed files with 2965 additions and 1 deletions
@@ -0,0 +1,117 @@
---
id: 69f35a5bb823ed620fcb7cb8
title: "Challenge 279: Longest Domino Chain"
challengeType: 28
dashedName: challenge-279
---
# --description--
Given a 2D array representing a set of dominoes, return the longest valid chain.
- Each domino is a pair of numbers from 06, e.g. `[3, 2]`.
- A chain is valid when the second number of each domino matches the first number of the next.
- The first number of the first domino and the second number of the last one don't need to match anything.
- Any domino can be flipped, so `[3, 2]` can be played as `[2, 3]`.
- There is always exactly one longest valid chain.
For example, given `[[1, 2], [4, 5], [2, 3]]`, return `[[1, 2], [2, 3]]`.
# --hints--
`getLongestChain([[1, 2], [4, 5], [2, 3]])` should return `[[1, 2], [2, 3]]`.
```js
const chain = JSON.stringify(getLongestChain([[1, 2], [4, 5], [2, 3]]));
const result1 = JSON.stringify([[1, 2], [2, 3]]);
const result2 = JSON.stringify([[3, 2], [2, 1]]);
assert.isTrue(chain === result1 || chain === result2);
```
`getLongestChain([[2, 1], [4, 3], [5, 3]])` should return `[[4, 3], [3, 5]]`.
```js
const chain = JSON.stringify(getLongestChain([[2, 1], [4, 3], [5, 3]]));
const result1 = JSON.stringify([[4, 3], [3, 5]]);
const result2 = JSON.stringify([[5, 3], [3, 4]]);
assert.isTrue(chain === result1 || chain === result2);
```
`getLongestChain([[1, 2], [3, 4], [2, 3], [4, 0]])` should return `[[1, 2], [2, 3], [3, 4], [4, 0]]`.
```js
const chain = JSON.stringify(getLongestChain([[1, 2], [3, 4], [2, 3], [4, 0]]));
const result1 = JSON.stringify([[1, 2], [2, 3], [3, 4], [4, 0]]);
const result2 = JSON.stringify([[0, 4], [4, 3], [3, 2], [2, 1]]);
assert.isTrue(chain === result1 || chain === result2);
```
`getLongestChain([[6, 6], [6, 1], [1, 1], [0, 3], [2, 3], [4, 1], [5, 6]])` should return `[[4, 1], [1, 1], [1, 6], [6, 6], [6, 5]]`.
```js
const chain = JSON.stringify(getLongestChain([[6, 6], [6, 1], [1, 1], [0, 3], [2, 3], [4, 1], [5, 6]]));
const result1 = JSON.stringify([[4, 1], [1, 1], [1, 6], [6, 6], [6, 5]]);
const result2 = JSON.stringify([[5, 6], [6, 6], [6, 1], [1, 1], [1, 4]]);
assert.isTrue(chain === result1 || chain === result2);
```
`getLongestChain([[0, 4], [3, 3], [0, 3], [5, 6], [4, 5], [4, 2], [5, 5], [1, 2], [4, 4]])` should return `[[3, 3], [3, 0], [0, 4], [4, 4], [4, 5], [5, 5], [5, 6]]`.
```js
const chain = JSON.stringify(getLongestChain([[0, 4], [3, 3], [0, 3], [5, 6], [4, 5], [4, 2], [5, 5], [1, 2], [4, 4]]));
const result1 = JSON.stringify([[3, 3], [3, 0], [0, 4], [4, 4], [4, 5], [5, 5], [5, 6]]);
const result2 = JSON.stringify([[6, 5], [5, 5], [5, 4], [4, 4], [4, 0], [0, 3], [3, 3]]);
assert.isTrue(chain === result1 || chain === result2);
```
# --seed--
## --seed-contents--
```js
function getLongestChain(dominoes) {
return dominoes;
}
```
# --solutions--
```js
function getLongestChain(dominoes) {
function search(chain, remaining) {
let best = chain;
const last = chain[chain.length - 1][1];
for (let i = 0; i < remaining.length; i++) {
const [a, b] = remaining[i];
const rest = remaining.filter((_, j) => j !== i);
if (a === last) {
const result = search([...chain, [a, b]], rest);
if (result.length > best.length) best = result;
}
if (b === last && a !== b) {
const result = search([...chain, [b, a]], rest);
if (result.length > best.length) best = result;
}
}
return best;
}
let best = [];
for (let i = 0; i < dominoes.length; i++) {
const [a, b] = dominoes[i];
const rest = dominoes.filter((_, j) => j !== i);
const r1 = search([[a, b]], rest);
if (r1.length > best.length) best = r1;
if (a !== b) {
const r2 = search([[b, a]], rest);
if (r2.length > best.length) best = r2;
}
}
return best;
}
```
@@ -0,0 +1,66 @@
---
id: 69f35a5bb823ed620fcb7cb9
title: "Challenge 280: Mongo ID Date"
challengeType: 28
dashedName: challenge-280
---
# --description--
Given a MongoDB ID string, return its creation time as an ISO 8601 string.
- A MongoDB ID is a 24-character hex string. The first 8 characters represent a Unix timestamp (in seconds) encoded as a base-16 integer.
For example, `"6a094b50bcf86cd799439011"` has a timestamp of `"6a094b50"` in hex, which is `1778994000` in decimal, representing a creation time of `"2026-05-17T05:00:00.000Z"`.
# --hints--
`mongoIdToDate("6a094b50bcf86cd799439011")` should return `"2026-05-17T05:00:00.000Z"`.
```js
assert.equal(mongoIdToDate("6a094b50bcf86cd799439011"), "2026-05-17T05:00:00.000Z");
```
`mongoIdToDate("695344eb1f4a4c1123042128")` should return `"2025-12-30T03:20:11.000Z"`.
```js
assert.equal(mongoIdToDate("695344eb1f4a4c1123042128"), "2025-12-30T03:20:11.000Z");
```
`mongoIdToDate("386da62df34123ac54617e56")` should return `"2000-01-01T07:01:01.000Z"`.
```js
assert.equal(mongoIdToDate("386da62df34123ac54617e56"), "2000-01-01T07:01:01.000Z");
```
`mongoIdToDate("69f571c3d7711807afd3dd55")` should return `"2026-05-02T03:38:43.000Z"`.
```js
assert.equal(mongoIdToDate("69f571c3d7711807afd3dd55"), "2026-05-02T03:38:43.000Z");
```
`mongoIdToDate("68adce01c0e1144d0a90295a")` should return `"2025-08-26T15:08:49.000Z"`.
```js
assert.equal(mongoIdToDate("68adce01c0e1144d0a90295a"), "2025-08-26T15:08:49.000Z");
```
# --seed--
## --seed-contents--
```js
function mongoIdToDate(id) {
return id;
}
```
# --solutions--
```js
function mongoIdToDate(id) {
const timestamp = parseInt(id.slice(0, 8), 16);
return new Date(timestamp * 1000).toISOString();
}
```
@@ -0,0 +1,73 @@
---
id: 69f35a5bb823ed620fcb7cba
title: "Challenge 281: Bingo Range"
challengeType: 28
dashedName: challenge-281
---
# --description--
Given a bingo letter, return the number range associated with that letter.
| Letter | Number Range |
| - | - |
| `"B"` | 1-15 |
| `"I"` | 16-30 |
| `"N"` | 31-45 |
| `"G"` | 46-60 |
| `"O"` | 61-75 |
Return an array with all numbers in the range from smallest to largest.
# --hints--
`getBingoRange("B")` should return `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]`.
```js
assert.deepEqual(getBingoRange("B"), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
```
`getBingoRange("I")` should return `[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]`.
```js
assert.deepEqual(getBingoRange("I"), [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]);
```
`getBingoRange("N")` should return `[31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]`.
```js
assert.deepEqual(getBingoRange("N"), [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]);
```
`getBingoRange("G")` should return `[46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]`.
```js
assert.deepEqual(getBingoRange("G"), [46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]);
```
`getBingoRange("O")` should return `[61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]`.
```js
assert.deepEqual(getBingoRange("O"), [61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]);
```
# --seed--
## --seed-contents--
```js
function getBingoRange(letter) {
return letter;
}
```
# --solutions--
```js
function getBingoRange(letter) {
const ranges = { B: [1, 15], I: [16, 30], N: [31, 45], G: [46, 60], O: [61, 75] };
const [start, end] = ranges[letter];
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}
```
@@ -0,0 +1,65 @@
---
id: 69f35a5bb823ed620fcb7cbb
title: "Challenge 282: Sleep Debt"
challengeType: 28
dashedName: challenge-282
---
# --description--
Given an array of hours slept each night leading up to today, and a target number of hours per night, return how many hours of sleep you need tonight to eliminate your sleep debt.
- Include tonight's hours in the total time needed to catch up.
- If you've slept enough to cover tonight's target or more, return `0`.
# --hints--
`sleepDebt([6, 6, 6, 6, 6, 6], 8)` should return `20`.
```js
assert.equal(sleepDebt([6, 6, 6, 6, 6, 6], 8), 20);
```
`sleepDebt([6, 7, 8, 4, 8, 6], 7)` should return `10`.
```js
assert.equal(sleepDebt([6, 7, 8, 4, 8, 6], 7), 10);
```
`sleepDebt([10, 10, 9, 10, 9, 11], 9)` should return `4`.
```js
assert.equal(sleepDebt([10, 10, 9, 10, 9, 11], 9), 4);
```
`sleepDebt([8, 7, 6, 7, 6, 8], 6)` should return `0`.
```js
assert.equal(sleepDebt([8, 7, 6, 7, 6, 8], 6), 0);
```
`sleepDebt([8, 9, 10, 9, 10, 7], 7)` should return `0`.
```js
assert.equal(sleepDebt([8, 9, 10, 9, 10, 7], 7), 0);
```
# --seed--
## --seed-contents--
```js
function sleepDebt(hoursSlept, targetHours) {
return hoursSlept;
}
```
# --solutions--
```js
function sleepDebt(hoursSlept, targetHours) {
const debt = (hoursSlept.length + 1) * targetHours - hoursSlept.reduce((sum, h) => sum + h, 0);
return Math.max(0, debt);
}
```
@@ -0,0 +1,69 @@
---
id: 69f35a5bb823ed620fcb7cbc
title: "Challenge 283: String Zipper"
challengeType: 28
dashedName: challenge-283
---
# --description--
Given two strings, return a new string that interleaves their characters one at a time. If one string is longer, append the remaining characters at the end.
Begin with the first character of the first string.
# --hints--
`zipStrings("abc", "123")` should return `"a1b2c3"`.
```js
assert.equal(zipStrings("abc", "123"), "a1b2c3");
```
`zipStrings("acegikmoqsuwy", "bdfhjlnprtvxz")` should return `"abcdefghijklmnopqrstuvwxyz"`.
```js
assert.equal(zipStrings("acegikmoqsuwy", "bdfhjlnprtvxz"), "abcdefghijklmnopqrstuvwxyz");
```
`zipStrings("day", "night")` should return `"dnaiyght"`.
```js
assert.equal(zipStrings("day", "night"), "dnaiyght");
```
`zipStrings("python", "javascript")` should return `"pjyatvhaosncript"`.
```js
assert.equal(zipStrings("python", "javascript"), "pjyatvhaosncript");
```
`zipStrings("feCdCm", "reoeap")` should return `"freeCodeCamp"`.
```js
assert.equal(zipStrings("feCdCm", "reoeap"), "freeCodeCamp");
```
# --seed--
## --seed-contents--
```js
function zipStrings(a, b) {
return a;
}
```
# --solutions--
```js
function zipStrings(a, b) {
let result = '';
const len = Math.max(a.length, b.length);
for (let i = 0; i < len; i++) {
if (i < a.length) result += a[i];
if (i < b.length) result += b[i];
}
return result;
}
```
@@ -0,0 +1,69 @@
---
id: 69f35a5bb823ed620fcb7cbd
title: "Challenge 284: I Before E"
challengeType: 28
dashedName: challenge-284
---
# --description--
Given a word or sentence, return a corrected version where every word follows the "I before E except after C" rule.
- If a word contains `"ei"` not preceded by `"c"`, replace it with `"ie"`.
- If a word contains `"ie"` preceded by `"c"`, replace it with `"ei"`.
- All other words are left unchanged.
# --hints--
`iBeforeE("beleive")` should return `"believe"`.
```js
assert.equal(iBeforeE("beleive"), "believe");
```
`iBeforeE("recieve")` should return `"receive"`.
```js
assert.equal(iBeforeE("recieve"), "receive");
```
`iBeforeE("we recieved a breif")` should return `"we received a brief"`.
```js
assert.equal(iBeforeE("we recieved a breif"), "we received a brief");
```
`iBeforeE("she beleived the friendly niece could percieve the greif")` should return `"she believed the friendly niece could perceive the grief"`.
```js
assert.equal(iBeforeE("she beleived the friendly niece could percieve the greif"), "she believed the friendly niece could perceive the grief");
```
`iBeforeE("we recieved relief after the theif gave us a breif piece of feirce deceit")` should return `"we received relief after the thief gave us a brief piece of fierce deceit"`.
```js
assert.equal(iBeforeE("we recieved relief after the theif gave us a breif piece of feirce deceit"), "we received relief after the thief gave us a brief piece of fierce deceit");
```
# --seed--
## --seed-contents--
```js
function iBeforeE(sentence) {
return sentence;
}
```
# --solutions--
```js
function iBeforeE(sentence) {
return sentence.split(' ').map(word => {
word = word.replace(/([^c])ei/g, '$1ie');
word = word.replace(/cie/g, 'cei');
return word;
}).join(' ');
}
```
@@ -0,0 +1,80 @@
---
id: 69f35a5bb823ed620fcb7cbe
title: "Challenge 285: Meeting Time"
challengeType: 28
dashedName: challenge-285
---
# --description--
Given a 3D array representing availability windows for multiple people, return the earliest time where everyone has one hour free. If no such time exists, return `"None"`.
- Each person's availability is an array of `[start, end]` integer pairs in 24-hour time. For example, `[10, 12]` would mean the person is available from 10 to 12. Start times range from 0-23, and end times range from 1-24.
For example, given:
```json
[
[[10, 12], [15, 16]], // person 1
[[11, 14], [15, 16]] // person 2
]
```
Return `11`, the start of their first shared free hour.
# --hints--
`getMeetingTime([[[10, 12], [15, 16]], [[11, 14], [15, 16]]])` should return `11`.
```js
assert.equal(getMeetingTime([[[10, 12], [15, 16]], [[11, 14], [15, 16]]]), 11);
```
`getMeetingTime([[[9, 10], [12, 15]], [[10, 11], [13, 14]], [[9, 11], [10, 14]]])` should return `13`.
```js
assert.equal(getMeetingTime([[[9, 10], [12, 15]], [[10, 11], [13, 14]], [[9, 11], [10, 14]]]), 13);
```
`getMeetingTime([[[7, 8], [9, 11], [12, 14], [15, 16]], [[8, 11], [12, 13], [14, 15]]])` should return `9`.
```js
assert.equal(getMeetingTime([[[7, 8], [9, 11], [12, 14], [15, 16]], [[8, 11], [12, 13], [14, 15]]]), 9);
```
`getMeetingTime([[[7, 8], [10, 12], [13, 15]], [[8, 11], [12, 13], [14, 15]], [[6, 7], [8, 9], [12, 13]]])` should return `None`.
```js
assert.equal(getMeetingTime([[[7, 8], [10, 12], [13, 15]], [[8, 11], [12, 13], [14, 15]], [[6, 7], [8, 9], [12, 13]]]), "None");
```
`getMeetingTime([[[1, 3], [4, 6], [8, 10], [20, 23]], [[15, 16], [17, 18], [19, 22], [23, 24]], [[14, 16], [17, 23]], [[2, 4], [5, 6], [18, 19], [21, 22], [23, 24]]])` should return `21`.
```js
assert.equal(getMeetingTime([[[1, 3], [4, 6], [8, 10], [20, 23]], [[15, 16], [17, 18], [19, 22], [23, 24]], [[14, 16], [17, 23]], [[2, 4], [5, 6], [18, 19], [21, 22], [23, 24]]]), 21);
```
# --seed--
## --seed-contents--
```js
function getMeetingTime(availability) {
return availability;
}
```
# --solutions--
```js
function getMeetingTime(availability) {
for (let hour = 0; hour < 24; hour++) {
const allFree = availability.every(person =>
person.some(([start, end]) => start <= hour && hour + 1 <= end)
);
if (allFree) return hour;
}
return "None";
}
```
@@ -0,0 +1,85 @@
---
id: 69f8c998d78ad3171a0713b9
title: "Challenge 286: Open Issues"
challengeType: 28
dashedName: challenge-286
---
# --description--
Given an array of issue numbers and another array of pull request (PR) numbers, return an array of issues that remain open after all PRs have been merged.
- A PR closes an issue if their digits are a rotation of each other. For example, issue 123 would be closed by PR 231 or 312.
- A PR does not close an issue with the exact same number. For example, PR 123 does not close issue 123. So an issue with all the same number can't get closed.
- Either number may have leading zeros stripped. For example, PR 201 would close issue 12 (012, a rotation of 201). Similarily, issue 201 would be closed by PR 12.
Return the remaining open issues in the order they were given.
# --hints--
`getOpenIssues([123, 234], [231])` should return `[234]`.
```js
assert.deepEqual(getOpenIssues([123, 234], [231]), [234]);
```
`getOpenIssues([123, 345, 16], [345, 231])` should return `[345, 16]`.
```js
assert.deepEqual(getOpenIssues([123, 345, 16], [345, 231]), [345, 16]);
```
`getOpenIssues([456, 332, 12, 15], [201, 945, 180])` should return `[456, 332, 15]`.
```js
assert.deepEqual(getOpenIssues([456, 332, 12, 15], [201, 945, 180]), [456, 332, 15]);
```
`getOpenIssues([12, 115, 296, 170, 24], [17, 18, 19, 20, 21])` should return `[115, 296, 24]`.
```js
assert.deepEqual(getOpenIssues([12, 115, 296, 170, 24], [17, 18, 19, 20, 21]), [115, 296, 24]);
```
`getOpenIssues([19, 95, 422, 395, 754, 102, 296, 709, 237, 4400, 1802], [395, 440, 9001, 95, 242, 21, 287, 169, 14])` should return `[95, 395, 754, 296, 709, 237, 1802]`.
```js
assert.deepEqual(getOpenIssues([19, 95, 422, 395, 754, 102, 296, 709, 237, 4400, 1802], [395, 440, 9001, 95, 242, 21, 287, 169, 14]), [95, 395, 754, 296, 709, 237, 1802]);
```
# --seed--
## --seed-contents--
```js
function getOpenIssues(issues, prs) {
return issues;
}
```
# --solutions--
```js
function getOpenIssues(issues, prs) {
function getRotations(n) {
const s = String(n);
const rotations = new Set();
for (let i = 0; i < s.length; i++) {
const rotated = s.slice(i) + s.slice(0, i);
rotations.add(Number(rotated));
}
return rotations;
}
function areRotations(a, b) {
if (a === b) return false;
const rotations = getRotations(a);
return rotations.has(b);
}
return issues.filter(issue =>
!prs.some(pr => areRotations(pr, issue) || areRotations(issue, pr))
);
}
```
@@ -0,0 +1,97 @@
---
id: 69f8c998d78ad3171a0713ba
title: "Challenge 287: Roman Numeral Fixer"
challengeType: 28
dashedName: challenge-287
---
# --description--
Given a string of malformed Roman numerals, return the value in standard Roman numeral notation.
The input will only use additive notation, so each symbol adds its value to the total. As a reminder, here are the symbols and values:
| Symbol | Value |
| ------ | ----- |
| `"I"` | 1 |
| `"V"` | 5 |
| `"X"` | 10 |
| `"L"` | 50 |
| `"C"` | 100 |
| `"D"` | 500 |
| `"M"` | 1000 |
When re-encoding, use the largest possible symbol at each step, using subtractive pairs (`"IV"`, `"IX"`, `"XL"`, `"XC"`, `"CD"`, `"CM"`) where needed.
# --hints--
`fixNumerals("XIIIII")` should return `"XV"`.
```js
assert.equal(fixNumerals("XIIIII"), "XV");
```
`fixNumerals("IIIILX")` should return `"LXIV"`.
```js
assert.equal(fixNumerals("IIIILX"), "LXIV");
```
`fixNumerals("XXVVVIIIII")` should return `"XL"`.
```js
assert.equal(fixNumerals("XXVVVIIIII"), "XL");
```
`fixNumerals("MDCCLXXXXVIIII")` should return `"MDCCXCIX"`.
```js
assert.equal(fixNumerals("MDCCLXXXXVIIII"), "MDCCXCIX");
```
`fixNumerals("IIIIVVVVXXXXLLLLCCDD")` should return `"MCDLXIV"`.
```js
assert.equal(fixNumerals("IIIIVVVVXXXXLLLLCCDD"), "MCDLXIV");
```
`fixNumerals("ILCDMIVDIIXLCVCXDL")` should return `"MMCMLXXXIV"`.
```js
assert.equal(fixNumerals("ILCDMIVDIIXLCVCXDL"), "MMCMLXXXIV");
```
# --seed--
## --seed-contents--
```js
function fixNumerals(str) {
return str;
}
```
# --solutions--
```js
function fixNumerals(str) {
const values = { I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000 };
const encoding = [
[1000, "M"], [900, "CM"], [500, "D"], [400, "CD"],
[100, "C"], [90, "XC"], [50, "L"], [40, "XL"],
[10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]
];
let total = [...str].reduce((sum, c) => sum + values[c], 0);
let result = "";
for (const [value, symbol] of encoding) {
while (total >= value) {
result += symbol;
total -= value;
}
}
return result;
}
```
@@ -0,0 +1,74 @@
---
id: 69f8c998d78ad3171a0713bb
title: "Challenge 288: Secret Number"
challengeType: 28
dashedName: challenge-288
---
# --description--
Given a secret number and a guess, determine if the guess is correct.
Return:
- `"higher"` if the secret number is higher than the guess.
- `"lower"` if the secret number is lower than the guess.
- `"you got it!"` if the guess is correct.
# --hints--
`guessNumber(50, 30)` should return `"higher"`.
```js
assert.equal(guessNumber(50, 30), "higher");
```
`guessNumber(85, 99)` should return `"lower"`.
```js
assert.equal(guessNumber(85, 99), "lower");
```
`guessNumber(2026, 2026)` should return `"you got it!"`.
```js
assert.equal(guessNumber(2026, 2026), "you got it!");
```
`guessNumber(92904, 11283)` should return `"higher"`.
```js
assert.equal(guessNumber(92904, 11283), "higher");
```
`guessNumber(230495, 423920)` should return `"lower"`.
```js
assert.equal(guessNumber(230495, 423920), "lower");
```
`guessNumber(120349, 120349)` should return `"you got it!"`.
```js
assert.equal(guessNumber(120349, 120349), "you got it!");
```
# --seed--
## --seed-contents--
```js
function guessNumber(secret, guess) {
return secret;
}
```
# --solutions--
```js
function guessNumber(secret, guess) {
if (guess === secret) return "you got it!";
return guess < secret ? "higher" : "lower";
}
```
@@ -0,0 +1,57 @@
---
id: 69f8c998d78ad3171a0713bc
title: "Challenge 289: Sum of Differences"
challengeType: 28
dashedName: challenge-289
---
# --description--
Given an array of numbers, return the sum of the differences between each number and the one that follows it.
For example, given `[1, 3, 4]`, return `3` (2 + 1).
# --hints--
`sumOfDifferences([1, 3, 4])` should return `3`.
```js
assert.equal(sumOfDifferences([1, 3, 4]), 3);
```
`sumOfDifferences([5, -3, 3, 9, 10])` should return `5`.
```js
assert.equal(sumOfDifferences([5, -3, 3, 9, 10]), 5);
```
`sumOfDifferences([9, 6, 15, -20, 33, 14, 25, 16, -7])` should return `-16`.
```js
assert.equal(sumOfDifferences([9, 6, 15, -20, 33, 14, 25, 16, -7]), -16);
```
`sumOfDifferences([50, 102, -46, 82, -49, 29, 71, 902, -237, 111, -61, 75])` should return `25`.
```js
assert.equal(sumOfDifferences([50, 102, -46, 82, -49, 29, 71, 902, -237, 111, -61, 75]), 25);
```
# --seed--
## --seed-contents--
```js
function sumOfDifferences(arr) {
return arr;
}
```
# --solutions--
```js
function sumOfDifferences(arr) {
return arr.slice(0, -1).reduce((sum, n, i) => sum + (arr[i + 1] - n), 0);
}
```
@@ -0,0 +1,76 @@
---
id: 69f8c998d78ad3171a0713bd
title: "Challenge 290: Pizza Party"
challengeType: 28
dashedName: challenge-290
---
# --description--
Given an array of hours worked today per person, return the number of pizzas to order for a pizza party.
- Divide each person's hours worked by 3 to get their slice count.
- You can't eat a partial slice, so round each person's slice count up to the nearest whole number.
- Each person gets a minimum of two slices.
- Each pizza has 8 slices. Round the total number of pizzas up to the nearest whole pizza.
# --hints--
`getPizzasToOrder([8, 8, 8])` should return `2`.
```js
assert.equal(getPizzasToOrder([8, 8, 8]), 2);
```
`getPizzasToOrder([10, 9, 8, 2, 2, 6, 10])` should return `3`.
```js
assert.equal(getPizzasToOrder([10, 9, 8, 2, 2, 6, 10]), 3);
```
`getPizzasToOrder([1, 2, 3, 4, 5])` should return `2`.
```js
assert.equal(getPizzasToOrder([1, 2, 3, 4, 5]), 2);
```
`getPizzasToOrder([8, 8, 8, 8, 8, 8, 8, 8])` should return `3`.
```js
assert.equal(getPizzasToOrder([8, 8, 8, 8, 8, 8, 8, 8]), 3);
```
`getPizzasToOrder([9, 9, 6])` should return `1`.
```js
assert.equal(getPizzasToOrder([9, 9, 6]), 1);
```
`getPizzasToOrder([10, 12, 16, 9, 8, 11, 15, 8, 0])` should return `5`.
```js
assert.equal(getPizzasToOrder([10, 12, 16, 9, 8, 11, 15, 8, 0]), 5);
```
# --seed--
## --seed-contents--
```js
function getPizzasToOrder(hoursWorked) {
return hoursWorked;
}
```
# --solutions--
```js
function getPizzasToOrder(hoursWorked) {
const totalSlices = hoursWorked.reduce((sum, hours) => {
return sum + Math.max(Math.ceil(hours / 3), 2);
}, 0);
return Math.ceil(totalSlices / 8);
}
```
@@ -0,0 +1,74 @@
---
id: 69f8c998d78ad3171a0713be
title: "Challenge 291: FizzBuzz Count"
challengeType: 28
dashedName: challenge-291
---
# --description--
Given a start and end number, count the number of fizz and buzz appearances in the range (inclusive).
- Numbers divisible by 3 count as a fizz.
- Numbers divisible by 5 count as a buzz.
- Numbers divisible by both 3 and 5 count as both a fizz and a buzz.
Return an object or dictionary with the counts in the format: `{ fizz, buzz }`.
# --hints--
`fizzBuzzCount(1, 11)` should return `{fizz: 3, buzz: 2}`.
```js
assert.deepEqual(fizzBuzzCount(1, 11), {fizz: 3, buzz: 2});
```
`fizzBuzzCount(14, 41)` should return `{fizz: 9, buzz: 6}`.
```js
assert.deepEqual(fizzBuzzCount(14, 41), {fizz: 9, buzz: 6});
```
`fizzBuzzCount(24, 100)` should return `{fizz: 26, buzz: 16}`.
```js
assert.deepEqual(fizzBuzzCount(24, 100), {fizz: 26, buzz: 16});
```
`fizzBuzzCount(-635, -14)` should return `{fizz: 207, buzz: 125}`.
```js
assert.deepEqual(fizzBuzzCount(-635, -14), {fizz: 207, buzz: 125});
```
`fizzBuzzCount(-5432, 6789)` should return `{fizz: 4074, buzz: 2444}`.
```js
assert.deepEqual(fizzBuzzCount(-5432, 6789), {fizz: 4074, buzz: 2444});
```
# --seed--
## --seed-contents--
```js
function fizzBuzzCount(start, end) {
return start;
}
```
# --solutions--
```js
function fizzBuzzCount(start, end) {
let fizz = 0, buzz = 0;
for (let i = start; i <= end; i++) {
if (i % 3 === 0) fizz++;
if (i % 5 === 0) buzz++;
}
return { fizz, buzz };
}
```
@@ -0,0 +1,84 @@
---
id: 69f8c998d78ad3171a0713bf
title: "Challenge 292: Wider Aspect Ratio"
challengeType: 28
dashedName: challenge-292
---
# --description--
Given two strings for different image dimensions, return the aspect ratio of the image with a greater width-to-height ratio.
- The given strings will be in the format `"WxH"`, for example, `"1920x1080"`.
- The aspect ratio is the ratio of width to height, reduced to the lowest whole numbers. For example, `"1920x1080"` reduces to `"16:9"`.
- Return a string in format `"W:H"`, for example, `"16:9"`.
# --hints--
`getWiderAspectRatio("1920x1080", "800x600")` should return `"16:9"`.
```js
assert.equal(getWiderAspectRatio("1920x1080", "800x600"), "16:9");
```
`getWiderAspectRatio("1080x1350", "2048x1536")` should return `"4:3"`.
```js
assert.equal(getWiderAspectRatio("1080x1350", "2048x1536"), "4:3");
```
`getWiderAspectRatio("640x480", "2440x1220")` should return `"2:1"`.
```js
assert.equal(getWiderAspectRatio("640x480", "2440x1220"), "2:1");
```
`getWiderAspectRatio("360x640", "1080x1920")` should return `"9:16"`.
```js
assert.equal(getWiderAspectRatio("360x640", "1080x1920"), "9:16");
```
`getWiderAspectRatio("3440x1440", "2048x858")` should return `"43:18"`.
```js
assert.equal(getWiderAspectRatio("3440x1440", "2048x858"), "43:18");
```
`getWiderAspectRatio("12345x61234", "12534x51234")` should return `"2089:8539"`.
```js
assert.equal(getWiderAspectRatio("12345x61234", "12534x51234"), "2089:8539");
```
# --seed--
## --seed-contents--
```js
function getWiderAspectRatio(a, b) {
return a;
}
```
# --solutions--
```js
function getWiderAspectRatio(a, b) {
function gcd(x, y) {
return y === 0 ? x : gcd(y, x % y);
}
function parse(str) {
const [w, h] = str.split("x").map(Number);
const g = gcd(w, h);
return { ratio: w / h, simplified: `${w / g}:${h / g}` };
}
const imageA = parse(a);
const imageB = parse(b);
return imageA.ratio >= imageB.ratio ? imageA.simplified : imageB.simplified;
}
```
@@ -0,0 +1,143 @@
---
id: 69f90c1329a94b37e2a2086c
title: "Challenge 293: Best Hand"
challengeType: 28
dashedName: challenge-293
---
# --description--
Given an array of five strings representing playing cards, return the name of the best hand.
- Each card is represented as a two-character string: the rank followed by the suit, `"2h"` for example.
- Ranks, from low to high, are: `"2"`, `"3"`, `"4"`, `"5"`, `"6"`, `"7"`, `"8"`, `"9"`, `"T"`, `"J"`, `"Q"`, `"K"`, and `"A"`.
- Suits are: `"h"`, `"d"`, `"c"`, and `"s"`.
- Aces (`"A"`) can be used as high or low in a straight.
The hands, in order from worst to best, are:
| Name | Description |
| - | - |
| `"High Card"` | No pair or better |
| `"Pair"` | Two of one rank |
| `"Two Pair"` | Two of one rank and two of another |
| `"Three of a Kind"` | Three of one rank |
| `"Straight"` | Five ranks in a row |
| `"Flush"` | Five of the same suit |
| `"Full House"` | Three of one rank, and two of another |
| `"Four of a Kind"` | Four of one rank |
| `"Straight Flush"` | Five ranks in a row of the same suit |
| `"Royal Flush"` | `"A"`, `"K"`, `"Q"`, `"J"`, `"T"` of the same suit |
Return the name of the best hand.
# --hints--
`getBestHand(["7s", "7h", "7d", "2c", "5h"])` should return `"Three of a Kind"`.
```js
assert.equal(getBestHand(["7s", "7h", "7d", "2c", "5h"]), "Three of a Kind");
```
`getBestHand(["Ks", "Kh", "Kd", "4s", "4h"])` should return `"Full House"`.
```js
assert.equal(getBestHand(["Ks", "Kh", "Kd", "4s", "4h"]), "Full House");
```
`getBestHand(["2h", "5h", "7h", "9h", "Jh"])` should return `"Flush"`.
```js
assert.equal(getBestHand(["2h", "5h", "7h", "9h", "Jh"]), "Flush");
```
`getBestHand(["As", "Ah", "Ad", "Ac", "Kh"])` should return `"Four of a Kind"`.
```js
assert.equal(getBestHand(["As", "Ah", "Ad", "Ac", "Kh"]), "Four of a Kind");
```
`getBestHand(["Ts", "Th", "9d", "9c", "8h"])` should return `"Two Pair"`.
```js
assert.equal(getBestHand(["Ts", "Th", "9d", "9c", "8h"]), "Two Pair");
```
`getBestHand(["9c", "8c", "7c", "6c", "5c"])` should return `"Straight Flush"`.
```js
assert.equal(getBestHand(["9c", "8c", "7c", "6c", "5c"]), "Straight Flush");
```
`getBestHand(["As", "Kh", "Jd", "8c", "5h"])` should return `"High Card"`.
```js
assert.equal(getBestHand(["As", "Kh", "Jd", "8c", "5h"]), "High Card");
```
`getBestHand(["As", "2h", "3d", "4c", "5h"])` should return `"Straight"`.
```js
assert.equal(getBestHand(["As", "2h", "3d", "4c", "5h"]), "Straight");
```
`getBestHand(["Ts", "Th", "7c", "6d", "5h"])` should return `"Pair"`.
```js
assert.equal(getBestHand(["Ts", "Th", "7c", "6d", "5h"]), "Pair");
```
`getBestHand(["As", "Ks", "Qs", "Js", "Ts"])` should return `"Royal Flush"`.
```js
assert.equal(getBestHand(["As", "Ks", "Qs", "Js", "Ts"]), "Royal Flush");
```
# --seed--
## --seed-contents--
```js
function getBestHand(cards) {
return cards;
}
```
# --solutions--
```js
function getBestHand(cards) {
const rankOrder = "23456789TJQKA";
const ranks = cards.map(c => c[0]);
const suits = cards.map(c => c[1]);
const isFlush = suits.every(s => s === suits[0]);
const rankIndices = ranks.map(r => rankOrder.indexOf(r)).sort((a, b) => a - b);
function isStraight(indices) {
const isRegular = indices.every((r, i) => i === 0 || r === indices[i - 1] + 1);
const isLowAce = JSON.stringify(indices) === JSON.stringify([0, 1, 2, 3, 12]);
return isRegular || isLowAce;
}
const straight = isStraight(rankIndices);
const counts = {};
ranks.forEach(r => counts[r] = (counts[r] || 0) + 1);
const freq = Object.values(counts).sort((a, b) => b - a);
if (isFlush && JSON.stringify(rankIndices) === JSON.stringify([8, 9, 10, 11, 12])) return "Royal Flush";
if (isFlush && straight) return "Straight Flush";
if (freq[0] === 4) return "Four of a Kind";
if (freq[0] === 3 && freq[1] === 2) return "Full House";
if (isFlush) return "Flush";
if (straight) return "Straight";
if (freq[0] === 3) return "Three of a Kind";
if (freq[0] === 2 && freq[1] === 2) return "Two Pair";
if (freq[0] === 2) return "Pair";
return "High Card";
}
```
@@ -0,0 +1,82 @@
---
id: 69f90c1329a94b37e2a2086d
title: "Challenge 294: Parentheses Combinations"
challengeType: 28
dashedName: challenge-294
---
# --description--
Given an integer, `n`, return the number of valid combinations of `n` pairs of parentheses.
- A valid combination is a string where every opening parentheses has a corresponding closing parentheses, and no closing parentheses appears before its matching opening parentheses.
For example, given `2`, there are 2 valid combinations:
```json
(())
()()
```
# --hints--
`getCombinations(2)` should return `2`.
```js
assert.equal(getCombinations(2), 2);
```
`getCombinations(3)` should return `5`.
```js
assert.equal(getCombinations(3), 5);
```
`getCombinations(5)` should return `42`.
```js
assert.equal(getCombinations(5), 42);
```
`getCombinations(8)` should return `1430`.
```js
assert.equal(getCombinations(8), 1430);
```
`getCombinations(13)` should return `742900`.
```js
assert.equal(getCombinations(13), 742900);
```
# --seed--
## --seed-contents--
```js
function getCombinations(n) {
return n;
}
```
# --solutions--
```js
function getCombinations(n) {
let count = 0;
function generate(open, close) {
if (open === 0 && close === 0) {
count++;
return;
}
if (open > 0) generate(open - 1, close);
if (close > open) generate(open, close - 1);
}
generate(n, n);
return count;
}
```
@@ -0,0 +1,112 @@
---
id: 69f35a5bb823ed620fcb7cb8
title: "Challenge 279: Longest Domino Chain"
challengeType: 29
dashedName: challenge-279
---
# --description--
Given a 2D array representing a set of dominoes, return the longest valid chain.
- Each domino is a pair of numbers from 06, e.g. `[3, 2]`.
- A chain is valid when the second number of each domino matches the first number of the next.
- The first number of the first domino and the second number of the last one don't need to match anything.
- Any domino can be flipped, so `[3, 2]` can be played as `[2, 3]`.
- There is always exactly one longest valid chain.
For example, given `[[1, 2], [4, 5], [2, 3]]`, return `[[1, 2], [2, 3]]`.
# --hints--
`get_longest_chain([[1, 2], [4, 5], [2, 3]])` should return `[[1, 2], [2, 3]]`.
```js
({test: () => { runPython(`
from unittest import TestCase
result = get_longest_chain([[1, 2], [4, 5], [2, 3]])
TestCase().assertIn(result, [[[1, 2], [2, 3]], [[3, 2], [2, 1]]])`)
}})
```
`get_longest_chain([[2, 1], [4, 3], [5, 3]])` should return `[[4, 3], [3, 5]]`.
```js
({test: () => { runPython(`
from unittest import TestCase
result = get_longest_chain([[2, 1], [4, 3], [5, 3]])
TestCase().assertIn(result, [[[4, 3], [3, 5]], [[5, 3], [3, 4]]])`)
}})
```
`get_longest_chain([[1, 2], [3, 4], [2, 3], [4, 0]])` should return `[[1, 2], [2, 3], [3, 4], [4, 0]]`.
```js
({test: () => { runPython(`
from unittest import TestCase
result = get_longest_chain([[1, 2], [3, 4], [2, 3], [4, 0]])
TestCase().assertIn(result, [[[1, 2], [2, 3], [3, 4], [4, 0]], [[0, 4], [4, 3], [3, 2], [2, 1]]])`)
}})
```
`get_longest_chain([[6, 6], [6, 1], [1, 1], [0, 3], [2, 3], [4, 1], [5, 6]])` should return `[[4, 1], [1, 1], [1, 6], [6, 6], [6, 5]]`.
```js
({test: () => { runPython(`
from unittest import TestCase
result = get_longest_chain([[6, 6], [6, 1], [1, 1], [0, 3], [2, 3], [4, 1], [5, 6]])
TestCase().assertIn(result, [[[4, 1], [1, 1], [1, 6], [6, 6], [6, 5]], [[5, 6], [6, 6], [6, 1], [1, 1], [1, 4]]])`)
}})
```
`get_longest_chain([[0, 4], [3, 3], [0, 3], [5, 6], [4, 5], [4, 2], [5, 5], [1, 2], [4, 4]])` should return `[[3, 3], [3, 0], [0, 4], [4, 4], [4, 5], [5, 5], [5, 6]]`.
```js
({test: () => { runPython(`
from unittest import TestCase
result = get_longest_chain([[0, 4], [3, 3], [0, 3], [5, 6], [4, 5], [4, 2], [5, 5], [1, 2], [4, 4]])
TestCase().assertIn(result, [[[3, 3], [3, 0], [0, 4], [4, 4], [4, 5], [5, 5], [5, 6]], [[6, 5], [5, 5], [5, 4], [4, 4], [4, 0], [0, 3], [3, 3]]])`)
}})
```
# --seed--
## --seed-contents--
```py
def get_longest_chain(dominoes):
return dominoes
```
# --solutions--
```py
def get_longest_chain(dominoes):
def search(chain, remaining):
best = chain
last = chain[-1][1]
for i, (a, b) in enumerate(remaining):
rest = remaining[:i] + remaining[i+1:]
if a == last:
result = search(chain + [[a, b]], rest)
if len(result) > len(best):
best = result
if b == last and a != b:
result = search(chain + [[b, a]], rest)
if len(result) > len(best):
best = result
return best
best = []
for i, (a, b) in enumerate(dominoes):
rest = dominoes[:i] + dominoes[i+1:]
r1 = search([[a, b]], rest)
if len(r1) > len(best):
best = r1
if a != b:
r2 = search([[b, a]], rest)
if len(r2) > len(best):
best = r2
return best
```
@@ -0,0 +1,82 @@
---
id: 69f35a5bb823ed620fcb7cb9
title: "Challenge 280: Mongo ID Date"
challengeType: 29
dashedName: challenge-280
---
# --description--
Given a MongoDB ID string, return its creation time as an ISO 8601 string.
- A MongoDB ID is a 24-character hex string. The first 8 characters represent a Unix timestamp (in seconds) encoded as a base-16 integer.
For example, `"6a094b50bcf86cd799439011"` has a timestamp of `"6a094b50"` in hex, which is `1778994000` in decimal, representing a creation time of `"2026-05-17T05:00:00.000Z"`.
# --hints--
`mongo_id_to_date("6a094b50bcf86cd799439011")` should return `"2026-05-17T05:00:00.000Z"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(mongo_id_to_date("6a094b50bcf86cd799439011"), "2026-05-17T05:00:00.000Z")`)
}})
```
`mongo_id_to_date("695344eb1f4a4c1123042128")` should return `"2025-12-30T03:20:11.000Z"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(mongo_id_to_date("695344eb1f4a4c1123042128"), "2025-12-30T03:20:11.000Z")`)
}})
```
`mongo_id_to_date("386da62df34123ac54617e56")` should return `"2000-01-01T07:01:01.000Z"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(mongo_id_to_date("386da62df34123ac54617e56"), "2000-01-01T07:01:01.000Z")`)
}})
```
`mongo_id_to_date("69f571c3d7711807afd3dd55")` should return `"2026-05-02T03:38:43.000Z"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(mongo_id_to_date("69f571c3d7711807afd3dd55"), "2026-05-02T03:38:43.000Z")`)
}})
```
`mongo_id_to_date("68adce01c0e1144d0a90295a")` should return `"2025-08-26T15:08:49.000Z"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(mongo_id_to_date("68adce01c0e1144d0a90295a"), "2025-08-26T15:08:49.000Z")`)
}})
```
# --seed--
## --seed-contents--
```py
def mongo_id_to_date(s):
return s
```
# --solutions--
```py
from datetime import datetime, timezone
def mongo_id_to_date(s):
timestamp = int(s[:8], 16)
dt = datetime.fromtimestamp(timestamp, tz=timezone.utc)
return dt.strftime("%Y-%m-%dT%H:%M:%S.000Z")
```
@@ -0,0 +1,86 @@
---
id: 69f35a5bb823ed620fcb7cba
title: "Challenge 281: Bingo Range"
challengeType: 29
dashedName: challenge-281
---
# --description--
Given a bingo letter, return the number range associated with that letter.
| Letter | Number Range |
| - | - |
| `"B"` | 1-15 |
| `"I"` | 16-30 |
| `"N"` | 31-45 |
| `"G"` | 46-60 |
| `"O"` | 61-75 |
Return an array with all numbers in the range from smallest to largest.
# --hints--
`get_bingo_range("B")` should return `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_bingo_range("B"), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])`)
}})
```
`get_bingo_range("I")` should return `[16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_bingo_range("I"), [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30])`)
}})
```
`get_bingo_range("N")` should return `[31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_bingo_range("N"), [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45])`)
}})
```
`get_bingo_range("G")` should return `[46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_bingo_range("G"), [46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60])`)
}})
```
`get_bingo_range("O")` should return `[61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_bingo_range("O"), [61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75])`)
}})
```
# --seed--
## --seed-contents--
```py
def get_bingo_range(letter):
return letter
```
# --solutions--
```py
def get_bingo_range(letter):
ranges = {"B": (1, 15), "I": (16, 30), "N": (31, 45), "G": (46, 60), "O": (61, 75)}
start, end = ranges[letter]
return list(range(start, end + 1))
```
@@ -0,0 +1,78 @@
---
id: 69f35a5bb823ed620fcb7cbb
title: "Challenge 282: Sleep Debt"
challengeType: 29
dashedName: challenge-282
---
# --description--
Given an array of hours slept each night leading up to today, and a target number of hours per night, return how many hours of sleep you need tonight to eliminate your sleep debt.
- Include tonight's hours in the total time needed to catch up.
- If you've slept enough to cover tonight's target or more, return `0`.
# --hints--
`sleep_debt([6, 6, 6, 6, 6, 6], 8)` should return `20`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sleep_debt([6, 6, 6, 6, 6, 6], 8), 20)`)
}})
```
`sleep_debt([6, 7, 8, 4, 8, 6], 7)` should return `10`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sleep_debt([6, 7, 8, 4, 8, 6], 7), 10)`)
}})
```
`sleep_debt([10, 10, 9, 10, 9, 11], 9)` should return `4`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sleep_debt([10, 10, 9, 10, 9, 11], 9), 4)`)
}})
```
`sleep_debt([8, 7, 6, 7, 6, 8], 6)` should return `0`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sleep_debt([8, 7, 6, 7, 6, 8], 6), 0)`)
}})
```
`sleep_debt([8, 9, 10, 9, 10, 7], 7)` should return `0`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sleep_debt([8, 9, 10, 9, 10, 7], 7), 0)`)
}})
```
# --seed--
## --seed-contents--
```py
def sleep_debt(hours_slept, target_hours):
return hours_slept
```
# --solutions--
```py
def sleep_debt(hours_slept, target_hours):
debt = (len(hours_slept) + 1) * target_hours - sum(hours_slept)
return max(0, debt)
```
@@ -0,0 +1,82 @@
---
id: 69f35a5bb823ed620fcb7cbc
title: "Challenge 283: String Zipper"
challengeType: 29
dashedName: challenge-283
---
# --description--
Given two strings, return a new string that interleaves their characters one at a time. If one string is longer, append the remaining characters at the end.
Begin with the first character of the first string.
# --hints--
`zip_strings("abc", "123")` should return `"a1b2c3"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(zip_strings("abc", "123"), "a1b2c3")`)
}})
```
`zip_strings("acegikmoqsuwy", "bdfhjlnprtvxz")` should return `"abcdefghijklmnopqrstuvwxyz"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(zip_strings("acegikmoqsuwy", "bdfhjlnprtvxz"), "abcdefghijklmnopqrstuvwxyz")`)
}})
```
`zip_strings("day", "night")` should return `"dnaiyght"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(zip_strings("day", "night"), "dnaiyght")`)
}})
```
`zip_strings("python", "javascript")` should return `"pjyatvhaosncript"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(zip_strings("python", "javascript"), "pjyatvhaosncript")`)
}})
```
`zip_strings("feCdCm", "reoeap")` should return `"freeCodeCamp"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(zip_strings("feCdCm", "reoeap"), "freeCodeCamp")`)
}})
```
# --seed--
## --seed-contents--
```py
def zip_strings(a, b):
return a
```
# --solutions--
```py
def zip_strings(a, b):
result = ""
for i in range(max(len(a), len(b))):
if i < len(a):
result += a[i]
if i < len(b):
result += b[i]
return result
```
@@ -0,0 +1,85 @@
---
id: 69f35a5bb823ed620fcb7cbd
title: "Challenge 284: I Before E"
challengeType: 29
dashedName: challenge-284
---
# --description--
Given a word or sentence, return a corrected version where every word follows the "I before E except after C" rule.
- If a word contains `"ei"` not preceded by `"c"`, replace it with `"ie"`.
- If a word contains `"ie"` preceded by `"c"`, replace it with `"ei"`.
- All other words are left unchanged.
# --hints--
`i_before_e("beleive")` should return `"believe"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(i_before_e("beleive"), "believe")`)
}})
```
`i_before_e("recieve")` should return `"receive"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(i_before_e("recieve"), "receive")`)
}})
```
`i_before_e("we recieved a breif")` should return `"we received a brief"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(i_before_e("we recieved a breif"), "we received a brief")`)
}})
```
`i_before_e("she beleived the friendly niece could percieve the greif")` should return `"she believed the friendly niece could perceive the grief"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(i_before_e("she beleived the friendly niece could percieve the greif"), "she believed the friendly niece could perceive the grief")`)
}})
```
`i_before_e("we recieved relief after the theif gave us a breif piece of feirce deceit")` should return `"we received relief after the thief gave us a brief piece of fierce deceit"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(i_before_e("we recieved relief after the theif gave us a breif piece of feirce deceit"), "we received relief after the thief gave us a brief piece of fierce deceit")`)
}})
```
# --seed--
## --seed-contents--
```py
def i_before_e(sentence):
return sentence
```
# --solutions--
```py
import re
def i_before_e(sentence):
words = []
for word in sentence.split(" "):
word = re.sub(r"([^c])ei", r"\1ie", word)
word = re.sub(r"cie", "cei", word)
words.append(word)
return " ".join(words)
```
@@ -0,0 +1,93 @@
---
id: 69f35a5bb823ed620fcb7cbe
title: "Challenge 285: Meeting Time"
challengeType: 29
dashedName: challenge-285
---
# --description--
Given a 3D array representing availability windows for multiple people, return the earliest time where everyone has one hour free. If no such time exists, return `"None"`.
- Each person's availability is an array of `[start, end]` integer pairs in 24-hour time. For example, `[10, 12]` would mean the person is available from 10 to 12. Start times range from 0-23, and end times range from 1-24.
For example, given:
```json
[
[[10, 12], [15, 16]], // person 1
[[11, 14], [15, 16]] // person 2
]
```
Return `11`, the start of their first shared free hour.
# --hints--
`get_meeting_time([[[10, 12], [15, 16]], [[11, 14], [15, 16]]])` should return `11`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_meeting_time([[[10, 12], [15, 16]], [[11, 14], [15, 16]]]), 11)`)
}})
```
`get_meeting_time([[[9, 10], [12, 15]], [[10, 11], [13, 14]], [[9, 11], [10, 14]]])` should return `13`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_meeting_time([[[9, 10], [12, 15]], [[10, 11], [13, 14]], [[9, 11], [10, 14]]]), 13)`)
}})
```
`get_meeting_time([[[7, 8], [9, 11], [12, 14], [15, 16]], [[8, 11], [12, 13], [14, 15]]])` should return `9`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_meeting_time([[[7, 8], [9, 11], [12, 14], [15, 16]], [[8, 11], [12, 13], [14, 15]]]), 9)`)
}})
```
`get_meeting_time([[[7, 8], [10, 12], [13, 15]], [[8, 11], [12, 13], [14, 15]], [[6, 7], [8, 9], [12, 13]]])` should return `None`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_meeting_time([[[7, 8], [10, 12], [13, 15]], [[8, 11], [12, 13], [14, 15]], [[6, 7], [8, 9], [12, 13]]]), "None")`)
}})
```
`get_meeting_time([[[1, 3], [4, 6], [8, 10], [20, 23]], [[15, 16], [17, 18], [19, 22], [23, 24]], [[14, 16], [17, 23]], [[2, 4], [5, 6], [18, 19], [21, 22], [23, 24]]])` should return `21`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_meeting_time([[[1, 3], [4, 6], [8, 10], [20, 23]], [[15, 16], [17, 18], [19, 22], [23, 24]], [[14, 16], [17, 23]], [[2, 4], [5, 6], [18, 19], [21, 22], [23, 24]]]), 21)`)
}})
```
# --seed--
## --seed-contents--
```py
def get_meeting_time(availability):
return availability
```
# --solutions--
```py
def get_meeting_time(availability):
for hour in range(24):
if all(
any(start <= hour and hour + 1 <= end for start, end in person)
for person in availability
):
return hour
return "None"
```
@@ -0,0 +1,93 @@
---
id: 69f8c998d78ad3171a0713b9
title: "Challenge 286: Open Issues"
challengeType: 29
dashedName: challenge-286
---
# --description--
Given an array of issue numbers and another array of pull request (PR) numbers, return an array of issues that remain open after all PRs have been merged.
- A PR closes an issue if their digits are a rotation of each other. For example, issue 123 would be closed by PR 231 or 312.
- A PR does not close an issue with the exact same number. For example, PR 123 does not close issue 123. So an issue with all the same number can't get closed.
- Either number may have leading zeros stripped. For example, PR 201 would close issue 12 (012, a rotation of 201). Similarily, issue 201 would be closed by PR 12.
Return the remaining open issues in the order they were given.
# --hints--
`get_open_issues([123, 234], [231])` should return `[234]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_open_issues([123, 234], [231]), [234])`)
}})
```
`get_open_issues([123, 345, 16], [345, 231])` should return `[345, 16]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_open_issues([123, 345, 16], [345, 231]), [345, 16])`)
}})
```
`get_open_issues([456, 332, 12, 15], [201, 945, 180])` should return `[456, 332, 15]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_open_issues([456, 332, 12, 15], [201, 945, 180]), [456, 332, 15])`)
}})
```
`get_open_issues([12, 115, 296, 170, 24], [17, 18, 19, 20, 21])` should return `[115, 296, 24]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_open_issues([12, 115, 296, 170, 24], [17, 18, 19, 20, 21]), [115, 296, 24])`)
}})
```
`get_open_issues([19, 95, 422, 395, 754, 102, 296, 709, 237, 4400, 1802], [395, 440, 9001, 95, 242, 21, 287, 169, 14])` should return `[95, 395, 754, 296, 709, 237, 1802]`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_open_issues([19, 95, 422, 395, 754, 102, 296, 709, 237, 4400, 1802], [395, 440, 9001, 95, 242, 21, 287, 169, 14]), [95, 395, 754, 296, 709, 237, 1802])`)
}})
```
# --seed--
## --seed-contents--
```py
def get_open_issues(issues, prs):
return issues
```
# --solutions--
```py
def get_open_issues(issues, prs):
def get_rotations(n):
s = str(n)
rotations = set()
for i in range(len(s)):
rotated = s[i:] + s[:i]
rotations.add(int(rotated))
return rotations
def are_rotations(a, b):
if a == b:
return False
return b in get_rotations(a)
return [issue for issue in issues if not any(are_rotations(pr, issue) or are_rotations(issue, pr) for pr in prs)]
```
@@ -0,0 +1,111 @@
---
id: 69f8c998d78ad3171a0713ba
title: "Challenge 287: Roman Numeral Fixer"
challengeType: 29
dashedName: challenge-287
---
# --description--
Given a string of malformed Roman numerals, return the value in standard Roman numeral notation.
The input will only use additive notation, so each symbol adds its value to the total. As a reminder, here are the symbols and values:
| Symbol | Value |
| ------ | ----- |
| `"I"` | 1 |
| `"V"` | 5 |
| `"X"` | 10 |
| `"L"` | 50 |
| `"C"` | 100 |
| `"D"` | 500 |
| `"M"` | 1000 |
When re-encoding, use the largest possible symbol at each step, using subtractive pairs (`"IV"`, `"IX"`, `"XL"`, `"XC"`, `"CD"`, `"CM"`) where needed.
# --hints--
`fix_numerals("XIIIII")` should return `"XV"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("XIIIII"), "XV")`)
}})
```
`fix_numerals("IIIILX")` should return `"LXIV"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("IIIILX"), "LXIV")`)
}})
```
`fix_numerals("XXVVVIIIII")` should return `"XL"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("XXVVVIIIII"), "XL")`)
}})
```
`fix_numerals("MDCCLXXXXVIIII")` should return `"MDCCXCIX"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("MDCCLXXXXVIIII"), "MDCCXCIX")`)
}})
```
`fix_numerals("IIIIVVVVXXXXLLLLCCDD")` should return `"MCDLXIV"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("IIIIVVVVXXXXLLLLCCDD"), "MCDLXIV")`)
}})
```
`fix_numerals("ILCDMIVDIIXLCVCXDL")` should return `"MMCMLXXXIV"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fix_numerals("ILCDMIVDIIXLCVCXDL"), "MMCMLXXXIV")`)
}})
```
# --seed--
## --seed-contents--
```py
def fix_numerals(s):
return s
```
# --solutions--
```py
def fix_numerals(s):
values = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
encoding = [
(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
(100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
(10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")
]
total = sum(values[c] for c in s)
result = ""
for value, symbol in encoding:
while total >= value:
result += symbol
total -= value
return result
```
@@ -0,0 +1,91 @@
---
id: 69f8c998d78ad3171a0713bb
title: "Challenge 288: Secret Number"
challengeType: 29
dashedName: challenge-288
---
# --description--
Given a secret number and a guess, determine if the guess is correct.
Return:
- `"higher"` if the secret number is higher than the guess.
- `"lower"` if the secret number is lower than the guess.
- `"you got it!"` if the guess is correct.
# --hints--
`guess_number(50, 30)` should return `"higher"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(50, 30), "higher")`)
}})
```
`guess_number(85, 99)` should return `"lower"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(85, 99), "lower")`)
}})
```
`guess_number(2026, 2026)` should return `"you got it!"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(2026, 2026), "you got it!")`)
}})
```
`guess_number(92904, 11283)` should return `"higher"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(92904, 11283), "higher")`)
}})
```
`guess_number(230495, 423920)` should return `"lower"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(230495, 423920), "lower")`)
}})
```
`guess_number(120349, 120349)` should return `"you got it!"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(guess_number(120349, 120349), "you got it!")`)
}})
```
# --seed--
## --seed-contents--
```py
def guess_number(secret, guess):
return secret
```
# --solutions--
```py
def guess_number(secret, guess):
if guess == secret:
return "you got it!"
return "higher" if guess < secret else "lower"
```
@@ -0,0 +1,67 @@
---
id: 69f8c998d78ad3171a0713bc
title: "Challenge 289: Sum of Differences"
challengeType: 29
dashedName: challenge-289
---
# --description--
Given an array of numbers, return the sum of the differences between each number and the one that follows it.
For example, given `[1, 3, 4]`, return `3` (2 + 1).
# --hints--
`sum_of_differences([1, 3, 4])` should return `3`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sum_of_differences([1, 3, 4]), 3)`)
}})
```
`sum_of_differences([5, -3, 3, 9, 10])` should return `5`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sum_of_differences([5, -3, 3, 9, 10]), 5)`)
}})
```
`sum_of_differences([9, 6, 15, -20, 33, 14, 25, 16, -7])` should return `-16`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sum_of_differences([9, 6, 15, -20, 33, 14, 25, 16, -7]), -16)`)
}})
```
`sum_of_differences([50, 102, -46, 82, -49, 29, 71, 902, -237, 111, -61, 75])` should return `25`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(sum_of_differences([50, 102, -46, 82, -49, 29, 71, 902, -237, 111, -61, 75]), 25)`)
}})
```
# --seed--
## --seed-contents--
```py
def sum_of_differences(arr):
return arr
```
# --solutions--
```py
def sum_of_differences(arr):
return sum(arr[i + 1] - arr[i] for i in range(len(arr) - 1))
```
@@ -0,0 +1,91 @@
---
id: 69f8c998d78ad3171a0713bd
title: "Challenge 290: Pizza Party"
challengeType: 29
dashedName: challenge-290
---
# --description--
Given an array of hours worked today per person, return the number of pizzas to order for a pizza party.
- Divide each person's hours worked by 3 to get their slice count.
- You can't eat a partial slice, so round each person's slice count up to the nearest whole number.
- Each person gets a minimum of two slices.
- Each pizza has 8 slices. Round the total number of pizzas up to the nearest whole pizza.
# --hints--
`get_pizzas_to_order([8, 8, 8])` should return `2`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([8, 8, 8]), 2)`)
}})
```
`get_pizzas_to_order([10, 9, 8, 2, 2, 6, 10])` should return `3`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([10, 9, 8, 2, 2, 6, 10]), 3)`)
}})
```
`get_pizzas_to_order([1, 2, 3, 4, 5])` should return `2`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([1, 2, 3, 4, 5]), 2)`)
}})
```
`get_pizzas_to_order([8, 8, 8, 8, 8, 8, 8, 8])` should return `3`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([8, 8, 8, 8, 8, 8, 8, 8]), 3)`)
}})
```
`get_pizzas_to_order([9, 9, 6])` should return `1`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([9, 9, 6]), 1)`)
}})
```
`get_pizzas_to_order([10, 12, 16, 9, 8, 11, 15, 8, 0])` should return `5`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_pizzas_to_order([10, 12, 16, 9, 8, 11, 15, 8, 0]), 5)`)
}})
```
# --seed--
## --seed-contents--
```py
def get_pizzas_to_order(hours_worked):
return hours_worked
```
# --solutions--
```py
import math
def get_pizzas_to_order(hours_worked):
total_slices = sum(max(math.ceil(h / 3), 2) for h in hours_worked)
return math.ceil(total_slices / 8)
```
@@ -0,0 +1,82 @@
---
id: 69f8c998d78ad3171a0713be
title: "Challenge 291: FizzBuzz Count"
challengeType: 29
dashedName: challenge-291
---
# --description--
Given a start and end number, count the number of fizz and buzz appearances in the range (inclusive).
- Numbers divisible by 3 count as a fizz.
- Numbers divisible by 5 count as a buzz.
- Numbers divisible by both 3 and 5 count as both a fizz and a buzz.
Return an object or dictionary with the counts in the format: `{ fizz, buzz }`.
# --hints--
`fizz_buzz_count(1, 11)` should return `{"fizz": 3, "buzz": 2}`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fizz_buzz_count(1, 11), {"fizz": 3, "buzz": 2})`)
}})
```
`fizz_buzz_count(14, 41)` should return `{"fizz": 9, "buzz": 6}`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fizz_buzz_count(14, 41), {"fizz": 9, "buzz": 6})`)
}})
```
`fizz_buzz_count(24, 100)` should return `{"fizz": 26, "buzz": 16}`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fizz_buzz_count(24, 100), {"fizz": 26, "buzz": 16})`)
}})
```
`fizz_buzz_count(-635, -14)` should return `{"fizz": 207, "buzz": 125}`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fizz_buzz_count(-635, -14), {"fizz": 207, "buzz": 125})`)
}})
```
`fizz_buzz_count(-5432, 6789)` should return `{"fizz": 4074, "buzz": 2444}`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(fizz_buzz_count(-5432, 6789), {"fizz": 4074, "buzz": 2444})`)
}})
```
# --seed--
## --seed-contents--
```py
def fizz_buzz_count(start, end):
return start
```
# --solutions--
```py
def fizz_buzz_count(start, end):
fizz = sum(1 for i in range(start, end + 1) if i % 3 == 0)
buzz = sum(1 for i in range(start, end + 1) if i % 5 == 0)
return {"fizz": fizz, "buzz": buzz}
```
@@ -0,0 +1,97 @@
---
id: 69f8c998d78ad3171a0713bf
title: "Challenge 292: Wider Aspect Ratio"
challengeType: 29
dashedName: challenge-292
---
# --description--
Given two strings for different image dimensions, return the aspect ratio of the image with a greater width-to-height ratio.
- The given strings will be in the format `"WxH"`, for example, `"1920x1080"`.
- The aspect ratio is the ratio of width to height, reduced to the lowest whole numbers. For example, `"1920x1080"` reduces to `"16:9"`.
- Return a string in format `"W:H"`, for example, `"16:9"`.
# --hints--
`get_wider_aspect_ratio("1920x1080", "800x600")` should return `"16:9"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("1920x1080", "800x600"), "16:9")`)
}})
```
`get_wider_aspect_ratio("1080x1350", "2048x1536")` should return `"4:3"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("1080x1350", "2048x1536"), "4:3")`)
}})
```
`get_wider_aspect_ratio("640x480", "2440x1220")` should return `"2:1"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("640x480", "2440x1220"), "2:1")`)
}})
```
`get_wider_aspect_ratio("360x640", "1080x1920")` should return `"9:16"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("360x640", "1080x1920"), "9:16")`)
}})
```
`get_wider_aspect_ratio("3440x1440", "2048x858")` should return `"43:18"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("3440x1440", "2048x858"), "43:18")`)
}})
```
`get_wider_aspect_ratio("12345x61234", "12534x51234")` should return `"2089:8539"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_wider_aspect_ratio("12345x61234", "12534x51234"), "2089:8539")`)
}})
```
# --seed--
## --seed-contents--
```py
def get_wider_aspect_ratio(a, b):
return a
```
# --solutions--
```py
from math import gcd
def get_wider_aspect_ratio(a, b):
def parse(s):
w, h = map(int, s.split("x"))
g = gcd(w, h)
return w / h, f"{w // g}:{h // g}"
ratio_a, simplified_a = parse(a)
ratio_b, simplified_b = parse(b)
return simplified_a if ratio_a >= ratio_b else simplified_b
```
@@ -0,0 +1,179 @@
---
id: 69f90c1329a94b37e2a2086c
title: "Challenge 293: Best Hand"
challengeType: 29
dashedName: challenge-293
---
# --description--
Given an array of five strings representing playing cards, return the name of the best hand.
- Each card is represented as a two-character string: the rank followed by the suit, `"2h"` for example.
- Ranks, from low to high, are: `"2"`, `"3"`, `"4"`, `"5"`, `"6"`, `"7"`, `"8"`, `"9"`, `"T"`, `"J"`, `"Q"`, `"K"`, and `"A"`.
- Suits are: `"h"`, `"d"`, `"c"`, and `"s"`.
- Aces (`"A"`) can be used as high or low in a straight.
The hands, in order from worst to best, are:
| Name | Description |
| - | - |
| `"High Card"` | No pair or better |
| `"Pair"` | Two of one rank |
| `"Two Pair"` | Two of one rank and two of another |
| `"Three of a Kind"` | Three of one rank |
| `"Straight"` | Five ranks in a row |
| `"Flush"` | Five of the same suit |
| `"Full House"` | Three of one rank, and two of another |
| `"Four of a Kind"` | Four of one rank |
| `"Straight Flush"` | Five ranks in a row of the same suit |
| `"Royal Flush"` | `"A"`, `"K"`, `"Q"`, `"J"`, `"T"` of the same suit |
Return the name of the best hand.
# --hints--
`get_best_hand(["7s", "7h", "7d", "2c", "5h"])` should return `"Three of a Kind"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["7s", "7h", "7d", "2c", "5h"]), "Three of a Kind")`)
}})
```
`get_best_hand(["Ks", "Kh", "Kd", "4s", "4h"])` should return `"Full House"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["Ks", "Kh", "Kd", "4s", "4h"]), "Full House")`)
}})
```
`get_best_hand(["2h", "5h", "7h", "9h", "Jh"])` should return `"Flush"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["2h", "5h", "7h", "9h", "Jh"]), "Flush")`)
}})
```
`get_best_hand(["As", "Ah", "Ad", "Ac", "Kh"])` should return `"Four of a Kind"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["As", "Ah", "Ad", "Ac", "Kh"]), "Four of a Kind")`)
}})
```
`get_best_hand(["Ts", "Th", "9d", "9c", "8h"])` should return `"Two Pair"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["Ts", "Th", "9d", "9c", "8h"]), "Two Pair")`)
}})
```
`get_best_hand(["9c", "8c", "7c", "6c", "5c"])` should return `"Straight Flush"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["9c", "8c", "7c", "6c", "5c"]), "Straight Flush")`)
}})
```
`get_best_hand(["As", "Kh", "Jd", "8c", "5h"])` should return `"High Card"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["As", "Kh", "Jd", "8c", "5h"]), "High Card")`)
}})
```
`get_best_hand(["As", "2h", "3d", "4c", "5h"])` should return `"Straight"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["As", "2h", "3d", "4c", "5h"]), "Straight")`)
}})
```
`get_best_hand(["Ts", "Th", "7c", "6d", "5h"])` should return `"Pair"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["Ts", "Th", "7c", "6d", "5h"]), "Pair")`)
}})
```
`get_best_hand(["As", "Ks", "Qs", "Js", "Ts"])` should return `"Royal Flush"`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_best_hand(["As", "Ks", "Qs", "Js", "Ts"]), "Royal Flush")`)
}})
```
# --seed--
## --seed-contents--
```py
def get_best_hand(cards):
return cards
```
# --solutions--
```py
def get_best_hand(cards):
rank_order = "23456789TJQKA"
ranks = [c[0] for c in cards]
suits = [c[1] for c in cards]
is_flush = len(set(suits)) == 1
rank_indices = sorted(rank_order.index(r) for r in ranks)
def is_straight(indices):
is_regular = all(indices[i] == indices[i - 1] + 1 for i in range(1, len(indices)))
is_low_ace = indices == [0, 1, 2, 3, 12]
return is_regular or is_low_ace
straight = is_straight(rank_indices)
counts = {}
for r in ranks:
counts[r] = counts.get(r, 0) + 1
freq = sorted(counts.values(), reverse=True)
if is_flush and rank_indices == [8, 9, 10, 11, 12]:
return "Royal Flush"
if is_flush and straight:
return "Straight Flush"
if freq[0] == 4:
return "Four of a Kind"
if freq[0] == 3 and freq[1] == 2:
return "Full House"
if is_flush:
return "Flush"
if straight:
return "Straight"
if freq[0] == 3:
return "Three of a Kind"
if freq[0] == 2 and freq[1] == 2:
return "Two Pair"
if freq[0] == 2:
return "Pair"
return "High Card"
```
@@ -0,0 +1,96 @@
---
id: 69f90c1329a94b37e2a2086d
title: "Challenge 294: Parentheses Combinations"
challengeType: 29
dashedName: challenge-294
---
# --description--
Given an integer, `n`, return the number of valid combinations of `n` pairs of parentheses.
- A valid combination is a string where every opening parentheses has a corresponding closing parentheses, and no closing parentheses appears before its matching opening parentheses.
For example, given `2`, there are 2 valid combinations:
```json
(())
()()
```
# --hints--
`get_combinations(2)` should return `2`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_combinations(2), 2)`)
}})
```
`get_combinations(3)` should return `5`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_combinations(3), 5)`)
}})
```
`get_combinations(5)` should return `42`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_combinations(5), 42)`)
}})
```
`get_combinations(8)` should return `1430`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_combinations(8), 1430)`)
}})
```
`get_combinations(13)` should return `742900`.
```js
({test: () => { runPython(`
from unittest import TestCase
TestCase().assertEqual(get_combinations(13), 742900)`)
}})
```
# --seed--
## --seed-contents--
```py
def get_combinations(n):
return n
```
# --solutions--
```py
def get_combinations(n):
count = 0
def generate(op, cl):
nonlocal count
if op == 0 and cl == 0:
count += 1
return
if op > 0:
generate(op - 1, cl)
if cl > op:
generate(op, cl - 1)
generate(n, n)
return count
```
@@ -1117,6 +1117,70 @@
{
"id": "69e2383af7832c8032603b94",
"title": "Challenge 278: Coffee Order Parser"
},
{
"id": "69f35a5bb823ed620fcb7cb8",
"title": "Challenge 279: Longest Domino Chain"
},
{
"id": "69f35a5bb823ed620fcb7cb9",
"title": "Challenge 280: Mongo ID Date"
},
{
"id": "69f35a5bb823ed620fcb7cba",
"title": "Challenge 281: Bingo Range"
},
{
"id": "69f35a5bb823ed620fcb7cbb",
"title": "Challenge 282: Sleep Debt"
},
{
"id": "69f35a5bb823ed620fcb7cbc",
"title": "Challenge 283: String Zipper"
},
{
"id": "69f35a5bb823ed620fcb7cbd",
"title": "Challenge 284: I Before E"
},
{
"id": "69f35a5bb823ed620fcb7cbe",
"title": "Challenge 285: Meeting Time"
},
{
"id": "69f8c998d78ad3171a0713b9",
"title": "Challenge 286: Open Issues"
},
{
"id": "69f8c998d78ad3171a0713ba",
"title": "Challenge 287: Roman Numeral Fixer"
},
{
"id": "69f8c998d78ad3171a0713bb",
"title": "Challenge 288: Secret Number"
},
{
"id": "69f8c998d78ad3171a0713bc",
"title": "Challenge 289: Sum of Differences"
},
{
"id": "69f8c998d78ad3171a0713bd",
"title": "Challenge 290: Pizza Party"
},
{
"id": "69f8c998d78ad3171a0713be",
"title": "Challenge 291: FizzBuzz Count"
},
{
"id": "69f8c998d78ad3171a0713bf",
"title": "Challenge 292: Wider Aspect Ratio"
},
{
"id": "69f90c1329a94b37e2a2086c",
"title": "Challenge 293: Best Hand"
},
{
"id": "69f90c1329a94b37e2a2086d",
"title": "Challenge 294: Parentheses Combinations"
}
]
}
@@ -1116,6 +1116,70 @@
{
"id": "69e2383af7832c8032603b94",
"title": "Challenge 278: Coffee Order Parser"
},
{
"id": "69f35a5bb823ed620fcb7cb8",
"title": "Challenge 279: Longest Domino Chain"
},
{
"id": "69f35a5bb823ed620fcb7cb9",
"title": "Challenge 280: Mongo ID Date"
},
{
"id": "69f35a5bb823ed620fcb7cba",
"title": "Challenge 281: Bingo Range"
},
{
"id": "69f35a5bb823ed620fcb7cbb",
"title": "Challenge 282: Sleep Debt"
},
{
"id": "69f35a5bb823ed620fcb7cbc",
"title": "Challenge 283: String Zipper"
},
{
"id": "69f35a5bb823ed620fcb7cbd",
"title": "Challenge 284: I Before E"
},
{
"id": "69f35a5bb823ed620fcb7cbe",
"title": "Challenge 285: Meeting Time"
},
{
"id": "69f8c998d78ad3171a0713b9",
"title": "Challenge 286: Open Issues"
},
{
"id": "69f8c998d78ad3171a0713ba",
"title": "Challenge 287: Roman Numeral Fixer"
},
{
"id": "69f8c998d78ad3171a0713bb",
"title": "Challenge 288: Secret Number"
},
{
"id": "69f8c998d78ad3171a0713bc",
"title": "Challenge 289: Sum of Differences"
},
{
"id": "69f8c998d78ad3171a0713bd",
"title": "Challenge 290: Pizza Party"
},
{
"id": "69f8c998d78ad3171a0713be",
"title": "Challenge 291: FizzBuzz Count"
},
{
"id": "69f8c998d78ad3171a0713bf",
"title": "Challenge 292: Wider Aspect Ratio"
},
{
"id": "69f90c1329a94b37e2a2086c",
"title": "Challenge 293: Best Hand"
},
{
"id": "69f90c1329a94b37e2a2086d",
"title": "Challenge 294: Parentheses Combinations"
}
]
}
@@ -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 = 278;
const EXPECTED_CHALLENGE_COUNT = 294;
// 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)**