1. Problems 31–40
Same format as the previous modules: expand a problem to see the approach and both commented solutions.
P31
FizzBuzz
1 to 15: replace multiples of 3 with "Fizz", of 5 with "Buzz", of both with "FizzBuzz".
FizzBuzz
1 to 15: replace multiples of 3 with "Fizz", of 5 with "Buzz", of both with "FizzBuzz".
Approach: check the most specific condition first — divisible by both 3 and 5 (equivalently, by 15) — before falling back to the individual checks, otherwise a multiple of 15 would incorrectly print only "Fizz".
JavaScript
function fizzBuzz(n) {
const output = [];
for (let i = 1; i <= n; i++) {
if (i % 15 === 0) output.push("FizzBuzz"); // divisible by both 3 and 5
else if (i % 3 === 0) output.push("Fizz");
else if (i % 5 === 0) output.push("Buzz");
else output.push(String(i));
}
return output;
}
console.log(fizzBuzz(15).join(" "));
// 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
Python
def fizz_buzz(n: int) -> list:
output = []
for i in range(1, n + 1):
if i % 15 == 0: # divisible by both 3 and 5
output.append("FizzBuzz")
elif i % 3 == 0:
output.append("Fizz")
elif i % 5 == 0:
output.append("Buzz")
else:
output.append(str(i))
return output
print(" ".join(fizz_buzz(15)))
# 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
P32
Right-Angled Triangle of Stars
5 rows: row i gets i stars.
Right-Angled Triangle of Stars
5 rows: row i gets i stars.
Approach: loop from row 1 to the total row count, and on row i repeat the "*" character i times before moving to the next line.
JavaScript
function starTriangle(rows) {
let output = "";
for (let i = 1; i <= rows; i++) {
output += "*".repeat(i) + "\n"; // row i gets i stars
}
return output;
}
console.log(starTriangle(5));
// *
// **
// ***
// ****
// *****
Python
def star_triangle(rows: int) -> str:
output = ""
for i in range(1, rows + 1):
output += "*" * i + "\n" # row i gets i stars
return output
print(star_triangle(5))
# *
# **
# ***
# ****
# *****
P33
Sum of Numbers from 1 to n
1 + 2 + ... + 10 = 55.
Sum of Numbers from 1 to n
1 + 2 + ... + 10 = 55.
Approach: the simplest possible accumulator loop — start a running total at 0 and add each number from 1 to n as you go.
JavaScript
function sumToN(n) {
let sum = 0;
for (let i = 1; i <= n; i++) {
sum += i;
}
return sum;
}
console.log(sumToN(10)); // 55
Python
def sum_to_n(n: int) -> int:
total = 0
for i in range(1, n + 1):
total += i
return total
print(sum_to_n(10)) # 55
P34
Count Even and Odd Numbers in a Range
1 to 10 has 5 evens and 5 odds.
Count Even and Odd Numbers in a Range
1 to 10 has 5 evens and 5 odds.
Approach: loop through the range once, and on each number check % 2 to decide which of two counters to increment.
JavaScript
function countEvenOdd(n) {
let evens = 0, odds = 0;
for (let i = 1; i <= n; i++) {
if (i % 2 === 0) evens++;
else odds++;
}
return { evens, odds };
}
console.log(countEvenOdd(10)); // { evens: 5, odds: 5 }
Python
def count_even_odd(n: int) -> dict:
evens = odds = 0
for i in range(1, n + 1):
if i % 2 == 0:
evens += 1
else:
odds += 1
return {"evens": evens, "odds": odds}
print(count_even_odd(10)) # {'evens': 5, 'odds': 5}
P35
All Prime Numbers up to n
Up to 20: 2, 3, 5, 7, 11, 13, 17, 19.
All Prime Numbers up to n
Up to 20: 2, 3, 5, 7, 11, 13, 17, 19.
Approach: the outer loop tries every candidate number; the inner loop reruns the Module 2 primality check against it. A nested loop is exactly "for each X, check every Y."
JavaScript
function primesUpTo(n) {
const primes = [];
for (let num = 2; num <= n; num++) {
let prime = true;
for (let i = 2; i * i <= num; i++) {
if (num % i === 0) { prime = false; break; } // found a divisor
}
if (prime) primes.push(num);
}
return primes;
}
console.log(primesUpTo(20)); // [2, 3, 5, 7, 11, 13, 17, 19]
Python
def primes_up_to(n: int) -> list:
primes = []
for num in range(2, n + 1):
prime = True
i = 2
while i * i <= num:
if num % i == 0: # found a divisor
prime = False
break
i += 1
if prime:
primes.append(num)
return primes
print(primes_up_to(20)) # [2, 3, 5, 7, 11, 13, 17, 19]
P36
Print a Multiplication Table
7 x 1 through 7 x 5.
Print a Multiplication Table
7 x 1 through 7 x 5.
Approach: loop from 1 up to however many rows are wanted, and on each pass print n x i = n * i using string interpolation.
JavaScript
function multiplicationTable(n, upTo = 10) {
let output = "";
for (let i = 1; i <= upTo; i++) {
output += `${n} x ${i} = ${n * i}\n`;
}
return output;
}
console.log(multiplicationTable(7, 5));
// 7 x 1 = 7
// 7 x 2 = 14
// 7 x 3 = 21
// 7 x 4 = 28
// 7 x 5 = 35
Python
def multiplication_table(n: int, up_to: int = 10) -> str:
output = ""
for i in range(1, up_to + 1):
output += f"{n} x {i} = {n * i}\n"
return output
print(multiplication_table(7, 5))
# 7 x 1 = 7
# 7 x 2 = 14
# 7 x 3 = 21
# 7 x 4 = 28
# 7 x 5 = 35
P37
Largest of Three Numbers
Of 4, 9 and 7, the largest is 9.
Largest of Three Numbers
Of 4, 9 and 7, the largest is 9.
Approach: a is the largest if it's greater than or equal to both others; otherwise check b the same way; if neither wins, c must be the largest. No sorting needed for just three values.
JavaScript
function largestOfThree(a, b, c) {
if (a >= b && a >= c) return a;
if (b >= a && b >= c) return b;
return c;
}
console.log(largestOfThree(4, 9, 7)); // 9
Python
def largest_of_three(a: float, b: float, c: float) -> float:
if a >= b and a >= c:
return a
if b >= a and b >= c:
return b
return c
print(largest_of_three(4, 9, 7)) # 9
# Idiomatic one-liner for real code: max(a, b, c)
P38
Leap Year Checker
2024 and 2000 are leap years; 2100 isn't.
Leap Year Checker
2024 and 2000 are leap years; 2100 isn't.
Approach: the actual rule has three parts: divisible by 4, unless also divisible by 100, unless also divisible by 400. Written as one boolean expression: divisible by 4 AND (not divisible by 100 OR divisible by 400).
JavaScript
function isLeapYear(year) {
// Divisible by 4 AND (not divisible by 100 OR divisible by 400)
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
}
console.log(isLeapYear(2024)); // true
console.log(isLeapYear(2100)); // false (divisible by 100, not by 400)
console.log(isLeapYear(2000)); // true (divisible by 400)
Python
def is_leap_year(year: int) -> bool:
# Divisible by 4 AND (not divisible by 100 OR divisible by 400)
return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0)
print(is_leap_year(2024)) # True
print(is_leap_year(2100)) # False (divisible by 100, not by 400)
print(is_leap_year(2000)) # True (divisible by 400)
P39
Count the Digits of a Number
48213 has 5 digits.
Count the Digits of a Number
48213 has 5 digits.
Approach: the same digit-peeling while loop from Module 2, but this time only counting how many times it runs rather than doing anything with each digit. Zero needs its own special case, since the loop would otherwise never run for it.
JavaScript
function countDigits(n) {
n = Math.abs(n);
if (n === 0) return 1; // zero itself has one digit
let count = 0;
while (n > 0) {
count++;
n = Math.floor(n / 10); // drop the last digit each pass
}
return count;
}
console.log(countDigits(48213)); // 5
Python
def count_digits(n: int) -> int:
n = abs(n)
if n == 0: # zero itself has one digit
return 1
count = 0
while n > 0:
count += 1
n //= 10 # drop the last digit each pass
return count
print(count_digits(48213)) # 5
P40
Number Pyramid Pattern
Row i counts up from 1 to i: 1 / 12 / 123 / 1234 / 12345.
Number Pyramid Pattern
Row i counts up from 1 to i: 1 / 12 / 123 / 1234 / 12345.
Approach: a nested loop, like problem 35's prime sieve — the outer loop picks the row number, the inner loop counts from 1 up to that row number and appends each digit.
JavaScript
function numberPyramid(rows) {
let output = "";
for (let i = 1; i <= rows; i++) {
let row = "";
for (let j = 1; j <= i; j++) {
row += j; // count up to the row number on each row
}
output += row + "\n";
}
return output;
}
console.log(numberPyramid(5));
// 1
// 12
// 123
// 1234
// 12345
Python
def number_pyramid(rows: int) -> str:
output = ""
for i in range(1, rows + 1):
row = ""
for j in range(1, i + 1):
row += str(j) # count up to the row number on each row
output += row + "\n"
return output
print(number_pyramid(5))
# 1
# 12
# 123
# 1234
# 12345
2. Key Takeaways
- Order matters in an if/else-if chain — always check the most specific or most restrictive condition first (FizzBuzz's "divisible by 15" before "divisible by 3").
- A nested loop is just "for each row, do a smaller loop" — that one idea builds triangles, pyramids, multiplication tables and the prime sieve identically.
- Compound conditions (leap years) read most clearly when you write out the plain-English rule as a comment first, then translate it term by term into
&&/andand||/or.