Tasks
All the tasks of the course in one place. First 50 standalone tasks from "Hello, World" to the shortest path in a grid, each with an example and a solution in JavaScript checked with a real compiler. Then the tasks from the lessons, by module: each one leads to the lesson that explains what you need.
50 tasks to practise
1. Hello World
Print the text Hello, World! to the console; the program takes no input.
No input.
Output Hello, World!What you need is in the lesson: Your first program
Solution
console.log("Hello, World!");2. Greet the user
Read a name from one line and greet the person by name as "Hello, <name>!".
Input MariaOutput Hello, Maria!What you need is in the lesson: Input and output
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const name = await ask("");console.log("Hello, " + name + "!");rl.close();3. Print the age
Read the user's age (a whole number), store it in a variable and print it in a sentence.
Input 17Output You are 17 years old.What you need is in the lesson: Variables and types
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const age = Number(await ask(""));console.log("You are " + age + " years old.");rl.close();4. Unit converter
Read a length in inches (it may be a decimal) and convert it to centimetres: 1 inch = 2.54 cm. Print the result with 2 decimal places.
Input 12.5Output 31.75 cmWhat you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const inches = Number(await ask(""));console.log((inches * 2.54).toFixed(2) + " cm");rl.close();5. Even or odd
Read a whole number and print whether it is even or odd.
Input 7Output 7 is odd.What you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const number = Number(await ask(""));if (number % 2 === 0) {console.log(number + " is even.");} else {console.log(number + " is odd.");}rl.close();6. Sum of two numbers
Read two whole numbers, each on its own line, and print their sum.
Input 1230Output The sum is 42.What you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const first = Number(await ask(""));const second = Number(await ask(""));console.log("The sum is " + (first + second) + ".");rl.close();7. Area of a square
Read the side of a square (a whole number) and print its area.
Input 5Output The area is 25.What you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const side = Number(await ask(""));console.log("The area is " + side * side + ".");rl.close();8. Volume of a sphere
Read the radius r (it may be a decimal) and print the volume of the sphere V = 4/3 · π · r³ with 2 decimal places.
Input 3Output The volume is 113.10.What you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const r = Number(await ask(""));const volume = (4 / 3) * Math.PI * r ** 3;console.log("The volume is " + volume.toFixed(2) + ".");rl.close();9. Compare two numbers
Read two whole numbers, each on its own line, and print the larger one (if they are equal, either will do).
Input 815Output The larger one is 15.What you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const a = Number(await ask(""));const b = Number(await ask(""));if (a > b) {console.log("The larger one is " + a + ".");} else {console.log("The larger one is " + b + ".");}rl.close();10. Triangle check
Read three whole numbers, each on its own line, and check whether they can be the sides of a triangle: any two of them must add up to more than the third.
Input 345Output They can form a triangle.What you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const a = Number(await ask(""));const b = Number(await ask(""));const c = Number(await ask(""));if (a + b > c && a + c > b && b + c > a) {console.log("They can form a triangle.");} else {console.log("They cannot form a triangle.");}rl.close();11. Grade to words
Read a mark on the Bulgarian scale from 2 to 6 (it may be a decimal) and print it in words: 5.50 and up is Excellent, 4.50 and up Very good, 3.50 and up Good, 3.00 and up Average, below 3.00 Poor.
Input 4.75Output Very goodWhat you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const grade = Number(await ask(""));if (grade >= 5.5) {console.log("Excellent");} else if (grade >= 4.5) {console.log("Very good");} else if (grade >= 3.5) {console.log("Good");} else if (grade >= 3) {console.log("Average");} else {console.log("Poor");}rl.close();12. Hours to seconds
Read a number of hours (a whole number) and print how many seconds that is.
Input 2Output 7200 secondsWhat you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const hours = Number(await ask(""));console.log(hours * 3600 + " seconds");rl.close();13. Count to N
Read a whole number N and print the numbers from 1 to N, each on a new line.
Input 5Output 12345What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));for (let i = 1; i <= n; i++) {console.log(i);}rl.close();14. ASCII value
Read one character (the first character of the line) and print its ASCII code, the number the computer stores it as.
Input AOutput The code of A is 65.What you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const symbol = (await ask(""))[0];console.log("The code of " + symbol + " is " + symbol.charCodeAt(0) + ".");rl.close();15. Quadratic equation
Read a, b and c, each on its own line, and solve ax² + bx + c = 0. With two roots print "x1 = …, x2 = …" (x1 uses +√D), with one root "x = …", with 2 decimal places; if there are no real roots or a is 0, say so.
Input 1-32Output x1 = 2.00, x2 = 1.00What you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const a = Number(await ask(""));const b = Number(await ask(""));const c = Number(await ask(""));if (a === 0) {console.log("This is not a quadratic equation");} else {const d = b * b - 4 * a * c;if (d > 0) {const x1 = (-b + Math.sqrt(d)) / (2 * a);const x2 = (-b - Math.sqrt(d)) / (2 * a);console.log("x1 = " + x1.toFixed(2) + ", x2 = " + x2.toFixed(2));} else if (d === 0) {console.log("x = " + (-b / (2 * a)).toFixed(2));} else {console.log("No real roots");}}rl.close();16. Positive or negative
Read a whole number and print whether it is positive, negative or zero.
Input -4Output NegativeWhat you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const number = Number(await ask(""));if (number > 0) {console.log("Positive");} else if (number < 0) {console.log("Negative");} else {console.log("Zero");}rl.close();17. Seasons
Read a month number (1–12) and print its season: 12, 1, 2 are Winter, 3–5 Spring, 6–8 Summer, 9–11 Autumn. For any other number print "Invalid month".
Input 4Output SpringWhat you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const month = Number(await ask(""));if (month < 1 || month > 12) {console.log("Invalid month");} else if (month === 12 || month <= 2) {console.log("Winter");} else if (month <= 5) {console.log("Spring");} else if (month <= 8) {console.log("Summer");} else {console.log("Autumn");}rl.close();18. Reverse a number
Read a positive whole number and print the number with its digits in reverse order: 123 becomes 321. Zeros that end up in front disappear (1200 becomes 21). Take the last digit with % 10 and drop it by dividing by 10.
Input 9071Output 1709What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}let n = Number(await ask(""));let reversed = 0;while (n > 0) {reversed = reversed * 10 + (n % 10);n = Math.floor(n / 10);}console.log(reversed);rl.close();19. Temperature converter
Read a temperature in degrees Celsius (it may have a decimal point) and print it in Fahrenheit with two decimal places. The formula is F = C * 9 / 5 + 32.
Input 36.6Output 97.88 °FWhat you need is in the lesson: Operators and arithmetic
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const celsius = Number(await ask(""));const fahrenheit = (celsius * 9) / 5 + 32;console.log(`${fahrenheit.toFixed(2)} °F`);rl.close();20. Longest name
The first line holds the number of names n, and each of the next n lines holds one name. Print the name with the most letters and their count in brackets; if two names are equally long, print the first of them.
Input 4MiaAlexandraJohnCharlotteOutput Alexandra (9 letters)What you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));let longest = "";for (let i = 0; i < n; i++) {const name = await ask("");if (name.length > longest.length) {longest = name;}}console.log(`${longest} (${longest.length} letters)`);rl.close();21. Word counter
Read one line of text and print how many words it has. Words are separated by one or more spaces, so the empty pieces between two spaces are not words.
Input I write code every day and get betterOutput 8What you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const line = await ask("");const words = line.split(" ").filter((word) => word !== "");console.log(words.length);rl.close();22. Prime number
Read a whole number n and check whether it is prime: greater than 1 and divisible only by 1 and itself. It is enough to try the divisors i for which i * i <= n.
Input 91Output 91 is not primeWhat you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));let prime = n > 1;for (let i = 2; i * i <= n; i++) {if (n % i === 0) {prime = false;break;}}if (prime) {console.log(`${n} is prime`);} else {console.log(`${n} is not prime`);}rl.close();23. Day of the week
Read a number from 1 to 7 and print the name of that day of the week, where 1 is Monday. Keep the names in an array; for any other number print "No such day".
Input 5Output FridayWhat you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const day = Number(await ask(""));const days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];if (day >= 1 && day <= 7) {console.log(days[day - 1]);} else {console.log("No such day");}rl.close();24. Factorial
Read a whole number n from 0 to 15 and print n! = 1 * 2 * ... * n (0! is 1). Already 13! does not fit in an int, so in Java and C# keep the product in a long.
Input 15Output 15! = 1307674368000What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));let factorial = 1;for (let i = 2; i <= n; i++) {factorial *= i;}console.log(`${n}! = ${factorial}`);rl.close();25. Valid date
Read a day, a month and a year, each on its own line, and print "Valid date" or "Invalid date". The year is at least 1, the month is from 1 to 12 and the day from 1 to the number of days in that month; February has 29 days in a leap year (divisible by 4 but not by 100, unless it is divisible by 400).
Input 2922100Output Invalid dateWhat you need is in the lesson: Conditions
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const day = Number(await ask(""));const month = Number(await ask(""));const year = Number(await ask(""));const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;let days;if (month === 2) {days = leap ? 29 : 28;} else if (month === 4 || month === 6 || month === 9 || month === 11) {days = 30;} else {days = 31;}if (year >= 1 && month >= 1 && month <= 12 && day >= 1 && day <= days) {console.log("Valid date");} else {console.log("Invalid date");}rl.close();26. Letter frequency
Read one line of text and print how many times each letter appears in it, ignoring upper and lower case. Print the letters in alphabetical order, one per line, as "a: 5"; spaces and punctuation are not counted.
Input Hello, World!Output d: 1e: 1h: 1l: 3o: 2r: 1w: 1What you need is in the lesson: Map and Set
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = (await ask("")).toLowerCase();const counts = new Map();for (const c of text) {if (/\p{L}/u.test(c)) {counts.set(c, (counts.get(c) ?? 0) + 1);}}for (const c of [...counts.keys()].sort()) {console.log(`${c}: ${counts.get(c)}`);}rl.close();27. Minimum and maximum in an array
The first line holds the count n, and each of the next n lines holds one whole number. Read them into an array and print the smallest and the largest, starting from the first element and comparing it with the rest.
Input 57-31204Output Smallest: -3Largest: 12What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));const numbers = [];for (let i = 0; i < n; i++) {numbers.push(Number(await ask("")));}let min = numbers[0];let max = numbers[0];for (let i = 1; i < n; i++) {if (numbers[i] < min) {min = numbers[i];}if (numbers[i] > max) {max = numbers[i];}}console.log(`Smallest: ${min}`);console.log(`Largest: ${max}`);rl.close();28. Sort an array
The first line holds the count n, and each of the next n lines holds one whole number. Sort them yourself in ascending order with bubble sort (n - 1 passes, each swapping neighbours that are in the wrong order) and print them on one line, separated by spaces.
Input 6529156Output 1 2 5 5 6 9What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));const numbers = [];for (let i = 0; i < n; i++) {numbers.push(Number(await ask("")));}for (let pass = 0; pass < n - 1; pass++) {for (let i = 0; i < n - 1 - pass; i++) {if (numbers[i] > numbers[i + 1]) {const temp = numbers[i];numbers[i] = numbers[i + 1];numbers[i + 1] = temp;}}}console.log(numbers.join(" "));rl.close();29. Replace the vowels
Read one line of text and print it with every vowel, upper or lower case, replaced by the character *. The vowels are a, e, i, o, u.
Input I love programmingOutput * l*v* pr*gr*mm*ngWhat you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = await ask("");const vowels = "aeiou";let result = "";for (const c of text) {if (vowels.includes(c.toLowerCase())) {result += "*";} else {result += c;}}console.log(result);rl.close();30. Sum of the digits
Read a whole non-negative number and print the sum of its digits. The last digit is n % 10, and n / 10 drops it (n // 10 in Python).
Input 9875Output 29What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}let n = Number(await ask(""));let sum = 0;while (n > 0) {sum += n % 10;n = Math.floor(n / 10);}console.log(sum);rl.close();31. Palindrome
Read one line of text and check whether it is a palindrome, that is, it reads the same backwards. Upper and lower case count as the same and spaces are skipped. Print "Palindrome" or "Not a palindrome".
Input Never odd or evenOutput PalindromeWhat you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = (await ask("")).toLowerCase().replaceAll(" ", "");let palindrome = true;for (let i = 0; i < text.length / 2; i++) {if (text[i] !== text[text.length - 1 - i]) {palindrome = false;break;}}if (palindrome) {console.log("Palindrome");} else {console.log("Not a palindrome");}rl.close();32. Strong password
Read passwords, one per line, until a strong one arrives: at least 8 characters, at least one digit, one uppercase and one lowercase letter. For each weak one print the first rule it breaks, in this order ("Too short", "No digit", "No uppercase letter", "No lowercase letter"); for the strong one print "Password accepted" and stop.
Input kotkakotkamiaukotkamiau7Kotkamiau7Output Too shortNo digitNo uppercase letterPassword acceptedWhat you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}while (true) {const password = await ask("");let digit = false;let upper = false;let lower = false;for (const c of password) {if (c >= "0" && c <= "9") {digit = true;} else if (c !== c.toLowerCase()) {upper = true;} else if (c !== c.toUpperCase()) {lower = true;}}if (password.length < 8) {console.log("Too short");} else if (!digit) {console.log("No digit");} else if (!upper) {console.log("No uppercase letter");} else if (!lower) {console.log("No lowercase letter");} else {console.log("Password accepted");break;}}rl.close();33. Reverse an array
The first line holds the count n, and each of the next n lines holds one whole number. Read them into an array and print them in reverse order on one line, separated by spaces: walk the array from the last index down to zero.
Input 410-273Output 3 7 -2 10What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));const numbers = [];for (let i = 0; i < n; i++) {numbers.push(Number(await ask("")));}let line = "";for (let i = n - 1; i >= 0; i--) {line += numbers[i];if (i > 0) {line += " ";}}console.log(line);rl.close();34. Count the elements
Read one line of words separated by single spaces and print how many times each word appears, as "word: count". The words come out in the order in which they first appeared.
Input apple pear apple plum pear appleOutput apple: 3pear: 2plum: 1What you need is in the lesson: Map and Set
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const line = await ask("");const counts = new Map();for (const word of line.split(" ")) {counts.set(word, (counts.get(word) ?? 0) + 1);}for (const [word, count] of counts) {console.log(`${word}: ${count}`);}rl.close();35. Prime numbers
Read a number N and print all prime numbers from 2 to N on one line, separated by spaces.
Input 30Output 2 3 5 7 11 13 17 19 23 29What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));const primes = [];for (let i = 2; i <= n; i++) {let prime = true;for (let d = 2; d * d <= i; d++) {if (i % d === 0) {prime = false;break;}}if (prime) {primes.push(i);}}console.log(primes.join(" "));rl.close();36. Average
One line holds whole numbers separated by spaces. Print their average with two digits after the decimal point.
Input 5 8 12 6Output Average: 7.75What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const parts = (await ask("")).split(" ");let sum = 0;for (let i = 0; i < parts.length; i++) {sum += Number(parts[i]);}const average = sum / parts.length;console.log("Average: " + average.toFixed(2));rl.close();37. Sort by length
One line holds words separated by spaces. Sort them by length from shortest to longest (words of equal length keep their input order) and print them on one line.
Input cherry fig banana kiwi plumOutput fig kiwi plum cherry bananaWhat you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const words = (await ask("")).split(" ");for (let i = 0; i < words.length - 1; i++) {for (let j = 0; j < words.length - 1 - i; j++) {if (words[j].length > words[j + 1].length) {const temp = words[j];words[j] = words[j + 1];words[j + 1] = temp;}}}console.log(words.join(" "));rl.close();38. Sentence counter
Read one line of text and print how many sentences it has. A sentence ends with a full stop, an exclamation mark or a question mark; a run of such marks (like "..." or "?!") is a single ending.
Input Hi! How are you? I am fine... And you?!Output Sentences: 4What you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = await ask("");const ends = ".!?";let count = 0;for (let i = 0; i < text.length; i++) {const isEnd = ends.includes(text[i]);const nextIsEnd = i + 1 < text.length && ends.includes(text[i + 1]);if (isEnd && !nextIsEnd) {count++;}}console.log("Sentences: " + count);rl.close();39. Fibonacci numbers
The Fibonacci sequence starts with 1, 1, and every next number is the sum of the previous two. Read N (from 1 to 50) and print the N-th number of the sequence.
Input 40Output 102334155What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const n = Number(await ask(""));let previous = 0;let current = 1;for (let i = 1; i < n; i++) {const next = previous + current;previous = current;current = next;}console.log(current);rl.close();40. Finding the median
One line holds whole numbers separated by spaces. Print their median with one digit after the decimal point: the middle number once they are sorted, or the mean of the two middle ones when the count is even.
Input 12 3 7 9 1 8Output Median: 7.5What you need is in the lesson: Arrays: push, splice and sort
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const numbers = [];for (const part of (await ask("")).split(" ")) {numbers.push(Number(part));}numbers.sort((a, b) => a - b);const n = numbers.length;let median;if (n % 2 === 1) {median = numbers[Math.floor(n / 2)];} else {median = (numbers[n / 2 - 1] + numbers[n / 2]) / 2;}console.log("Median: " + median.toFixed(1));rl.close();41. Character chart
Read one line of text. For every character except the space, in order of first appearance, print a line "character | stars" with one star for each time it occurs in the text.
Input banana breadOutput b | **a | ****n | **r | *e | *d | *What you need is in the lesson: Strings: working with text
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = await ask("");for (let i = 0; i < text.length; i++) {const c = text[i];if (c !== " " && text.indexOf(c) === i) {let count = 0;for (let j = 0; j < text.length; j++) {if (text[j] === c) {count++;}}console.log(c + " | " + "*".repeat(count));}}rl.close();42. Transposing a matrix
The first line holds the number of rows R and columns C, followed by R lines of C numbers separated by spaces. Print the transposed matrix: C lines of R numbers, where rows become columns.
Input 2 31 2 34 5 6Output 1 42 53 6What you need is in the lesson: Two-dimensional arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const size = (await ask("")).split(" ");const rows = Number(size[0]);const cols = Number(size[1]);const matrix = [];for (let r = 0; r < rows; r++) {matrix.push((await ask("")).split(" ").map(Number));}for (let c = 0; c < cols; c++) {const line = [];for (let r = 0; r < rows; r++) {line.push(matrix[r][c]);}console.log(line.join(" "));}rl.close();43. Paths in a maze
The first line holds R and C, followed by R lines of C characters: "." is a free cell and "#" is a wall. Moving only right or down and never stepping on a wall, print the number of all paths from the top-left to the bottom-right corner.
Input 4 5......#.#....#.#....Output Paths: 4What you need is in the lesson: Recursion
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}function countPaths(maze, r, c) {if (r >= maze.length || c >= maze[0].length || maze[r][c] === "#") {return 0;}if (r === maze.length - 1 && c === maze[0].length - 1) {return 1;}return countPaths(maze, r + 1, c) + countPaths(maze, r, c + 1);}const size = (await ask("")).split(" ");const rows = Number(size[0]);const maze = [];for (let r = 0; r < rows; r++) {maze.push(await ask(""));}console.log("Paths: " + countPaths(maze, 0, 0));rl.close();44. Grade statistics
One line holds grades from 2 to 6 (the Bulgarian school scale, 6 is best), separated by spaces. Print how many are excellent, very good, good, satisfactory and poor, each category on its own line.
Input 6 4 5 6 3 5 2 6 5 4Output Excellent (6): 3Very good (5): 3Good (4): 2Satisfactory (3): 1Poor (2): 1What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const names = ["", "", "Poor", "Satisfactory", "Good", "Very good", "Excellent"];const counts = [0, 0, 0, 0, 0, 0, 0];const parts = (await ask("")).split(" ");for (let i = 0; i < parts.length; i++) {counts[Number(parts[i])]++;}for (let grade = 6; grade >= 2; grade--) {console.log(names[grade] + " (" + grade + "): " + counts[grade]);}rl.close();45. Roman numerals
Read a whole number from 1 to 3999 and print it in Roman numerals (I, V, X, L, C, D, M, where 4 is IV, 9 is IX, 40 is XL and so on).
Input 1994Output MCMXCIVWhat you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}let number = Number(await ask(""));const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];const symbols = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"];let roman = "";for (let i = 0; i < values.length; i++) {while (number >= values[i]) {roman += symbols[i];number -= values[i];}}console.log(roman);rl.close();46. Coin toss simulation
Read a seed x (from 1 to 2147483646) and a number of tosses N, each on its own line. On every toss set x = x * 16807 % 2147483647; an even x is heads (H), an odd x is tails (T). Print the tosses on one line, then how many heads and how many tails came up.
Input 4210Output HTTTHTTHHTHeads: 4Tails: 6What you need is in the lesson: Loops
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}let x = Number(await ask(""));const n = Number(await ask(""));let tosses = "";let heads = 0;for (let i = 0; i < n; i++) {x = x * 16807 % 2147483647;if (x % 2 === 0) {tosses += "H";heads++;} else {tosses += "T";}}console.log(tosses);console.log("Heads: " + heads);console.log("Tails: " + (n - heads));rl.close();47. Symmetric array
One line holds whole numbers separated by spaces. Check whether the array is symmetric, that is, it reads the same from left to right and from right to left.
Input 1 2 3 2 1Output SymmetricWhat you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const numbers = (await ask("")).split(" ").map(Number);let symmetric = true;for (let i = 0; i < Math.floor(numbers.length / 2); i++) {if (numbers[i] !== numbers[numbers.length - 1 - i]) {symmetric = false;break;}}console.log(symmetric ? "Symmetric" : "Not symmetric");rl.close();48. Balanced brackets
Read one line of text and check whether its brackets (), [] and {} are balanced: every opening bracket has a closing one of the same kind and the pairs do not cross. Other characters are ignored.
Input (a + [b) * c]Output Not balancedWhat you need is in the lesson: Stack, queue and linked list
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const text = await ask("");const opening = "([{";const closing = ")]}";const stack = [];let balanced = true;for (const c of text) {if (opening.includes(c)) {stack.push(c);} else if (closing.includes(c)) {if (stack.length === 0 || opening.indexOf(stack.pop()) !== closing.indexOf(c)) {balanced = false;break;}}}if (balanced && stack.length === 0) {console.log("Balanced");} else {console.log("Not balanced");}rl.close();49. Run of equal elements
One line holds whole numbers separated by spaces. Find the longest run of equal neighbouring numbers and print it on one line; if several runs have the same length, print the first one.
Input 2 1 1 3 3 3 2 2 2 5Output 3 3 3What you need is in the lesson: Arrays
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const numbers = (await ask("")).split(" ").map(Number);let bestValue = numbers[0];let bestLength = 1;let length = 1;for (let i = 1; i < numbers.length; i++) {if (numbers[i] === numbers[i - 1]) {length++;} else {length = 1;}if (length > bestLength) {bestLength = length;bestValue = numbers[i];}}const run = [];for (let i = 0; i < bestLength; i++) {run.push(bestValue);}console.log(run.join(" "));rl.close();50. Shortest path in a grid
The first line holds R and C, followed by R lines of C characters: "." is a free cell, "#" is a wall, "S" is the start and "E" is the goal. Moving up, down, left and right, print the smallest number of moves from S to E, or "No path" if E cannot be reached.
Input 5 6S.#....##.#....#..#.#..#...E.#Output 7What you need is in the lesson: Stack, queue and linked list
Solution
import { createInterface } from "node:readline";const rl = createInterface({ input: process.stdin });const lines = rl[Symbol.asyncIterator]();async function ask(question) {process.stdout.write(question);return (await lines.next()).value;}const size = (await ask("")).split(" ");const rows = Number(size[0]);const cols = Number(size[1]);const grid = [];for (let r = 0; r < rows; r++) {grid.push(await ask(""));}const dist = [];const queue = [];for (let r = 0; r < rows; r++) {dist.push([]);for (let c = 0; c < cols; c++) {dist[r].push(-1);if (grid[r][c] === "S") {dist[r][c] = 0;queue.push([r, c]);}}}const dr = [-1, 1, 0, 0];const dc = [0, 0, -1, 1];let answer = "No path";while (queue.length > 0) {const [r, c] = queue.shift();if (grid[r][c] === "E") {answer = String(dist[r][c]);break;}for (let d = 0; d < 4; d++) {const nr = r + dr[d];const nc = c + dc[d];if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && grid[nr][nc] !== "#" && dist[nr][nc] === -1) {dist[nr][nc] = dist[r][c] + 1;queue.push([nr, nc]);}}}console.log(answer);rl.close();
Tasks from the lessons
Section titled "Tasks from the lessons"Language basics
- Your first program: Hello World · Business card · Frame
- Variables and types: Swap · Age · A hotel card
- Input and output: Greeting by name · Sum of two numbers · Two texts in one · π with two digits
- Operators and arithmetic: Average of three numbers · Seconds into hours · Volume of a sphere · Celsius to Fahrenheit
- Conditions: A cinema ticket · A mini calculator · A quadratic equation · A valid date
- Loops: Multiplication table · Prime number · The digits of a number · Guess the number
- Arrays: Sum, even, odd · Reversed · Lowest, highest, average
- Arrays: Sorting · Longest run · Grade statistics
- Two-dimensional arrays: Diagonals and rows · Flip the table
- Two-dimensional arrays: How many paths are there? · The shortest path
- Strings: working with text: The name backward · Word count · Palindrome
- Strings: working with text: Strong password
Functions
- Functions: Receipt · Triangle
- Parameters and return: Average · Prime number · Temperatures · Calculator · A triangle with a parameter
- Parameters and return
- Default values: The largest · Average grade · A receipt line · Free delivery
- Recursion: Factorial two ways · Sum of digits · Fibonacci · Palindrome
Classes and objects
- Classes and objects: Book · Car · The cart · Most expensive first
- Constructors and this: Person · Animal · Dance move
- Instance methods
- Instance methods
- Encapsulation: Person · An account with no minus · Animal
- static: what all objects share: Orders · Calculator · Exchange
Inheritance and polymorphism
- Inheritance: Family car · Student · Breakdance · Electric car
- Polymorphism: Animal shelter · The student introduces themselves · Party
- Abstract classes without abstract: Area and perimeter · Animals
- Abstract classes without abstract: Vehicles · Performances
- Interfaces without interface: Horn · Details · Dance · DJ · The pond
- Type checks: Parking lot · Dances · Fleet · Zoo
- OOP principles
- OOP principles: A contractor · The terrace without if
Errors and exceptions
- Exceptions: Text to number · No such product · Average order
- try, catch and finally: Price per person · Calculator
- Throwing and your own exceptions: Music shop · An account with rules · Invalid age
Text and files
- Strings: Palindrome · A receipt with columns · Words in reverse
- Regular expressions: Date · Mobile number · Email · Shopping list
- Regular expressions: groups and replacing: Find and replace · Words with a prefix · Addresses in text · Dates to ISO
- Files: A configuration file · A log file filter · Folder contents · An index file
- Data in files: CSV analysis · Saving the hero · Duplicate text
Collections
- Arrays: push, splice and sort: A bookshelf · An event log · A notebook · Mental math
- Stack, queue and linked list: A toy train · A bus route · A stock ticker · Balanced brackets · Your own linked list
- Map and Set: A user table · Word frequency · Documents by keyword · A contact network
- Hash codes and hash functions: A key for a person · The robot in the warehouse · A hash of a file
- Nested classes and data: Shopping cart · Web server monitor · Building manager · Ranking
Modern JavaScript
- Arrow functions: Sorting by several fields · Filtering orders · Discounts one after another
- Array methods: Sales by category · Top 3 products · Average grade · The words in a text
- Data, switch and destructuring: Shapes · Delivery price · A point as a key
- Design patterns: Discounts as strategies · "Notify me when it is in stock" · A notification factory · An old thermometer
Real-world programs
- Tests with node:test: The discount calculator · The account · The bug in the average grade
- Async, await and threads: Parallel sum · Downloading with a pool · A counter without losses
- Network programming: Echo server · A server with commands · A chat for two
- Databases: Catalog · Search by part of the name · A transfer that fails halfway
- Reflection: All the fields and the chain · Mini JSON · Your own test runner
Let's make a game
- How to think about a game: A race for two · Guess the number · Who won at tic-tac-toe?
- RPG 1: the heroes: A sixth hero · The party roster · Who is the strongest?
- RPG 2: the battle: A new monster · A healing potion · A battle report
- RPG 3: the whole game: A menu · Progress · A boss
- Epic Cosmos 1: the objects in space: The solar system · Distance · The whole tree
- Epic Cosmos 2: resources, buildings, ships: 100 metal as fast as possible · A cargo ship · A 10-turn simulation
- The locked lab 1: rooms and commands: Inventory · A new room · Synonyms
- The locked lab 2: puzzles and the way out: The dark cellar · A timer · A hint for a move
Chronicles of Arcanum
- The game loop
- A stack of screens
- Screens that return an answer
- Drawing in the console
- The map and line of sight
- Heroes, enemies, stats
- The combat system
- Blood, wounds and effects
- Skills and actions as commands
- Enemies that think
- Items, inventory, loot
- Levels, dialogs and quests
- Saving and loading
- The whole game and the balance
Epic Cosmos: the empire
- The galaxy from a seed
- The technology tree
- Fleets and space battle
- The rivals
- The turn of the galaxy
- The whole strategy
Project
- Hotel reservations: Changing rooms