diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629efe.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629efe.md index 7fb5e7385e4..b972b66ae03 100644 --- a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629efe.md +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629efe.md @@ -12,6 +12,7 @@ Given a distance in miles as a number, return the equivalent distance in kilomet - The input will always be a non-negative number. - 1 mile equals 1.60934 kilometers. - Round the result to two decimal places. +- Remove unnecessary trailing zeros from the rounded result. # --hints-- diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629f00.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629f00.md index f0294d8f5a0..c0829c4a038 100644 --- a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629f00.md +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69162d64f96574d9bb629f00.md @@ -18,7 +18,7 @@ A valid ordered list item in Markdown must: If the string doesn't have the exact format above, return `"Invalid format"`. Otherwise, wrap the list item text in `li` tags and return the string. -For example, given `"1. My item"`, return `"
  • My item
  • "` +For example, given `"1. My item"`, return `"
  • My item
  • "`. Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b480.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b480.md new file mode 100644 index 00000000000..3616c5e967f --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b480.md @@ -0,0 +1,72 @@ +--- +id: 691b559495c5cb5a37b9b480 +title: "Challenge 120: Pounds to Kilograms" +challengeType: 28 +dashedName: challenge-120 +--- + +# --description-- + +Given a weight in pounds as a number, return the string `"(lbs) pounds equals (kgs) kilograms."`. + +- Replace `"(lbs)"` with the input number. +- Replace `"(kgs)"` with the input converted to kilograms, rounded to two decimals and always include two decimal places in the value. +- 1 pound equals 0.453592 kilograms. +- If the input is `1`, use `"pound"` instead of `"pounds"`. +- If the converted value is `1`, use `"kilogram"` instead of `"kilograms"`. + +# --hints-- + +`convertToKgs(1)` should return `"1 pound equals 0.45 kilograms."`. + +```js +assert.equal(convertToKgs(1), "1 pound equals 0.45 kilograms."); +``` + +`convertToKgs(0)` should return `"0 pounds equals 0.00 kilograms."`. + +```js +assert.equal(convertToKgs(0), "0 pounds equals 0.00 kilograms."); +``` + +`convertToKgs(100)` should return `"100 pounds equals 45.36 kilograms."`. + +```js +assert.equal(convertToKgs(100), "100 pounds equals 45.36 kilograms."); +``` + +`convertToKgs(2.5)` should return `"2.5 pounds equals 1.13 kilograms."`. + +```js +assert.equal(convertToKgs(2.5), "2.5 pounds equals 1.13 kilograms."); +``` + +`convertToKgs(2.20462)` should return `"2.20462 pounds equals 1.00 kilogram."`. + +```js +assert.equal(convertToKgs(2.20462), "2.20462 pounds equals 1.00 kilogram."); +``` + +# --seed-- + +## --seed-contents-- + +```js +function convertToKgs(lbs) { + return lbs; +} +``` + +# --solutions-- + +```js +function convertToKgs(lbs) { + const KG_PER_POUND = 0.453592; + const kgs = (lbs * KG_PER_POUND).toFixed(2); + + const poundWord = lbs === 1 ? "pound" : "pounds"; + const kilogramWord = kgs === "1.00" ? "kilogram" : "kilograms"; + + return `${lbs} ${poundWord} equals ${kgs} ${kilogramWord}.`; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b481.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b481.md new file mode 100644 index 00000000000..0992da304b2 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b481.md @@ -0,0 +1,68 @@ +--- +id: 691b559495c5cb5a37b9b481 +title: "Challenge 121: Most Frequent" +challengeType: 28 +dashedName: challenge-121 +--- + +# --description-- + +Given an array of elements, return the element that appears most frequently. + +- There will always be a single most frequent element. + +# --hints-- + +`mostFrequent(["a", "b", "a", "c"])` should return `"a"`. + +```js +assert.equal(mostFrequent(["a", "b", "a", "c"]), "a"); +``` + +`mostFrequent([2, 3, 5, 2, 6, 3, 2, 7, 2, 9])` should return `2`. + +```js +assert.equal(mostFrequent([2, 3, 5, 2, 6, 3, 2, 7, 2, 9]), 2); +``` + +`mostFrequent([true, false, "false", "true", false])` should return `false`. + +```js +assert.isFalse(mostFrequent([true, false, "false", "true", false])); +``` + +`mostFrequent([40, 20, 70, 30, 10, 40, 10, 50, 40, 60])` should return `40`. + +```js +assert.equal(mostFrequent([40, 20, 70, 30, 10, 40, 10, 50, 40, 60]), 40); +``` + +# --seed-- + +## --seed-contents-- + +```js +function mostFrequent(arr) { + return arr; +} +``` + +# --solutions-- + +```js +function mostFrequent(arr) { + const freq = {}; + let maxCount = 0; + let mostElem = null; + + for (const el of arr) { + freq[el] = (freq[el] || 0) + 1; + if (freq[el] > maxCount) { + maxCount = freq[el]; + mostElem = el; + } + } + + return mostElem; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b482.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b482.md new file mode 100644 index 00000000000..2385fad17e4 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b482.md @@ -0,0 +1,72 @@ +--- +id: 691b559495c5cb5a37b9b482 +title: "Challenge 122: Markdown Bold Parser" +challengeType: 28 +dashedName: challenge-122 +--- + +# --description-- + +Given a string that may include some bold text in Markdown, return the equivalent HTML string. + +- Bold text in Markdown is any text that starts and ends with two asterisks (`**`) or two underscores (`__`). +- There cannot be any spaces between the text and the asterisks or underscores, but there can be + spaces in the text itself. +- Convert all bold occurrences to HTML `b` tags and return the string. + +For example, given `"**This is bold**"`, return `"This is bold"`. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parseBold("**This is bold**")` should return `"This is bold"`. + +```js +assert.equal(parseBold("**This is bold**"), "This is bold"); +``` + +`parseBold("__This is also bold__")` should return `"This is also bold"`. + +```js +assert.equal(parseBold("__This is also bold__"), "This is also bold"); +``` + +`parseBold("**This is not bold **")` should return `"**This is not bold **"`. + +```js +assert.equal(parseBold("**This is not bold **"), "**This is not bold **"); +``` + +`parseBold("__ This is also not bold__")` should return `"__ This is also not bold__"`. + +```js +assert.equal(parseBold("__ This is also not bold__"), "__ This is also not bold__"); +``` + +`parseBold("The **quick** brown fox __jumps__ over the **lazy** dog.")` should return `"The quick brown fox jumps over the lazy dog."`. + +```js +assert.equal(parseBold("The **quick** brown fox __jumps__ over the **lazy** dog."), "The quick brown fox jumps over the lazy dog."); +``` + +# --seed-- + +## --seed-contents-- + +```js +function parseBold(markdown) { + return markdown; +} +``` + +# --solutions-- + +```js +function parseBold(markdown) { + markdown = markdown.replace(/\*\*(\S(?:.*?\S)?)\*\*/g, "$1"); + markdown = markdown.replace(/__(\S(?:.*?\S)?)__/g, "$1"); + + return markdown; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b483.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b483.md new file mode 100644 index 00000000000..53488b6d41c --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b483.md @@ -0,0 +1,103 @@ +--- +id: 691b559495c5cb5a37b9b483 +title: "Challenge 123: Roman Numeral Builder" +challengeType: 28 +dashedName: challenge-123 +--- + +# --description-- + +Given an integer, return its equivalent value in Roman numerals. + +Roman numerals use these symbols: + +| Symbol | Value | +| ------ | ----- | +| I | 1 | +| V | 5 | +| X | 10 | +| L | 50 | +| C | 100 | +| D | 500 | +| M | 1000 | + +Roman numerals are written from largest to smallest, left to right using the following rules: + +- Addition is used when a symbol is followed by one of equal or smaller value. For example, `18` is written as `XVIII` (10 + 5 + 1 + 1 + 1 = 18). +- Subtraction is used when a smaller symbol appears before a larger one, to represent 4 or 9 in any place value. For example, 19 is written as `XIX` (10 + (10 - 1)). +- No symbol may be repeated more than three times in a row. Subtraction is used when you would otherwise need to write a symbol more than three times in a row. So the largest number you can write is 3999. + +Here's one more example: given `1464`, return `"MCDLXIV"` (1000 + (500 - 100) + 50 + 10 + (5 - 1)). + +# --hints-- + +`toRoman(18)` should return `"XVIII"`. + +```js +assert.equal(toRoman(18), "XVIII"); +``` + +`toRoman(19)` should return `"XIX"`. + +```js +assert.equal(toRoman(19), "XIX"); +``` + +`toRoman(1464)` should return `"MCDLXIV"`. + +```js +assert.equal(toRoman(1464), "MCDLXIV"); +``` + +`toRoman(2025)` should return `"MMXXV"`. + +```js +assert.equal(toRoman(2025), "MMXXV"); +``` + +`toRoman(3999)` should return `"MMMCMXCIX"`. + +```js +assert.equal(toRoman(3999), "MMMCMXCIX"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function toRoman(num) { + return num; +} +``` + +# --solutions-- + +```js +function toRoman(num) { + const symbols = [ + ["M", 1000], + ["CM", 900], + ["D", 500], + ["CD", 400], + ["C", 100], + ["XC", 90], + ["L", 50], + ["XL", 40], + ["X", 10], + ["IX", 9], + ["V", 5], + ["IV", 4], + ["I", 1] + ]; + + let result = ""; + for (const [sym, val] of symbols) { + while (num >= val) { + result += sym; + num -= val; + } + } + return result; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b484.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b484.md new file mode 100644 index 00000000000..addbd3323bf --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b484.md @@ -0,0 +1,76 @@ +--- +id: 691b559495c5cb5a37b9b484 +title: "Challenge 124: Inventory Update" +challengeType: 28 +dashedName: challenge-124 +--- + +# --description-- + +Given a 2D array representing the inventory of your store, and another 2D array representing a shipment you have received, return your updated inventory. + +- Each element in the arrays will have the format: `[quantity, "item"]`, where `quantity` is an integer and `"item"` is a string. +- Update items in the inventory by adding the quantity of any matching items from the shipment. +- If a received item does not exist in the current inventory, add it as a new entry to the end of the inventory. +- Return inventory in the order it was given with new items at the end in the order they appear in the shipment. + +For example, given an inventory of `[[2, "apples"], [5, "bananas"]]` and a shipment of `[[1, "apples"], [3, "bananas"]]`, return `[[3, "apples"], [8, "bananas"]]`. + +# --hints-- + +`updateInventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"]])` should return `[[3, "apples"], [8, "bananas"]]`. + +```js +assert.deepEqual(updateInventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"]]), [[3, "apples"], [8, "bananas"]]); +``` + +`updateInventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"], [4, "oranges"]])` should return `[[3, "apples"], [8, "bananas"], [4, "oranges"]]`. + +```js +assert.deepEqual(updateInventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"], [4, "oranges"]]), [[3, "apples"], [8, "bananas"], [4, "oranges"]]); +``` + +`updateInventory([], [[10, "apples"], [30, "bananas"], [20, "oranges"]])` should return `[[10, "apples"], [30, "bananas"], [20, "oranges"]]`. + +```js +assert.deepEqual(updateInventory([], [[10, "apples"], [30, "bananas"], [20, "oranges"]]), [[10, "apples"], [30, "bananas"], [20, "oranges"]]); +``` + +`updateInventory([[0, "Bowling Ball"], [0, "Dirty Socks"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]])` should return `[[1, "Bowling Ball"], [0, "Dirty Socks"], [1, "Hair Pin"], [0, "Microphone"], [1, "Half-Eaten Apple"], [1, "Toothpaste"]]`. + +```js +assert.deepEqual(updateInventory([[0, "Bowling Ball"], [0, "Dirty Socks"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]]), [[1, "Bowling Ball"], [0, "Dirty Socks"], [1, "Hair Pin"], [0, "Microphone"], [1, "Half-Eaten Apple"], [1, "Toothpaste"]]); +``` + +# --seed-- + +## --seed-contents-- + +```js +function updateInventory(inventory, shipment) { + return inventory; +} +``` + +# --solutions-- + +```js +function updateInventory(inventory, shipment) { + const inventoryMap = new Map(); + inventory.forEach(([qty, item], index) => { + inventoryMap.set(item, index); + }); + + shipment.forEach(([qty, item]) => { + if (inventoryMap.has(item)) { + const index = inventoryMap.get(item); + inventory[index][0] += qty; + } else { + inventory.push([qty, item]); + inventoryMap.set(item, inventory.length - 1); + } + }); + + return inventory; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b485.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b485.md new file mode 100644 index 00000000000..b94b4291d3b --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b485.md @@ -0,0 +1,123 @@ +--- +id: 691b559495c5cb5a37b9b485 +title: "Challenge 125: Game of Life" +challengeType: 28 +dashedName: challenge-125 +--- + +# --description-- + +Given a matrix (array of arrays) representing the current state in Conway's Game of Life, return the next state of the matrix using these rules: + +- Each cell is either `1` (alive) or `0` (dead). +- A cell's neighbors are the up to eight surrounding cells (vertically, horizontally, and diagonally). +- Cells on the edges have fewer than eight neighbors. + +Rules for updating each cell: + +- Any live cell with fewer than two live neighbors dies (underpopulation). +- Any live cell with two or three live neighbors lives on. +- Any live cell with more than three live neighbors dies (overpopulation). +- Any dead cell with exactly three live neighbors becomes alive (reproduction). + +For example, given: + +```json +[ + [0, 1, 0], + [0, 1, 1], + [1, 1, 0] +] +``` + +return: + +```json +[ + [0, 1, 1], + [0, 0, 1], + [1, 1, 1] +] +``` + +Each cell updates according to the number of live neighbors. For instance, `[0][0]` stays dead (2 live neighbors), `[0][1]` stays alive (2 live neighbors), `[0][2]` dies (3 live neighbors), and so on. + +# --hints-- + +`gameOfLife([[0, 1, 0], [0, 1, 1], [1, 1, 0]])` should return `[[0, 1, 1], [0, 0, 1], [1, 1, 1]]`. + +```js +assert.deepEqual(gameOfLife([[0, 1, 0], [0, 1, 1], [1, 1, 0]]), [[0, 1, 1], [0, 0, 1], [1, 1, 1]]); +``` + +`gameOfLife([[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 1], [0, 0, 1, 0]])` should return `[[1, 1, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1], [0, 1, 1, 1]]`. + +```js +assert.deepEqual(gameOfLife([[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 1], [0, 0, 1, 0]]), [[1, 1, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1], [0, 1, 1, 1]]); +``` + +`gameOfLife([[1, 0, 0], [0, 1, 0], [0, 0, 1]])` should return `[[0, 0, 0], [0, 1, 0], [0, 0, 0]]`. + +```js +assert.deepEqual(gameOfLife([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), [[0, 0, 0], [0, 1, 0], [0, 0, 0]]); +``` + +`gameOfLife([[0, 1, 1, 0], [1, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0]])` should return `[[1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]`. + +```js +assert.deepEqual(gameOfLife([[0, 1, 1, 0], [1, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0]]), [[1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]); +``` + +# --seed-- + +## --seed-contents-- + +```js +function gameOfLife(grid) { + return grid; +} +``` + +# --solutions-- + +```js +function gameOfLife(grid) { + const rows = grid.length; + const cols = grid[0].length; + + const countLiveNeighbors = (r, c) => { + let count = 0; + for (let i = r - 1; i <= r + 1; i++) { + for (let j = c - 1; j <= c + 1; j++) { + if ( + i >= 0 && + i < rows && + j >= 0 && + j < cols && + !(i === r && j === c) && + grid[i][j] === 1 + ) { + count++; + } + } + } + return count; + }; + + const next = grid.map(row => [...row]); + + for (let r = 0; r < rows; r++) { + for (let c = 0; c < cols; c++) { + const liveNeighbors = countLiveNeighbors(r, c); + + if (grid[r][c] === 1) { + if (liveNeighbors < 2 || liveNeighbors > 3) next[r][c] = 0; + } else { + if (liveNeighbors === 3) next[r][c] = 1; + } + } + } + + return next; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b486.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b486.md new file mode 100644 index 00000000000..4ff92162fbd --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b486.md @@ -0,0 +1,61 @@ +--- +id: 691b559495c5cb5a37b9b486 +title: "Challenge 126: Capitalize It" +challengeType: 28 +dashedName: challenge-126 +--- + +# --description-- + +Given a string title, return a new string formatted in title case using the following rules: + +- Capitalize the first letter of each word. +- Make all other letters in each word lowercase. +- Words are always separated by a single space. + +# --hints-- + +`titleCase("hello world")` should return `"Hello World"`. + +```js +assert.equal(titleCase("hello world"), "Hello World"); +``` + +`titleCase("the quick brown fox")` should return `"The Quick Brown Fox"`. + +```js +assert.equal(titleCase("the quick brown fox"), "The Quick Brown Fox"); +``` + +`titleCase("JAVASCRIPT AND PYTHON")` should return `"Javascript And Python"`. + +```js +assert.equal(titleCase("JAVASCRIPT AND PYTHON"), "Javascript And Python"); +``` + +`titleCase("AvOcAdO tOAst fOr brEAkfAst")` should return `"Avocado Toast For Breakfast"`. + +```js +assert.equal(titleCase("AvOcAdO tOAst fOr brEAkfAst"), "Avocado Toast For Breakfast"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function titleCase(title) { + return title; +} +``` + +# --solutions-- + +```js +function titleCase(title) { + return title + .split(" ") + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(" "); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b487.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b487.md new file mode 100644 index 00000000000..9fb04f5d018 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b487.md @@ -0,0 +1,83 @@ +--- +id: 691b559495c5cb5a37b9b487 +title: "Challenge 127: Speed Check" +challengeType: 28 +dashedName: challenge-127 +--- + +# --description-- + +Given the speed you are traveling in miles per hour (MPH), and a speed limit in kilometers per hour (KPH), determine whether you are speeding and if you will get a warning or a ticket. + +- 1 mile equals 1.60934 kilometers. +- If you are travelling less than or equal to the speed limit, return `"Not Speeding"`. +- If you are travelling 5 KPH or less over the speed limit, return `"Warning"`. +- If you are travelling more than 5 KPH over the speed limit, return `"Ticket"`. + +# --hints-- + +`speedCheck(30, 70)` should return `"Not Speeding"`. + +```js +assert.equal(speedCheck(30, 70), "Not Speeding"); +``` + +`speedCheck(40, 60)` should return `"Warning"`. + +```js +assert.equal(speedCheck(40, 60), "Warning"); +``` + +`speedCheck(40, 65)` should return `"Not Speeding"`. + +```js +assert.equal(speedCheck(40, 65), "Not Speeding"); +``` + +`speedCheck(60, 90)` should return `"Ticket"`. + +```js +assert.equal(speedCheck(60, 90), "Ticket"); +``` + +`speedCheck(65, 100)` should return `"Warning"`. + +```js +assert.equal(speedCheck(65, 100), "Warning"); +``` + +`speedCheck(88, 40)` should return `"Ticket"`. + +```js +assert.equal(speedCheck(88, 40), "Ticket"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function speedCheck(speedMph, speedLimitKph) { + return speedMph; +} +``` + +# --solutions-- + +```js +function speedCheck(speedMph, speedLimitKph) { + const speedKph = speedMph * 1.60934; + + if (speedKph <= speedLimitKph) { + return "Not Speeding"; + } + + const over = speedKph - speedLimitKph; + + if (over <= 5) { + return "Warning"; + } + + return "Ticket"; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b488.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b488.md new file mode 100644 index 00000000000..9e4fee43aee --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b488.md @@ -0,0 +1,76 @@ +--- +id: 691b559495c5cb5a37b9b488 +title: "Challenge 128: Consonant Count" +challengeType: 28 +dashedName: challenge-128 +--- + +# --description-- + +Given a string and a target number, determine whether the string contains exactly the target number of consonants. + +- Consonants are all alphabetic characters except `"a"`, `"e"`, `"i"`, `"o"`, and `"u"` in any case. +- Ignore digits, punctuation, spaces, and other non-letter characters when counting. + +# --hints-- + +`hasConsonantCount("helloworld", 7)` should return `true`. + +```js +assert.isTrue(hasConsonantCount("helloworld", 7)); +``` + +`hasConsonantCount("eieio", 5)` should return `false`. + +```js +assert.isFalse(hasConsonantCount("eieio", 5)); +``` + +`hasConsonantCount("freeCodeCamp Rocks!", 11)` should return `true`. + +```js +assert.isTrue(hasConsonantCount("freeCodeCamp Rocks!", 11)); +``` + +`hasConsonantCount("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 24)` should return `false`. + +```js +assert.isFalse( + hasConsonantCount("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 24) +); +``` + +`hasConsonantCount("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 23)` should return `true`. + +```js +assert.isTrue( + hasConsonantCount("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 23) +); +``` + +# --seed-- + +## --seed-contents-- + +```js +function hasConsonantCount(text, target) { + return text; +} +``` + +# --solutions-- + +```js +function hasConsonantCount(text, target) { + const vowels = new Set(["a", "e", "i", "o", "u"]); + let count = 0; + + for (const char of text.toLowerCase()) { + if (/[a-z]/.test(char) && !vowels.has(char)) { + count++; + } + } + + return count === target; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b489.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b489.md new file mode 100644 index 00000000000..7e0695b5bde --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b559495c5cb5a37b9b489.md @@ -0,0 +1,65 @@ +--- +id: 691b559495c5cb5a37b9b489 +title: "Challenge 129: Markdown Blockquote Parser" +challengeType: 28 +dashedName: challenge-129 +--- + +# --description-- + +Given a string that includes a blockquote in Markdown, return the equivalent HTML string. + +A blockquote in Markdown is any line that: + +- Starts with zero or more spaces +- Followed by a greater-than sign (`>`) +- Then, one or more spaces +- And finally, the blockquote text. + +Return the blockquote text surrounded by opening and closing HTML `blockquote` tags. + +For example, given `"> This is a quote"`, return `
    This is a quote
    `. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parseBlockquote("> This is a quote")` should return `"
    This is a quote
    "`. + +```js +assert.equal(parseBlockquote("> This is a quote"), "
    This is a quote
    "); +``` + +`parseBlockquote(" > This is also a quote")` should return `"
    This is also a quote
    "`. + +```js +assert.equal(parseBlockquote(" > This is also a quote"), "
    This is also a quote
    "); +``` + +`parseBlockquote(" > So Is This")` should return `"
    So Is This
    "`. + +```js +assert.equal(parseBlockquote(" > So Is This"), "
    So Is This
    "); +``` + +# --seed-- + +## --seed-contents-- + +```js +function parseBlockquote(markdown) { + return markdown; +} +``` + +# --solutions-- + +```js +function parseBlockquote(markdown) { + const blockquoteRegex = /^\s*>\s+(.+)$/; + const match = markdown.match(blockquoteRegex); + + const text = match[1]; + return `
    ${text}
    `; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b5597f0f3e85a588a5c94.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b5597f0f3e85a588a5c94.md new file mode 100644 index 00000000000..f3a8913f195 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691b5597f0f3e85a588a5c94.md @@ -0,0 +1,78 @@ +--- +id: 691b5597f0f3e85a588a5c94 +title: "Challenge 130: Checkerboard" +challengeType: 28 +dashedName: challenge-130 +--- + +# --description-- + +Given an array with two numbers, the first being the number of rows and the second being the number of columns, return a matrix (an array of arrays) filled with `"X"` and `"O"` characters of the given size. + +- The characters should alternate like a checkerboard. +- The top-left cell must always be `"X"`. + +For example, given `[3, 3]`, return: + +```json +[ + ["X", "O", "X"], + ["O", "X", "O"], + ["X", "O", "X"] +] +``` + +# --hints-- + +`createBoard([3, 3])` should return `[["X", "O", "X"], ["O", "X", "O"], ["X", "O", "X"]]`. + +```js +assert.deepEqual(createBoard([3, 3]), [["X", "O", "X"], ["O", "X", "O"], ["X", "O", "X"]]); +``` + +`createBoard([6, 1])` should return `[["X"], ["O"], ["X"], ["O"], ["X"], ["O"]]`. + +```js +assert.deepEqual(createBoard([6, 1]), [["X"], ["O"], ["X"], ["O"], ["X"], ["O"]]); +``` + +`createBoard([2, 10])` should return `[["X", "O", "X", "O", "X", "O", "X", "O", "X", "O"], ["O", "X", "O", "X", "O", "X", "O", "X", "O", "X"]]`. + +```js +assert.deepEqual(createBoard([2, 10]), [["X", "O", "X", "O", "X", "O", "X", "O", "X", "O"], ["O", "X", "O", "X", "O", "X", "O", "X", "O", "X"]]); +``` + +`createBoard([5, 4])` should return `[["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"]]`. + +```js +assert.deepEqual(createBoard([5, 4]), [["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"]]); +``` + +# --seed-- + +## --seed-contents-- + +```js +function createBoard(dimensions) { + return dimensions; +} +``` + +# --solutions-- + +```js +function createBoard(dimensions) { + const [rows, cols] = dimensions; + const board = []; + + for (let r = 0; r < rows; r++) { + const row = []; + for (let c = 0; c < cols; c++) { + row.push((r + c) % 2 === 0 ? "X" : "O"); + } + board.push(row); + } + + return board; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5eca.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5eca.md new file mode 100644 index 00000000000..8f3eedff928 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5eca.md @@ -0,0 +1,72 @@ +--- +id: 691f7773cddba1caf1bf5eca +title: "Challenge 131: Pairwise" +challengeType: 28 +dashedName: challenge-131 +--- + +# --description-- + +Given an array of integers and a target number, find all pairs of elements in the array whose values add up to the target and return the sum of their indices. + +For example, given `[2, 3, 4, 6, 8]` and `10`, you will find two valid pairs: + +- `2` and `8` (2 + 8 = 10), whose indices are `0` and `4` +- `4` and `6` (4 + 6 = 10), whose indices are `2` and `3` + +Add all the indices together to get a return value of `9`. + +# --hints-- + +`pairwise([2, 3, 4, 6, 8], 10)` should return `9`. + +```js +assert.equal(pairwise([2, 3, 4, 6, 8], 10), 9); +``` + +`pairwise([4, 1, 5, 2, 6, 3], 7)` should return `15`. + +```js +assert.equal(pairwise([4, 1, 5, 2, 6, 3], 7), 15); +``` + +`pairwise([-30, -15, 5, 10, 15, -5, 20, -40], -20)` should return `22`. + +```js +assert.equal(pairwise([-30, -15, 5, 10, 15, -5, 20, -40], -20), 22); +``` + +`pairwise([7, 9, 13, 19, 21, 6, 3, 1, 4, 8, 12, 22], 24)` should return `10`. + +```js +assert.equal(pairwise([7, 9, 13, 19, 21, 6, 3, 1, 4, 8, 12, 22], 24), 10); +``` + +# --seed-- + +## --seed-contents-- + +```js +function pairwise(arr, target) { + + return arr; +} +``` + +# --solutions-- + +```js +function pairwise(arr, target) { + let total = 0; + + for (let i = 0; i < arr.length; i++) { + for (let j = i + 1; j < arr.length; j++) { + if (arr[i] + arr[j] === target) { + total += i + j; + } + } + } + + return total; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecb.md new file mode 100644 index 00000000000..d4964999b71 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecb.md @@ -0,0 +1,69 @@ +--- +id: 691f7773cddba1caf1bf5ecb +title: "Challenge 132: Purge Most Frequent" +challengeType: 28 +dashedName: challenge-132 +--- + +# --description-- + +Given an array of values, remove all occurrences of the most frequently occurring element and return the resulting array. + +- If multiple values are tied for most frequent, remove all of them. +- Do not change any of the other elements or their order. + +# --hints-- + +`purgeMostFrequent([1, 2, 2, 3])` should return `[1, 3]`. + +```js +assert.deepEqual(purgeMostFrequent([1, 2, 2, 3]), [1, 3]); +``` + +`purgeMostFrequent(["a", "b", "d", "b", "c", "d", "c", "d", "c", "d"])` should return `["a", "b", "b", "c", "c", "c"]`. + +```js +assert.deepEqual(purgeMostFrequent(["a", "b", "d", "b", "c", "d", "c", "d", "c", "d"]), ["a", "b", "b", "c", "c", "c"]); +``` + +`purgeMostFrequent(["red", "blue", "green", "red", "blue", "green", "blue"])` should return `["red", "green", "red", "green"]`. + +```js +assert.deepEqual(purgeMostFrequent(["red", "blue", "green", "red", "blue", "green", "blue"]), ["red", "green", "red", "green"]); +``` + +`purgeMostFrequent([5, 5, 5, 5])` should return `[]`. + +```js +assert.deepEqual(purgeMostFrequent([5, 5, 5, 5]), []); +``` + +# --seed-- + +## --seed-contents-- + +```js +function purgeMostFrequent(arr) { + + return arr; +} +``` + +# --solutions-- + +```js +function purgeMostFrequent(arr) { + const freq = {}; + for (const val of arr) { + freq[val] = (freq[val] || 0) + 1; + } + + const maxFreq = Math.max(...Object.values(freq)); + + const toRemove = new Set( + Object.keys(freq).filter(key => freq[key] === maxFreq) + ); + + return arr.filter(val => !toRemove.has(String(val))); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecc.md new file mode 100644 index 00000000000..34bb054efaf --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecc.md @@ -0,0 +1,123 @@ +--- +id: 691f7773cddba1caf1bf5ecc +title: "Challenge 133: Daylight Hours" +challengeType: 28 +dashedName: challenge-133 +--- + +# --description-- + +December 21st is the winter solstice for the northern hemisphere and the summer solstice for the southern hemisphere. That means it's the day with the least daylight in the north and the most daylight in the south. + +Given a latitude number from -90 to 90, return a rough approximation of daylight hours on the solstice using the following table: + +|Latitude|Daylight Hours| +|-|-| +|-90|24| +|-75|23| +|-60|21| +|-45|15| +|-30|13| +|-15|12| +|0|12| +|15|11| +|30|10| +|45|9| +|60|6| +|75|2| +|90|0| + +- If the given latitude does not exactly match a table entry, use the value of the closest latitude. + +# --hints-- + +`daylightHours(45)` should return `9`. + +```js +assert.equal(daylightHours(45), 9); +``` + +`daylightHours(0)` should return `12`. + +```js +assert.equal(daylightHours(0), 12); +``` + +`daylightHours(-90)` should return `24`. + +```js +assert.equal(daylightHours(-90), 24); +``` + +`daylightHours(-10)` should return `12`. + +```js +assert.equal(daylightHours(-10), 12); +``` + +`daylightHours(23)` should return `10`. + +```js +assert.equal(daylightHours(23), 10); +``` + +`daylightHours(88)` should return `0`. + +```js +assert.equal(daylightHours(88), 0); +``` + +`daylightHours(-33)` should return `13`. + +```js +assert.equal(daylightHours(-33), 13); +``` + +`daylightHours(70)` should return `2`. + +```js +assert.equal(daylightHours(70), 2); +``` + +# --seed-- + +## --seed-contents-- + +```js +function daylightHours(latitude) { + + return latitude; +} +``` + +# --solutions-- + +```js +function daylightHours(latitude) { + const table = [ + { lat: -90, hours: 24 }, + { lat: -75, hours: 23 }, + { lat: -60, hours: 21 }, + { lat: -45, hours: 15 }, + { lat: -30, hours: 13 }, + { lat: -15, hours: 12 }, + { lat: 0, hours: 12 }, + { lat: 15, hours: 11 }, + { lat: 30, hours: 10 }, + { lat: 45, hours: 9 }, + { lat: 60, hours: 6 }, + { lat: 75, hours: 2 }, + { lat: 90, hours: 0 } + ]; + + let closest = table[0]; + + for (const entry of table) { + if (Math.abs(entry.lat - latitude) < Math.abs(closest.lat - latitude)) { + closest = entry; + } + } + + return closest.hours; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecd.md new file mode 100644 index 00000000000..2fc50c7aaba --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ecd.md @@ -0,0 +1,99 @@ +--- +id: 691f7773cddba1caf1bf5ecd +title: "Challenge 134: Traveling Shopper" +challengeType: 28 +dashedName: challenge-134 +--- + +# --description-- + +Given an amount of money you have, and an array of items you want to buy, determine how many of them you can afford. + +- The given amount will be in the format `["Amount", "Currency Code"]`. For example: `["150.00", "USD"]` or `["6000", "JPY"]`. +- Each array item you want to purchase will be in the same format. + +Use the following exchange rates to convert values: + +|Currency|1 Unit Equals| +|-|-| +|USD|1.00 USD| +|EUR|1.10 USD| +|GBP|1.25 USD| +|JPY|0.0070 USD| +|CAD|0.75 USD| + +- If you can afford all the items in the list, return `"Buy them all!"`. +- Otherwise, return `"Buy the first X items."`, where `X` is the number of items you can afford when purchased in the order given. + +# --hints-- + +`buyItems(["150.00", "USD"], [["50.00", "USD"], ["75.00", "USD"], ["30.00", "USD"]])` should return `"Buy the first 2 items."`. + +```js +assert.equal(buyItems(["150.00", "USD"], [["50.00", "USD"], ["75.00", "USD"], ["30.00", "USD"]]), "Buy the first 2 items."); +``` + +`buyItems(["200.00", "EUR"], [["50.00", "USD"], ["50.00", "USD"]])` should return `"Buy them all!"`. + +```js +assert.equal(buyItems(["200.00", "EUR"], [["50.00", "USD"], ["50.00", "USD"]]), "Buy them all!"); +``` + +`buyItems(["100.00", "CAD"], [["20.00", "USD"], ["15.00", "EUR"], ["10.00", "GBP"], ["6000", "JPY"], ["5.00", "CAD"], ["10.00", "USD"]])` should return `"Buy the first 3 items."`. + +```js +assert.equal(buyItems(["100.00", "CAD"], [["20.00", "USD"], ["15.00", "EUR"], ["10.00", "GBP"], ["6000", "JPY"], ["5.00", "CAD"], ["10.00", "USD"]]), "Buy the first 3 items."); +``` + +`buyItems(["5000", "JPY"], [["3.00", "USD"], ["1000", "JPY"], ["5.00", "CAD"], ["2.00", "EUR"], ["4.00", "USD"], ["2000", "JPY"]])` should return `"Buy them all!"`. + +```js +assert.equal(buyItems(["5000", "JPY"], [["3.00", "USD"], ["1000", "JPY"], ["5.00", "CAD"], ["2.00", "EUR"], ["4.00", "USD"], ["2000", "JPY"]]), "Buy them all!"); +``` + +`buyItems(["200.00", "USD"], [["50.00", "USD"], ["40.00", "EUR"], ["30.00", "GBP"], ["5000", "JPY"], ["25.00", "CAD"], ["20.00", "USD"]])` should return `"Buy the first 5 items."`. + +```js +assert.equal(buyItems(["200.00", "USD"], [["50.00", "USD"], ["40.00", "EUR"], ["30.00", "GBP"], ["5000", "JPY"], ["25.00", "CAD"], ["20.00", "USD"]]), "Buy the first 5 items."); +``` + +# --seed-- + +## --seed-contents-- + +```js +function buyItems(funds, items) { + + return funds; +} +``` + +# --solutions-- + +```js +function buyItems(funds, items) { + const rates = { + USD: 1.00, + EUR: 1.10, + GBP: 1.25, + JPY: 0.0070, + CAD: 0.75 + }; + + const [amount, currency] = funds; + let money = parseFloat(amount) * rates[currency]; + + for (let i = 0; i < items.length; i++) { + const [itemAmount, itemCurrency] = items[i]; + const itemCostUSD = parseFloat(itemAmount) * rates[itemCurrency]; + + if (itemCostUSD > money) { + return `Buy the first ${i} items.`; + } + + money -= itemCostUSD; + } + + return "Buy them all!"; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ece.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ece.md new file mode 100644 index 00000000000..756dc8524dd --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/691f7773cddba1caf1bf5ece.md @@ -0,0 +1,81 @@ +--- +id: 691f7773cddba1caf1bf5ece +title: "Challenge 135: Re: Fwd: Fw: Count" +challengeType: 28 +dashedName: challenge-135 +--- + +# --description-- + +Given a string representing the subject line of an email, determine how many times the email has been forwarded or replied to. + +For simplicity, consider an email forwarded or replied to if the string contains any of the following markers (case-insensitive): + +- `"fw:"` +- `"fwd:"` +- `"re:"` + +Return the total number of occurrences of these markers. + +# --hints-- + +`emailChainCount("Re: Meeting Notes")` should return `1`. + +```js +assert.equal(emailChainCount("Re: Meeting Notes"), 1); +``` + +`emailChainCount("Meeting Notes")` should return `0`. + +```js +assert.equal(emailChainCount("Meeting Notes"), 0); +``` + +`emailChainCount("Re: re: RE: rE: Meeting Notes")` should return `4`. + +```js +assert.equal(emailChainCount("Re: re: RE: rE: Meeting Notes"), 4); +``` + +`emailChainCount("Re: Fwd: Re: Fw: Re: Meeting Notes")` should return `5`. + +```js +assert.equal(emailChainCount("Re: Fwd: Re: Fw: Re: Meeting Notes"), 5); +``` + +`emailChainCount("re:Ref:fw:re:review:FW:Re:fw:report:Re:FW:followup:re:summary:Fwd:Re:fw:NextStep:RE:FW:re:Project:Fwd:Re:fw:Notes:RE:re:Update:FWD:Re:fw:Summary")` should return `23`. + +```js +assert.equal(emailChainCount("re:Ref:fw:re:review:FW:Re:fw:report:Re:FW:followup:re:summary:Fwd:Re:fw:NextStep:RE:FW:re:Project:Fwd:Re:fw:Notes:RE:re:Update:FWD:Re:fw:Summary"), 23); +``` + +# --seed-- + +## --seed-contents-- + +```js +function emailChainCount(subject) { + + return subject; +} +``` + +# --solutions-- + +```js +function emailChainCount(subject) { + const markers = ["re:", "fwd:", "fw:"]; + const lower = subject.toLowerCase(); + let count = 0; + + for (const marker of markers) { + let index = 0; + while ((index = lower.indexOf(marker, index)) !== -1) { + count++; + index += marker.length; + } + } + + return count; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1a.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1a.md new file mode 100644 index 00000000000..bdaae54f4a1 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1a.md @@ -0,0 +1,67 @@ +--- +id: 6925e2068081f40f549ced1a +title: "Challenge 136: Markdown Image Parser" +challengeType: 28 +dashedName: challenge-136 +--- + +# --description-- + +Given a string of an image in Markdown, return the equivalent HTML string. + +A Markdown image has the following format: `"![alt text](image_url)"`. Where: + +- `alt text` is the description of the image (the `alt` attribute value). +- `image_url` is the source URL of the image (the `src` attribute value). + +Return a string of the HTML `img` tag with the `src` set to the image URL and the `alt` set to the alt text. + +For example, given `"![Cute cat](cat.png)"` return `'Cute cat'`; + +- Make sure the tag, order of attributes, spacing, and quote usage is the same as above. + +Note: The console may not display HTML tags in strings when logging messages — check the browser console to see logs with tags included. + +# --hints-- + +`parseImage("![Cute cat](cat.png)")` should return `'Cute cat'`. + +```js +assert.equal(parseImage("![Cute cat](cat.png)"), 'Cute cat'); +``` + +`parseImage("![Rocket Ship](https://freecodecamp.org/cdn/rocket-ship.jpg)")` should return `'Rocket Ship'`. + +```js +assert.equal(parseImage("![Rocket Ship](https://freecodecamp.org/cdn/rocket-ship.jpg)"), 'Rocket Ship'); +``` + +`parseImage("![Cute cats!](https://freecodecamp.org/cats.jpeg)")` should return `'Cute cats!'`. + +```js +assert.equal(parseImage("![Cute cats!](https://freecodecamp.org/cats.jpeg)"), 'Cute cats!'); +``` + +# --seed-- + +## --seed-contents-- + +```js +function parseImage(markdown) { + + return markdown; +} +``` + +# --solutions-- + +```js +function parseImage(markdown) { + const regex = /!\[(.*?)\]\((.*?)\)/; + const match = markdown.match(regex); + if (!match) return ""; + const alt = match[1]; + const src = match[2]; + return `${alt}`; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1b.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1b.md new file mode 100644 index 00000000000..8ea36a05b3a --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1b.md @@ -0,0 +1,88 @@ +--- +id: 6925e2068081f40f549ced1b +title: "Challenge 137: Snowflake Generator" +challengeType: 28 +dashedName: challenge-137 +--- + +# --description-- + +Given a multi-line string that uses newline characters (`\n`) to represent a line break, return a new string where each line is mirrored horizontally and attached to the end of the original line. + +- Mirror a line by reversing all of its characters, including spaces. + +For example, given `"* \n *\n* "`, which logs to the console as: + +```sh +* + * +* +``` + +Return `"* *\n ** \n* *"`, which logs to the console as: + +```sh +* * + ** +* * +``` + +Take careful note of the whitespaces in the given and returned strings. Be sure not to trim any of them. + +# --hints-- + +`generateSnowflake("* \n *\n* ")` should return `"* *\n ** \n* *"`. + +```js +assert.equal(generateSnowflake("* \n *\n* "), "* *\n ** \n* *"); +``` + +`generateSnowflake("X=~")` should return `"X=~~=X"`. + +```js +assert.equal(generateSnowflake("X=~"), "X=~~=X"); +``` + +`generateSnowflake(" X \n v \nX--=\n ^ \n X ")` should return `" X X \n v v \nX--==--X\n ^ ^ \n X X "`. + +```js +assert.equal(generateSnowflake(" X \n v \nX--=\n ^ \n X "), " X X \n v v \nX--==--X\n ^ ^ \n X X "); +``` + +`generateSnowflake("* *\n * * \n* * *\n * * \n* *")` should return `"* ** *\n * * * * \n* * ** * *\n * * * * \n* ** *"`. + +```js +assert.equal(generateSnowflake("* *\n * * \n* * *\n * * \n* *"), "* ** *\n * * * * \n* * ** * *\n * * * * \n* ** *"); +``` + +`generateSnowflake("* -\n * -\n* -")` should return `"* -- *\n * -- * \n* -- *"`. + +```js +assert.equal(generateSnowflake("* -\n * -\n* -"), "* -- *\n * -- * \n* -- *"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function generateSnowflake(crystals) { + + return crystals; +} +``` + +# --solutions-- + +```js +function generateSnowflake(crystals) { + const lines = crystals.split("\n"); + + const mirroredLines = lines.map(line => { + const reversed = line.split("").reverse().join(""); + return line + reversed; + }); + + return mirroredLines.join("\n"); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1c.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1c.md new file mode 100644 index 00000000000..4d04bf9bb7b --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1c.md @@ -0,0 +1,78 @@ +--- +id: 6925e2068081f40f549ced1c +title: "Challenge 138: Sum of Divisors" +challengeType: 28 +dashedName: challenge-138 +--- + +# --description-- + +Given a positive integer, return the sum of all its divisors. + +- A divisor is any integer that divides the number evenly (the remainder is `0`). +- Only count each divisor once. + +For example, given `6`, return `12` because the divisors of `6` are `1`, `2`, `3`, and `6`, and the sum of those is `12`. + +# --hints-- + +`sumDivisors(6)` should return `12`. + +```js +assert.equal(sumDivisors(6), 12); +``` + +`sumDivisors(13)` should return `14`. + +```js +assert.equal(sumDivisors(13), 14); +``` + +`sumDivisors(28)` should return `56`. + +```js +assert.equal(sumDivisors(28), 56); +``` + +`sumDivisors(84)` should return `224`. + +```js +assert.equal(sumDivisors(84), 224); +``` + +`sumDivisors(549)` should return `806`. + +```js +assert.equal(sumDivisors(549), 806); +``` + +`sumDivisors(9348)` should return `23520`. + +```js +assert.equal(sumDivisors(9348), 23520); +``` + +# --seed-- + +## --seed-contents-- + +```js +function sumDivisors(n) { + + return n; +} +``` + +# --solutions-- + +```js +function sumDivisors(n) { + let sum = 0; + for (let i = 1; i <= n; i++) { + if (n % i === 0) { + sum += i; + } + } + return sum; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1d.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1d.md new file mode 100644 index 00000000000..b2747d092d8 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/6925e2068081f40f549ced1d.md @@ -0,0 +1,88 @@ +--- +id: 6925e2068081f40f549ced1d +title: "Challenge 139: Rock, Paper, Scissors" +challengeType: 28 +dashedName: challenge-139 +--- + +# --description-- + +Given two strings, the first representing Player 1 and the second representing Player 2, determine the winner of a match of Rock, Paper, Scissors. + +- The input strings will always be `"Rock"`, `"Paper"`, or `"Scissors"`. +- `"Rock"` beats `"Scissors"`. +- `"Paper"` beats `"Rock"`. +- `"Scissors"` beats `"Paper"`. + +Return: + +- `"Player 1 wins"` if Player 1 wins. +- `"Player 2 wins"` if Player 2 wins. +- `"Tie"` if both players choose the same option. + +# --hints-- + +`rockPaperScissors("Rock", "Rock")` should return `"Tie"`. + +```js +assert.equal(rockPaperScissors("Rock", "Rock"), "Tie"); +``` + +`rockPaperScissors("Rock", "Paper")` should return `"Player 2 wins"`. + +```js +assert.equal(rockPaperScissors("Rock", "Paper"), "Player 2 wins"); +``` + +`rockPaperScissors("Scissors", "Paper")` should return `"Player 1 wins"`. + +```js +assert.equal(rockPaperScissors("Scissors", "Paper"), "Player 1 wins"); +``` + +`rockPaperScissors("Rock", "Scissors")` should return `"Player 1 wins"`. + +```js +assert.equal(rockPaperScissors("Rock", "Scissors"), "Player 1 wins"); +``` + +`rockPaperScissors("Scissors", "Scissors")` should return `"Tie"`. + +```js +assert.equal(rockPaperScissors("Scissors", "Scissors"), "Tie"); +``` + +`rockPaperScissors("Scissors", "Rock")` should return `"Player 2 wins"`. + +```js +assert.equal(rockPaperScissors("Scissors", "Rock"), "Player 2 wins"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function rockPaperScissors(player1, player2) { + + return player1; +} +``` + +# --solutions-- + +```js +function rockPaperScissors(player1, player2) { + if (player1 === player2) return "Tie"; + + if ( + (player1 === "Rock" && player2 === "Scissors") || + (player1 === "Paper" && player2 === "Rock") || + (player1 === "Scissors" && player2 === "Paper") + ) { + return "Player 1 wins"; + } else { + return "Player 2 wins"; + } +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c3.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c3.md new file mode 100644 index 00000000000..1d9e6db93fe --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c3.md @@ -0,0 +1,78 @@ +--- +id: 69272dcf1c24b44fd79137c3 +title: "Challenge 140: SCREAMING_SNAKE_CASE" +challengeType: 28 +dashedName: challenge-140 +--- + +# --description-- + +Given a string representing a variable name, return the variable name converted to SCREAMING_SNAKE_CASE. + +The given variable names will be written in one of the following formats: + +- `camelCase` +- `PascalCase` +- `snake_case` +- `kebab-case` + +In the above formats, words are separated by an underscore (`_`), a hyphen (`-`), or a new word starts with a capital letter. + +To convert to SCREAMING_SNAKE_CASE: + +- Make all letters uppercase +- Separate words with an underscore (`_`) + +# --hints-- + +`toScreamingSnakeCase("userEmail")` should return `"USER_EMAIL"`. + +```js +assert.equal(toScreamingSnakeCase("userEmail"), "USER_EMAIL"); +``` + +`toScreamingSnakeCase("UserPassword")` should return `"USER_PASSWORD"`. + +```js +assert.equal(toScreamingSnakeCase("UserPassword"), "USER_PASSWORD"); +``` + +`toScreamingSnakeCase("user_id")` should return `"USER_ID"`. + +```js +assert.equal(toScreamingSnakeCase("userEmail"), "USER_EMAIL"); +``` + +`toScreamingSnakeCase("user-address")` should return `"USER_ADDRESS"`. + +```js +assert.equal(toScreamingSnakeCase("user-address"), "USER_ADDRESS"); +``` + +`toScreamingSnakeCase("username")` should return `"USERNAME"`. + +```js +assert.equal(toScreamingSnakeCase("username"), "USERNAME"); +``` + +# --seed-- + +## --seed-contents-- + +```js +function toScreamingSnakeCase(variableName) { + + return variableName; +} +``` + +# --solutions-- + +```js +function toScreamingSnakeCase(variableName) { + let temp = variableName.replace(/[-_]+/g, ' '); + temp = temp.replace(/([a-z0-9])([A-Z])/g, '$1 $2'); + const words = temp.trim().split(/\s+/); + return words.join('_').toUpperCase();; +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c4.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c4.md new file mode 100644 index 00000000000..e2b8f5ced98 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c4.md @@ -0,0 +1,70 @@ +--- +id: 69272dcf1c24b44fd79137c4 +title: "Challenge 141: Takeoff Fuel" +challengeType: 28 +dashedName: challenge-141 +--- + +# --description-- + +Given the numbers of gallons of fuel currently in your airplane, and the required number of liters of fuel to reach your destination, determine how many additional gallons of fuel you should add. + +- 1 gallon equals 3.78541 liters. +- If the airplane already has enough fuel, return `0`. +- You can only add whole gallons. +- Do not include decimals in the return number. + +# --hints-- + +`fuelToAdd(0, 1)` should return `1`. + +```js +assert.equal(fuelToAdd(0, 1), 1); +``` + +`fuelToAdd(5, 40)` should return `6`. + +```js +assert.equal(fuelToAdd(5, 40), 6); +``` + +`fuelToAdd(10, 30)` should return `0`. + +```js +assert.equal(fuelToAdd(10, 30), 0); +``` + +`fuelToAdd(896, 20500)` should return `4520`. + +```js +assert.equal(fuelToAdd(896, 20500), 4520); +``` + +`fuelToAdd(1000, 50000)` should return `12209`. + +```js +assert.equal(fuelToAdd(1000, 50000), 12209); +``` + +# --seed-- + +## --seed-contents-- + +```js +function fuelToAdd(currentGallons, requiredLiters) { + + return currentGallons; +} +``` + +# --solutions-- + +```js +function fuelToAdd(currentGallons, requiredLiters) { + const litersPerGallon = 3.78541; + const currentLiters = currentGallons * litersPerGallon; + if (currentLiters >= requiredLiters) return 0; + const litersNeeded = requiredLiters - currentLiters; + return Math.ceil(litersNeeded / litersPerGallon); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c5.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c5.md new file mode 100644 index 00000000000..b1119b7c11e --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c5.md @@ -0,0 +1,65 @@ +--- +id: 69272dcf1c24b44fd79137c5 +title: "Challenge 142: Sum the String" +challengeType: 28 +dashedName: challenge-142 +--- + +# --description-- + +Given a string containing digits and other characters, return the sum of all numbers in the string. + +- Treat consecutive digits as a single number. For example, `"13"` counts as 13, not 1 + 3. +- Ignore any non-digit characters. + +# --hints-- + +`stringSum("3apples2bananas")` should return `5`. + +```js +assert.equal(stringSum("3apples2bananas"), 5); +``` + +`stringSum("10cats5dogs2birds")` should return `17`. + +```js +assert.equal(stringSum("10cats5dogs2birds"), 17); +``` + +`stringSum("125344")` should return `125344`. + +```js +assert.equal(stringSum("125344"), 125344); +``` + +`stringSum("a1b20c300")` should return `321`. + +```js +assert.equal(stringSum("a1b20c300"), 321); +``` + +`stringSum("a12b34c56d78e90f123g456h789i0j1k2l3m4n5")` should return `1653`. + +```js +assert.equal(stringSum("a12b34c56d78e90f123g456h789i0j1k2l3m4n5"), 1653); +``` + +# --seed-- + +## --seed-contents-- + +```js +function stringSum(str) { + + return arg; +} +``` + +# --solutions-- + +```js +function stringSum(str) { + const matches = str.match(/\d+/g); // find all consecutive digits + return matches.reduce((sum, num) => sum + Number(num), 0); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c6.md b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c6.md new file mode 100644 index 00000000000..d23917a95bb --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-javascript/69272dcf1c24b44fd79137c6.md @@ -0,0 +1,69 @@ +--- +id: 69272dcf1c24b44fd79137c6 +title: "Challenge 143: Markdown Italic Parser" +challengeType: 28 +dashedName: challenge-143 +--- + +# --description-- + +Given a string that may include some italic text in Markdown, return the equivalent HTML string. + +- Italic text in Markdown is any text that starts and ends with a single asterisk (`*`) or a single underscore (`_`). +- There cannot be any spaces between the text and the asterisk or underscore, but there can be spaces in the text itself. +- Convert all italic occurrences to HTML `i` tags and return the string. + +For example, given `"*This is italic*"`, return `"This is italic"`. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parseItalic("*This is italic*")` should return `"This is italic"`. + +```js +assert.equal(parseItalics("*This is italic*"), "This is italic"); +``` + +`parseItalic("_This is also italic_")` should return `"This is also italic"`. + +```js +assert.equal(parseItalics("_This is also italic_"), "This is also italic"); +``` + +`parseItalic("*This is not italic *")` should return `"*This is not italic *"`. + +```js +assert.equal(parseItalics("*This is not italic *"), "*This is not italic *"); +``` + +`parseItalic("_ This is also not italic_")` should return `"_ This is also not italic_"`. + +```js +assert.equal(parseItalics("_ This is also not italic_"), "_ This is also not italic_"); +``` + +`parseItalic("The *quick* brown fox _jumps_ over the *lazy* dog.")` should return `"The quick brown fox jumps over the lazy dog."`. + +```js +assert.equal(parseItalics("The *quick* brown fox _jumps_ over the *lazy* dog."), "The quick brown fox jumps over the lazy dog."); +``` + +# --seed-- + +## --seed-contents-- + +```js +function parseItalics(markdown) { + + return markdown; +} +``` + +# --solutions-- + +```js +function parseItalics(markdown) { + return markdown.replace(/(\*|_)([^\s][^]*?[^\s])\1/g, '$2'); +} +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629efe.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629efe.md index 8955a3a1b0b..1ad10919a7e 100644 --- a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629efe.md +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629efe.md @@ -12,6 +12,7 @@ Given a distance in miles as a number, return the equivalent distance in kilomet - The input will always be a non-negative number. - 1 mile equals 1.60934 kilometers. - Round the result to two decimal places. +- Remove unnecessary trailing zeros from the rounded result. # --hints-- diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629f00.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629f00.md index 9ea9725d711..b3e8de2c697 100644 --- a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629f00.md +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69162d64f96574d9bb629f00.md @@ -18,7 +18,7 @@ A valid ordered list item in Markdown must: If the string doesn't have the exact format above, return `"Invalid format"`. Otherwise, wrap the list item text in `li` tags and return the string. -For example, given `"1. My item"`, return `"
  • My item
  • "` +For example, given `"1. My item"`, return `"
  • My item
  • "`. Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b480.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b480.md new file mode 100644 index 00000000000..b4faa036234 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b480.md @@ -0,0 +1,86 @@ +--- +id: 691b559495c5cb5a37b9b480 +title: "Challenge 120: Pounds to Kilograms" +challengeType: 29 +dashedName: challenge-120 +--- + +# --description-- + +Given a weight in pounds as a number, return the string `"(lbs) pounds equals (kgs) kilograms."`. + +- Replace `"(lbs)"` with the input number. +- Replace `"(kgs)"` with the input converted to kilograms, rounded to two decimals and always include two decimal places in the value. +- 1 pound equals 0.453592 kilograms. +- If the input is `1`, use `"pound"` instead of `"pounds"`. +- If the converted value is `1`, use `"kilogram"` instead of `"kilograms"`. + +# --hints-- + +`convert_to_kgs(1)` should return `"1 pound equals 0.45 kilograms."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(convert_to_kgs(1), "1 pound equals 0.45 kilograms.")`) +}}) +``` + +`convert_to_kgs(0)` should return `"0 pounds equals 0.00 kilograms."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(convert_to_kgs(0), "0 pounds equals 0.00 kilograms.")`) +}}) +``` + +`convert_to_kgs(100)` should return `"100 pounds equals 45.36 kilograms."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(convert_to_kgs(100), "100 pounds equals 45.36 kilograms.")`) +}}) +``` + +`convert_to_kgs(2.5)` should return `"2.5 pounds equals 1.13 kilograms."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(convert_to_kgs(2.5), "2.5 pounds equals 1.13 kilograms.")`) +}}) +``` + +`convert_to_kgs(2.20462)` should return `"2.20462 pounds equals 1.00 kilogram."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(convert_to_kgs(2.20462), "2.20462 pounds equals 1.00 kilogram.")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def convert_to_kgs(lbs): + + return lbs +``` + +# --solutions-- + +```py +def convert_to_kgs(lbs): + KG_PER_POUND = 0.453592 + kgs = f"{lbs * KG_PER_POUND:.2f}" + + pound_word = "pound" if lbs == 1 else "pounds" + kilogram_word = "kilogram" if kgs == "1.00" else "kilograms" + + return f"{lbs} {pound_word} equals {kgs} {kilogram_word}." +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b481.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b481.md new file mode 100644 index 00000000000..d2aa811a691 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b481.md @@ -0,0 +1,77 @@ +--- +id: 691b559495c5cb5a37b9b481 +title: "Challenge 121: Most Frequent" +challengeType: 29 +dashedName: challenge-121 +--- + +# --description-- + +Given an array of elements, return the element that appears most frequently. + +- There will always be a single most frequent element. + +# --hints-- + +`most_frequent(["a", "b", "a", "c"])` should return `"a"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(most_frequent(["a", "b", "a", "c"]), "a")`) +}}) +``` + +`most_frequent([2, 3, 5, 2, 6, 3, 2, 7, 2, 9])` should return `2`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(most_frequent([2, 3, 5, 2, 6, 3, 2, 7, 2, 9]), 2)`) +}}) +``` + +`most_frequent([True, False, "False", "True", False])` should return `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(most_frequent([True, False, "False", "True", False]), False)`) +}}) +``` + +`most_frequent([40, 20, 70, 30, 10, 40, 10, 50, 40, 60])` should return `40`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(most_frequent([40, 20, 70, 30, 10, 40, 10, 50, 40, 60]), 40)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def most_frequent(arr): + + return arr +``` + +# --solutions-- + +```py +def most_frequent(arr): + freq = {} + max_count = 0 + most_elem = None + + for el in arr: + freq[el] = freq.get(el, 0) + 1 + if freq[el] > max_count: + max_count = freq[el] + most_elem = el + + return most_elem +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b482.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b482.md new file mode 100644 index 00000000000..6562f96bf6e --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b482.md @@ -0,0 +1,87 @@ +--- +id: 691b559495c5cb5a37b9b482 +title: "Challenge 122: Markdown Bold Parser" +challengeType: 29 +dashedName: challenge-122 +--- + +# --description-- + +Given a string that may include some bold text in Markdown, return the equivalent HTML string. + +- Bold text in Markdown is any text that starts and ends with two asterisks (`**`) or two underscores (`__`). +- There cannot be any spaces between the text and the asterisks or underscores, but there can be + spaces in the text itself. +- Convert all bold occurrences to HTML `b` tags and return the string. + +For example, given `"**This is bold**"`, return `"This is bold"`. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parse_bold("**This is bold**")` should return `"This is bold"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_bold("**This is bold**"), "This is bold")`) +}}) +``` + +`parse_bold("__This is also bold__")` should return `"This is also bold"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_bold("__This is also bold__"), "This is also bold")`) +}}) +``` + +`parse_bold("**This is not bold **")` should return `"**This is not bold **"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_bold("**This is not bold **"), "**This is not bold **")`) +}}) +``` + +`parse_bold("__ This is also not bold__")` should return `"__ This is also not bold__"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_bold("__ This is also not bold__"), "__ This is also not bold__")`) +}}) +``` + +`parse_bold("The **quick** brown fox __jumps__ over the **lazy** dog.")` should return `"The quick brown fox jumps over the lazy dog."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_bold("The **quick** brown fox __jumps__ over the **lazy** dog."), "The quick brown fox jumps over the lazy dog.")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def parse_bold(markdown): + + return markdown +``` + +# --solutions-- + +```py +import re +def parse_bold(markdown): + markdown = re.sub(r'\*\*(\S(?:.*?\S)?)\*\*', r'\1', markdown) + markdown = re.sub(r'__(\S(?:.*?\S)?)__', r'\1', markdown) + + return markdown +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b483.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b483.md new file mode 100644 index 00000000000..f95c57c701d --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b483.md @@ -0,0 +1,115 @@ +--- +id: 691b559495c5cb5a37b9b483 +title: "Challenge 123: Roman Numeral Builder" +challengeType: 29 +dashedName: challenge-123 +--- + +# --description-- + +Given an integer, return its equivalent value in Roman numerals. + +Roman numerals use these symbols: + +| Symbol | Value | +| ------ | ----- | +| I | 1 | +| V | 5 | +| X | 10 | +| L | 50 | +| C | 100 | +| D | 500 | +| M | 1000 | + +Roman numerals are written from largest to smallest, left to right using the following rules: + +- Addition is used when a symbol is followed by one of equal or smaller value. For example, `18` is written as `XVIII` (10 + 5 + 1 + 1 + 1 = 18). +- Subtraction is used when a smaller symbol appears before a larger one, to represent 4 or 9 in any place value. For example, 19 is written as `XIX` (10 + (10 - 1)). +- No symbol may be repeated more than three times in a row. Subtraction is used when you would otherwise need to write a symbol more than three times in a row. So the largest number you can write is 3999. + +Here's one more example: given `1464`, return `"MCDLXIV"` (1000 + (500 - 100) + 50 + 10 + (5 - 1)). + +# --hints-- + +`to_roman(18)` should return `"XVIII"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_roman(18), "XVIII")`) +}}) +``` + +`to_roman(19)` should return `"XIX"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_roman(19), "XIX")`) +}}) +``` + +`to_roman(1464)` should return `"MCDLXIV"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_roman(1464), "MCDLXIV")`) +}}) +``` + +`to_roman(2025)` should return `"MMXXV"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_roman(2025), "MMXXV")`) +}}) +``` + +`to_roman(3999)` should return `"MMMCMXCIX"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_roman(3999), "MMMCMXCIX")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def to_roman(num): + + return num +``` + +# --solutions-- + +```py +def to_roman(num): + symbols = [ + ("M", 1000), + ("CM", 900), + ("D", 500), + ("CD", 400), + ("C", 100), + ("XC", 90), + ("L", 50), + ("XL", 40), + ("X", 10), + ("IX", 9), + ("V", 5), + ("IV", 4), + ("I", 1) + ] + + result = "" + for sym, val in symbols: + while num >= val: + result += sym + num -= val + return result +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b484.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b484.md new file mode 100644 index 00000000000..89f8ecc08a0 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b484.md @@ -0,0 +1,82 @@ +--- +id: 691b559495c5cb5a37b9b484 +title: "Challenge 124: Inventory Update" +challengeType: 29 +dashedName: challenge-124 +--- + +# --description-- + +Given a 2D array representing the inventory of your store, and another 2D array representing a shipment you have received, return your updated inventory. + +- Each element in the arrays will have the format: `[quantity, "item"]`, where `quantity` is an integer and `"item"` is a string. +- Update items in the inventory by adding the quantity of any matching items from the shipment. +- If a received item does not exist in the current inventory, add it as a new entry to the end of the inventory. +- Return inventory in the order it was given with new items at the end in the order they appear in the shipment. + +For example, given an inventory of `[[2, "apples"], [5, "bananas"]]` and a shipment of `[[1, "apples"], [3, "bananas"]]`, return `[[3, "apples"], [8, "bananas"]]`. + +# --hints-- + +`update_inventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"]])` should return `[[3, "apples"], [8, "bananas"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(update_inventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"]]), [[3, "apples"], [8, "bananas"]])`) +}}) +``` + +`update_inventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"], [4, "oranges"]])` should return `[[3, "apples"], [8, "bananas"], [4, "oranges"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(update_inventory([[2, "apples"], [5, "bananas"]], [[1, "apples"], [3, "bananas"], [4, "oranges"]]), [[3, "apples"], [8, "bananas"], [4, "oranges"]])`) +}}) +``` + +`update_inventory([], [[10, "apples"], [30, "bananas"], [20, "oranges"]])` should return `[[10, "apples"], [30, "bananas"], [20, "oranges"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(update_inventory([], [[10, "apples"], [30, "bananas"], [20, "oranges"]]), [[10, "apples"], [30, "bananas"], [20, "oranges"]])`) +}}) +``` + +`update_inventory([[0, "Bowling Ball"], [0, "Dirty Socks"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]])` should return `[[1, "Bowling Ball"], [0, "Dirty Socks"], [1, "Hair Pin"], [0, "Microphone"], [1, "Half-Eaten Apple"], [1, "Toothpaste"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(update_inventory([[0, "Bowling Ball"], [0, "Dirty Socks"], [0, "Hair Pin"], [0, "Microphone"]], [[1, "Hair Pin"], [1, "Half-Eaten Apple"], [1, "Bowling Ball"], [1, "Toothpaste"]]), [[1, "Bowling Ball"], [0, "Dirty Socks"], [1, "Hair Pin"], [0, "Microphone"], [1, "Half-Eaten Apple"], [1, "Toothpaste"]])`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def update_inventory(inventory, shipment): + + return inventory +``` + +# --solutions-- + +```py +def update_inventory(inventory, shipment): + inventory_map = {item: i for i, (qty, item) in enumerate(inventory)} + + for qty, item in shipment: + if item in inventory_map: + index = inventory_map[item] + inventory[index][0] += qty + else: + inventory.append([qty, item]) + inventory_map[item] = len(inventory) - 1 + + return inventory +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b485.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b485.md new file mode 100644 index 00000000000..7d0932c4b31 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b485.md @@ -0,0 +1,121 @@ +--- +id: 691b559495c5cb5a37b9b485 +title: "Challenge 125: Game of Life" +challengeType: 29 +dashedName: challenge-125 +--- + +# --description-- + +Given a matrix (array of arrays) representing the current state in Conway's Game of Life, return the next state of the matrix using these rules: + +- Each cell is either `1` (alive) or `0` (dead). +- A cell's neighbors are the up to eight surrounding cells (vertically, horizontally, and diagonally). +- Cells on the edges have fewer than eight neighbors. + +Rules for updating each cell: + +- Any live cell with fewer than two live neighbors dies (underpopulation). +- Any live cell with two or three live neighbors lives on. +- Any live cell with more than three live neighbors dies (overpopulation). +- Any dead cell with exactly three live neighbors becomes alive (reproduction). + +For example, given: + +```json +[ + [0, 1, 0], + [0, 1, 1], + [1, 1, 0] +] +``` + +return: + +```json +[ + [0, 1, 1], + [0, 0, 1], + [1, 1, 1] +] +``` + +Each cell updates according to the number of live neighbors. For instance, `[0][0]` stays dead (2 live neighbors), `[0][1]` stays alive (2 live neighbors), `[0][2]` dies (3 live neighbors), and so on. + +# --hints-- + +`game_of_life([[0, 1, 0], [0, 1, 1], [1, 1, 0]])` should return `[[0, 1, 1], [0, 0, 1], [1, 1, 1]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(game_of_life([[0, 1, 0], [0, 1, 1], [1, 1, 0]]), [[0, 1, 1], [0, 0, 1], [1, 1, 1]])`) +}}) +``` + +`game_of_life([[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 1], [0, 0, 1, 0]])` should return `[[1, 1, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1], [0, 1, 1, 1]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(game_of_life([[1, 1, 0, 0], [1, 0, 1, 0], [0, 1, 1, 1], [0, 0, 1, 0]]), [[1, 1, 0, 0], [1, 0, 0, 1], [0, 0, 0, 1], [0, 1, 1, 1]])`) +}}) +``` + +`game_of_life([[1, 0, 0], [0, 1, 0], [0, 0, 1]])` should return `[[0, 0, 0], [0, 1, 0], [0, 0, 0]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(game_of_life([[1, 0, 0], [0, 1, 0], [0, 0, 1]]), [[0, 0, 0], [0, 1, 0], [0, 0, 0]])`) +}}) +``` + +`game_of_life([[0, 1, 1, 0], [1, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0]])` should return `[[1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(game_of_life([[0, 1, 1, 0], [1, 1, 0, 1], [0, 1, 1, 0], [0, 0, 1, 0]]), [[1, 1, 1, 0], [1, 0, 0, 1], [1, 0, 0, 1], [0, 1, 1, 0]])`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def game_of_life(grid): + + return grid +``` + +# --solutions-- + +```py +def game_of_life(grid): + rows, cols = len(grid), len(grid[0]) + + def count_live_neighbors(r, c): + count = 0 + for i in range(r-1, r+2): + for j in range(c-1, c+2): + if 0 <= i < rows and 0 <= j < cols and (i != r or j != c): + count += grid[i][j] + return count + + next_state = [row[:] for row in grid] + + for r in range(rows): + for c in range(cols): + live_neighbors = count_live_neighbors(r, c) + + if grid[r][c] == 1: + if live_neighbors < 2 or live_neighbors > 3: + next_state[r][c] = 0 + else: + if live_neighbors == 3: + next_state[r][c] = 1 + + return next_state +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b486.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b486.md new file mode 100644 index 00000000000..171f5aef333 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b486.md @@ -0,0 +1,72 @@ +--- +id: 691b559495c5cb5a37b9b486 +title: "Challenge 126: Capitalize It" +challengeType: 29 +dashedName: challenge-126 +--- + +# --description-- + +Given a string title, return a new string formatted in title case using the following rules: + +- Capitalize the first letter of each word. +- Make all other letters in each word lowercase. +- Words are always separated by a single space. + +# --hints-- + +`title_case("hello world")` should return `"Hello World"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(title_case("hello world"), "Hello World")`) +}}) +``` + +`title_case("the quick brown fox")` should return `"The Quick Brown Fox"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(title_case("the quick brown fox"), "The Quick Brown Fox")`) +}}) +``` + +`title_case("JAVASCRIPT AND PYTHON")` should return `"Javascript And Python"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(title_case("JAVASCRIPT AND PYTHON"), "Javascript And Python")`) +}}) +``` + +`title_case("AvOcAdO tOAst fOr brEAkfAst")` should return `"Avocado Toast For Breakfast"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(title_case("AvOcAdO tOAst fOr brEAkfAst"), "Avocado Toast For Breakfast")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def title_case(title): + + return title +``` + +# --solutions-- + +```py +def title_case(title): + return " ".join( + w[:1].upper() + w[1:].lower() + for w in title.split(" ") + ) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b487.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b487.md new file mode 100644 index 00000000000..99e4091fd39 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b487.md @@ -0,0 +1,98 @@ +--- +id: 691b559495c5cb5a37b9b487 +title: "Challenge 127: Speed Check" +challengeType: 29 +dashedName: challenge-127 +--- + +# --description-- + +Given the speed you are traveling in miles per hour (MPH), and a speed limit in kilometers per hour (KPH), determine whether you are speeding and if you will get a warning or a ticket. + +- 1 mile equals 1.60934 kilometers. +- If you are travelling less than or equal to the speed limit, return `"Not Speeding"`. +- If you are travelling 5 KPH or less over the speed limit, return `"Warning"`. +- If you are travelling more than 5 KPH over the speed limit, return `"Ticket"`. + +# --hints-- + +`speed_check(30, 70)` should return `"Not Speeding"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(30, 70), "Not Speeding")`) +}}) +``` + +`speed_check(40, 60)` should return `"Warning"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(40, 60), "Warning")`) +}}) +``` + +`speed_check(40, 65)` should return `"Not Speeding"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(40, 65), "Not Speeding")`) +}}) +``` + +`speed_check(60, 90)` should return `"Ticket"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(60, 90), "Ticket")`) +}}) +``` + +`speed_check(65, 100)` should return `"Warning"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(65, 100), "Warning")`) +}}) +``` + +`speed_check(88, 40)` should return `"Ticket"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(speed_check(88, 40), "Ticket")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def speed_check(speed_mph, speed_limit_kph): + + return speed_mph +``` + +# --solutions-- + +```py +def speed_check(speed_mph, speed_limit_kph): + speed_kph = speed_mph * 1.60934 + + if speed_kph <= speed_limit_kph: + return "Not Speeding" + + over = speed_kph - speed_limit_kph + + if over <= 5: + return "Warning" + + return "Ticket" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b488.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b488.md new file mode 100644 index 00000000000..f6cbaf2b1c6 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b488.md @@ -0,0 +1,84 @@ +--- +id: 691b559495c5cb5a37b9b488 +title: "Challenge 128: Consonant Count" +challengeType: 29 +dashedName: challenge-128 +--- + +# --description-- + +Given a string and a target number, determine whether the string contains exactly the target number of consonants. + +- Consonants are all alphabetic characters except `"a"`, `"e"`, `"i"`, `"o"`, and `"u"` in any case. +- Ignore digits, punctuation, spaces, and other non-letter characters when counting. + +# --hints-- + +`has_consonant_count("helloworld", 7)` should return `True`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(has_consonant_count("helloworld", 7), True)`) +}}) +``` + +`has_consonant_count("eieio", 5)` should return `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(has_consonant_count("eieio", 5), False)`) +}}) +``` + +`has_consonant_count("freeCodeCamp Rocks!", 11)` should return `True`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(has_consonant_count("freeCodeCamp Rocks!", 11), True)`) +}}) +``` + +`has_consonant_count("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 24)` should return `False`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(has_consonant_count("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 24), False)`) +}}) +``` + +`has_consonant_count("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 23)` should return `True`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertIs(has_consonant_count("Th3 Qu!ck Br0wn F0x Jump5 0ver Th3 L@zy D0g.", 23), True)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def has_consonant_count(text, target): + + return text +``` + +# --solutions-- + +```py +def has_consonant_count(text, target): + vowels = {"a", "e", "i", "o", "u"} + count = 0 + + for ch in text.lower(): + if ch.isalpha() and ch not in vowels: + count += 1 + + return count == target +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b489.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b489.md new file mode 100644 index 00000000000..11a3167445b --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b559495c5cb5a37b9b489.md @@ -0,0 +1,74 @@ +--- +id: 691b559495c5cb5a37b9b489 +title: "Challenge 129: Markdown Blockquote Parser" +challengeType: 29 +dashedName: challenge-129 +--- + +# --description-- + +Given a string that includes a blockquote in Markdown, return the equivalent HTML string. + +A blockquote in Markdown is any line that: + +- Starts with zero or more spaces +- Followed by a greater-than sign (`>`) +- Then, one or more spaces +- And finally, the blockquote text. + +Return the blockquote text surrounded by opening and closing HTML `blockquote` tags. + +For example, given `"> This is a quote"`, return `
    This is a quote
    `. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parse_blockquote("> This is a quote")` should return `"
    This is a quote
    "`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_blockquote("> This is a quote"), "
    This is a quote
    ")`) +}}) +``` + +`parse_blockquote(" > This is also a quote")` should return `"
    This is also a quote
    "`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_blockquote(" > This is also a quote"), "
    This is also a quote
    ")`) +}}) +``` + +`parse_blockquote(" > So Is This")` should return `"
    So Is This
    "`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_blockquote(" > So Is This"), "
    So Is This
    ")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def parse_blockquote(markdown): + + return markdown +``` + +# --solutions-- + +```py +import re +def parse_blockquote(markdown): + pattern = r"^\s*>\s+(.+)$" + match = re.match(pattern, markdown) + + text = match.group(1) + return f"
    {text}
    " +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b5597f0f3e85a588a5c94.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b5597f0f3e85a588a5c94.md new file mode 100644 index 00000000000..db0d436b6a4 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691b5597f0f3e85a588a5c94.md @@ -0,0 +1,87 @@ +--- +id: 691b5597f0f3e85a588a5c94 +title: "Challenge 130: Checkerboard" +challengeType: 29 +dashedName: challenge-130 +--- + +# --description-- + +Given an array with two numbers, the first being the number of rows and the second being the number of columns, return a matrix (an array of arrays) filled with `"X"` and `"O"` characters of the given size. + +- The characters should alternate like a checkerboard. +- The top-left cell must always be `"X"`. + +For example, given `[3, 3]`, return: + +```json +[ + ["X", "O", "X"], + ["O", "X", "O"], + ["X", "O", "X"] +] +``` + +# --hints-- + +`create_board([3, 3])` should return `[["X", "O", "X"], ["O", "X", "O"], ["X", "O", "X"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(create_board([3, 3]), [["X", "O", "X"], ["O", "X", "O"], ["X", "O", "X"]])`) +}}) +``` + +`create_board([6, 1])` should return `[["X"], ["O"], ["X"], ["O"], ["X"], ["O"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(create_board([6, 1]), [["X"], ["O"], ["X"], ["O"], ["X"], ["O"]])`) +}}) +``` + +`create_board([2, 10])` should return `[["X", "O", "X", "O", "X", "O", "X", "O", "X", "O"], ["O", "X", "O", "X", "O", "X", "O", "X", "O", "X"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(create_board([2, 10]), [["X", "O", "X", "O", "X", "O", "X", "O", "X", "O"], ["O", "X", "O", "X", "O", "X", "O", "X", "O", "X"]])`) +}}) +``` + +`create_board([5, 4])` should return `[["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"]]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(create_board([5, 4]), [["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"], ["O", "X", "O", "X"], ["X", "O", "X", "O"]])`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def create_board(dimensions): + + return dimensions +``` + +# --solutions-- + +```py +def create_board(dimensions): + rows, cols = dimensions + board = [] + + for r in range(rows): + row = [] + for c in range(cols): + row.append("X" if (r + c) % 2 == 0 else "O") + board.append(row) + + return board +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5eca.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5eca.md new file mode 100644 index 00000000000..f0304ca8bb0 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5eca.md @@ -0,0 +1,79 @@ +--- +id: 691f7773cddba1caf1bf5eca +title: "Challenge 131: Pairwise" +challengeType: 29 +dashedName: challenge-131 +--- + +# --description-- + +Given an array of integers and a target number, find all pairs of elements in the array whose values add up to the target and return the sum of their indices. + +For example, given `[2, 3, 4, 6, 8]` and `10`, you will find two valid pairs: + +- `2` and `8` (2 + 8 = 10), whose indices are `0` and `4` +- `4` and `6` (4 + 6 = 10), whose indices are `2` and `3` + +Add all the indices together to get a return value of `9`. + +# --hints-- + +`pairwise([2, 3, 4, 6, 8], 10)` should return `9`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(pairwise([2, 3, 4, 6, 8], 10), 9)`) +}}) +``` + +`pairwise([4, 1, 5, 2, 6, 3], 7)` should return `15`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(pairwise([4, 1, 5, 2, 6, 3], 7), 15)`) +}}) +``` + +`pairwise([-30, -15, 5, 10, 15, -5, 20, -40], -20)` should return `22`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(pairwise([-30, -15, 5, 10, 15, -5, 20, -40], -20), 22)`) +}}) +``` + +`pairwise([7, 9, 13, 19, 21, 6, 3, 1, 4, 8, 12, 22], 24)` should return `10`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(pairwise([7, 9, 13, 19, 21, 6, 3, 1, 4, 8, 12, 22], 24), 10)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def pairwise(arr, target): + + return arr +``` + +# --solutions-- + +```py +def pairwise(arr, target): + total = 0 + + for i in range(len(arr)): + for j in range(i + 1, len(arr)): + if arr[i] + arr[j] == target: + total += i + j + + return total +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecb.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecb.md new file mode 100644 index 00000000000..59404db1f28 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecb.md @@ -0,0 +1,75 @@ +--- +id: 691f7773cddba1caf1bf5ecb +title: "Challenge 132: Purge Most Frequent" +challengeType: 29 +dashedName: challenge-132 +--- + +# --description-- + +Given an array of values, remove all occurrences of the most frequently occurring element and return the resulting array. + +- If multiple values are tied for most frequent, remove all of them. +- Do not change any of the other elements or their order. + +# --hints-- + +`purge_most_frequent([1, 2, 2, 3])` should return `[1, 3]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(purge_most_frequent([1, 2, 2, 3]), [1, 3])`) +}}) +``` + +`purge_most_frequent(["a", "b", "d", "b", "c", "d", "c", "d", "c", "d"])` should return `["a", "b", "b", "c", "c", "c"]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(purge_most_frequent(["a", "b", "d", "b", "c", "d", "c", "d", "c", "d"]), ["a", "b", "b", "c", "c", "c"])`) +}}) +``` + +`purge_most_frequent(["red", "blue", "green", "red", "blue", "green", "blue"])` should return `["red", "green", "red", "green"]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(purge_most_frequent(["red", "blue", "green", "red", "blue", "green", "blue"]), ["red", "green", "red", "green"])`) +}}) +``` + +`purge_most_frequent([5, 5, 5, 5])` should return `[]`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(purge_most_frequent([5, 5, 5, 5]), [])`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def purge_most_frequent(arr): + + return arr +``` + +# --solutions-- + +```py +def purge_most_frequent(arr): + freq = {} + for val in arr: + freq[val] = freq.get(val, 0) + 1 + + max_freq = max(freq.values()) + to_remove = {val for val, count in freq.items() if count == max_freq} + + return [val for val in arr if val not in to_remove] +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecc.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecc.md new file mode 100644 index 00000000000..8c97356a7ec --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecc.md @@ -0,0 +1,143 @@ +--- +id: 691f7773cddba1caf1bf5ecc +title: "Challenge 133: Daylight Hours" +challengeType: 29 +dashedName: challenge-133 +--- + +# --description-- + +December 21st is the winter solstice for the northern hemisphere and the summer solstice for the southern hemisphere. That means it's the day with the least daylight in the north and the most daylight in the south. + +Given a latitude number from -90 to 90, return a rough approximation of daylight hours on the solstice using the following table: + +|Latitude|Daylight Hours| +|-|-| +|-90|24| +|-75|23| +|-60|21| +|-45|15| +|-30|13| +|-15|12| +|0|12| +|15|11| +|30|10| +|45|9| +|60|6| +|75|2| +|90|0| + +- If the given latitude does not exactly match a table entry, use the value of the closest latitude. + +# --hints-- + +`daylight_hours(45)` should return `9`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(45), 9)`) +}}) +``` + +`daylight_hours(0)` should return `12`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(0), 12)`) +}}) +``` + +`daylight_hours(-90)` should return `24`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(-90), 24)`) +}}) +``` + +`daylight_hours(-10)` should return `12`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(-10), 12)`) +}}) +``` + +`daylight_hours(23)` should return `10`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(23), 10)`) +}}) +``` + +`daylight_hours(88)` should return `0`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(88), 0)`) +}}) +``` + +`daylight_hours(-33)` should return `13`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(-33), 13)`) +}}) +``` + +`daylight_hours(70)` should return `2`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(daylight_hours(70), 2)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def daylight_hours(latitude): + + return latitude +``` + +# --solutions-- + +```py +def daylight_hours(latitude): + table = [ + (-90, 24), + (-75, 23), + (-60, 21), + (-45, 15), + (-30, 13), + (-15, 12), + (0, 12), + (15, 11), + (30, 10), + (45, 9), + (60, 6), + (75, 2), + (90, 0) + ] + + closest_lat, hours = table[0] + + for lat, h in table: + if abs(lat - latitude) < abs(closest_lat - latitude): + closest_lat, hours = lat, h + + return hours +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecd.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecd.md new file mode 100644 index 00000000000..d45710dba59 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ecd.md @@ -0,0 +1,110 @@ +--- +id: 691f7773cddba1caf1bf5ecd +title: "Challenge 134: Traveling Shopper" +challengeType: 29 +dashedName: challenge-134 +--- + +# --description-- + +Given an amount of money you have, and an array of items you want to buy, determine how many of them you can afford. + +- The given amount will be in the format `["Amount", "Currency Code"]`. For example: `["150.00", "USD"]` or `["6000", "JPY"]`. +- Each array item you want to purchase will be in the same format. + +Use the following exchange rates to convert values: + +|Currency|1 Unit Equals| +|-|-| +|USD|1.00 USD| +|EUR|1.10 USD| +|GBP|1.25 USD| +|JPY|0.0070 USD| +|CAD|0.75 USD| + +- If you can afford all the items in the list, return `"Buy them all!"`. +- Otherwise, return `"Buy the first X items."`, where `X` is the number of items you can afford when purchased in the order given. + + +# --hints-- + +`buy_items(["150.00", "USD"], [["50.00", "USD"], ["75.00", "USD"], ["30.00", "USD"]])` should return `"Buy the first 2 items."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(buy_items(["150.00", "USD"], [["50.00", "USD"], ["75.00", "USD"], ["30.00", "USD"]]), "Buy the first 2 items.")`) +}}) +``` + +`buy_items(["200.00", "EUR"], [["50.00", "USD"], ["50.00", "USD"]])` should return `"Buy them all!"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(buy_items(["200.00", "EUR"], [["50.00", "USD"], ["50.00", "USD"]]), "Buy them all!")`) +}}) +``` + +`buy_items(["100.00", "CAD"], [["20.00", "USD"], ["15.00", "EUR"], ["10.00", "GBP"], ["6000", "JPY"], ["5.00", "CAD"], ["10.00", "USD"]])` should return `"Buy the first 3 items."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(buy_items(["100.00", "CAD"], [["20.00", "USD"], ["15.00", "EUR"], ["10.00", "GBP"], ["6000", "JPY"], ["5.00", "CAD"], ["10.00", "USD"]]), "Buy the first 3 items.")`) +}}) +``` + +`buy_items(["5000", "JPY"], [["3.00", "USD"], ["1000", "JPY"], ["5.00", "CAD"], ["2.00", "EUR"], ["4.00", "USD"], ["2000", "JPY"]])` should return `"Buy them all!"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(buy_items(["5000", "JPY"], [["3.00", "USD"], ["1000", "JPY"], ["5.00", "CAD"], ["2.00", "EUR"], ["4.00", "USD"], ["2000", "JPY"]]), "Buy them all!")`) +}}) +``` + +`buy_items(["200.00", "USD"], [["50.00", "USD"], ["40.00", "EUR"], ["30.00", "GBP"], ["5000", "JPY"], ["25.00", "CAD"], ["20.00", "USD"]])` should return `"Buy the first 5 items."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(buy_items(["200.00", "USD"], [["50.00", "USD"], ["40.00", "EUR"], ["30.00", "GBP"], ["5000", "JPY"], ["25.00", "CAD"], ["20.00", "USD"]]), "Buy the first 5 items.")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def buy_items(funds, items): + + return funds +``` + +# --solutions-- + +```py +def buy_items(funds, items): + rates = { + "USD": 1.00, + "EUR": 1.10, + "GBP": 1.25, + "JPY": 0.0070, + "CAD": 0.75 + } + + amount, currency = funds + money = float(amount) * rates[currency] + + for i, (item_amount, item_currency) in enumerate(items): + item_cost_usd = float(item_amount) * rates[item_currency] + + if item_cost_usd > money: + return f"Buy the first {i} items." + + money -= item_cost_usd + + return "Buy them all!" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ece.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ece.md new file mode 100644 index 00000000000..f001f94e160 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/691f7773cddba1caf1bf5ece.md @@ -0,0 +1,95 @@ +--- +id: 691f7773cddba1caf1bf5ece +title: "Challenge 135: Re: Fwd: Fw: Count" +challengeType: 29 +dashedName: challenge-135 +--- + +# --description-- + +Given a string representing the subject line of an email, determine how many times the email has been forwarded or replied to. + +For simplicity, consider an email forwarded or replied to if the string contains any of the following markers (case-insensitive): + +- `"fw:"` +- `"fwd:"` +- `"re:"` + +Return the total number of occurrences of these markers. + +# --hints-- + +`email_chain_count("Re: Meeting Notes")` should return `1`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(email_chain_count("Re: Meeting Notes"), 1)`) +}}) +``` + +`email_chain_count("Meeting Notes")` should return `0`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(email_chain_count("Meeting Notes"), 0)`) +}}) +``` + +`email_chain_count("Re: re: RE: rE: Meeting Notes")` should return `4`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(email_chain_count("Re: re: RE: rE: Meeting Notes"), 4)`) +}}) +``` + +`email_chain_count("Re: Fwd: Re: Fw: Re: Meeting Notes")` should return `5`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(email_chain_count("Re: Fwd: Re: Fw: Re: Meeting Notes"), 5)`) +}}) +``` + +`email_chain_count("re:Ref:fw:re:review:FW:Re:fw:report:Re:FW:followup:re:summary:Fwd:Re:fw:NextStep:RE:FW:re:Project:Fwd:Re:fw:Notes:RE:re:Update:FWD:Re:fw:Summary")` should return `23`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(email_chain_count("re:Ref:fw:re:review:FW:Re:fw:report:Re:FW:followup:re:summary:Fwd:Re:fw:NextStep:RE:FW:re:Project:Fwd:Re:fw:Notes:RE:re:Update:FWD:Re:fw:Summary"), 23)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def email_chain_count(subject): + + return subject +``` + +# --solutions-- + +```py +def email_chain_count(subject): + markers = ["re:", "fwd:", "fw:"] + lower = subject.lower() + count = 0 + + for marker in markers: + start = 0 + while True: + idx = lower.find(marker, start) + if idx == -1: + break + count += 1 + start = idx + len(marker) + + return count +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1a.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1a.md new file mode 100644 index 00000000000..7cc8efa744a --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1a.md @@ -0,0 +1,74 @@ +--- +id: 6925e2068081f40f549ced1a +title: "Challenge 136: Markdown Image Parser" +challengeType: 29 +dashedName: challenge-136 +--- + +# --description-- + +Given a string of an image in Markdown, return the equivalent HTML string. + +A Markdown image has the following format: `"![alt text](image_url)"`. Where: + +- `alt text` is the description of the image (the `alt` attribute value). +- `image_url` is the source URL of the image (the `src` attribute value). + +Return a string of the HTML `img` tag with the `src` set to the image URL and the `alt` set to the alt text. + +For example, given `"![Cute cat](cat.png)"` return `'Cute cat'`; + +- Make sure the tag, order of attributes, spacing, and quote usage is the same as above. + +Note: The console may not display HTML tags in strings when logging messages — check the browser console to see logs with tags included. + +# --hints-- + +`parse_image("![Cute cat](cat.png)")` should return `'Cute cat'`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_image("![Cute cat](cat.png)"), 'Cute cat')`) +}}) +``` + +`parse_image("![Rocket Ship](https://freecodecamp.org/cdn/rocket-ship.jpg)")` should return `'Rocket Ship'`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_image("![Rocket Ship](https://freecodecamp.org/cdn/rocket-ship.jpg)"), 'Rocket Ship')`) +}}) +``` + +`parse_image("![Cute cats!](https://freecodecamp.org/cats.jpeg)")` should return `'Cute cats!'`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_image("![Cute cats!](https://freecodecamp.org/cats.jpeg)"), 'Cute cats!')`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def parse_image(markdown): + + return markdown +``` + +# --solutions-- + +```py +import re +def parse_image(markdown): + match = re.search(r'!\[(.*?)\]\((.*?)\)', markdown) + if not match: + return "" + alt, src = match.groups() + return f'{alt}' +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1b.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1b.md new file mode 100644 index 00000000000..d0c170ab033 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1b.md @@ -0,0 +1,101 @@ +--- +id: 6925e2068081f40f549ced1b +title: "Challenge 137: Snowflake Generator" +challengeType: 29 +dashedName: challenge-137 +--- + +# --description-- + +Given a multi-line string that uses newline characters (`\n`) to represent a line break, return a new string where each line is mirrored horizontally and attached to the end of the original line. + +- Mirror a line by reversing all of its characters, including spaces. + +For example, given `"* \n *\n* "`, which logs to the console as: + +```sh +* + * +* +``` + +Return `"* *\n ** \n* *"`, which logs to the console as: + +```sh +* * + ** +* * +``` + +Take careful note of the whitespaces in the given and returned strings. Be sure not to trim any of them. + +# --hints-- + +`generate_snowflake("* \n *\n* ")` should return `"* *\n ** \n* *"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(generate_snowflake("* \\n *\\n* "), "* *\\n ** \\n* *")`) +}}) +``` + +`generate_snowflake("X=~")` should return `"X=~~=X"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(generate_snowflake("X=~"), "X=~~=X")`) +}}) +``` + +`generate_snowflake(" X \n v \nX--=\n ^ \n X ")` should return `" X X \n v v \nX--==--X\n ^ ^ \n X X "`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(generate_snowflake(" X \\n v \\nX--=\\n ^ \\n X "), " X X \\n v v \\nX--==--X\\n ^ ^ \\n X X ")`) +}}) +``` + +`generate_snowflake("* *\n * * \n* * *\n * * \n* *")` should return `"* ** *\n * * * * \n* * ** * *\n * * * * \n* ** *"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(generate_snowflake("* *\\n * * \\n* * *\\n * * \\n* *"), "* ** *\\n * * * * \\n* * ** * *\\n * * * * \\n* ** *")`) +}}) +``` + +`generate_snowflake("* -\n * -\n* -")` should return `"* -- *\n * -- * \n* -- *"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(generate_snowflake("* -\\n * -\\n* -"), "* -- *\\n * -- * \\n* -- *")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def generate_snowflake(crystals): + + return crystals +``` + +# --solutions-- + +```py +def generate_snowflake(crystals): + lines = crystals.split("\n") + mirrored = [] + + for line in lines: + reversed_line = line[::-1] + mirrored.append(line + reversed_line) + + return "\n".join(mirrored) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1c.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1c.md new file mode 100644 index 00000000000..0b4dbf283a1 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1c.md @@ -0,0 +1,92 @@ +--- +id: 6925e2068081f40f549ced1c +title: "Challenge 138: Sum of Divisors" +challengeType: 29 +dashedName: challenge-138 +--- + +# --description-- + +Given a positive integer, return the sum of all its divisors. + +- A divisor is any integer that divides the number evenly (the remainder is `0`). +- Only count each divisor once. + +For example, given `6`, return `12` because the divisors of `6` are `1`, `2`, `3`, and `6`, and the sum of those is `12`. + +# --hints-- + +`sum_divisors(6)` should return `12`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(6), 12)`) +}}) +``` + +`sum_divisors(13)` should return `14`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(13), 14)`) +}}) +``` + +`sum_divisors(28)` should return `56`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(28), 56)`) +}}) +``` + +`sum_divisors(84)` should return `224`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(84), 224)`) +}}) +``` + +`sum_divisors(549)` should return `806`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(549), 806)`) +}}) +``` + +`sum_divisors(9348)` should return `23520`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(sum_divisors(9348), 23520)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def sum_divisors(n): + + return n +``` + +# --solutions-- + +```py +def sum_divisors(n): + total = 0 + for i in range(1, n + 1): + if n % i == 0: + total += i + return total +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1d.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1d.md new file mode 100644 index 00000000000..8a28504b335 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/6925e2068081f40f549ced1d.md @@ -0,0 +1,102 @@ +--- +id: 6925e2068081f40f549ced1d +title: "Challenge 139: Rock, Paper, Scissors" +challengeType: 29 +dashedName: challenge-139 +--- + +# --description-- + +Given two strings, the first representing Player 1 and the second representing Player 2, determine the winner of a match of Rock, Paper, Scissors. + +- The input strings will always be `"Rock"`, `"Paper"`, or `"Scissors"`. +- `"Rock"` beats `"Scissors"`. +- `"Paper"` beats `"Rock"`. +- `"Scissors"` beats `"Paper"`. + +Return: + +- `"Player 1 wins"` if Player 1 wins. +- `"Player 2 wins"` if Player 2 wins. +- `"Tie"` if both players choose the same option. + +# --hints-- + +`rock_paper_scissors("Rock", "Rock")` should return `"Tie"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Rock", "Rock"), "Tie")`) +}}) +``` + +`rock_paper_scissors("Rock", "Paper")` should return `"Player 2 wins"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Rock", "Paper"), "Player 2 wins")`) +}}) +``` + +`rock_paper_scissors("Scissors", "Paper")` should return `"Player 1 wins"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Scissors", "Paper"), "Player 1 wins")`) +}}) +``` + +`rock_paper_scissors("Rock", "Scissors")` should return `"Player 1 wins"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Rock", "Scissors"), "Player 1 wins")`) +}}) +``` + +`rock_paper_scissors("Scissors", "Scissors")` should return `"Tie"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Scissors", "Scissors"), "Tie")`) +}}) +``` + +`rock_paper_scissors("Scissors", "Rock")` should return `"Player 2 wins"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(rock_paper_scissors("Scissors", "Rock"), "Player 2 wins")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def rock_paper_scissors(player1, player2): + + return player1 +``` + +# --solutions-- + +```py +def rock_paper_scissors(player1, player2): + if player1 == player2: + return "Tie" + + if (player1 == "Rock" and player2 == "Scissors") or \ + (player1 == "Paper" and player2 == "Rock") or \ + (player1 == "Scissors" and player2 == "Paper"): + return "Player 1 wins" + else: + return "Player 2 wins" +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c3.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c3.md new file mode 100644 index 00000000000..fd252729f8d --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c3.md @@ -0,0 +1,92 @@ +--- +id: 69272dcf1c24b44fd79137c3 +title: "Challenge 140: SCREAMING_SNAKE_CASE" +challengeType: 29 +dashedName: challenge-140 +--- + +# --description-- + +Given a string representing a variable name, return the variable name converted to SCREAMING_SNAKE_CASE. + +The given variable names will be written in one of the following formats: + +- `camelCase` +- `PascalCase` +- `snake_case` +- `kebab-case` + +In the above formats, words are separated by an underscore (`_`), a hyphen (`-`), or a new word starts with a capital letter. + +To convert to SCREAMING_SNAKE_CASE: + +- Make all letters uppercase +- Separate words with an underscore (`_`) + +# --hints-- + +`to_screaming_snake_case("userEmail")` should return `"USER_EMAIL"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_screaming_snake_case("userEmail"), "USER_EMAIL")`) +}}) +``` + +`to_screaming_snake_case("UserPassword")` should return `"USER_PASSWORD"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_screaming_snake_case("UserPassword"), "USER_PASSWORD")`) +}}) +``` + +`to_screaming_snake_case("user_id")` should return `"USER_ID"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_screaming_snake_case("user_id"), "USER_ID")`) +}}) +``` + +`to_screaming_snake_case("user-address")` should return `"USER_ADDRESS"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_screaming_snake_case("user-address"), "USER_ADDRESS")`) +}}) +``` + +`to_screaming_snake_case("username")` should return `"USERNAME"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(to_screaming_snake_case("username"), "USERNAME")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def to_screaming_snake_case(variable_name): + + return variable_name +``` + +# --solutions-- + +```py +import re +def to_screaming_snake_case(variable_name): + temp = re.sub(r'[-_]+', ' ', variable_name) + temp = re.sub(r'([a-z0-9])([A-Z])', r'\1 \2', temp) + words = temp.strip().split() + return '_'.join(words).upper() +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c4.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c4.md new file mode 100644 index 00000000000..a292320b251 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c4.md @@ -0,0 +1,85 @@ +--- +id: 69272dcf1c24b44fd79137c4 +title: "Challenge 141: Takeoff Fuel" +challengeType: 29 +dashedName: challenge-141 +--- + +# --description-- + +Given the numbers of gallons of fuel currently in your airplane, and the required number of liters of fuel to reach your destination, determine how many additional gallons of fuel you should add. + +- 1 gallon equals 3.78541 liters. +- If the airplane already has enough fuel, return `0`. +- You can only add whole gallons. +- Do not include decimals in the return number. + +# --hints-- + +`fuel_to_add(0, 1)` should return `1`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(fuel_to_add(0, 1), 1)`) +}}) +``` + +`fuel_to_add(5, 40)` should return `6`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(fuel_to_add(5, 40), 6)`) +}}) +``` + +`fuel_to_add(10, 30)` should return `0`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(fuel_to_add(10, 30), 0)`) +}}) +``` + +`fuel_to_add(896, 20500)` should return `4520`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(fuel_to_add(896, 20500), 4520)`) +}}) +``` + +`fuel_to_add(1000, 50000)` should return `12209`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(fuel_to_add(1000, 50000), 12209)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def fuel_to_add(current_gallons, required_liters): + + return current_gallons +``` + +# --solutions-- + +```py +import math +def fuel_to_add(current_gallons, required_liters): + liters_per_gallon = 3.78541 + current_liters = current_gallons * liters_per_gallon + if current_liters >= required_liters: + return 0 + liters_needed = required_liters - current_liters + return math.ceil(liters_needed / liters_per_gallon) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c5.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c5.md new file mode 100644 index 00000000000..1bc1e3d9ae4 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c5.md @@ -0,0 +1,79 @@ +--- +id: 69272dcf1c24b44fd79137c5 +title: "Challenge 142: Sum the String" +challengeType: 29 +dashedName: challenge-142 +--- + +# --description-- + +Given a string containing digits and other characters, return the sum of all numbers in the string. + +- Treat consecutive digits as a single number. For example, `"13"` counts as 13, not 1 + 3. +- Ignore any non-digit characters. + +# --hints-- + +`string_sum("3apples2bananas")` should return `5`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(string_sum("3apples2bananas"), 5)`) +}}) +``` + +`string_sum("10cats5dogs2birds")` should return `17`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(string_sum("10cats5dogs2birds"), 17)`) +}}) +``` + +`string_sum("125344")` should return `125344`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(string_sum("125344"), 125344)`) +}}) +``` + +`string_sum("a1b20c300")` should return `321`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(string_sum("a1b20c300"), 321)`) +}}) +``` + +`string_sum("a12b34c56d78e90f123g456h789i0j1k2l3m4n5")` should return `1653`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(string_sum("a12b34c56d78e90f123g456h789i0j1k2l3m4n5"), 1653)`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def string_sum(s): + + return s +``` + +# --solutions-- + +```py +import re +def string_sum(s): + numbers = re.findall(r'\d+', s) + return sum(int(num) for num in numbers) +``` diff --git a/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c6.md b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c6.md new file mode 100644 index 00000000000..c13527218e6 --- /dev/null +++ b/curriculum/challenges/english/blocks/daily-coding-challenges-python/69272dcf1c24b44fd79137c6.md @@ -0,0 +1,85 @@ +--- +id: 69272dcf1c24b44fd79137c6 +title: "Challenge 143: Markdown Italic Parser" +challengeType: 29 +dashedName: challenge-143 +--- + +# --description-- + +Given a string that may include some italic text in Markdown, return the equivalent HTML string. + +- Italic text in Markdown is any text that starts and ends with a single asterisk (`*`) or a single underscore (`_`). +- There cannot be any spaces between the text and the asterisk or underscore, but there can be spaces in the text itself. +- Convert all italic occurrences to HTML `i` tags and return the string. + +For example, given `"*This is italic*"`, return `"This is italic"`. + +Note: The console may not display HTML tags in strings when logging messages. Check the browser console to see logs with tags included. + +# --hints-- + +`parse_italics("*This is italic*")` should return `"This is italic"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_italics("*This is italic*"), "This is italic")`) +}}) +``` + +`parse_italics("_This is also italic_")` should return `"This is also italic"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_italics("_This is also italic_"), "This is also italic")`) +}}) +``` + +`parse_italics("*This is not italic *")` should return `"*This is not italic *"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_italics("*This is not italic *"), "*This is not italic *")`) +}}) +``` + +`parse_italics("_ This is also not italic_")` should return `"_ This is also not italic_"`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_italics("_ This is also not italic_"), "_ This is also not italic_")`) +}}) +``` + +`parse_italics("The *quick* brown fox _jumps_ over the *lazy* dog.")` should return `"The quick brown fox jumps over the lazy dog."`. + +```js +({test: () => { runPython(` +from unittest import TestCase +TestCase().assertEqual(parse_italics("The *quick* brown fox _jumps_ over the *lazy* dog."), "The quick brown fox jumps over the lazy dog.")`) +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +def parse_italics(markdown): + + return markdown +``` + +# --solutions-- + +```py +import re +def parse_italics(markdown): + pattern = r'(\*|_)([^\s][^]*?[^\s])\1' + pattern = r'(\*|_)([^\s].*?[^\s])\1' + return re.sub(pattern, r'\2', markdown) +``` diff --git a/curriculum/structure/blocks/daily-coding-challenges-javascript.json b/curriculum/structure/blocks/daily-coding-challenges-javascript.json index 318a1c7c51c..d97f303b043 100644 --- a/curriculum/structure/blocks/daily-coding-challenges-javascript.json +++ b/curriculum/structure/blocks/daily-coding-challenges-javascript.json @@ -482,6 +482,102 @@ { "id": "69162d64f96574d9bb629f04", "title": "Challenge 119: String Compression" + }, + { + "id": "691b559495c5cb5a37b9b480", + "title": "Challenge 120: Pounds to Kilograms" + }, + { + "id": "691b559495c5cb5a37b9b481", + "title": "Challenge 121: Most Frequent" + }, + { + "id": "691b559495c5cb5a37b9b482", + "title": "Challenge 122: Markdown Bold Parser" + }, + { + "id": "691b559495c5cb5a37b9b483", + "title": "Challenge 123: Roman Numeral Builder" + }, + { + "id": "691b559495c5cb5a37b9b484", + "title": "Challenge 124: Inventory Update" + }, + { + "id": "691b559495c5cb5a37b9b485", + "title": "Challenge 125: Game of Life" + }, + { + "id": "691b559495c5cb5a37b9b486", + "title": "Challenge 126: Capitalize It" + }, + { + "id": "691b559495c5cb5a37b9b487", + "title": "Challenge 127: Speed Check" + }, + { + "id": "691b559495c5cb5a37b9b488", + "title": "Challenge 128: Consonant Count" + }, + { + "id": "691b559495c5cb5a37b9b489", + "title": "Challenge 129: Markdown Blockquote Parser" + }, + { + "id": "691b5597f0f3e85a588a5c94", + "title": "Challenge 130: Checkerboard" + }, + { + "id": "691f7773cddba1caf1bf5eca", + "title": "Challenge 131: Pairwise" + }, + { + "id": "691f7773cddba1caf1bf5ecb", + "title": "Challenge 132: Purge Most Frequent" + }, + { + "id": "691f7773cddba1caf1bf5ecc", + "title": "Challenge 133: Daylight Hours" + }, + { + "id": "691f7773cddba1caf1bf5ecd", + "title": "Challenge 134: Traveling Shopper" + }, + { + "id": "691f7773cddba1caf1bf5ece", + "title": "Challenge 135: Re: Fwd: Fw: Count" + }, + { + "id": "6925e2068081f40f549ced1a", + "title": "Challenge 136: Markdown Image Parser" + }, + { + "id": "6925e2068081f40f549ced1b", + "title": "Challenge 137: Snowflake Generator" + }, + { + "id": "6925e2068081f40f549ced1c", + "title": "Challenge 138: Sum of Divisors" + }, + { + "id": "6925e2068081f40f549ced1d", + "title": "Challenge 139: Rock, Paper, Scissors" + }, + { + "id": "69272dcf1c24b44fd79137c3", + "title": "Challenge 140: SCREAMING_SNAKE_CASE" + }, + { + "id": "69272dcf1c24b44fd79137c4", + "title": "Challenge 141: Takeoff Fuel" + }, + { + "id": "69272dcf1c24b44fd79137c5", + "title": "Challenge 142: Sum the String" + }, + { + "id": "69272dcf1c24b44fd79137c6", + "title": "Challenge 143: Markdown Italic Parser" } ] } diff --git a/curriculum/structure/blocks/daily-coding-challenges-python.json b/curriculum/structure/blocks/daily-coding-challenges-python.json index 98e315c5a77..b9d85b57a5e 100644 --- a/curriculum/structure/blocks/daily-coding-challenges-python.json +++ b/curriculum/structure/blocks/daily-coding-challenges-python.json @@ -481,6 +481,102 @@ { "id": "69162d64f96574d9bb629f04", "title": "Challenge 119: String Compression" + }, + { + "id": "691b559495c5cb5a37b9b480", + "title": "Challenge 120: Pounds to Kilograms" + }, + { + "id": "691b559495c5cb5a37b9b481", + "title": "Challenge 121: Most Frequent" + }, + { + "id": "691b559495c5cb5a37b9b482", + "title": "Challenge 122: Markdown Bold Parser" + }, + { + "id": "691b559495c5cb5a37b9b483", + "title": "Challenge 123: Roman Numeral Builder" + }, + { + "id": "691b559495c5cb5a37b9b484", + "title": "Challenge 124: Inventory Update" + }, + { + "id": "691b559495c5cb5a37b9b485", + "title": "Challenge 125: Game of Life" + }, + { + "id": "691b559495c5cb5a37b9b486", + "title": "Challenge 126: Capitalize It" + }, + { + "id": "691b559495c5cb5a37b9b487", + "title": "Challenge 127: Speed Check" + }, + { + "id": "691b559495c5cb5a37b9b488", + "title": "Challenge 128: Consonant Count" + }, + { + "id": "691b559495c5cb5a37b9b489", + "title": "Challenge 129: Markdown Blockquote Parser" + }, + { + "id": "691b5597f0f3e85a588a5c94", + "title": "Challenge 130: Checkerboard" + }, + { + "id": "691f7773cddba1caf1bf5eca", + "title": "Challenge 131: Pairwise" + }, + { + "id": "691f7773cddba1caf1bf5ecb", + "title": "Challenge 132: Purge Most Frequent" + }, + { + "id": "691f7773cddba1caf1bf5ecc", + "title": "Challenge 133: Daylight Hours" + }, + { + "id": "691f7773cddba1caf1bf5ecd", + "title": "Challenge 134: Traveling Shopper" + }, + { + "id": "691f7773cddba1caf1bf5ece", + "title": "Challenge 135: Re: Fwd: Fw: Count" + }, + { + "id": "6925e2068081f40f549ced1a", + "title": "Challenge 136: Markdown Image Parser" + }, + { + "id": "6925e2068081f40f549ced1b", + "title": "Challenge 137: Snowflake Generator" + }, + { + "id": "6925e2068081f40f549ced1c", + "title": "Challenge 138: Sum of Divisors" + }, + { + "id": "6925e2068081f40f549ced1d", + "title": "Challenge 139: Rock, Paper, Scissors" + }, + { + "id": "69272dcf1c24b44fd79137c3", + "title": "Challenge 140: SCREAMING_SNAKE_CASE" + }, + { + "id": "69272dcf1c24b44fd79137c4", + "title": "Challenge 141: Takeoff Fuel" + }, + { + "id": "69272dcf1c24b44fd79137c5", + "title": "Challenge 142: Sum the String" + }, + { + "id": "69272dcf1c24b44fd79137c6", + "title": "Challenge 143: Markdown Italic Parser" } ] } diff --git a/tools/daily-challenges/seed-daily-challenges.ts b/tools/daily-challenges/seed-daily-challenges.ts index c257008d7d6..7682b02e211 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 = 119; +const EXPECTED_CHALLENGE_COUNT = 143; // 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)**