diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e6ff50d756c9b69366.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e6ff50d756c9b69366.md
index 324828b55a8..968c329b110 100644
--- a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e6ff50d756c9b69366.md
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/697a49e6ff50d756c9b69366.md
@@ -13,7 +13,7 @@ To determine the rating:
- Calculate the steepness of the hill by taking the drop divided by the distance.
- Then, calculate the adjusted steepness based on the hill type:
- - `"Downhill"` multiply steepness by 1.2
+ - `"Downhill"`: multiply steepness by 1.2
- `"Slalom"`: multiply steepness by 0.9
- `"Giant Slalom"`: multiply steepness by 1.0
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d4.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d4.md
new file mode 100644
index 00000000000..b62c5ae4dc8
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d4.md
@@ -0,0 +1,63 @@
+---
+id: 699c8e045ee7cb94ed2322d4
+title: "Challenge 213: Word Length Converter"
+challengeType: 28
+dashedName: challenge-213
+---
+
+# --description--
+
+Given a string of words, return a new string where each word is replaced by its length.
+
+- Words in the given string will be separated by a single space
+- Keep the spaces in the returned string.
+
+For example, given `"hello world"`, return `"5 5"`.
+
+# --hints--
+
+`convertWords("hello world")` should return `"5 5"`.
+
+```js
+assert.equal(convertWords("hello world"), "5 5");
+```
+
+`convertWords("Thanks and happy coding")` should return `"6 3 5 6"`.
+
+```js
+assert.equal(convertWords("Thanks and happy coding"), "6 3 5 6");
+```
+
+`convertWords("The quick brown fox jumps over the lazy dog")` should return `"3 5 5 3 5 4 3 4 3"`.
+
+```js
+assert.equal(convertWords("The quick brown fox jumps over the lazy dog"), "3 5 5 3 5 4 3 4 3");
+```
+
+`convertWords("Lorem ipsum dolor sit amet consectetur adipiscing elit donec ut ligula vehicula iaculis orci vel semper nisl")` should return `"5 5 5 3 4 11 10 4 5 2 6 8 7 4 3 6 4"`.
+
+```js
+assert.equal(convertWords("Lorem ipsum dolor sit amet consectetur adipiscing elit donec ut ligula vehicula iaculis orci vel semper nisl"), "5 5 5 3 4 11 10 4 5 2 6 8 7 4 3 6 4");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function convertWords(str) {
+
+ return str;
+}
+```
+
+# --solutions--
+
+```js
+function convertWords(str) {
+ return str
+ .split(" ")
+ .map(word => word.length)
+ .join(" ");
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d5.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d5.md
new file mode 100644
index 00000000000..5010da1a186
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d5.md
@@ -0,0 +1,69 @@
+---
+id: 699c8e045ee7cb94ed2322d5
+title: "Challenge 214: Domino Chain Validator"
+challengeType: 28
+dashedName: challenge-214
+---
+
+# --description--
+
+Given a 2D array representing a sequence of dominoes, determine whether it forms a valid chain.
+
+- Each element in the array represents a domino and will be an array of two numbers from 1 to 6, (inclusive).
+- For the chain to be valid, the second number of each domino must match the first number of the next domino.
+- The first number of the first domino and the last number of the last domino don't need to match anything.
+
+# --hints--
+
+`isValidDominoChain([[1, 3], [3, 6], [6, 5]])` should return `true`.
+
+```js
+assert.isTrue(isValidDominoChain([[1, 3], [3, 6], [6, 5]]));
+```
+
+`isValidDominoChain([[6, 2], [3, 4], [4, 1]])` should return `false`.
+
+```js
+assert.isFalse(isValidDominoChain([[6, 2], [3, 4], [4, 1]]));
+```
+
+`isValidDominoChain([[2, 5], [5, 6], [5, 1]])` should return `false`.
+
+```js
+assert.isFalse(isValidDominoChain([[2, 5], [5, 6], [5, 1]]));
+```
+
+`isValidDominoChain([[4, 3], [3, 1], [1, 6], [6, 6], [6, 5], [5, 1], [1, 1], [1, 4], [4, 4], [4, 2]])` should return `true`.
+
+```js
+assert.isTrue(isValidDominoChain([[4, 3], [3, 1], [1, 6], [6, 6], [6, 5], [5, 1], [1, 1], [1, 4], [4, 4], [4, 2]]));
+```
+
+`isValidDominoChain([[2, 3], [3, 3], [3, 6], [6, 1], [1, 4], [3, 5], [5, 5], [5, 4], [4, 2], [2, 2]])` should return `false`.
+
+```js
+assert.isFalse(isValidDominoChain([[2, 3], [3, 3], [3, 6], [6, 1], [1, 4], [3, 5], [5, 5], [5, 4], [4, 2], [2, 2]]));
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function isValidDominoChain(dominoes) {
+
+ return dominoes;
+}
+```
+
+# --solutions--
+
+```js
+function isValidDominoChain(dominoes) {
+ for (let i = 0; i < dominoes.length - 1; i++) {
+ if (dominoes[i][1] !== dominoes[i+1][0]) return false
+ }
+
+ return true;
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d6.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d6.md
new file mode 100644
index 00000000000..3f02eaf3a7f
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d6.md
@@ -0,0 +1,109 @@
+---
+id: 699c8e045ee7cb94ed2322d6
+title: "Challenge 215: Parking Fee Calculator"
+challengeType: 28
+dashedName: challenge-215
+---
+
+# --description--
+
+Given two strings representing the time you parked your car and the time you picked it up, calculate the parking fee.
+
+- The given strings will be in the format `"HH:MM"` using a 24-hour clock. So `"14:00"` is 2pm for example.
+- The first string will be the time you parked your car, and the second will be the time you picked it up.
+- If the pickup time is earlier than the entry time, it means the parking spanned past midnight into the next day.
+
+Fee rules:
+
+- Each hour parked costs $3.
+- Partial hours are rounded up to the next full hour.
+- If the parking spans overnight (past midnight), an additional $10 overnight fee is applied.
+- There is a minimum fee of $5 (only used if the total would be less than $5).
+
+Return the total cost in the format `"$cost"`, `"$5"` for example.
+
+# --hints--
+
+`calculateParkingFee("09:00", "11:00")` should return `"$6"`.
+
+```js
+assert.equal(calculateParkingFee("09:00", "11:00"), "$6");
+```
+
+`calculateParkingFee("10:00", "10:30")` should return `"$5"`.
+
+```js
+assert.equal(calculateParkingFee("10:00", "10:30"), "$5");
+```
+
+`calculateParkingFee("08:10", "10:45")` should return `"$9"`.
+
+```js
+assert.equal(calculateParkingFee("08:10", "10:45"), "$9");
+```
+
+`calculateParkingFee("14:40", "23:10")` should return `"$27"`.
+
+```js
+assert.equal(calculateParkingFee("14:40", "23:10"), "$27");
+```
+
+`calculateParkingFee("18:15", "01:30")` should return `"$34"`.
+
+```js
+assert.equal(calculateParkingFee("18:15", "01:30"), "$34");
+```
+
+`calculateParkingFee("11:11", "11:10")` should return `"$82"`.
+
+```js
+assert.equal(calculateParkingFee("11:11", "11:10"), "$82");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function calculateParkingFee(parkTime, pickupTime) {
+
+ return parkTime;
+}
+```
+
+# --solutions--
+
+```js
+function calculateParkingFee(parkTime, pickupTime) {
+ function toMinutes(time) {
+ const [hours, minutes] = time.split(":").map(Number);
+ return hours * 60 + minutes;
+ }
+
+ const entryMinutes = toMinutes(parkTime);
+ const exitMinutes = toMinutes(pickupTime);
+
+ let totalMinutes;
+ let overnight = false;
+
+ if (exitMinutes < entryMinutes) {
+ overnight = true;
+ totalMinutes = (24 * 60 - entryMinutes) + exitMinutes;
+ } else {
+ totalMinutes = exitMinutes - entryMinutes;
+ }
+
+ const hours = Math.ceil(totalMinutes / 60);
+ let cost = hours * 3;
+
+ if (overnight) {
+ cost += 10;
+ }
+
+ if (cost < 5) {
+ cost = 5;
+ }
+
+ return `$${cost}`;
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d7.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d7.md
new file mode 100644
index 00000000000..fe10a203dbe
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d7.md
@@ -0,0 +1,89 @@
+---
+id: 699c8e045ee7cb94ed2322d7
+title: "Challenge 216: Pi Day"
+challengeType: 28
+dashedName: challenge-216
+---
+
+# --description--
+
+Happy pi (π) day!
+
+Given an integer (`n`), where `n` is between 1 and 1000 (inclusive), return the `n`th decimal of π.
+
+- Make sure to return a number not a string.
+
+π with its first five decimals is 3.14159. So given `5` for example, return `9`, the fifth decimal.
+
+You may have to find the first 1000 decimals of π somewhere.
+
+# --hints--
+
+`getPiDecimal(5)` should return `9`.
+
+```js
+assert.strictEqual(getPiDecimal(5), 9);
+```
+
+`getPiDecimal(10)` should return `5`.
+
+```js
+assert.strictEqual(getPiDecimal(10), 5);
+```
+
+`getPiDecimal(22)` should return `6`.
+
+```js
+assert.strictEqual(getPiDecimal(22), 6);
+```
+
+`getPiDecimal(39)` should return `7`.
+
+```js
+assert.strictEqual(getPiDecimal(39), 7);
+```
+
+`getPiDecimal(76)` should return `2`.
+
+```js
+assert.strictEqual(getPiDecimal(76), 2);
+```
+
+`getPiDecimal(384)` should return `4`.
+
+```js
+assert.strictEqual(getPiDecimal(384), 4);
+```
+
+`getPiDecimal(601)` should return `0`.
+
+```js
+assert.strictEqual(getPiDecimal(601), 0);
+```
+
+`getPiDecimal(1000)` should return `9`.
+
+```js
+assert.strictEqual(getPiDecimal(1000), 9);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function getPiDecimal(n) {
+
+ return n;
+}
+```
+
+# --solutions--
+
+```js
+function getPiDecimal(n) {
+ const pi = "31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
+
+ return Number(pi[n]);
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d8.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d8.md
new file mode 100644
index 00000000000..61118b838c4
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d8.md
@@ -0,0 +1,98 @@
+---
+id: 699c8e045ee7cb94ed2322d8
+title: "Challenge 217: Captured Chess Pieces"
+challengeType: 28
+dashedName: challenge-217
+---
+
+# --description--
+
+Given an array of strings representing chess pieces you still have on the board, calculate the value of the pieces your opponent has captured.
+
+In chess, you start with 16 pieces:
+
+| Piece | Abbreviation | Quantity | Value |
+| ------ | -------------- | -------- | ----- |
+| Pawn | `"P"` | 8 | 1 |
+| Rook | `"R"` | 2 | 5 |
+| Knight | `"N"` | 2 | 3 |
+| Bishop | `"B"` | 2 | 3 |
+| Queen | `"Q"` | 1 | 9 |
+| King | `"K"` | 1 | 0 |
+
+- The given array will only contain the abbreviations above.
+- Any of the 16 pieces not included in the given array have been captured.
+- Return the total value of all captured pieces, unless...
+- If the King has been captured, return `"Checkmate"`.
+
+# --hints--
+
+`getCapturedValue(["P", "P", "P", "P", "P", "P", "R", "R", "N", "B", "Q", "K"])` should return `8`.
+
+```js
+assert.equal(getCapturedValue(["P", "P", "P", "P", "P", "P", "R", "R", "N", "B", "Q", "K"]), 8);
+```
+
+`getCapturedValue(["P", "P", "P", "P", "P", "R", "B", "K"])` should return `26`.
+
+```js
+assert.equal(getCapturedValue(["P", "P", "P", "P", "P", "R", "B", "K"]), 26);
+```
+
+`getCapturedValue(["K", "P", "P", "N", "P", "P", "R", "P", "B", "P", "N", "B"])` should return `16`.
+
+```js
+assert.equal(getCapturedValue(["K", "P", "P", "N", "P", "P", "R", "P", "B", "P", "N", "B"]), 16);
+```
+
+`getCapturedValue(["P", "Q", "N", "P", "P", "B", "K", "P", "R", "R", "P", "P", "B", "P"])` should return `4`.
+
+```js
+assert.equal(getCapturedValue(["P", "Q", "N", "P", "P", "B", "K", "P", "R", "R", "P", "P", "B", "P"]), 4);
+```
+
+`getCapturedValue(["P", "K"])` should return `38`.
+
+```js
+assert.equal(getCapturedValue(["P", "K"]), 38);
+```
+
+`getCapturedValue(["N", "P", "P", "B", "K", "P", "Q", "N", "P", "P", "R", "R", "P", "P", "P", "B"])` should return `0`.
+
+```js
+assert.equal(getCapturedValue(["N", "P", "P", "B", "K", "P", "Q", "N", "P", "P", "R", "R", "P", "P", "P", "B"]), 0);
+```
+
+`getCapturedValue(["N", "P", "P", "B", "P", "R", "Q", "P", "P", "P", "B"])` should return `"Checkmate"`.
+
+```js
+assert.equal(getCapturedValue(["N", "P", "P", "B", "P", "R", "Q", "P", "P", "P", "B"]), "Checkmate");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function getCapturedValue(pieces) {
+
+ return pieces;
+}
+```
+
+# --solutions--
+
+```js
+function getCapturedValue(pieces) {
+ if (!pieces.includes("K")) return "Checkmate";
+
+ const values = { P:1, R:5, N:3, B:3, Q:9, K:0 };
+ let remaining = "PPPPPPPPRRNNBBQK";
+
+ for (const p of pieces) {
+ remaining = remaining.replace(p, "");
+ }
+
+ return [...remaining].reduce((sum, p) => sum + values[p], 0);
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d9.md
new file mode 100644
index 00000000000..f9417c3f9e2
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322d9.md
@@ -0,0 +1,67 @@
+---
+id: 699c8e045ee7cb94ed2322d9
+title: "Challenge 218: Evenly Divisible"
+challengeType: 28
+dashedName: challenge-218
+---
+
+# --description--
+
+Given two integers, determine if you can evenly divide the first one by the second one.
+
+# --hints--
+
+`isEvenlyDivisible(4, 2)` should return `true`.
+
+```js
+assert.isTrue(isEvenlyDivisible(4, 2));
+```
+
+`isEvenlyDivisible(7, 3)` should return `false`.
+
+```js
+assert.isFalse(isEvenlyDivisible(7, 3));
+```
+
+`isEvenlyDivisible(5, 10)` should return `false`.
+
+```js
+assert.isFalse(isEvenlyDivisible(5, 10));
+```
+
+`isEvenlyDivisible(48, 6)` should return `true`.
+
+```js
+assert.isTrue(isEvenlyDivisible(48, 6));
+```
+
+`isEvenlyDivisible(3186, 9)` should return `true`.
+
+```js
+assert.isTrue(isEvenlyDivisible(3186, 9));
+```
+
+`isEvenlyDivisible(4192, 11)` should return `false`.
+
+```js
+assert.isFalse(isEvenlyDivisible(4192, 11));
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function isEvenlyDivisible(a, b) {
+
+ return a;
+}
+```
+
+# --solutions--
+
+```js
+function isEvenlyDivisible(a, b) {
+ return a % b === 0;
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322da.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322da.md
new file mode 100644
index 00000000000..a64177e161a
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322da.md
@@ -0,0 +1,115 @@
+---
+id: 699c8e045ee7cb94ed2322da
+title: "Challenge 219: Anniversary Milestones"
+challengeType: 28
+dashedName: challenge-219
+---
+
+# --description--
+
+Given an integer representing the number of years a couple has been married, return their most recent anniversary milestone according to this chart:
+
+| Years Married | Milestone |
+| ------------- | ------------ |
+| 1 | `"Paper"` |
+| 5 | `"Wood"` |
+| 10 | `"Tin"` |
+| 25 | `"Silver"` |
+| 40 | `"Ruby"` |
+| 50 | `"Gold"` |
+| 60 | `"Diamond"` |
+| 70 | `"Platinum"` |
+
+- If they haven't reached the first milestone, return `"Newlyweds"`.
+
+# --hints--
+
+`getMilestone(0)` should return `"Newlyweds"`.
+
+```js
+assert.equal(getMilestone(0), "Newlyweds");
+```
+
+`getMilestone(1)` should return `"Paper"`.
+
+```js
+assert.equal(getMilestone(1), "Paper");
+```
+
+`getMilestone(8)` should return `"Wood"`.
+
+```js
+assert.equal(getMilestone(8), "Wood");
+```
+
+`getMilestone(10)` should return `"Tin"`.
+
+```js
+assert.equal(getMilestone(10), "Tin");
+```
+
+`getMilestone(26)` should return `"Silver"`.
+
+```js
+assert.equal(getMilestone(26), "Silver");
+```
+
+`getMilestone(45)` should return `"Ruby"`.
+
+```js
+assert.equal(getMilestone(45), "Ruby");
+```
+
+`getMilestone(50)` should return `"Gold"`.
+
+```js
+assert.equal(getMilestone(50), "Gold");
+```
+
+`getMilestone(64)` should return `"Diamond"`.
+
+```js
+assert.equal(getMilestone(64), "Diamond");
+```
+
+`getMilestone(71)` should return `"Platinum"`.
+
+```js
+assert.equal(getMilestone(71), "Platinum");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function getMilestone(years) {
+
+ return years;
+}
+```
+
+# --solutions--
+
+```js
+function getMilestone(years) {
+ if (years < 1) return "Newlyweds";
+
+ const milestones = [
+ [1, "Paper"],
+ [5, "Wood"],
+ [10, "Tin"],
+ [25, "Silver"],
+ [40, "Ruby"],
+ [50, "Gold"],
+ [60, "Diamond"],
+ [70, "Platinum"]
+ ];
+
+ for (let i = milestones.length - 1; i >= 0; i--) {
+ if (years >= milestones[i][0]) {
+ return milestones[i][1];
+ }
+ }
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322db.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322db.md
new file mode 100644
index 00000000000..a8d059c2ea0
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322db.md
@@ -0,0 +1,59 @@
+---
+id: 699c8e045ee7cb94ed2322db
+title: "Challenge 220: Largest Number"
+challengeType: 28
+dashedName: challenge-220
+---
+
+# --description--
+
+Given a string of numbers separated by various punctuation, return the largest number.
+
+- The given string will only contain numbers and separators.
+- Separators can be commas (`","`), exclamation points (`"!"`), question marks (`"?"`), colons (`":"`), or semi-colons (`";"`).
+
+# --hints--
+
+`largestNumber("1,2")` should return `2`.
+
+```js
+assert.equal(largestNumber("1,2"), 2);
+```
+
+`largestNumber("4;15:60,26?52!0")` should return `60`.
+
+```js
+assert.equal(largestNumber("4;15:60,26?52!0"), 60);
+```
+
+`largestNumber("-402,-1032!-569:-947;-633?-800!-1012;-402,-723?-8102!-3011")` should return `-402`.
+
+```js
+assert.equal(largestNumber("-402,-1032!-569:-947;-633?-800!-1012;-402,-723?-8102!-3011"), -402);
+```
+
+`largestNumber("12;-50,99.9,49.1!-10.1?88?16")` should return `99.9`.
+
+```js
+assert.equal(largestNumber("12;-50,99.9,49.1!-10.1?88?16"), 99.9);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function largestNumber(str) {
+
+ return str;
+}
+```
+
+# --solutions--
+
+```js
+function largestNumber(str) {
+ const numbers = str.split(/[,!?:;]/).map(Number);
+ return Math.max(...numbers);
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dc.md
new file mode 100644
index 00000000000..d55d7ee382d
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dc.md
@@ -0,0 +1,86 @@
+---
+id: 699c8e045ee7cb94ed2322dc
+title: "Challenge 221: Inverted Matrix"
+challengeType: 28
+dashedName: challenge-221
+---
+
+# --description--
+
+Given a matrix (an array of arrays) filled with two distinct values, return a new matrix where all occurrences of one value are swapped with the other.
+
+For example, given:
+
+```js
+[
+ ["a", "b"],
+ ["a", "a"]
+]
+```
+
+Return:
+
+```js
+[
+ ["b", "a"],
+ ["b", "b"]
+]
+```
+
+# --hints--
+
+`invertMatrix([["a", "b"], ["a", "a"]])` should return `[["b", "a"], ["b", "b"]]`.
+
+```js
+assert.deepEqual(invertMatrix([["a", "b"], ["a", "a"]]), [["b", "a"], ["b", "b"]]);
+```
+
+`invertMatrix([[1, 0, 1], [1, 1, 1], [0, 1, 0]])` should return `[[0, 1, 0], [0, 0, 0], [1, 0, 1]]`.
+
+```js
+assert.deepEqual(invertMatrix([[1, 0, 1], [1, 1, 1], [0, 1, 0]]), [[0, 1, 0], [0, 0, 0], [1, 0, 1]]);
+```
+
+`invertMatrix([["apple", "banana", "banana", "apple"], ["banana", "apple", "apple", "banana"], ["banana", "banana", "banana", "apple"]])` should return `[["banana", "apple", "apple", "banana"], ["apple", "banana", "banana", "apple"], ["apple", "apple", "apple", "banana"]]`.
+
+```js
+assert.deepEqual(invertMatrix([["apple", "banana", "banana", "apple"], ["banana", "apple", "apple", "banana"], ["banana", "banana", "banana", "apple"]]), [["banana", "apple", "apple", "banana"], ["apple", "banana", "banana", "apple"], ["apple", "apple", "apple", "banana"]]);
+```
+
+`invertMatrix([[6, 7, 7, 7, 6], [7, 6, 7, 6, 7], [7, 7, 6, 7, 7], [7, 6, 7, 6, 7], [6, 7, 7, 7, 6]])` should return `[[7, 6, 6, 6, 7], [6, 7, 6, 7, 6], [6, 6, 7, 6, 6], [6, 7, 6, 7, 6], [7, 6, 6, 6, 7]]`.
+
+```js
+assert.deepEqual(invertMatrix([[6, 7, 7, 7, 6], [7, 6, 7, 6, 7], [7, 7, 6, 7, 7], [7, 6, 7, 6, 7], [6, 7, 7, 7, 6]]), [[7, 6, 6, 6, 7], [6, 7, 6, 7, 6], [6, 6, 7, 6, 6], [6, 7, 6, 7, 6], [7, 6, 6, 6, 7]]);
+```
+
+`invertMatrix([[1.2, 2.1, 2.1, 2.1], [2.1, 1.2, 2.1, 1.2], [1.2, 1.2, 2.1, 2.1]])` should return `[[2.1, 1.2, 1.2, 1.2], [1.2, 2.1, 1.2, 2.1], [2.1, 2.1, 1.2, 1.2]]`.
+
+```js
+assert.deepEqual(invertMatrix([[1.2, 2.1, 2.1, 2.1], [2.1, 1.2, 2.1, 1.2], [1.2, 1.2, 2.1, 2.1]]), [[2.1, 1.2, 1.2, 1.2], [1.2, 2.1, 1.2, 2.1], [2.1, 2.1, 1.2, 1.2]]);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function invertMatrix(matrix) {
+
+ return matrix;
+}
+```
+
+# --solutions--
+
+```js
+function invertMatrix(matrix) {
+ if (matrix.length === 0) return [];
+
+ const values = [...new Set(matrix.flat())];
+ const [val1, val2] = values;
+
+ return matrix.map(row =>
+ row.map(cell => (cell === val1 ? val2 : val1))
+ );
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dd.md
new file mode 100644
index 00000000000..69716348ed7
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/699c8e045ee7cb94ed2322dd.md
@@ -0,0 +1,115 @@
+---
+id: 699c8e045ee7cb94ed2322dd
+title: "Challenge 222: Equinox Shadows"
+challengeType: 28
+dashedName: challenge-222
+---
+
+# --description--
+
+Today is the equinox, when the sun is directly above the equator and perfectly overhead at noon. Given a time, determine the shadow cast by a 4-foot vertical pole.
+
+- The time will be a string in `"HH:MM"` 24-hour format (for example, `"15:00"` is 3pm).
+- You will only be given a time in 30 minute increments.
+
+Rules:
+
+- The sun rises at 6am directly `"east"`, and sets at 6pm directly `"west"`.
+- A shadow always points opposite the sun.
+- The shadow's length (in feet) is the number of hours away from noon, cubed.
+- There is no shadow before sunrise (before 6am), after sunset (6pm or later), or at noon.
+
+Return:
+
+- If a shadow exists, return `"(length)ft (direction)"`. For example, `"8ft west"`.
+- Otherwise, return `"No shadow"`.
+
+For example, given `"10:00"`, return `"8ft west"` because 10am is 2 hours from noon, so 23 = 8 feet, and the shadow points west because the sun is in the east at 10am.
+
+# --hints--
+
+`getShadow("10:00")` should return `"8ft west"`.
+
+```js
+assert.equal(getShadow("10:00"), "8ft west");
+```
+
+`getShadow("15:00")` should return `"27ft east"`.
+
+```js
+assert.equal(getShadow("15:00"), "27ft east");
+```
+
+`getShadow("12:00")` should return `"No shadow"`.
+
+```js
+assert.equal(getShadow("12:00"), "No shadow");
+```
+
+`getShadow("17:30")` should return `"166.375ft east"`.
+
+```js
+assert.equal(getShadow("17:30"), "166.375ft east");
+```
+
+`getShadow("05:00")` should return `"No shadow"`.
+
+```js
+assert.equal(getShadow("05:00"), "No shadow");
+```
+
+`getShadow("06:00")` should return `"216ft west"`.
+
+```js
+assert.equal(getShadow("06:00"), "216ft west");
+```
+
+`getShadow("18:00")` should return `"No shadow"`.
+
+```js
+assert.equal(getShadow("18:00"), "No shadow");
+```
+
+`getShadow("07:30")` should return `"91.125ft west"`.
+
+```js
+assert.equal(getShadow("07:30"), "91.125ft west");
+```
+
+`getShadow("00:00")` should return `"No shadow"`.
+
+```js
+assert.equal(getShadow("00:00"), "No shadow");
+```
+
+# --seed--
+
+## --seed-contents--
+
+```js
+function getShadow(time) {
+
+ return time;
+}
+```
+
+# --solutions--
+
+```js
+function getShadow(time) {
+ const [hourStr, minuteStr] = time.split(":");
+ const hours = Number(hourStr);
+ const minutes = Number(minuteStr);
+ const timeInHours = hours + minutes / 60;
+
+ if (timeInHours < 6 || timeInHours >= 18 || timeInHours === 12) {
+ return "No shadow";
+ }
+
+ const hoursFromNoon = Math.abs(12 - timeInHours);
+ const length = Math.pow(hoursFromNoon, 3);
+ const direction = timeInHours < 12 ? "west" : "east";
+
+ return `${length}ft ${direction}`;
+}
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/697a49e6ff50d756c9b69366.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/697a49e6ff50d756c9b69366.md
index b3c5cbb3ab9..aed18c911b2 100644
--- a/curriculum/challenges/english/blocks/daily-coding-challenges-python/697a49e6ff50d756c9b69366.md
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/697a49e6ff50d756c9b69366.md
@@ -13,7 +13,7 @@ To determine the rating:
- Calculate the steepness of the hill by taking the drop divided by the distance.
- Then, calculate the adjusted steepness based on the hill type:
- - `"Downhill"` multiply steepness by 1.2
+ - `"Downhill"`: multiply steepness by 1.2
- `"Slalom"`: multiply steepness by 0.9
- `"Giant Slalom"`: multiply steepness by 1.0
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d4.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d4.md
new file mode 100644
index 00000000000..8c33b9570a9
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d4.md
@@ -0,0 +1,71 @@
+---
+id: 699c8e045ee7cb94ed2322d4
+title: "Challenge 213: Word Length Converter"
+challengeType: 29
+dashedName: challenge-213
+---
+
+# --description--
+
+Given a string of words, return a new string where each word is replaced by its length.
+
+- Words in the given string will be separated by a single space
+- Keep the spaces in the returned string.
+
+For example, given `"hello world"`, return `"5 5"`.
+
+# --hints--
+
+`convert_words("hello world")` should return `"5 5"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(convert_words("hello world"), "5 5")`)
+}})
+```
+
+`convert_words("Thanks and happy coding")` should return `"6 3 5 6"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(convert_words("Thanks and happy coding"), "6 3 5 6")`)
+}})
+```
+
+`convert_words("The quick brown fox jumps over the lazy dog")` should return `"3 5 5 3 5 4 3 4 3"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(convert_words("The quick brown fox jumps over the lazy dog"), "3 5 5 3 5 4 3 4 3")`)
+}})
+```
+
+`convert_words("Lorem ipsum dolor sit amet consectetur adipiscing elit donec ut ligula vehicula iaculis orci vel semper nisl")` should return `"5 5 5 3 4 11 10 4 5 2 6 8 7 4 3 6 4"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(convert_words("Lorem ipsum dolor sit amet consectetur adipiscing elit donec ut ligula vehicula iaculis orci vel semper nisl"), "5 5 5 3 4 11 10 4 5 2 6 8 7 4 3 6 4")`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def convert_words(s):
+
+ return s
+```
+
+# --solutions--
+
+```py
+def convert_words(s):
+
+ return " ".join(str(len(word)) for word in s.split(" "))
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d5.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d5.md
new file mode 100644
index 00000000000..f3a1d29ef6e
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d5.md
@@ -0,0 +1,82 @@
+---
+id: 699c8e045ee7cb94ed2322d5
+title: "Challenge 214: Domino Chain Validator"
+challengeType: 29
+dashedName: challenge-214
+---
+
+# --description--
+
+Given a 2D array representing a sequence of dominoes, determine whether it forms a valid chain.
+
+- Each element in the array represents a domino and will be an array of two numbers from 1 to 6, (inclusive).
+- For the chain to be valid, the second number of each domino must match the first number of the next domino.
+- The first number of the first domino and the last number of the last domino don't need to match anything.
+
+# --hints--
+
+`is_valid_domino_chain([[1, 3], [3, 6], [6, 5]])` should return `True`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_valid_domino_chain([[1, 3], [3, 6], [6, 5]]), True)`)
+}})
+```
+
+`is_valid_domino_chain([[6, 2], [3, 4], [4, 1]])` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_valid_domino_chain([[6, 2], [3, 4], [4, 1]]), False)`)
+}})
+```
+
+`is_valid_domino_chain([[2, 5], [5, 6], [5, 1]])` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_valid_domino_chain([[2, 5], [5, 6], [5, 1]]), False)`)
+}})
+```
+
+`is_valid_domino_chain([[4, 3], [3, 1], [1, 6], [6, 6], [6, 5], [5, 1], [1, 1], [1, 4], [4, 4], [4, 2]])` should return `True`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_valid_domino_chain([[4, 3], [3, 1], [1, 6], [6, 6], [6, 5], [5, 1], [1, 1], [1, 4], [4, 4], [4, 2]]), True)`)
+}})
+```
+
+`is_valid_domino_chain([[2, 3], [3, 3], [3, 6], [6, 1], [1, 4], [3, 5], [5, 5], [5, 4], [4, 2], [2, 2]])` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_valid_domino_chain([[2, 3], [3, 3], [3, 6], [6, 1], [1, 4], [3, 5], [5, 5], [5, 4], [4, 2], [2, 2]]), False)`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def is_valid_domino_chain(dominoes):
+
+ return dominoes
+```
+
+# --solutions--
+
+```py
+def is_valid_domino_chain(dominoes):
+ for i in range(len(dominoes) - 1):
+ if dominoes[i][1] != dominoes[i + 1][0]:
+ return False
+
+ return True
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d6.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d6.md
new file mode 100644
index 00000000000..72e54880c75
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d6.md
@@ -0,0 +1,123 @@
+---
+id: 699c8e045ee7cb94ed2322d6
+title: "Challenge 215: Parking Fee Calculator"
+challengeType: 29
+dashedName: challenge-215
+---
+
+# --description--
+
+Given two strings representing the time you parked your car and the time you picked it up, calculate the parking fee.
+
+- The given strings will be in the format `"HH:MM"` using a 24-hour clock. So `"14:00"` is 2pm for example.
+- The first string will be the time you parked your car, and the second will be the time you picked it up.
+- If the pickup time is earlier than the entry time, it means the parking spanned past midnight into the next day.
+
+Fee rules:
+
+- Each hour parked costs $3.
+- Partial hours are rounded up to the next full hour.
+- If the parking spans overnight (past midnight), an additional $10 overnight fee is applied.
+- There is a minimum fee of $5 (only used if the total would be less than $5).
+
+Return the total cost in the format `"$cost"`, `"$5"` for example.
+
+# --hints--
+
+`calculate_parking_fee("09:00", "11:00")` should return `"$6"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("09:00", "11:00"), "$6")`)
+}})
+```
+
+`calculate_parking_fee("10:00", "10:30")` should return `"$5"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("10:00", "10:30"), "$5")`)
+}})
+```
+
+`calculate_parking_fee("08:10", "10:45")` should return `"$9"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("08:10", "10:45"), "$9")`)
+}})
+```
+
+`calculate_parking_fee("14:40", "23:10")` should return `"$27"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("14:40", "23:10"), "$27")`)
+}})
+```
+
+`calculate_parking_fee("18:15", "01:30")` should return `"$34"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("18:15", "01:30"), "$34")`)
+}})
+```
+
+`calculate_parking_fee("11:11", "11:10")` should return `"$82"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(calculate_parking_fee("11:11", "11:10"), "$82")`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def calculate_parking_fee(park_time, pickup_time):
+
+ return park_time
+```
+
+# --solutions--
+
+```py
+import math
+
+def calculate_parking_fee(park_time, pickup_time):
+ def to_minutes(time_str):
+ hours, minutes = map(int, time_str.split(":"))
+ return hours * 60 + minutes
+
+ entry_minutes = to_minutes(park_time)
+ exit_minutes = to_minutes(pickup_time)
+
+ overnight = False
+
+ if exit_minutes < entry_minutes:
+ overnight = True
+ total_minutes = (24 * 60 - entry_minutes) + exit_minutes
+ else:
+ total_minutes = exit_minutes - entry_minutes
+
+ hours = math.ceil(total_minutes / 60)
+
+ cost = hours * 3
+
+ if overnight:
+ cost += 10
+
+ if cost < 5:
+ cost = 5
+
+ return f"${cost}"
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d7.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d7.md
new file mode 100644
index 00000000000..17a084c0701
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d7.md
@@ -0,0 +1,111 @@
+---
+id: 699c8e045ee7cb94ed2322d7
+title: "Challenge 216: Pi Day"
+challengeType: 29
+dashedName: challenge-216
+---
+
+# --description--
+
+Happy pi (π) day!
+
+Given an integer (`n`), where `n` is between 1 and 1000 (inclusive), return the `n`th decimal of π.
+
+- Make sure to return a number not a string.
+
+π with its first five decimals is 3.14159. So given `5` for example, return `9`, the fifth decimal.
+
+You may have to find the first 1000 decimals of π somewhere.
+
+# --hints--
+
+`get_pi_decimal(5)` should return `9`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(5), 9)`)
+}})
+```
+
+`get_pi_decimal(10)` should return `5`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(10), 5)`)
+}})
+```
+
+`get_pi_decimal(22)` should return `6`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(22), 6)`)
+}})
+```
+
+`get_pi_decimal(39)` should return `7`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(39), 7)`)
+}})
+```
+
+`get_pi_decimal(76)` should return `2`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(76), 2)`)
+}})
+```
+
+`get_pi_decimal(384)` should return `4`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(384), 4)`)
+}})
+```
+
+`get_pi_decimal(601)` should return `0`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(601), 0)`)
+}})
+```
+
+`get_pi_decimal(1000)` should return `9`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_pi_decimal(1000), 9)`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def get_pi_decimal(n):
+
+ return n
+```
+
+# --solutions--
+
+```py
+def get_pi_decimal(n):
+ pi = "31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989"
+
+ return int(pi[n])
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d8.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d8.md
new file mode 100644
index 00000000000..d4f7ea516bf
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d8.md
@@ -0,0 +1,117 @@
+---
+id: 699c8e045ee7cb94ed2322d8
+title: "Challenge 217: Captured Chess Pieces"
+challengeType: 29
+dashedName: challenge-217
+---
+
+# --description--
+
+Given an array of strings representing chess pieces you still have on the board, calculate the value of the pieces your opponent has captured.
+
+In chess, you start with 16 pieces:
+
+| Piece | Abbreviation | Quantity | Value |
+| ------ | -------------- | -------- | ----- |
+| Pawn | `"P"` | 8 | 1 |
+| Rook | `"R"` | 2 | 5 |
+| Knight | `"N"` | 2 | 3 |
+| Bishop | `"B"` | 2 | 3 |
+| Queen | `"Q"` | 1 | 9 |
+| King | `"K"` | 1 | 0 |
+
+- The given array will only contain the abbreviations above.
+- Any of the 16 pieces not included in the given array have been captured.
+- Return the total value of all captured pieces, unless...
+- If the King has been captured, return `"Checkmate"`.
+
+# --hints--
+
+`get_captured_value(["P", "P", "P", "P", "P", "P", "R", "R", "N", "B", "Q", "K"])` should return `8`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["P", "P", "P", "P", "P", "P", "R", "R", "N", "B", "Q", "K"]), 8)`)
+}})
+```
+
+`get_captured_value(["P", "P", "P", "P", "P", "R", "B", "K"])` should return `26`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["P", "P", "P", "P", "P", "R", "B", "K"]), 26)`)
+}})
+```
+
+`get_captured_value(["K", "P", "P", "N", "P", "P", "R", "P", "B", "P", "N", "B"])` should return `16`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["K", "P", "P", "N", "P", "P", "R", "P", "B", "P", "N", "B"]), 16)`)
+}})
+```
+
+`get_captured_value(["P", "Q", "N", "P", "P", "B", "K", "P", "R", "R", "P", "P", "B", "P"])` should return `4`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["P", "Q", "N", "P", "P", "B", "K", "P", "R", "R", "P", "P", "B", "P"]), 4)`)
+}})
+```
+
+`get_captured_value(["P", "K"])` should return `38`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["P", "K"]), 38)`)
+}})
+```
+
+`get_captured_value(["N", "P", "P", "B", "K", "P", "Q", "N", "P", "P", "R", "R", "P", "P", "P", "B"])` should return `0`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["N", "P", "P", "B", "K", "P", "Q", "N", "P", "P", "R", "R", "P", "P", "P", "B"]), 0)`)
+}})
+```
+
+`get_captured_value(["N", "P", "P", "B", "P", "R", "Q", "P", "P", "P", "B"])` should return `"Checkmate"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_captured_value(["N", "P", "P", "B", "P", "R", "Q", "P", "P", "P", "B"]), "Checkmate")`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def get_captured_value(pieces):
+
+ return pieces
+```
+
+# --solutions--
+
+```py
+def get_captured_value(pieces):
+ if "K" not in pieces:
+ return "Checkmate"
+
+ values = {"P":1, "R":5, "N":3, "B":3, "Q":9, "K":0}
+ remaining = "PPPPPPPPRRNNBBQK"
+
+ for p in pieces:
+ remaining = remaining.replace(p, "", 1)
+
+ return sum(values[p] for p in remaining)
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d9.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d9.md
new file mode 100644
index 00000000000..e449f3639bd
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322d9.md
@@ -0,0 +1,83 @@
+---
+id: 699c8e045ee7cb94ed2322d9
+title: "Challenge 218: Evenly Divisible"
+challengeType: 29
+dashedName: challenge-218
+---
+
+# --description--
+
+Given two integers, determine if you can evenly divide the first one by the second one.
+
+# --hints--
+
+`is_evenly_divisible(4, 2)` should return `True`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(4, 2), True)`)
+}})
+```
+
+`is_evenly_divisible(7, 3)` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(7, 3), False)`)
+}})
+```
+
+`is_evenly_divisible(5, 10)` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(5, 10), False)`)
+}})
+```
+
+`is_evenly_divisible(48, 6)` should return `True`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(48, 6), True)`)
+}})
+```
+
+`is_evenly_divisible(3186, 9)` should return `True`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(3186, 9), True)`)
+}})
+```
+
+`is_evenly_divisible(4192, 11)` should return `False`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertIs(is_evenly_divisible(4192, 11), False)`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def is_evenly_divisible(a, b):
+
+ return a
+```
+
+# --solutions--
+
+```py
+def is_evenly_divisible(a, b):
+ return a % b == 0
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322da.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322da.md
new file mode 100644
index 00000000000..263afe32e9d
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322da.md
@@ -0,0 +1,139 @@
+---
+id: 699c8e045ee7cb94ed2322da
+title: "Challenge 219: Anniversary Milestones"
+challengeType: 29
+dashedName: challenge-219
+---
+
+# --description--
+
+Given an integer representing the number of years a couple has been married, return their most recent anniversary milestone according to this chart:
+
+| Years Married | Milestone |
+| ------------- | ------------ |
+| 1 | `"Paper"` |
+| 5 | `"Wood"` |
+| 10 | `"Tin"` |
+| 25 | `"Silver"` |
+| 40 | `"Ruby"` |
+| 50 | `"Gold"` |
+| 60 | `"Diamond"` |
+| 70 | `"Platinum"` |
+
+- If they haven't reached the first milestone, return `"Newlyweds"`.
+
+# --hints--
+
+`get_milestone(0)` should return `"Newlyweds"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(0), "Newlyweds")`)
+}})
+```
+
+`get_milestone(1)` should return `"Paper"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(1), "Paper")`)
+}})
+```
+
+`get_milestone(8)` should return `"Wood"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(8), "Wood")`)
+}})
+```
+
+`get_milestone(10)` should return `"Tin"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(10), "Tin")`)
+}})
+```
+
+`get_milestone(26)` should return `"Silver"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(26), "Silver")`)
+}})
+```
+
+`get_milestone(45)` should return `"Ruby"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(45), "Ruby")`)
+}})
+```
+
+`get_milestone(50)` should return `"Gold"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(50), "Gold")`)
+}})
+```
+
+`get_milestone(64)` should return `"Diamond"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(64), "Diamond")`)
+}})
+```
+
+`get_milestone(71)` should return `"Platinum"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_milestone(71), "Platinum")`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def get_milestone(years):
+
+ return years
+```
+
+# --solutions--
+
+```py
+def get_milestone(years):
+ if years < 1:
+ return "Newlyweds"
+
+ milestones = [
+ (1, "Paper"),
+ (5, "Wood"),
+ (10, "Tin"),
+ (25, "Silver"),
+ (40, "Ruby"),
+ (50, "Gold"),
+ (60, "Diamond"),
+ (70, "Platinum")
+ ]
+
+ for year, milestone in reversed(milestones):
+ if years >= year:
+ return milestone
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322db.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322db.md
new file mode 100644
index 00000000000..4963bf50afa
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322db.md
@@ -0,0 +1,70 @@
+---
+id: 699c8e045ee7cb94ed2322db
+title: "Challenge 220: Largest Number"
+challengeType: 29
+dashedName: challenge-220
+---
+
+# --description--
+
+Given a string of numbers separated by various punctuation, return the largest number.
+
+- The given string will only contain numbers and separators.
+- Separators can be commas (`","`), exclamation points (`"!"`), question marks (`"?"`), colons (`":"`), or semi-colons (`";"`).
+
+# --hints--
+
+`largest_number("1,2")` should return `2`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(largest_number("1,2"), 2)`)
+}})
+```
+
+`largest_number("4;15:60,26?52!0")` should return `60`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(largest_number("4;15:60,26?52!0"), 60)`)
+}})
+```
+
+`largest_number("-402,-1032!-569:-947;-633?-800!-1012;-402,-723?-8102!-3011")` should return `-402`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(largest_number("-402,-1032!-569:-947;-633?-800!-1012;-402,-723?-8102!-3011"), -402)`)
+}})
+```
+
+`largest_number("12;-50,99.9,49.1!-10.1?88?16")` should return `99.9`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(largest_number("12;-50,99.9,49.1!-10.1?88?16"), 99.9)`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def largest_number(s):
+
+ return s
+```
+
+# --solutions--
+
+```py
+import re
+def largest_number(s):
+ numbers = [float(n) for n in re.split(r'[,!?:;]', s)]
+ return max(numbers)
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dc.md
new file mode 100644
index 00000000000..c680fac3bed
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dc.md
@@ -0,0 +1,96 @@
+---
+id: 699c8e045ee7cb94ed2322dc
+title: "Challenge 221: Inverted Matrix"
+challengeType: 29
+dashedName: challenge-221
+---
+
+# --description--
+
+Given a matrix (an array of arrays) filled with two distinct values, return a new matrix where all occurrences of one value are swapped with the other.
+
+For example, given:
+
+```js
+[
+ ["a", "b"],
+ ["a", "a"]
+]
+```
+
+Return:
+
+```js
+[
+ ["b", "a"],
+ ["b", "b"]
+]
+```
+
+# --hints--
+
+`invert_matrix([["a", "b"], ["a", "a"]])` should return `[["b", "a"], ["b", "b"]]`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(invert_matrix([["a", "b"], ["a", "a"]]), [["b", "a"], ["b", "b"]])`)
+}})
+```
+
+`invert_matrix([[1, 0, 1], [1, 1, 1], [0, 1, 0]])` should return `[[0, 1, 0], [0, 0, 0], [1, 0, 1]]`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(invert_matrix([[1, 0, 1], [1, 1, 1], [0, 1, 0]]), [[0, 1, 0], [0, 0, 0], [1, 0, 1]])`)
+}})
+```
+
+`invert_matrix([["apple", "banana", "banana", "apple"], ["banana", "apple", "apple", "banana"], ["banana", "banana", "banana", "apple"]])` should return `[["banana", "apple", "apple", "banana"], ["apple", "banana", "banana", "apple"], ["apple", "apple", "apple", "banana"]]`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(invert_matrix([["apple", "banana", "banana", "apple"], ["banana", "apple", "apple", "banana"], ["banana", "banana", "banana", "apple"]]), [["banana", "apple", "apple", "banana"], ["apple", "banana", "banana", "apple"], ["apple", "apple", "apple", "banana"]])`)
+}})
+```
+
+`invert_matrix([[6, 7, 7, 7, 6], [7, 6, 7, 6, 7], [7, 7, 6, 7, 7], [7, 6, 7, 6, 7], [6, 7, 7, 7, 6]])` should return `[[7, 6, 6, 6, 7], [6, 7, 6, 7, 6], [6, 6, 7, 6, 6], [6, 7, 6, 7, 6], [7, 6, 6, 6, 7]]`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(invert_matrix([[6, 7, 7, 7, 6], [7, 6, 7, 6, 7], [7, 7, 6, 7, 7], [7, 6, 7, 6, 7], [6, 7, 7, 7, 6]]), [[7, 6, 6, 6, 7], [6, 7, 6, 7, 6], [6, 6, 7, 6, 6], [6, 7, 6, 7, 6], [7, 6, 6, 6, 7]])`)
+}})
+```
+
+`invert_matrix([[1.2, 2.1, 2.1, 2.1], [2.1, 1.2, 2.1, 1.2], [1.2, 1.2, 2.1, 2.1]])` should return `[[2.1, 1.2, 1.2, 1.2], [1.2, 2.1, 1.2, 2.1], [2.1, 2.1, 1.2, 1.2]]`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(invert_matrix([[1.2, 2.1, 2.1, 2.1], [2.1, 1.2, 2.1, 1.2], [1.2, 1.2, 2.1, 2.1]]), [[2.1, 1.2, 1.2, 1.2], [1.2, 2.1, 1.2, 2.1], [2.1, 2.1, 1.2, 1.2]])`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def invert_matrix(matrix):
+
+ return matrix
+```
+
+# --solutions--
+
+```py
+def invert_matrix(matrix):
+ flat = [cell for row in matrix for cell in row]
+ values = list(set(flat))
+ val1, val2 = values
+
+ return [[val2 if cell == val1 else val1 for cell in row] for row in matrix]
+```
diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dd.md
new file mode 100644
index 00000000000..5651c1debe2
--- /dev/null
+++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/699c8e045ee7cb94ed2322dd.md
@@ -0,0 +1,139 @@
+---
+id: 699c8e045ee7cb94ed2322dd
+title: "Challenge 222: Equinox Shadows"
+challengeType: 29
+dashedName: challenge-222
+---
+
+# --description--
+
+Today is the equinox, when the sun is directly above the equator and perfectly overhead at noon. Given a time, determine the shadow cast by a 4-foot vertical pole.
+
+- The time will be a string in `"HH:MM"` 24-hour format (for example, `"15:00"` is 3pm).
+- You will only be given a time in 30 minute increments.
+
+Rules:
+
+- The sun rises at 6am directly `"east"`, and sets at 6pm directly `"west"`.
+- A shadow always points opposite the sun.
+- The shadow's length (in feet) is the number of hours away from noon, cubed.
+- There is no shadow before sunrise (before 6am), after sunset (6pm or later), or at noon.
+
+Return:
+
+- If a shadow exists, return `"(length)ft (direction)"`. For example, `"8ft west"`.
+- Otherwise, return `"No shadow"`.
+
+For example, given `"10:00"`, return `"8ft west"` because 10am is 2 hours from noon, so 23 = 8 feet, and the shadow points west because the sun is in the east at 10am.
+
+# --hints--
+
+`get_shadow("10:00")` should return `"8ft west"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("10:00"), "8ft west")`)
+}})
+```
+
+`get_shadow("15:00")` should return `"27ft east"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("15:00"), "27ft east")`)
+}})
+```
+
+`get_shadow("12:00")` should return `"No shadow"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("12:00"), "No shadow")`)
+}})
+```
+
+`get_shadow("17:30")` should return `"166.375ft east"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("17:30"), "166.375ft east")`)
+}})
+```
+
+`get_shadow("05:00")` should return `"No shadow"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("05:00"), "No shadow")`)
+}})
+```
+
+`get_shadow("06:00")` should return `"216ft west"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("06:00"), "216ft west")`)
+}})
+```
+
+`get_shadow("18:00")` should return `"No shadow"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("18:00"), "No shadow")`)
+}})
+```
+
+`get_shadow("07:30")` should return `"91.125ft west"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("07:30"), "91.125ft west")`)
+}})
+```
+
+`get_shadow("00:00")` should return `"No shadow"`.
+
+```js
+({test: () => { runPython(`
+from unittest import TestCase
+TestCase().assertEqual(get_shadow("00:00"), "No shadow")`)
+}})
+```
+
+# --seed--
+
+## --seed-contents--
+
+```py
+def get_shadow(time):
+
+ return time
+```
+
+# --solutions--
+
+```py
+def get_shadow(time):
+ hour_str, minute_str = time.split(":")
+ hours = int(hour_str)
+ minutes = int(minute_str)
+ time_in_hours = hours + minutes / 60
+
+ if time_in_hours < 6 or time_in_hours >= 18 or time_in_hours == 12:
+ return "No shadow"
+
+ hours_from_noon = abs(12 - time_in_hours)
+ length = hours_from_noon ** 3
+ direction = "west" if time_in_hours < 12 else "east"
+
+ return f"{length:g}ft {direction}"
+```
diff --git a/curriculum/structure/blocks/daily-coding-challenges-javascript.json b/curriculum/structure/blocks/daily-coding-challenges-javascript.json
index c7fba86fe87..d0c5857ce60 100644
--- a/curriculum/structure/blocks/daily-coding-challenges-javascript.json
+++ b/curriculum/structure/blocks/daily-coding-challenges-javascript.json
@@ -854,6 +854,46 @@
{
"id": "6994cff2290543b3aec9f511",
"title": "Challenge 212: Array Insertion"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d4",
+ "title": "Challenge 213: Word Length Converter"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d5",
+ "title": "Challenge 214: Domino Chain Validator"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d6",
+ "title": "Challenge 215: Parking Fee Calculator"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d7",
+ "title": "Challenge 216: Pi Day"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d8",
+ "title": "Challenge 217: Captured Chess Pieces"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d9",
+ "title": "Challenge 218: Evenly Divisible"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322da",
+ "title": "Challenge 219: Anniversary Milestones"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322db",
+ "title": "Challenge 220: Largest Number"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322dc",
+ "title": "Challenge 221: Inverted Matrix"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322dd",
+ "title": "Challenge 222: Equinox Shadows"
}
]
}
diff --git a/curriculum/structure/blocks/daily-coding-challenges-python.json b/curriculum/structure/blocks/daily-coding-challenges-python.json
index e9ed05eec41..f14c814f7d6 100644
--- a/curriculum/structure/blocks/daily-coding-challenges-python.json
+++ b/curriculum/structure/blocks/daily-coding-challenges-python.json
@@ -853,6 +853,46 @@
{
"id": "6994cff2290543b3aec9f511",
"title": "Challenge 212: Array Insertion"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d4",
+ "title": "Challenge 213: Word Length Converter"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d5",
+ "title": "Challenge 214: Domino Chain Validator"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d6",
+ "title": "Challenge 215: Parking Fee Calculator"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d7",
+ "title": "Challenge 216: Pi Day"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d8",
+ "title": "Challenge 217: Captured Chess Pieces"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322d9",
+ "title": "Challenge 218: Evenly Divisible"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322da",
+ "title": "Challenge 219: Anniversary Milestones"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322db",
+ "title": "Challenge 220: Largest Number"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322dc",
+ "title": "Challenge 221: Inverted Matrix"
+ },
+ {
+ "id": "699c8e045ee7cb94ed2322dd",
+ "title": "Challenge 222: Equinox Shadows"
}
]
}
diff --git a/tools/daily-challenges/seed-daily-challenges.ts b/tools/daily-challenges/seed-daily-challenges.ts
index fa957652fe2..0ba891fd36f 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 = 212;
+const EXPECTED_CHALLENGE_COUNT = 222;
// 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)**