mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(curriculum): daily challenges 63-79 (#62367)
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com>
This commit is contained in:
+3
-3
@@ -9,9 +9,9 @@ dashedName: challenge-36
|
||||
|
||||
Given the current temperature of a room and a target temperature, return a string indicating how to adjust the room temperature based on these constraints:
|
||||
|
||||
- Return "heat" if the current temperature is below the target.
|
||||
- Return "cool" if the current temperature is above the target.
|
||||
- Return "hold" if the current temperature is equal to the target.
|
||||
- Return `"heat"` if the current temperature is below the target.
|
||||
- Return `"cool"` if the current temperature is above the target.
|
||||
- Return `"hold"` if the current temperature is equal to the target.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da001
|
||||
title: "Challenge 63: Battle of Words"
|
||||
challengeType: 28
|
||||
dashedName: challenge-63
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two sentences representing your team and an opposing team, where each word from your team battles the corresponding word from the opposing team, determine which team wins using the following rules:
|
||||
|
||||
- The given sentences will always contain the same number of words.
|
||||
- Words are separated by a single space and will only contain letters.
|
||||
- The value of each word is the sum of its letters.
|
||||
- Letters `a` to `z` correspond to the values `1` through `26`. For example, `a` is `1`, and `z` is `26`.
|
||||
- A capital letter doubles the value of the letter. For example, `A` is `2`, and `Z` is `52`.
|
||||
- Words battle in order: the first word of your team battles the first word of the opposing team, and so on.
|
||||
- A word wins if its value is greater than the opposing word's value.
|
||||
- The team with more winning words is the winner.
|
||||
|
||||
Return `"We win"` if your team is the winner, `"We lose"` if your team loses, and `"Draw"` if both teams have the same number of wins.
|
||||
|
||||
# --hints--
|
||||
|
||||
`battle("hello world", "hello word")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("hello world", "hello word"), "We win");
|
||||
```
|
||||
|
||||
`battle("Hello world", "hello world")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("Hello world", "hello world"), "We win");
|
||||
```
|
||||
|
||||
`battle("lorem ipsum", "kitty ipsum")` should return `"We lose"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("lorem ipsum", "kitty ipsum"), "We lose");
|
||||
```
|
||||
|
||||
`battle("hello world", "world hello")` should return `"Draw"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("hello world", "world hello"), "Draw");
|
||||
```
|
||||
|
||||
`battle("git checkout", "git switch")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("git checkout", "git switch"), "We win");
|
||||
```
|
||||
|
||||
`battle("Cheeseburger with fries", "Cheeseburger with Fries")` should return `"We lose"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("Cheeseburger with fries", "Cheeseburger with Fries"), "We lose");
|
||||
```
|
||||
|
||||
`battle("We must never surrender", "Our team must win")` should return `"Draw"`.
|
||||
|
||||
```js
|
||||
assert.equal(battle("We must never surrender", "Our team must win"), "Draw");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function battle(ourTeam, opponent) {
|
||||
|
||||
return ourTeam;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function getCharacterValue(char) {
|
||||
const lowerCaseValue = char.toLowerCase().charCodeAt(0) - 96;
|
||||
return char >= 'A' && char <= 'Z' ? lowerCaseValue * 2 : lowerCaseValue;
|
||||
}
|
||||
|
||||
function getWordValue(word) {
|
||||
let wordValue = 0;
|
||||
for (let i=0; i<word.length; i++) {
|
||||
wordValue += getCharacterValue(word[i])
|
||||
}
|
||||
|
||||
return wordValue;
|
||||
}
|
||||
|
||||
function battle(ourTeam, opponent) {
|
||||
const myWords = ourTeam.split(' ');
|
||||
const opponentWords = opponent.split(' ');
|
||||
|
||||
let myWins = 0, opponentWins = 0;
|
||||
|
||||
for (let i=0; i<myWords.length; i++) {
|
||||
const myWordValue = getWordValue(myWords[i]);
|
||||
const opponentWordValue = getWordValue(opponentWords[i])
|
||||
|
||||
if (myWordValue > opponentWordValue) myWins++;
|
||||
if (opponentWordValue > myWordValue) opponentWins++;
|
||||
}
|
||||
|
||||
if (myWins > opponentWins) return 'We win';
|
||||
if (opponentWins > myWins) return 'We lose';
|
||||
return 'Draw';
|
||||
}
|
||||
```
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da002
|
||||
title: "Challenge 64: 24 to 12"
|
||||
challengeType: 28
|
||||
dashedName: challenge-64
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing a time of the day in the 24-hour format of `"HHMM"`, return the time in its equivalent 12-hour format of `"H:MM AM"` or `"H:MM PM"`.
|
||||
|
||||
- The given input will always be a four-digit string in 24-hour time format, from `"0000"` to `"2359"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`to12("1124")` should return `"11:24 AM"`.
|
||||
|
||||
```js
|
||||
assert.equal(to12("1124"), "11:24 AM");
|
||||
```
|
||||
|
||||
`to12("0900")` should return `"9:00 AM"`.
|
||||
|
||||
```js
|
||||
assert.equal(to12("0900"), "9:00 AM");
|
||||
```
|
||||
|
||||
`to12("1455")` should return `"2:55 PM"`.
|
||||
|
||||
```js
|
||||
assert.equal(to12("1455"), "2:55 PM");
|
||||
```
|
||||
|
||||
`to12("2346")` should return `"11:46 PM"`.
|
||||
|
||||
```js
|
||||
assert.equal(to12("2346"), "11:46 PM");
|
||||
```
|
||||
|
||||
`to12("0030")` should return `"12:30 AM"`.
|
||||
|
||||
```js
|
||||
assert.equal(to12("0030"), "12:30 AM");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function to12(time) {
|
||||
|
||||
return time;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function convertHours(hours) {
|
||||
if (hours === 0) return 12;
|
||||
if (hours > 12) return hours - 12;
|
||||
return hours;
|
||||
}
|
||||
|
||||
function to12(time) {
|
||||
const hours = parseInt(time.slice(0, 2), 10);
|
||||
const minutes = time.slice(2);
|
||||
const period = hours < 12 ? 'AM' : 'PM';
|
||||
|
||||
return `${convertHours(hours)}:${minutes} ${period}`;
|
||||
}
|
||||
```
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da003
|
||||
title: "Challenge 65: String Count"
|
||||
challengeType: 28
|
||||
dashedName: challenge-65
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two strings, determine how many times the second string appears in the first.
|
||||
|
||||
- The pattern string can overlap in the first string. For example, `"aaa"` contains `"aa"` twice. The first two `a`'s and the second two.
|
||||
|
||||
# --hints--
|
||||
|
||||
`count('abcdefg', 'def')` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(count('abcdefg', 'def'), 1);
|
||||
```
|
||||
|
||||
`count('hello', 'world')` should return `0`.
|
||||
|
||||
```js
|
||||
assert.equal(count('hello', 'world'), 0);
|
||||
```
|
||||
|
||||
`count('mississippi', 'iss')` should return `2`.
|
||||
|
||||
```js
|
||||
assert.equal(count('mississippi', 'iss'), 2);
|
||||
```
|
||||
|
||||
`count('she sells seashells by the seashore', 'sh')` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(count('she sells seashells by the seashore', 'sh'), 3);
|
||||
```
|
||||
|
||||
`count('101010101010101010101', '101')` should return `10`.
|
||||
|
||||
```js
|
||||
assert.equal(count('101010101010101010101', '101'), 10);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function count(text, pattern) {
|
||||
|
||||
return text;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function count(text, pattern) {
|
||||
let occurrences = 0;
|
||||
|
||||
for (let i = 0; i <= text.length - pattern.length; i++) {
|
||||
if (text.slice(i, i + pattern.length) === pattern) {
|
||||
occurrences++;
|
||||
}
|
||||
}
|
||||
|
||||
return occurrences;
|
||||
}
|
||||
```
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da004
|
||||
title: "Challenge 66: HTML Tag Stripper"
|
||||
challengeType: 28
|
||||
dashedName: challenge-66
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of HTML code, remove the tags and return the plain text content.
|
||||
|
||||
- The input string will contain only valid HTML.
|
||||
- HTML tags may be nested.
|
||||
- Remove the tags and any attributes.
|
||||
|
||||
For example, `'<a href="#">Click here</a>'` should return `"Click here"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`stripTags('<a href="#">Click here</a>')` should return `"Click here"`.
|
||||
|
||||
```js
|
||||
assert.equal(stripTags('<a href="#">Click here</a>'), "Click here");
|
||||
```
|
||||
|
||||
`stripTags('<p class="center">Hello <b>World</b>!</p>')` should return `"Hello World!"`.
|
||||
|
||||
```js
|
||||
assert.equal(stripTags('<p class="center">Hello <b>World</b>!</p>'), "Hello World!");
|
||||
```
|
||||
|
||||
`stripTags('<img src="cat.jpg" alt="Cat">')` should return an empty string (`""`).
|
||||
|
||||
```js
|
||||
assert.equal(stripTags('<img src="cat.jpg" alt="Cat">'), "");
|
||||
```
|
||||
|
||||
`stripTags('<main id="main"><section class="section">section</section><section class="section">section</section></main>')` should return `sectionsection`.
|
||||
|
||||
```js
|
||||
assert.equal(stripTags('<main id="main"><section class="section">section</section><section class="section">section</section></main>'), "sectionsection");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function stripTags(html) {
|
||||
|
||||
return html;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function stripTags(html) {
|
||||
return html.replace(/<[^>]*>/g, '');
|
||||
}
|
||||
```
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da005
|
||||
title: "Challenge 67: Email Validator"
|
||||
challengeType: 28
|
||||
dashedName: challenge-67
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string, determine if it is a valid email address using the following constraints:
|
||||
|
||||
- It must contain exactly one `@` symbol.
|
||||
- The local part (before the `@`):
|
||||
- Can only contain letters (`a-z`, `A-Z`), digits (`0-9`), dots (`.`), underscores (`_`), or hyphens (`-`).
|
||||
- Cannot start or end with a dot.
|
||||
- The domain part (after the `@`):
|
||||
- Must contain at least one dot.
|
||||
- Must end with a dot followed by at least two letters.
|
||||
- Neither the local or domain part can have two dots in a row.
|
||||
|
||||
# --hints--
|
||||
|
||||
`validate("a@b.cd")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.isTrue(validate("a@b.cd"));
|
||||
```
|
||||
|
||||
`validate("hell.-w.rld@example.com")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.isTrue(validate("hell.-w.rld@example.com"));
|
||||
```
|
||||
|
||||
`validate(".b@sh.rc")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate(".b@sh.rc"));
|
||||
```
|
||||
|
||||
`validate("example@test.c0")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate("example@test.c0"));
|
||||
```
|
||||
|
||||
`validate("freecodecamp.org")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate("freecodecamp.org"));
|
||||
```
|
||||
|
||||
`validate("develop.ment_user@c0D!NG.R.CKS")` should return `true`.
|
||||
|
||||
```js
|
||||
assert.isTrue(validate("develop.ment_user@c0D!NG.R.CKS"));
|
||||
```
|
||||
|
||||
`validate("hello.@wo.rld")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate("hello.@wo.rld"));
|
||||
```
|
||||
|
||||
`validate("hello@world..com")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate("hello@world..com"));
|
||||
```
|
||||
|
||||
`validate("git@commit@push.io")` should return `false`.
|
||||
|
||||
```js
|
||||
assert.isFalse(validate("git@commit@push.io"));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function validate(email) {
|
||||
|
||||
return email;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function validate(email) {
|
||||
if (email.includes('..')) return false;
|
||||
|
||||
const parts = email.split('@');
|
||||
if (parts.length !== 2) return false;
|
||||
|
||||
const [local, domain] = parts;
|
||||
|
||||
if (local.startsWith('.') || local.endsWith('.')) return false;
|
||||
if (!/^[a-zA-Z0-9._-]+$/.test(local)) return false;
|
||||
if (!domain.includes('.')) return false;
|
||||
|
||||
const tld = domain.split('.').pop();
|
||||
if (tld.length < 2 || !/^[a-zA-Z]+$/.test(tld)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da006
|
||||
title: "Challenge 68: Credit Card Masker"
|
||||
challengeType: 28
|
||||
dashedName: challenge-68
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of credit card numbers, return a masked version of it using the following constraints:
|
||||
|
||||
- The string will contain four sets of four digits (`0-9`), with all sets being separated by a single space, or a single hyphen (`-`).
|
||||
- Replace all numbers, except the last four, with an asterisk (`*`).
|
||||
- Leave the remaining characters unchanged.
|
||||
|
||||
For example, given `"4012-8888-8888-1881"` return `"****-****-****-1881"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`mask("4012-8888-8888-1881")` should return `"****-****-****-1881"`.
|
||||
|
||||
```js
|
||||
assert.equal(mask("4012-8888-8888-1881"), "****-****-****-1881");
|
||||
```
|
||||
|
||||
`mask("5105 1051 0510 5100")` should return `"**** **** **** 5100"`.
|
||||
|
||||
```js
|
||||
assert.equal(mask("5105 1051 0510 5100"), "**** **** **** 5100");
|
||||
```
|
||||
|
||||
`mask("6011 1111 1111 1117")` should return `"**** **** **** 1117"`.
|
||||
|
||||
```js
|
||||
assert.equal(mask("6011 1111 1111 1117"), "**** **** **** 1117");
|
||||
```
|
||||
|
||||
`mask("2223-0000-4845-0010")` should return `"****-****-****-0010"`.
|
||||
|
||||
```js
|
||||
assert.equal(mask("2223-0000-4845-0010"), "****-****-****-0010");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function mask(card) {
|
||||
|
||||
return card;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function mask(card) {
|
||||
const split = card.split(card.includes('-') ? '-' : ' ');
|
||||
|
||||
return card.includes('-') ?
|
||||
`****-****-****-${split[3]}` :
|
||||
`**** **** **** ${split[3]}`;
|
||||
}
|
||||
```
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da007
|
||||
title: "Challenge 69: Missing Socks"
|
||||
challengeType: 28
|
||||
dashedName: challenge-69
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given an integer representing the number of pairs of socks you started with, and another integer representing how many wash cycles you have gone through, return the number of complete pairs of socks you currently have using the following constraints:
|
||||
|
||||
- Every 2 wash cycles, you lose a single sock.
|
||||
- Every 3 wash cycles, you find a single missing sock.
|
||||
- Every 5 wash cycles, a single sock is worn out and must be thrown away.
|
||||
- Every 10 wash cycles, you buy a pair of socks.
|
||||
- You can never have less than zero total socks.
|
||||
- Rules can overlap. For example, on wash cycle 10, you will lose a single sock, throw away a single sock, and buy a new pair of socks.
|
||||
- Return the number of complete pairs of socks.
|
||||
|
||||
# --hints--
|
||||
|
||||
`sockPairs(2, 5)` should return `1`.
|
||||
|
||||
```js
|
||||
assert.equal(sockPairs(2, 5), 1);
|
||||
```
|
||||
|
||||
`sockPairs(1, 2)` should return `0`.
|
||||
|
||||
```js
|
||||
assert.equal(sockPairs(1, 2), 0);
|
||||
```
|
||||
|
||||
`sockPairs(5, 11)` should return `4`.
|
||||
|
||||
```js
|
||||
assert.equal(sockPairs(5, 11), 4);
|
||||
```
|
||||
|
||||
`sockPairs(6, 25)` should return `3`.
|
||||
|
||||
```js
|
||||
assert.equal(sockPairs(6, 25), 3);
|
||||
```
|
||||
|
||||
`sockPairs(1, 8)` should return `0`.
|
||||
|
||||
```js
|
||||
assert.equal(sockPairs(1, 8), 0);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function sockPairs(pairs, cycles) {
|
||||
|
||||
return pairs;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function sockPairs(pairs, cycles) {
|
||||
let socks = pairs * 2;
|
||||
|
||||
for (let i = 1; i <= cycles; i++) {
|
||||
if (i % 2 === 0) socks -= 1;
|
||||
if (i % 3 === 0) socks += 1;
|
||||
if (i % 5 === 0) socks -= 1;
|
||||
if (i % 10 === 0) socks += 2;
|
||||
|
||||
if (socks < 0) socks = 0;
|
||||
}
|
||||
|
||||
return Math.floor(socks / 2);
|
||||
}
|
||||
```
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da008
|
||||
title: "Challenge 70: HTML Attribute Extractor"
|
||||
challengeType: 28
|
||||
dashedName: challenge-70
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of a valid HTML element, return the attributes of the element using the following criteria:
|
||||
|
||||
- You will only be given one element.
|
||||
- Attributes will be in the format: `attribute="value"`.
|
||||
- Return an array of strings with each attribute property and value, separated by a comma, in this format: `["attribute1, value1", "attribute2, value2"]`.
|
||||
- Return attributes in the order they are given.
|
||||
- If no attributes are found, return an empty array.
|
||||
|
||||
# --hints--
|
||||
|
||||
`extractAttributes('<span class="red"></span>')` should return `["class, red"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(extractAttributes('<span class="red"></span>'), ["class, red"]);
|
||||
```
|
||||
|
||||
`extractAttributes('<meta charset="UTF-8" />')` should return `["charset, UTF-8"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(extractAttributes('<meta charset="UTF-8" />'), ["charset, UTF-8"]);
|
||||
```
|
||||
|
||||
`extractAttributes("<p>Lorem ipsum dolor sit amet</p>")` should return `[]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(extractAttributes("<p>Lorem ipsum dolor sit amet</p>"), []);
|
||||
```
|
||||
|
||||
`extractAttributes('<input name="email" type="email" required="true" />')` should return `["name, email", "type, email", "required, true"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(extractAttributes('<input name="email" type="email" required="true" />'), ["name, email", "type, email", "required, true"]);
|
||||
```
|
||||
|
||||
`extractAttributes('<button id="submit" class="btn btn-primary">Submit</button>')` should return `["id, submit", "class, btn btn-primary"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(extractAttributes('<button id="submit" class="btn btn-primary">Submit</button>'), ["id, submit", "class, btn btn-primary"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function extractAttributes(element) {
|
||||
|
||||
return element;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function extractAttributes(element) {
|
||||
const regex = /(\w[\w-]*)="([^"]*)"/g;
|
||||
const result = [];
|
||||
let match;
|
||||
|
||||
while ((match = regex.exec(element)) !== null) {
|
||||
const attr = match[1];
|
||||
const val = match[2];
|
||||
result.push(`${attr}, ${val}`);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da009
|
||||
title: "Challenge 71: Tip Calculator"
|
||||
challengeType: 28
|
||||
dashedName: challenge-71
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given the price of your meal and a custom tip percent, return an array with three tip values; 15%, 20%, and the custom amount.
|
||||
|
||||
- Prices will be given in the format: `"$N.NN"`.
|
||||
- Custom tip percents will be given in this format: `"25%"`.
|
||||
- Return amounts in the same `"$N.NN"` format, rounded to two decimal places.
|
||||
|
||||
For example, given a `"$10.00"` meal price, and a `"25%"` custom tip value, return `["$1.50", "$2.00", "$2.50"]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`calculateTips("$10.00", "25%")` should return `["$1.50", "$2.00", "$2.50"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(calculateTips("$10.00", "25%"), ["$1.50", "$2.00", "$2.50"]);
|
||||
```
|
||||
|
||||
`calculateTips("$89.67", "26%")` should return `["$13.45", "$17.93", "$23.31"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(calculateTips("$89.67", "26%"), ["$13.45", "$17.93", "$23.31"]);
|
||||
```
|
||||
|
||||
`calculateTips("$19.85", "9%")` should return `["$2.98", "$3.97", "$1.79"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(calculateTips("$19.85", "9%"), ["$2.98", "$3.97", "$1.79"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function calculateTips(mealPrice, customTip) {
|
||||
|
||||
return mealPrice;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function calculateTips(mealPrice, customTip) {
|
||||
const meal = parseFloat(mealPrice.slice(1));
|
||||
const customPercent = parseFloat(customTip.slice(0, -1));
|
||||
const tips = [15, 20, customPercent];
|
||||
|
||||
return tips.map(percent => {
|
||||
const amount = (meal * percent / 100).toFixed(2);
|
||||
return `$${amount}`;
|
||||
});
|
||||
}
|
||||
```
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da00a
|
||||
title: "Challenge 72: Thermostat Adjuster 2"
|
||||
challengeType: 28
|
||||
dashedName: challenge-72
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given the current temperature of a room in Fahrenheit and a target temperature in Celsius, return a string indicating how to adjust the room temperature based on these constraints:
|
||||
|
||||
- Return `"Heat: X degrees Fahrenheit"` if the current temperature is below the target. With `X` being the number of degrees in Fahrenheit to heat the room to reach the target, rounded to 1 decimal place.
|
||||
- Return `"Cool: X degrees Fahrenheit"` if the current temperature is above the target. With `X` being the number of degrees in Fahrenheit to cool the room to reach the target, rounded to 1 decimal place.
|
||||
- Return `"Hold"` if the current temperature is equal to the target.
|
||||
|
||||
To convert Celsius to Fahrenheit, multiply the Celsius temperature by 1.8 and add 32 to the result (`F = (C * 1.8) + 32`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`adjustThermostat(32, 0)` should return `"Hold"`.
|
||||
|
||||
```js
|
||||
assert.equal(adjustThermostat(32, 0), "Hold");
|
||||
```
|
||||
|
||||
`adjustThermostat(70, 25)` should return `"Heat: 7.0 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
assert.equal(adjustThermostat(70, 25), "Heat: 7.0 degrees Fahrenheit");
|
||||
```
|
||||
|
||||
`adjustThermostat(72, 18)` should return `"Cool: 7.6 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
assert.equal(adjustThermostat(72, 18), "Cool: 7.6 degrees Fahrenheit");
|
||||
```
|
||||
|
||||
`adjustThermostat(212, 100)` should return `"Hold"`.
|
||||
|
||||
```js
|
||||
assert.equal(adjustThermostat(212, 100), "Hold");
|
||||
```
|
||||
|
||||
`adjustThermostat(59, 22)` should return `"Heat: 12.6 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
assert.equal(adjustThermostat(59, 22), "Heat: 12.6 degrees Fahrenheit");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function adjustThermostat(currentF, targetC) {
|
||||
|
||||
return currentF;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function adjustThermostat(currentF, targetC) {
|
||||
const targetF = targetC * 1.8 + 32;
|
||||
const diff = Math.abs(targetF - currentF).toFixed(1);
|
||||
|
||||
if (currentF < targetF) {
|
||||
return `Heat: ${diff} degrees Fahrenheit`;
|
||||
} else if (currentF > targetF) {
|
||||
return `Cool: ${diff} degrees Fahrenheit`;
|
||||
} else {
|
||||
return "Hold"
|
||||
}
|
||||
}
|
||||
```
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487ce
|
||||
title: "Challenge 73: Speak Wisely, You Must"
|
||||
challengeType: 28
|
||||
dashedName: challenge-73
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a sentence, return a version of it that sounds like advice from a wise teacher using the following rules:
|
||||
|
||||
- Words are separated by a single space.
|
||||
- Find the first occurrence of one of the following words in the sentence: `"have"`, `"must"`, `"are"`, `"will"`, `"can"`.
|
||||
- Move all words before and including that word to the end of the sentence and:
|
||||
- Preserve the order of the words when you move them.
|
||||
- Make them all lowercase.
|
||||
- And add a comma and space before them.
|
||||
- Capitalize the first letter of the new first word of the sentence.
|
||||
- All given sentences will end with a single punctuation mark. Keep the original punctuation of the sentence and move it to the end of the new sentence.
|
||||
- Return the new sentence, make sure there's a single space between each word and no spaces at the beginning or end of the sentence.
|
||||
|
||||
For example, given `"You must speak wisely."` return `"Speak wisely, you must."`
|
||||
|
||||
# --hints--
|
||||
|
||||
`wiseSpeak("You must speak wisely.")` should return `"Speak wisely, you must."`
|
||||
|
||||
```js
|
||||
assert.equal(wiseSpeak("You must speak wisely."), "Speak wisely, you must.");
|
||||
```
|
||||
|
||||
`wiseSpeak("You can do it!")` should return `"Do it, you can!"`
|
||||
|
||||
```js
|
||||
assert.equal(wiseSpeak("You can do it!"), "Do it, you can!");
|
||||
```
|
||||
|
||||
`wiseSpeak("Do you think you will complete this?")` should return `"Complete this, do you think you will?"`
|
||||
|
||||
```js
|
||||
assert.equal(wiseSpeak("Do you think you will complete this?"), "Complete this, do you think you will?");
|
||||
```
|
||||
|
||||
`wiseSpeak("All your base are belong to us.")` should return `"Belong to us, all your base are."`
|
||||
|
||||
```js
|
||||
assert.equal(wiseSpeak("All your base are belong to us."), "Belong to us, all your base are.");
|
||||
```
|
||||
|
||||
`wiseSpeak("You have much to learn.")` should return `"Much to learn, you have."`
|
||||
|
||||
```js
|
||||
assert.equal(wiseSpeak("You have much to learn."), "Much to learn, you have.");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function wiseSpeak(sentence) {
|
||||
|
||||
return sentence;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function wiseSpeak(sentence) {
|
||||
const triggers = ["have", "must", "are", "will", "can"];
|
||||
const punctuation = sentence[sentence.length - 1];
|
||||
const words = sentence.split(" ");
|
||||
|
||||
const triggerIndex = words.findIndex(w => triggers.includes(w));
|
||||
|
||||
const toMove = words.slice(0, triggerIndex + 1).map(w => w.toLowerCase());
|
||||
const remaining = words.slice(triggerIndex + 1);
|
||||
|
||||
const newStart = remaining.map((w, i) => {
|
||||
return i === 0 ? w[0].toUpperCase() + w.slice(1) :
|
||||
i === remaining.length - 1 ? w.slice(0, w.length - 1) : w;
|
||||
})
|
||||
|
||||
return newStart.join(" ") + ", " + toMove.join(" ") + punctuation;
|
||||
}
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487cf
|
||||
title: "Challenge 74: Favorite Songs"
|
||||
challengeType: 28
|
||||
dashedName: challenge-74
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Remember iPods? The first model came out 24 years ago today, on Oct. 23, 2001.
|
||||
|
||||
Given an array of song objects representing your iPod playlist, return an array with the titles of the two most played songs, with the most played song first.
|
||||
|
||||
- Each object will have a `"title"` property (string), and a `"plays"` property (integer).
|
||||
|
||||
# --hints--
|
||||
|
||||
`favoriteSongs([{"title": "Sync or Swim", "plays": 3}, {"title": "Byte Me", "plays": 1}, {"title": "Earbud Blues", "plays": 2} ])` should return `["Sync or Swim", "Earbud Blues"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(favoriteSongs([{"title": "Sync or Swim", "plays": 3}, {"title": "Byte Me", "plays": 1}, {"title": "Earbud Blues", "plays": 2} ]), ["Sync or Swim", "Earbud Blues"]);
|
||||
```
|
||||
|
||||
`favoriteSongs([{"title": "Skip Track", "plays": 98}, {"title": "99 Downloads", "plays": 99}, {"title": "Clickwheel Love", "plays": 100} ])` should return `["Clickwheel Love", "99 Downloads"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(favoriteSongs([{"title": "Skip Track", "plays": 98}, {"title": "99 Downloads", "plays": 99}, {"title": "Clickwheel Love", "plays": 100} ]), ["Clickwheel Love", "99 Downloads"]);
|
||||
```
|
||||
|
||||
`favoriteSongs([{"title": "Song A", "plays": 42}, {"title": "Song B", "plays": 99}, {"title": "Song C", "plays": 75} ])` should return `["Song B", "Song C"]`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(favoriteSongs([{"title": "Song A", "plays": 42}, {"title": "Song B", "plays": 99}, {"title": "Song C", "plays": 75} ]), ["Song B", "Song C"]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function favoriteSongs(playlist) {
|
||||
|
||||
return playlist;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function favoriteSongs(playlist) {
|
||||
const sorted = [...playlist].sort((a, b) => b.plays - a.plays);
|
||||
return sorted.slice(0, 2).map(song => song.title);
|
||||
}
|
||||
```
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487d0
|
||||
title: "Challenge 75: Missile Strike"
|
||||
challengeType: 28
|
||||
dashedName: challenge-75
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a 2D array representing the location of your ship in the ocean, and an array with the coordinates (`[row, column]`) of a missile strike, return `"Hit"`, `"Miss"`, or `"Sunk"` using the following rules:
|
||||
|
||||
- The given 2D array will contain exactly one unsunk ship.
|
||||
- Each cell in the 2D array will contain one of the following values:
|
||||
- `"-"`: Water (no ship).
|
||||
- `"O"`: A part of your ship that has not been struck.
|
||||
- `"X"`: A part of your ship that has already been struck.
|
||||
|
||||
- If the strike hits the water, return `"Miss"`.
|
||||
- If the strike hits your ship, but at least one other part of the ship remains unstruck, return `"Hit"`.
|
||||
- If the strike hits the last unstruck part of your ship, return `"Sunk"`.
|
||||
|
||||
For example, given:
|
||||
|
||||
```json
|
||||
[
|
||||
[ "-", "X"],
|
||||
[ "-", "X"],
|
||||
[ "-", "O"]
|
||||
]
|
||||
```
|
||||
|
||||
And `[2, 1]` for the coordinates of the missile strike, return `"Sunk"` because it hit the last unstruck part of your ship.
|
||||
|
||||
# --hints--
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 1])` should return `"Sunk"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 1]), "Sunk");
|
||||
```
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 0])` should return `"Miss"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 0]), "Miss");
|
||||
```
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "O"], [ "-", "O"]], [1, 1])` should return `"Hit"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "X"], [ "-", "O"], [ "-", "O"]], [1, 1]), "Hit");
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "X", "O", "X"], [ "-", "-", "-"]], [1, 2])` should return `"Hit"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "-", "-"], [ "X", "O", "X"], [ "-", "-", "-"]], [1, 2]), "Hit");
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [2, 0])` should return `"Sunk"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [2, 0]), "Sunk");
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [1, 2])` should return `"Miss"`.
|
||||
|
||||
```js
|
||||
assert.equal(strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [1, 2]), "Miss");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function strike(map, coordinates) {
|
||||
|
||||
return map;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function strike(map, coordinates) {
|
||||
const [row, col] = coordinates;
|
||||
const target = map[row][col];
|
||||
|
||||
if (target === "-") {
|
||||
return "Miss";
|
||||
}
|
||||
|
||||
if (target === "O") {
|
||||
for (let r = 0; r < map.length; r++) {
|
||||
for (let c = 0; c < map[r].length; c++) {
|
||||
if ((r !== row || c !== col) && map[r][c] === "O") {
|
||||
return "Hit";
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Sunk";
|
||||
}
|
||||
|
||||
return "Hit";
|
||||
}
|
||||
```
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46bc
|
||||
title: "Challenge 76: Complementary DNA"
|
||||
challengeType: 28
|
||||
dashedName: challenge-76
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing a DNA sequence, return its complementary strand using the following rules:
|
||||
|
||||
- DNA consists of the letters `"A"`, `"C"`, `"G"`, and `"T"`.
|
||||
- The letters `"A"` and `"T"` complement each other.
|
||||
- The letters `"C"` and `"G"` complement each other.
|
||||
|
||||
For example, given `"ACGT"`, return `"TGCA"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`complementaryDNA("ACGT")` should return `"TGCA"`.
|
||||
|
||||
```js
|
||||
assert.equal(complementaryDNA("ACGT"), "TGCA");
|
||||
```
|
||||
|
||||
`complementaryDNA("ATGCGTACGTTAGC")` should return `"TACGCATGCAATCG"`.
|
||||
|
||||
```js
|
||||
assert.equal(complementaryDNA("ATGCGTACGTTAGC"), "TACGCATGCAATCG");
|
||||
```
|
||||
|
||||
`complementaryDNA("GGCTTACGATCGAAG")` should return `"CCGAATGCTAGCTTC"`.
|
||||
|
||||
```js
|
||||
assert.equal(complementaryDNA("GGCTTACGATCGAAG"), "CCGAATGCTAGCTTC");
|
||||
```
|
||||
|
||||
`complementaryDNA("GATCTAGCTAGGCTAGCTAG")` should return `"CTAGATCGATCCGATCGATC"`.
|
||||
|
||||
```js
|
||||
assert.equal(complementaryDNA("GATCTAGCTAGGCTAGCTAG"), "CTAGATCGATCCGATCGATC");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function complementaryDNA(strand) {
|
||||
|
||||
return strand;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function complementaryDNA(strand) {
|
||||
const complements = { A: "T", T: "A", C: "G", G: "C" };
|
||||
return strand
|
||||
.split("")
|
||||
.map(c => complements[c])
|
||||
.join("");
|
||||
}
|
||||
```
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46bd
|
||||
title: "Challenge 77: Duration Formatter"
|
||||
challengeType: 28
|
||||
dashedName: challenge-77
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given an integer number of seconds, return a string representing the same duration in the format `"H:MM:SS"`, where `"H"` is the number of hours, `"MM"` is the number of minutes, and `"SS"` is the number of seconds. Return the time using the following rules:
|
||||
|
||||
- Seconds: Should always be two digits.
|
||||
- Minutes: Should omit leading zeros when they aren't needed. Use `"0"` if the duration is less than one minute.
|
||||
- Hours: Should be included only if they're greater than zero.
|
||||
|
||||
# --hints--
|
||||
|
||||
`format(500)` should return `"8:20"`.
|
||||
|
||||
```js
|
||||
assert.equal(format(500), "8:20");
|
||||
```
|
||||
|
||||
`format(4000)` should return `"1:06:40"`.
|
||||
|
||||
```js
|
||||
assert.equal(format(4000), "1:06:40");
|
||||
```
|
||||
|
||||
`format(1)` should return `"0:01"`.
|
||||
|
||||
```js
|
||||
assert.equal(format(1), "0:01");
|
||||
```
|
||||
|
||||
`format(5555)` should return `"1:32:35"`.
|
||||
|
||||
```js
|
||||
assert.equal(format(5555), "1:32:35");
|
||||
```
|
||||
|
||||
`format(99999)` should return `"27:46:39"`.
|
||||
|
||||
```js
|
||||
assert.equal(format(99999), "27:46:39");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function format(seconds) {
|
||||
|
||||
return seconds;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function format(seconds) {
|
||||
const h = Math.floor(seconds / 3600);
|
||||
const m = Math.floor((seconds % 3600) / 60);
|
||||
const s = seconds % 60;
|
||||
|
||||
const secondsStr = s.toString().padStart(2, "0");
|
||||
const minutesStr = m.toString();
|
||||
|
||||
if (h > 0) {
|
||||
const hoursStr = h.toString();
|
||||
return `${hoursStr}:${minutesStr.padStart(2, "0")}:${secondsStr}`;
|
||||
} else {
|
||||
return `${minutesStr}:${secondsStr}`;
|
||||
}
|
||||
}
|
||||
```
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46be
|
||||
title: "Challenge 78: Integer Sequence"
|
||||
challengeType: 28
|
||||
dashedName: challenge-78
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a positive integer, return a string with all of the integers from `1` up to, and including, the given number, in numerical order.
|
||||
|
||||
For example, given `5`, return `"12345"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`sequence(5)` should return `"12345"`.
|
||||
|
||||
```js
|
||||
assert.equal(sequence(5), "12345");
|
||||
```
|
||||
|
||||
`sequence(10)` should return `"12345678910"`.
|
||||
|
||||
```js
|
||||
assert.equal(sequence(10), "12345678910");
|
||||
```
|
||||
|
||||
`sequence(1)` should return `"1"`.
|
||||
|
||||
```js
|
||||
assert.strictEqual(sequence(1), "1");
|
||||
```
|
||||
|
||||
`sequence(27)` should return `"123456789101112131415161718192021222324252627"`.
|
||||
|
||||
```js
|
||||
assert.equal(sequence(27), "123456789101112131415161718192021222324252627");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function sequence(n) {
|
||||
|
||||
return n;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function sequence(n) {
|
||||
let result = "";
|
||||
for (let i = 1; i <= n; i++) {
|
||||
result += i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
```
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
---
|
||||
id: 68d30fc57588d97fd3027b30
|
||||
title: "Challenge 79: Navigator"
|
||||
challengeType: 28
|
||||
dashedName: challenge-79
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
On October 28, 1994, Netscape Navigator was released, helping millions explore the early web.
|
||||
|
||||
Given an array of browser commands you executed on Netscape Navigator, return the current page you are on after executing all the commands using the following rules:
|
||||
|
||||
- You always start on the `"Home"` page, which will not be included in the commands array.
|
||||
- Valid commands are:
|
||||
- `"Visit Page"`: Where `"Page"` is the name of the page you are visiting. For example, `"Visit About"` takes you to the `"About"` page. When you visit a new page, make sure to discard any forward history you have.
|
||||
- `"Back"`: Takes you to the previous page in your history or stays on the current page if there isn't one.
|
||||
- `"Forward"`: Takes you forward in the history to the page you came from or stays on the current page if there isn't one.
|
||||
|
||||
For example, given `["Visit About Us", "Back", "Forward"]`, return `"About Us"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`navigate(["Visit About Us", "Back", "Forward"])` should return `"About Us"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Visit About Us", "Back", "Forward"]), "About Us");
|
||||
```
|
||||
|
||||
`navigate(["Forward"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Forward"]), "Home");
|
||||
```
|
||||
|
||||
`navigate(["Back"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Back"]), "Home");
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Gallery"])` should return `"Gallery"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Visit About Us", "Visit Gallery"]), "Gallery");
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Gallery", "Back", "Back"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Visit About Us", "Visit Gallery", "Back", "Back"]), "Home");
|
||||
```
|
||||
|
||||
`navigate(["Visit About", "Visit Gallery", "Back", "Visit Contact", "Forward"])` should return `"Contact"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Visit About", "Visit Gallery", "Back", "Visit Contact", "Forward"]), "Contact");
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Visit Us", "Forward", "Visit Contact Us", "Back"])` should return `"Visit Us"`.
|
||||
|
||||
```js
|
||||
assert.equal(navigate(["Visit About Us", "Visit Visit Us", "Forward", "Visit Contact Us", "Back"]), "Visit Us");
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function navigate(commands) {
|
||||
|
||||
return commands;
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function navigate(commands) {
|
||||
const history = ["Home"];
|
||||
let currentPageIndex = 0;
|
||||
|
||||
for (const command of commands) {
|
||||
if (command.startsWith("Visit")) {
|
||||
history.splice(currentPageIndex + 1);
|
||||
history.push(command.slice(6));
|
||||
currentPageIndex++;
|
||||
} else if(command === "Back" && currentPageIndex > 0) {
|
||||
currentPageIndex--;
|
||||
} else if (command === "Forward" && currentPageIndex < history.length - 1) {
|
||||
currentPageIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return history[currentPageIndex];
|
||||
}
|
||||
```
|
||||
+3
-3
@@ -9,9 +9,9 @@ dashedName: challenge-36
|
||||
|
||||
Given the current temperature of a room and a target temperature, return a string indicating how to adjust the room temperature based on these constraints:
|
||||
|
||||
- Return "heat" if the current temperature is below the target.
|
||||
- Return "cool" if the current temperature is above the target.
|
||||
- Return "hold" if the current temperature is equal to the target.
|
||||
- Return `"heat"` if the current temperature is below the target.
|
||||
- Return `"cool"` if the current temperature is above the target.
|
||||
- Return `"hold"` if the current temperature is equal to the target.
|
||||
|
||||
# --hints--
|
||||
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da001
|
||||
title: "Challenge 63: Battle of Words"
|
||||
challengeType: 29
|
||||
dashedName: challenge-63
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two sentences representing your team and an opposing team, where each word from your team battles the corresponding word from the opposing team, determine which team wins using the following rules:
|
||||
|
||||
- The given sentences will always contain the same number of words.
|
||||
- Words are separated by a single space and will only contain letters.
|
||||
- The value of each word is the sum of its letters.
|
||||
- Letters `a` to `z` correspond to the values `1` through `26`. For example, `a` is `1`, and `z` is `26`.
|
||||
- A capital letter doubles the value of the letter. For example, `A` is `2`, and `Z` is `52`.
|
||||
- Words battle in order: the first word of your team battles the first word of the opposing team, and so on.
|
||||
- A word wins if its value is greater than the opposing word's value.
|
||||
- The team with more winning words is the winner.
|
||||
|
||||
Return `"We win"` if your team is the winner, `"We lose"` if your team loses, and `"Draw"` if both teams have the same number of wins.
|
||||
|
||||
# --hints--
|
||||
|
||||
`battle("hello world", "hello word")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("hello world", "hello word"), "We win")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("Hello world", "hello world")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("Hello world", "hello world"), "We win")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("lorem ipsum", "kitty ipsum")` should return `"We lose"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("lorem ipsum", "kitty ipsum"), "We lose")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("hello world", "world hello")` should return `"Draw"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("hello world", "world hello"), "Draw")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("git checkout", "git switch")` should return `"We win"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("git checkout", "git switch"), "We win")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("Cheeseburger with fries", "Cheeseburger with Fries")` should return `"We lose"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("Cheeseburger with fries", "Cheeseburger with Fries"), "We lose")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`battle("We must never surrender", "Our team must win")` should return `"Draw"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(battle("We must never surrender", "Our team must win"), "Draw")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def battle(our_team, opponent):
|
||||
|
||||
return our_team
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def get_word_value(word):
|
||||
value = 0
|
||||
for char in word:
|
||||
val = ord(char.lower()) - ord('a') + 1
|
||||
if char.isupper():
|
||||
val *= 2
|
||||
value += val
|
||||
return value
|
||||
|
||||
def battle(our_team, opponent):
|
||||
my_wins = 0
|
||||
opp_wins = 0
|
||||
|
||||
for my_word, opp_word in zip(our_team.split(), opponent.split()):
|
||||
my_val = get_word_value(my_word)
|
||||
opp_val = get_word_value(opp_word)
|
||||
|
||||
if my_val > opp_val:
|
||||
my_wins += 1
|
||||
elif opp_val > my_val:
|
||||
opp_wins += 1
|
||||
|
||||
if my_wins > opp_wins:
|
||||
return "We win"
|
||||
elif opp_wins > my_wins:
|
||||
return "We lose"
|
||||
else:
|
||||
return "Draw"
|
||||
```
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da002
|
||||
title: "Challenge 64: 24 to 12"
|
||||
challengeType: 29
|
||||
dashedName: challenge-64
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing a time of the day in the 24-hour format of `"HHMM"`, return the time in its equivalent 12-hour format of `"H:MM AM"` or `"H:MM PM"`.
|
||||
|
||||
- The given input will always be a four-digit string in 24-hour time format, from `"0000"` to `"2359"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`to_12("1124")` should return `"11:24 AM"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_12("1124"), "11:24 AM")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_12("0900")` should return `"9:00 AM"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_12("0900"), "9:00 AM")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_12("1455")` should return `"2:55 PM"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_12("1455"), "2:55 PM")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_12("2346")` should return `"11:46 PM"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_12("2346"), "11:46 PM")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`to_12("0030")` should return `"12:30 AM"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(to_12("0030"), "12:30 AM")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def to_12(time):
|
||||
|
||||
return time
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def convert_hours(hours):
|
||||
if hours == 0:
|
||||
return 12
|
||||
elif hours > 12:
|
||||
return hours - 12
|
||||
else:
|
||||
return hours
|
||||
|
||||
def to_12(time):
|
||||
hours = int(time[:2])
|
||||
minutes = time[2:]
|
||||
period = "AM" if hours < 12 else "PM"
|
||||
|
||||
return f"{convert_hours(hours)}:{minutes} {period}"
|
||||
```
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da003
|
||||
title: "Challenge 65: String Count"
|
||||
challengeType: 29
|
||||
dashedName: challenge-65
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given two strings, determine how many times the second string appears in the first.
|
||||
|
||||
- The pattern string can overlap in the first string. For example, `"aaa"` contains `"aa"` twice. The first two `a`'s and the second two.
|
||||
|
||||
# --hints--
|
||||
|
||||
`count('abcdefg', 'def')` should return `1`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count('abcdefg', 'def'), 1)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count('hello', 'world')` should return `0`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count('hello', 'world'), 0)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count('mississippi', 'iss')` should return `2`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count('mississippi', 'iss'), 2)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count('she sells seashells by the seashore', 'sh')` should return `3`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count('she sells seashells by the seashore', 'sh'), 3)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`count('101010101010101010101', '101')` should return `10`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(count('101010101010101010101', '101'), 10)`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def count(text, parameter):
|
||||
|
||||
return text
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def count(text, pattern):
|
||||
if not pattern:
|
||||
return 0
|
||||
occurrences = 0
|
||||
|
||||
for i in range(len(text) - len(pattern) + 1):
|
||||
if text[i:i+len(pattern)] == pattern:
|
||||
occurrences += 1
|
||||
|
||||
return occurrences
|
||||
```
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da004
|
||||
title: "Challenge 66: HTML Tag Stripper"
|
||||
challengeType: 29
|
||||
dashedName: challenge-66
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of HTML code, remove the tags and return the plain text content.
|
||||
|
||||
- The input string will contain only valid HTML.
|
||||
- HTML tags may be nested.
|
||||
- Remove the tags and any attributes.
|
||||
|
||||
For example, `'<a href="#">Click here</a>'` should return `"Click here"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`strip_tags('<a href="#">Click here</a>')` should return `"Click here"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strip_tags('<a href="#">Click here</a>'), "Click here")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strip_tags('<p class="center">Hello <b>World</b>!</p>')` should return `"Hello World!"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strip_tags('<p class="center">Hello <b>World</b>!</p>'), "Hello World!")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strip_tags('<img src="cat.jpg" alt="Cat">')` should return an empty string (`""`).
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strip_tags('<img src="cat.jpg" alt="Cat">'), "")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strip_tags('<main id="main"><section class="section">section</section><section class="section">section</section></main>')` should return `sectionsection`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strip_tags('<main id="main"><section class="section">section</section><section class="section">section</section></main>'), "sectionsection")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def strip_tags(html):
|
||||
|
||||
return html
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def strip_tags(html):
|
||||
return re.sub(r'<[^>]*>', '', html)
|
||||
```
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da005
|
||||
title: "Challenge 67: Email Validator"
|
||||
challengeType: 29
|
||||
dashedName: challenge-67
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string, determine if it is a valid email address using the following constraints:
|
||||
|
||||
- It must contain exactly one `@` symbol.
|
||||
- The local part (before the `@`):
|
||||
- Can only contain letters (`a-z`, `A-Z`), digits (`0-9`), dots (`.`), underscores (`_`), or hyphens (`-`).
|
||||
- Cannot start or end with a dot.
|
||||
- The domain part (after the `@`):
|
||||
- Must contain at least one dot.
|
||||
- Must end with a dot followed by at least two letters.
|
||||
- Neither the local or domain part can have two dots in a row.
|
||||
|
||||
# --hints--
|
||||
|
||||
`validate("a@b.cd")` should return `True`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("a@b.cd"), True)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("hell.-w.rld@example.com")` should return `True`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("hell.-w.rld@example.com"), True)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate(".b@sh.rc")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate(".b@sh.rc"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("example@test.c0")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("example@test.c0"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("freecodecamp.org")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("freecodecamp.org"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("develop.ment_user@c0D!NG.R.CKS")` should return `True`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("develop.ment_user@c0D!NG.R.CKS"), True)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("hello.@wo.rld")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("hello.@wo.rld"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("hello@world..com")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("hello@world..com"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`validate("git@commit@push.io")` should return `False`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertIs(validate("git@commit@push.io"), False)`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def validate(email):
|
||||
|
||||
return email
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def validate(email):
|
||||
if '..' in email:
|
||||
return False
|
||||
|
||||
parts = email.split('@')
|
||||
if len(parts) != 2:
|
||||
return False
|
||||
|
||||
local, domain = parts
|
||||
|
||||
if local.startswith('.') or local.endswith('.'):
|
||||
return False
|
||||
if not re.match(r'^[a-zA-Z0-9._-]+$', local):
|
||||
return False
|
||||
|
||||
if '.' not in domain:
|
||||
return False
|
||||
|
||||
tld = domain.split('.')[-1]
|
||||
if len(tld) < 2 or not tld.isalpha():
|
||||
return False
|
||||
|
||||
return True
|
||||
```
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da006
|
||||
title: "Challenge 68: Credit Card Masker"
|
||||
challengeType: 29
|
||||
dashedName: challenge-68
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of credit card numbers, return a masked version of it using the following constraints:
|
||||
|
||||
- The string will contain four sets of four digits (`0-9`), with all sets being separated by a single space, or a single hyphen (`-`).
|
||||
- Replace all numbers, except the last four, with an asterisk (`*`).
|
||||
- Leave the remaining characters unchanged.
|
||||
|
||||
For example, given `"4012-8888-8888-1881"` return `"****-****-****-1881"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`mask("4012-8888-8888-1881")` should return `"****-****-****-1881"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(mask("4012-8888-8888-1881"), "****-****-****-1881")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`mask("5105 1051 0510 5100")` should return `"**** **** **** 5100"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(mask("5105 1051 0510 5100"), "**** **** **** 5100")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`mask("6011 1111 1111 1117")` should return `"**** **** **** 1117"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(mask("6011 1111 1111 1117"), "**** **** **** 1117")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`mask("2223-0000-4845-0010")` should return `"****-****-****-0010"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(mask("2223-0000-4845-0010"), "****-****-****-0010")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def mask(card):
|
||||
|
||||
return card
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def mask(card):
|
||||
if '-' in card:
|
||||
split = card.split('-')
|
||||
return f"****-****-****-{split[3]}"
|
||||
else:
|
||||
split = card.split(' ')
|
||||
return f"**** **** **** {split[3]}"
|
||||
```
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da007
|
||||
title: "Challenge 69: Missing Socks"
|
||||
challengeType: 29
|
||||
dashedName: challenge-69
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given an integer representing the number of pairs of socks you started with, and another integer representing how many wash cycles you have gone through, return the number of complete pairs of socks you currently have using the following constraints:
|
||||
|
||||
- Every 2 wash cycles, you lose a single sock.
|
||||
- Every 3 wash cycles, you find a single missing sock.
|
||||
- Every 5 wash cycles, a single sock is worn out and must be thrown away.
|
||||
- Every 10 wash cycles, you buy a pair of socks.
|
||||
- You can never have less than zero total socks.
|
||||
- Rules can overlap. For example, on wash cycle 10, you will lose a single sock, throw away a single sock, and buy a new pair of socks.
|
||||
- Return the number of complete pairs of socks.
|
||||
|
||||
# --hints--
|
||||
|
||||
`sock_pairs(2, 5)` should return `1`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sock_pairs(2, 5), 1)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sock_pairs(1, 2)` should return `0`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sock_pairs(1, 2), 0)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sock_pairs(5, 11)` should return `4`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sock_pairs(5, 11), 4)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sock_pairs(6, 25)` should return `3`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sock_pairs(6, 25), 3)`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sock_pairs(1, 8)` should return `0`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sock_pairs(1, 8), 0)`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def sock_pairs(pairs, cycles):
|
||||
|
||||
return pairs
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def sock_pairs(pairs, cycles):
|
||||
socks = pairs * 2
|
||||
|
||||
for i in range(1, cycles + 1):
|
||||
if i % 2 == 0:
|
||||
socks -= 1
|
||||
if i % 3 == 0:
|
||||
socks += 1
|
||||
if i % 5 == 0:
|
||||
socks -= 1
|
||||
if i % 10 == 0:
|
||||
socks += 2
|
||||
|
||||
if socks < 0:
|
||||
socks = 0
|
||||
|
||||
return socks // 2
|
||||
```
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da008
|
||||
title: "Challenge 70: HTML Attribute Extractor"
|
||||
challengeType: 29
|
||||
dashedName: challenge-70
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string of a valid HTML element, return the attributes of the element using the following criteria:
|
||||
|
||||
- You will only be given one element.
|
||||
- Attributes will be in the format: `attribute="value"`.
|
||||
- Return an array of strings with each attribute property and value, separated by a comma, in this format: `["attribute1, value1", "attribute2, value2"]`.
|
||||
- Return attributes in the order they are given.
|
||||
- If no attributes are found, return an empty array.
|
||||
|
||||
# --hints--
|
||||
|
||||
`extract_attributes('<span class="red"></span>')` should return `["class, red"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(extract_attributes('<span class="red"></span>'), ["class, red"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`extract_attributes('<meta charset="UTF-8" />')` should return `["charset, UTF-8"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(extract_attributes('<meta charset="UTF-8" />'), ["charset, UTF-8"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`extract_attributes("<p>Lorem ipsum dolor sit amet</p>")` should return `[]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(extract_attributes("<p>Lorem ipsum dolor sit amet</p>"), [])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`extract_attributes('<input name="email" type="email" required="true" />')` should return `["name, email", "type, email", "required, true"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(extract_attributes('<input name="email" type="email" required="true" />'), ["name, email", "type, email", "required, true"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`extract_attributes('<button id="submit" class="btn btn-primary">Submit</button>')` should return `["id, submit", "class, btn btn-primary"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(extract_attributes('<button id="submit" class="btn btn-primary">Submit</button>'), ["id, submit", "class, btn btn-primary"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def extract_attributes(element):
|
||||
|
||||
return element
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
import re
|
||||
def extract_attributes(element):
|
||||
pattern = r'([\w-]+)="([^"]*)"'
|
||||
matches = re.findall(pattern, element)
|
||||
return [f"{attr}, {val}" for attr, val in matches]
|
||||
```
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da009
|
||||
title: "Challenge 71: Tip Calculator"
|
||||
challengeType: 29
|
||||
dashedName: challenge-71
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given the price of your meal and a custom tip percent, return an array with three tip values; 15%, 20%, and the custom amount.
|
||||
|
||||
- Prices will be given in the format: `"$N.NN"`.
|
||||
- Custom tip percents will be given in this format: `"25%"`.
|
||||
- Return amounts in the same `"$N.NN"` format, rounded to two decimal places.
|
||||
|
||||
For example, given a `"$10.00"` meal price, and a `"25%"` custom tip value, return `["$1.50", "$2.00", "$2.50"]`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`calculate_tips("$10.00", "25%")` should return `["$1.50", "$2.00", "$2.50"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(calculate_tips("$10.00", "25%"), ["$1.50", "$2.00", "$2.50"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`calculate_tips("$89.67", "26%")` should return `["$13.45", "$17.93", "$23.31"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(calculate_tips("$89.67", "26%"), ["$13.45", "$17.93", "$23.31"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`calculate_tips("$19.85", "9%")` should return `["$2.98", "$3.97", "$1.79"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(calculate_tips("$19.85", "9%"), ["$2.98", "$3.97", "$1.79"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def calculate_tips(meal_price, custom_tip):
|
||||
|
||||
return meal_price
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def calculate_tips(meal_price, custom_tip):
|
||||
meal = float(meal_price[1:])
|
||||
custom_percent = float(custom_tip[:-1])
|
||||
|
||||
tips_percent = [15, 20, custom_percent]
|
||||
tips = [f"${meal * p / 100:.2f}" for p in tips_percent]
|
||||
|
||||
return tips
|
||||
```
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 68cae5b538ff798bbd4da00a
|
||||
title: "Challenge 72: Thermostat Adjuster 2"
|
||||
challengeType: 29
|
||||
dashedName: challenge-72
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given the current temperature of a room in Fahrenheit and a target temperature in Celsius, return a string indicating how to adjust the room temperature based on these constraints:
|
||||
|
||||
- Return `"Heat: X degrees Fahrenheit"` if the current temperature is below the target. With `X` being the number of degrees in Fahrenheit to heat the room to reach the target, rounded to 1 decimal place.
|
||||
- Return `"Cool: X degrees Fahrenheit"` if the current temperature is above the target. With `X` being the number of degrees in Fahrenheit to cool the room to reach the target, rounded to 1 decimal place.
|
||||
- Return `"Hold"` if the current temperature is equal to the target.
|
||||
|
||||
To convert Celsius to Fahrenheit, multiply the Celsius temperature by 1.8 and add 32 to the result (`F = (C * 1.8) + 32`).
|
||||
|
||||
# --hints--
|
||||
|
||||
`adjust_thermostat(32, 0)` should return `"Hold"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(adjust_thermostat(32, 0), "Hold")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`adjust_thermostat(70, 25)` should return `"Heat: 7.0 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(adjust_thermostat(70, 25), "Heat: 7.0 degrees Fahrenheit")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`adjust_thermostat(72, 18)` should return `"Cool: 7.6 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(adjust_thermostat(72, 18), "Cool: 7.6 degrees Fahrenheit")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`adjust_thermostat(212, 100)` should return `"Hold"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(adjust_thermostat(212, 100), "Hold")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`adjust_thermostat(59, 22)` should return `"Heat: 12.6 degrees Fahrenheit"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(adjust_thermostat(59, 22), "Heat: 12.6 degrees Fahrenheit")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def adjust_thermostat(current_f, target_c):
|
||||
|
||||
return current_f
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def adjust_thermostat(current_f, target_c):
|
||||
target_f = (target_c * 1.8) + 32
|
||||
diff = round(abs(target_f - current_f), 1)
|
||||
|
||||
if current_f < target_f:
|
||||
return f"Heat: {diff} degrees Fahrenheit"
|
||||
elif current_f > target_f:
|
||||
return f"Cool: {diff} degrees Fahrenheit"
|
||||
else:
|
||||
return "Hold"
|
||||
```
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487ce
|
||||
title: "Challenge 73: Speak Wisely, You Must"
|
||||
challengeType: 29
|
||||
dashedName: challenge-73
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a sentence, return a version of it that sounds like advice from a wise teacher using the following rules:
|
||||
|
||||
- Words are separated by a single space.
|
||||
- Find the first occurrence of one of the following words in the sentence: `"have"`, `"must"`, `"are"`, `"will"`, `"can"`.
|
||||
- Move all words before and including that word to the end of the sentence and:
|
||||
- Preserve the order of the words when you move them.
|
||||
- Make them all lowercase.
|
||||
- And add a comma and space before them.
|
||||
- Capitalize the first letter of the new first word of the sentence.
|
||||
- All given sentences will end with a single punctuation mark. Keep the original punctuation of the sentence and move it to the end of the new sentence.
|
||||
- Return the new sentence, make sure there's a single space between each word and no spaces at the beginning or end of the sentence.
|
||||
|
||||
For example, given `"You must speak wisely."` return `"Speak wisely, you must."`
|
||||
|
||||
# --hints--
|
||||
|
||||
`wise_speak("You must speak wisely.")` should return `"Speak wisely, you must."`
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(wise_speak("You must speak wisely."), "Speak wisely, you must.")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`wise_speak("You can do it!")` should return `"Do it, you can!"`
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(wise_speak("You can do it!"), "Do it, you can!")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`wise_speak("Do you think you will complete this?")` should return `"Complete this, do you think you will?"`
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(wise_speak("Do you think you will complete this?"), "Complete this, do you think you will?")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`wise_speak("All your base are belong to us.")` should return `"Belong to us, all your base are."`
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(wise_speak("All your base are belong to us."), "Belong to us, all your base are.")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`wise_speak("You have much to learn.")` should return `"Much to learn, you have."`
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(wise_speak("You have much to learn."), "Much to learn, you have.")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def wise_speak(sentence):
|
||||
|
||||
return sentence
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def wise_speak(sentence):
|
||||
triggers = ["have", "must", "are", "will", "can"]
|
||||
punctuation = sentence[-1]
|
||||
words = sentence[:-1].split(" ")
|
||||
|
||||
index = next(i for i, w in enumerate(words) if w in triggers)
|
||||
|
||||
to_move = [w.lower() for w in words[:index + 1]]
|
||||
remaining = words[index + 1:]
|
||||
|
||||
if remaining:
|
||||
remaining[0] = remaining[0][0].upper() + remaining[0][1:]
|
||||
|
||||
return " ".join(remaining) + ", " + " ".join(to_move) + punctuation
|
||||
```
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487cf
|
||||
title: "Challenge 74: Favorite Songs"
|
||||
challengeType: 29
|
||||
dashedName: challenge-74
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Remember iPods? The first model came out 24 years ago today, on Oct. 23, 2001.
|
||||
|
||||
Given an array of song objects representing your iPod playlist, return an array with the titles of the two most played songs, with the most played song first.
|
||||
|
||||
- Each object will have a `"title"` property (string), and a `"plays"` property (integer).
|
||||
|
||||
# --hints--
|
||||
|
||||
`favorite_songs([{"title": "Sync or Swim", "plays": 3}, {"title": "Byte Me", "plays": 1}, {"title": "Earbud Blues", "plays": 2} ])` should return `["Sync or Swim", "Earbud Blues"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(favorite_songs([{"title": "Sync or Swim", "plays": 3}, {"title": "Byte Me", "plays": 1}, {"title": "Earbud Blues", "plays": 2} ]), ["Sync or Swim", "Earbud Blues"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`favorite_songs([{"title": "Skip Track", "plays": 98}, {"title": "99 Downloads", "plays": 99}, {"title": "Clickwheel Love", "plays": 100} ])` should return `["Clickwheel Love", "99 Downloads"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(favorite_songs([{"title": "Skip Track", "plays": 98}, {"title": "99 Downloads", "plays": 99}, {"title": "Clickwheel Love", "plays": 100} ]), ["Clickwheel Love", "99 Downloads"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
`favorite_songs([{"title": "Song A", "plays": 42}, {"title": "Song B", "plays": 99}, {"title": "Song C", "plays": 75} ])` should return `["Song B", "Song C"]`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(favorite_songs([{"title": "Song A", "plays": 42}, {"title": "Song B", "plays": 99}, {"title": "Song C", "plays": 75} ]), ["Song B", "Song C"])`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def favorite_songs(playlist):
|
||||
|
||||
return playlist
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def favorite_songs(playlist):
|
||||
sorted_songs = sorted(playlist, key=lambda x: x["plays"], reverse=True)
|
||||
return [song["title"] for song in sorted_songs[:2]]
|
||||
```
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: 68d2ba1468508398389487d0
|
||||
title: "Challenge 75: Missile Strike"
|
||||
challengeType: 29
|
||||
dashedName: challenge-75
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a 2D array representing the location of your ship in the ocean, and an array with the coordinates (`[row, column]`) of a missile strike, return `"Hit"`, `"Miss"`, or `"Sunk"` using the following rules:
|
||||
|
||||
- The given 2D array will contain exactly one unsunk ship.
|
||||
- Each cell in the 2D array will contain one of the following values:
|
||||
- `"-"`: Water (no ship).
|
||||
- `"O"`: A part of your ship that has not been struck.
|
||||
- `"X"`: A part of your ship that has already been struck.
|
||||
|
||||
- If the strike hits the water, return `"Miss"`.
|
||||
- If the strike hits your ship, but at least one other part of the ship remains unstruck, return `"Hit"`.
|
||||
- If the strike hits the last unstruck part of your ship, return `"Sunk"`.
|
||||
|
||||
For example, given:
|
||||
|
||||
```json
|
||||
[
|
||||
[ "-", "X"],
|
||||
[ "-", "X"],
|
||||
[ "-", "O"]
|
||||
]
|
||||
```
|
||||
|
||||
And `[2, 1]` for the coordinates of the missile strike, return `"Sunk"` because it hit the last unstruck part of your ship.
|
||||
|
||||
# --hints--
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 1])` should return `"Sunk"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 1]), "Sunk")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 0])` should return `"Miss"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "X"], [ "-", "X"], [ "-", "O"]], [2, 0]), "Miss")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strike([[ "-", "X"], [ "-", "O"], [ "-", "O"]], [1, 1])` should return `"Hit"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "X"], [ "-", "O"], [ "-", "O"]], [1, 1]), "Hit")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "X", "O", "X"], [ "-", "-", "-"]], [1, 2])` should return `"Hit"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "-", "-"], [ "X", "O", "X"], [ "-", "-", "-"]], [1, 2]), "Hit")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [2, 0])` should return `"Sunk"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [2, 0]), "Sunk")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [1, 2])` should return `"Miss"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(strike([[ "-", "-", "-"], [ "-", "-", "-"], [ "O", "X", "X"]], [1, 2]), "Miss")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def strike(map, coordinates):
|
||||
|
||||
return map
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def strike(map, coordinates):
|
||||
row, col = coordinates
|
||||
target = map[row][col]
|
||||
|
||||
if target == "-":
|
||||
return "Miss"
|
||||
|
||||
if target == "O":
|
||||
for r in range(len(map)):
|
||||
for c in range(len(map[r])):
|
||||
if (r != row or c != col) and map[r][c] == "O":
|
||||
return "Hit"
|
||||
return "Sunk"
|
||||
|
||||
return "Hit"
|
||||
```
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46bc
|
||||
title: "Challenge 76: Complementary DNA"
|
||||
challengeType: 29
|
||||
dashedName: challenge-76
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a string representing a DNA sequence, return its complementary strand using the following rules:
|
||||
|
||||
- DNA consists of the letters `"A"`, `"C"`, `"G"`, and `"T"`.
|
||||
- The letters `"A"` and `"T"` complement each other.
|
||||
- The letters `"C"` and `"G"` complement each other.
|
||||
|
||||
For example, given `"ACGT"`, return `"TGCA"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`complementary_dna("ACGT")` should return `"TGCA"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(complementary_dna("ACGT"), "TGCA")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`complementary_dna("ATGCGTACGTTAGC")` should return `"TACGCATGCAATCG"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(complementary_dna("ATGCGTACGTTAGC"), "TACGCATGCAATCG")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`complementary_dna("GGCTTACGATCGAAG")` should return `"CCGAATGCTAGCTTC"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(complementary_dna("GGCTTACGATCGAAG"), "CCGAATGCTAGCTTC")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`complementary_dna("GATCTAGCTAGGCTAGCTAG")` should return `"CTAGATCGATCCGATCGATC"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(complementary_dna("GATCTAGCTAGGCTAGCTAG"), "CTAGATCGATCCGATCGATC")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def complementary_dna(strand):
|
||||
|
||||
return strand
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def complementary_dna(strand):
|
||||
complements = { "A": "T", "T": "A", "C": "G", "G": "C" }
|
||||
return "".join(complements[n] for n in strand)
|
||||
```
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46bd
|
||||
title: "Challenge 77: Duration Formatter"
|
||||
challengeType: 29
|
||||
dashedName: challenge-77
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given an integer number of seconds, return a string representing the same duration in the format `"H:MM:SS"`, where `"H"` is the number of hours, `"MM"` is the number of minutes, and `"SS"` is the number of seconds. Return the time using the following rules:
|
||||
|
||||
- Seconds: Should always be two digits.
|
||||
- Minutes: Should omit leading zeros when they aren't needed. Use `"0"` if the duration is less than one minute.
|
||||
- Hours: Should be included only if they're greater than zero.
|
||||
|
||||
# --hints--
|
||||
|
||||
`format(500)` should return `"8:20"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format(500), "8:20")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format(4000)` should return `"1:06:40"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format(4000), "1:06:40")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format(1)` should return `"0:01"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format(1), "0:01")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format(5555)` should return `"1:32:35"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format(5555), "1:32:35")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`format(99999)` should return `"27:46:39"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(format(99999), "27:46:39")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def format(seconds):
|
||||
|
||||
return seconds
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def format(seconds):
|
||||
h = seconds // 3600
|
||||
m = (seconds % 3600) // 60
|
||||
s = seconds % 60
|
||||
|
||||
seconds_str = f"{s:02d}"
|
||||
minutes_str = str(m)
|
||||
|
||||
if h > 0:
|
||||
hours_str = str(h)
|
||||
return f"{hours_str}:{minutes_str.zfill(2)}:{seconds_str}"
|
||||
else:
|
||||
return f"{minutes_str}:{seconds_str}"
|
||||
```
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
---
|
||||
id: 68d30845cc08266018fc46be
|
||||
title: "Challenge 78: Integer Sequence"
|
||||
challengeType: 29
|
||||
dashedName: challenge-78
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Given a positive integer, return a string with all of the integers from `1` up to, and including, the given number, in numerical order.
|
||||
|
||||
For example, given `5`, return `"12345"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`sequence(5)` should return `"12345"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sequence(5), "12345")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sequence(10)` should return `"12345678910"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sequence(10), "12345678910")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sequence(1)` should return `"1"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sequence(1), "1")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`sequence(27)` should return `"123456789101112131415161718192021222324252627"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(sequence(27), "123456789101112131415161718192021222324252627")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def sequence(n):
|
||||
|
||||
return n
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def sequence(n):
|
||||
result = ""
|
||||
for i in range(1, n + 1):
|
||||
result += str(i)
|
||||
return result
|
||||
```
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
---
|
||||
id: 68d30fc57588d97fd3027b30
|
||||
title: "Challenge 79: Navigator"
|
||||
challengeType: 29
|
||||
dashedName: challenge-79
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
On October 28, 1994, Netscape Navigator was released, helping millions explore the early web.
|
||||
|
||||
Given an array of browser commands you executed on Netscape Navigator, return the current page you are on after executing all the commands using the following rules:
|
||||
|
||||
- You always start on the `"Home"` page, which will not be included in the commands array.
|
||||
- Valid commands are:
|
||||
- `"Visit Page"`: Where `"Page"` is the name of the page you are visiting. For example, `"Visit About"` takes you to the `"About"` page. When you visit a new page, make sure to discard any forward history you have.
|
||||
- `"Back"`: Takes you to the previous page in your history or stays on the current page if there isn't one.
|
||||
- `"Forward"`: Takes you forward in the history to the page you came from or stays on the current page if there isn't one.
|
||||
|
||||
For example, given `["Visit About Us", "Back", "Forward"]`, return `"About Us"`.
|
||||
|
||||
# --hints--
|
||||
|
||||
`navigate(["Visit About Us", "Back", "Forward"])` should return `"About Us"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Visit About Us", "Back", "Forward"]), "About Us")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Forward"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Forward"]), "Home")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Back"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Back"]), "Home")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Gallery"])` should return `"Gallery"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Visit About Us", "Visit Gallery"]), "Gallery")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Gallery", "Back", "Back"])` should return `"Home"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Visit About Us", "Visit Gallery", "Back", "Back"]), "Home")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Visit About", "Visit Gallery", "Back", "Visit Contact", "Forward"])` should return `"Contact"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Visit About", "Visit Gallery", "Back", "Visit Contact", "Forward"]), "Contact")`)
|
||||
}})
|
||||
```
|
||||
|
||||
`navigate(["Visit About Us", "Visit Visit Us", "Forward", "Visit Contact Us", "Back"])` should return `"Visit Us"`.
|
||||
|
||||
```js
|
||||
({test: () => { runPython(`
|
||||
from unittest import TestCase
|
||||
TestCase().assertEqual(navigate(["Visit About Us", "Visit Visit Us", "Forward", "Visit Contact Us", "Back"]), "Visit Us")`)
|
||||
}})
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def navigate(commands):
|
||||
|
||||
return commands
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def navigate(commands):
|
||||
history = ["Home"]
|
||||
current_index = 0
|
||||
|
||||
for command in commands:
|
||||
if command.startswith("Visit "):
|
||||
history = history[:current_index + 1]
|
||||
history.append(command[6:])
|
||||
current_index += 1
|
||||
elif command == "Back" and current_index > 0:
|
||||
current_index -= 1
|
||||
elif command == "Forward" and current_index < len(history) - 1:
|
||||
current_index += 1
|
||||
|
||||
return history[current_index]
|
||||
```
|
||||
@@ -254,6 +254,74 @@
|
||||
{
|
||||
"id": "68c497f3aaefc9fd9f1b0e26",
|
||||
"title": "Challenge 62: Hex to Decimal"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da001",
|
||||
"title": "Challenge 63: Battle of Words"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da002",
|
||||
"title": "Challenge 64: 24 to 12"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da003",
|
||||
"title": "Challenge 65: String Count"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da004",
|
||||
"title": "Challenge 66: HTML Tag Stripper"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da005",
|
||||
"title": "Challenge 67: Email Validator"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da006",
|
||||
"title": "Challenge 68: Credit Card Masker"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da007",
|
||||
"title": "Challenge 69: Missing Socks"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da008",
|
||||
"title": "Challenge 70: HTML Attribute Extractor"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da009",
|
||||
"title": "Challenge 71: Tip Calculator"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da00a",
|
||||
"title": "Challenge 72: Thermostat Adjuster 2"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487ce",
|
||||
"title": "Challenge 73: Speak Wisely, You Must"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487cf",
|
||||
"title": "Challenge 74: Favorite Songs"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487d0",
|
||||
"title": "Challenge 75: Missile Strike"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46bc",
|
||||
"title": "Challenge 76: Complementary DNA"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46bd",
|
||||
"title": "Challenge 77: Duration Formatter"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46be",
|
||||
"title": "Challenge 78: Integer Sequence"
|
||||
},
|
||||
{
|
||||
"id": "68d30fc57588d97fd3027b30",
|
||||
"title": "Challenge 79: Navigator"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -253,6 +253,74 @@
|
||||
{
|
||||
"id": "68c497f3aaefc9fd9f1b0e26",
|
||||
"title": "Challenge 62: Hex to Decimal"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da001",
|
||||
"title": "Challenge 63: Battle of Words"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da002",
|
||||
"title": "Challenge 64: 24 to 12"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da003",
|
||||
"title": "Challenge 65: String Count"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da004",
|
||||
"title": "Challenge 66: HTML Tag Stripper"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da005",
|
||||
"title": "Challenge 67: Email Validator"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da006",
|
||||
"title": "Challenge 68: Credit Card Masker"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da007",
|
||||
"title": "Challenge 69: Missing Socks"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da008",
|
||||
"title": "Challenge 70: HTML Attribute Extractor"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da009",
|
||||
"title": "Challenge 71: Tip Calculator"
|
||||
},
|
||||
{
|
||||
"id": "68cae5b538ff798bbd4da00a",
|
||||
"title": "Challenge 72: Thermostat Adjuster 2"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487ce",
|
||||
"title": "Challenge 73: Speak Wisely, You Must"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487cf",
|
||||
"title": "Challenge 74: Favorite Songs"
|
||||
},
|
||||
{
|
||||
"id": "68d2ba1468508398389487d0",
|
||||
"title": "Challenge 75: Missile Strike"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46bc",
|
||||
"title": "Challenge 76: Complementary DNA"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46bd",
|
||||
"title": "Challenge 77: Duration Formatter"
|
||||
},
|
||||
{
|
||||
"id": "68d30845cc08266018fc46be",
|
||||
"title": "Challenge 78: Integer Sequence"
|
||||
},
|
||||
{
|
||||
"id": "68d30fc57588d97fd3027b30",
|
||||
"title": "Challenge 79: Navigator"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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 = 62;
|
||||
const EXPECTED_CHALLENGE_COUNT = 79;
|
||||
|
||||
// Date to set for the first challenge, second challenge will be one day later, etc...
|
||||
// **DO NOT CHANGE THIS AFTER RELEASE (if seeding production - okay for local dev)**
|
||||
|
||||
Reference in New Issue
Block a user