Ten short tasks. Try each one in the editor before opening the solution. Each states what the output should be, and there is more than one correct way to solve most of them.
1. Greeting
Create two variables, name and hour. Print Good morning, <name>! if hour is below 12, Good afternoon, <name>! if below 18, and Good evening, <name>! otherwise. Use a template literal.
Expected: with name = "Maya" and hour = 14, the output is Good afternoon, Maya!.
Show a possible solution
const name = "Maya";
const hour = 14;
let greeting;
if (hour < 12) greeting = "Good morning";
else if (hour < 18) greeting = "Good afternoon";
else greeting = "Good evening";
console.log(`${greeting}, ${name}!`); // → Good afternoon, Maya!
2. Clean a title into a slug
Write slugify(text) that trims the text, lowercases it, replaces spaces with - and removes everything except letters, digits and dashes.
Expected: slugify(" Hello, Big World! ") returns hello-big-world.
Show a possible solution
function slugify(text) {
return text
.trim()
.toLowerCase()
.replaceAll(" ", "-")
.replace(/[^a-z0-9-]/g, "");
}
console.log(slugify(" Hello, Big World! ")); // → hello-big-world
3. FizzBuzz
Print the numbers from 1 to 15. For multiples of 3 print Fizz, for multiples of 5 print Buzz, for multiples of both print FizzBuzz.
Expected: the 15th line is FizzBuzz, the 9th is Fizz, the 10th is Buzz.
Show a possible solution
for (let i = 1; i <= 15; i++) {
if (i % 15 === 0) console.log("FizzBuzz");
else if (i % 3 === 0) console.log("Fizz");
else if (i % 5 === 0) console.log("Buzz");
else console.log(i);
}
Test for 15 first, otherwise the % 3 branch would catch it.
4. Sum and average
Write stats(numbers) that returns an object { sum, average, max }. Return average: 0 for an empty array.
Expected: stats([2, 4, 9]) gives { sum: 15, average: 5, max: 9 }.
Show a possible solution
function stats(numbers) {
const sum = numbers.reduce((total, n) => total + n, 0);
return {
sum,
average: numbers.length ? sum / numbers.length : 0,
max: numbers.length ? Math.max(...numbers) : 0
};
}
console.log(stats([2, 4, 9])); // → { sum: 15, average: 5, max: 9 }
console.log(stats([])); // → { sum: 0, average: 0, max: 0 }
5. Count the vowels
Write countVowels(text) that counts a e i o u, ignoring case.
Expected: countVowels("JavaScript") returns 3.
Show a possible solution
const countVowels = text => [...text.toLowerCase()].filter(c => "aeiou".includes(c)).length;
console.log(countVowels("JavaScript")); // → 3
console.log(countVowels("Rhythm")); // → 0
6. Remove duplicates
Write unique(array) that returns a new array without duplicates, keeping the first occurrences in order.
Expected: unique([3, 1, 3, 2, 1]) returns [3, 1, 2].
Show a possible solution
const unique = array => [...new Set(array)];
console.log(unique([3, 1, 3, 2, 1])); // → [3, 1, 2]
7. Group people by city
Given an array of { name, city } objects, return an object that maps each city to a list of names.
Expected: { Pune: ["Maya", "Sam"], Delhi: ["Arjun"] }.
Show a possible solution
const people = [
{ name: "Maya", city: "Pune" },
{ name: "Arjun", city: "Delhi" },
{ name: "Sam", city: "Pune" }
];
const byCity = people.reduce((groups, person) => {
(groups[person.city] ??= []).push(person.name);
return groups;
}, {});
console.log(byCity); // → { Pune: ["Maya", "Sam"], Delhi: ["Arjun"] }
8. A counter with a closure
Write makeCounter(start = 0) that returns a function. Each call to that function returns the next number.
Expected: const next = makeCounter(5); next(); next(); returns 5 then 6.
Show a possible solution
function makeCounter(start = 0) {
let n = start;
return () => n++;
}
const next = makeCounter(5);
console.log(next()); // → 5
console.log(next()); // → 6
9. Palindrome
Write isPalindrome(text) that ignores case, spaces and punctuation.
Expected: isPalindrome("A man, a plan, a canal: Panama") is true.
Show a possible solution
function isPalindrome(text) {
const clean = text.toLowerCase().replace(/[^a-z0-9]/g, "");
return clean === [...clean].reverse().join("");
}
console.log(isPalindrome("A man, a plan, a canal: Panama")); // → true
console.log(isPalindrome("hello")); // → false
10. Async wait
Write an async function delayedGreeting(name, ms) that waits ms milliseconds (use a promise around setTimeout) and then returns Hello, <name>!.
Expected: await delayedGreeting("Maya", 100) gives Hello, Maya! after 100 ms.
Show a possible solution
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
async function delayedGreeting(name, ms) {
await wait(ms);
return `Hello, ${name}!`;
}
delayedGreeting("Maya", 100).then(message => console.log(message)); // → Hello, Maya!
When these feel comfortable, move on to the DOM and Event Challenges.