From 3e5f5cc93890c3bd6cea7ad536ddce9713fab5d8 Mon Sep 17 00:00:00 2001 From: Tom <20648924+moT01@users.noreply.github.com> Date: Mon, 11 May 2026 09:49:57 -0500 Subject: [PATCH] feat(curriculum): daily challenges 279-294 (#67227) --- .../69f35a5bb823ed620fcb7cb8.md | 117 ++++++++++++ .../69f35a5bb823ed620fcb7cb9.md | 66 +++++++ .../69f35a5bb823ed620fcb7cba.md | 73 +++++++ .../69f35a5bb823ed620fcb7cbb.md | 65 +++++++ .../69f35a5bb823ed620fcb7cbc.md | 69 +++++++ .../69f35a5bb823ed620fcb7cbd.md | 69 +++++++ .../69f35a5bb823ed620fcb7cbe.md | 80 ++++++++ .../69f8c998d78ad3171a0713b9.md | 85 +++++++++ .../69f8c998d78ad3171a0713ba.md | 97 ++++++++++ .../69f8c998d78ad3171a0713bb.md | 74 ++++++++ .../69f8c998d78ad3171a0713bc.md | 57 ++++++ .../69f8c998d78ad3171a0713bd.md | 76 ++++++++ .../69f8c998d78ad3171a0713be.md | 74 ++++++++ .../69f8c998d78ad3171a0713bf.md | 84 ++++++++ .../69f90c1329a94b37e2a2086c.md | 143 ++++++++++++++ .../69f90c1329a94b37e2a2086d.md | 82 ++++++++ .../69f35a5bb823ed620fcb7cb8.md | 112 +++++++++++ .../69f35a5bb823ed620fcb7cb9.md | 82 ++++++++ .../69f35a5bb823ed620fcb7cba.md | 86 +++++++++ .../69f35a5bb823ed620fcb7cbb.md | 78 ++++++++ .../69f35a5bb823ed620fcb7cbc.md | 82 ++++++++ .../69f35a5bb823ed620fcb7cbd.md | 85 +++++++++ .../69f35a5bb823ed620fcb7cbe.md | 93 +++++++++ .../69f8c998d78ad3171a0713b9.md | 93 +++++++++ .../69f8c998d78ad3171a0713ba.md | 111 +++++++++++ .../69f8c998d78ad3171a0713bb.md | 91 +++++++++ .../69f8c998d78ad3171a0713bc.md | 67 +++++++ .../69f8c998d78ad3171a0713bd.md | 91 +++++++++ .../69f8c998d78ad3171a0713be.md | 82 ++++++++ .../69f8c998d78ad3171a0713bf.md | 97 ++++++++++ .../69f90c1329a94b37e2a2086c.md | 179 ++++++++++++++++++ .../69f90c1329a94b37e2a2086d.md | 96 ++++++++++ .../daily-coding-challenges-javascript.json | 64 +++++++ .../daily-coding-challenges-python.json | 64 +++++++ .../daily-challenges/seed-daily-challenges.ts | 2 +- 35 files changed, 2965 insertions(+), 1 deletion(-) create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb8.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb9.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cba.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbb.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbc.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbd.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbe.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713b9.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713ba.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bb.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bc.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bd.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713be.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bf.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086c.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086d.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb8.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb9.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cba.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbb.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbc.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbd.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbe.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713b9.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713ba.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bb.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bc.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bd.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713be.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bf.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086c.md create mode 100644 curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086d.md diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb8.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb8.md new file mode 100644 index 00000000000..326254cdd2d --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb8.md @@ -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 0–6, 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; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb9.md new file mode 100644 index 00000000000..c51cfaf69c9 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cb9.md @@ -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(); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cba.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cba.md new file mode 100644 index 00000000000..11a1b4abad2 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cba.md @@ -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); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbb.md new file mode 100644 index 00000000000..18667c87af8 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbb.md @@ -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); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbc.md new file mode 100644 index 00000000000..bd6e2dbdbf3 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbc.md @@ -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; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbd.md new file mode 100644 index 00000000000..fd251e6638b --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbd.md @@ -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(' '); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbe.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbe.md new file mode 100644 index 00000000000..80e261a2656 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f35a5bb823ed620fcb7cbe.md @@ -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"; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713b9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713b9.md new file mode 100644 index 00000000000..dbb468abe5e --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713b9.md @@ -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)) + ); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713ba.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713ba.md new file mode 100644 index 00000000000..a743e4235e6 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713ba.md @@ -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; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bb.md new file mode 100644 index 00000000000..81432597a13 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bb.md @@ -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"; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bc.md new file mode 100644 index 00000000000..cc70c00a24e --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bc.md @@ -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); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bd.md new file mode 100644 index 00000000000..f25e68266f2 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bd.md @@ -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); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713be.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713be.md new file mode 100644 index 00000000000..c1fd9d1a208 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713be.md @@ -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 }; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bf.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bf.md new file mode 100644 index 00000000000..858418ecafb --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f8c998d78ad3171a0713bf.md @@ -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; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086c.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086c.md new file mode 100644 index 00000000000..cb725110403 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086c.md @@ -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"; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086d.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086d.md new file mode 100644 index 00000000000..847aa2d6430 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69f90c1329a94b37e2a2086d.md @@ -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; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb8.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb8.md new file mode 100644 index 00000000000..bfca2fb65bb --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb8.md @@ -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 0–6, 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 +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb9.md new file mode 100644 index 00000000000..15b060032a0 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cb9.md @@ -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") +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cba.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cba.md new file mode 100644 index 00000000000..40905965cd5 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cba.md @@ -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)) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbb.md new file mode 100644 index 00000000000..bb8674075f9 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbb.md @@ -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) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbc.md new file mode 100644 index 00000000000..a66865f4d2c --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbc.md @@ -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 +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbd.md new file mode 100644 index 00000000000..0e11efaf091 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbd.md @@ -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) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbe.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbe.md new file mode 100644 index 00000000000..365704aba93 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f35a5bb823ed620fcb7cbe.md @@ -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" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713b9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713b9.md new file mode 100644 index 00000000000..41d2ba403af --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713b9.md @@ -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)] +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713ba.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713ba.md new file mode 100644 index 00000000000..2d73a8e5ddb --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713ba.md @@ -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 +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bb.md new file mode 100644 index 00000000000..4149d6bfeee --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bb.md @@ -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" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bc.md new file mode 100644 index 00000000000..00e9efcfdbe --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bc.md @@ -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)) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bd.md new file mode 100644 index 00000000000..3c86ebc6319 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bd.md @@ -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) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713be.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713be.md new file mode 100644 index 00000000000..f2a8443314a --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713be.md @@ -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} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bf.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bf.md new file mode 100644 index 00000000000..77731e7916b --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f8c998d78ad3171a0713bf.md @@ -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 +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086c.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086c.md new file mode 100644 index 00000000000..57b59b37cd1 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086c.md @@ -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" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086d.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086d.md new file mode 100644 index 00000000000..780f2cc88fc --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69f90c1329a94b37e2a2086d.md @@ -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 +``` diff --git a/curriculum/structure/blocks/daily-coding-challenges-javascript.json b/curriculum/structure/blocks/daily-coding-challenges-javascript.json index 08a8fea770c..4cfc640db3a 100644 --- a/curriculum/structure/blocks/daily-coding-challenges-javascript.json +++ b/curriculum/structure/blocks/daily-coding-challenges-javascript.json @@ -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" } ] } diff --git a/curriculum/structure/blocks/daily-coding-challenges-python.json b/curriculum/structure/blocks/daily-coding-challenges-python.json index 06bee879420..e3dd2b996c6 100644 --- a/curriculum/structure/blocks/daily-coding-challenges-python.json +++ b/curriculum/structure/blocks/daily-coding-challenges-python.json @@ -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" } ] } diff --git a/tools/daily-challenges/seed-daily-challenges.ts b/tools/daily-challenges/seed-daily-challenges.ts index 96ca69caa7c..7258879c83e 100644 --- a/tools/daily-challenges/seed-daily-challenges.ts +++ b/tools/daily-challenges/seed-daily-challenges.ts @@ -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)**