Deliberate practice

Turn concepts into instincts.

76 challenges across 10 topics. Solve, run automated checks, inspect failures, and compare approaches after you've tried.

Debugging Lab

21 broken-code exercises covering syntax, reference, type, scope, async, and mutation bugs.

Fundamentalseasy

Sum Two Numbers

Return the sum of two numbers passed as arguments.

10m 50
Fundamentalseasy

Temperature Converter

Convert a Celsius temperature to Fahrenheit using F = C * 9/5 + 32.

10m 50
Fundamentalseasy

Calculate Discount

Return the final price after applying a percentage discount.

10m 50
Fundamentalseasy

Even or Odd

Return "even" or "odd" for a given integer.

10m 50
Fundamentalseasy

Positive, Negative, or Zero

Return "positive", "negative", or "zero" for a number.

10m 50
Fundamentalseasy

Largest of Three Numbers

Return the largest of three numbers.

10m 50
Fundamentalsmedium

Leap Year Checker

Return true if a year is a leap year (divisible by 4, but not by 100 unless also by 400).

18m 75
Fundamentalsmedium

Grade Calculator

Convert a numeric score (0-100) into a letter grade: A (90+), B (80+), C (70+), D (60+), else F.

18m 75
Stringseasy

Reverse a String

Return the supplied text in reverse order.

10m 50
Stringseasy

Count Characters

Return the number of characters in a string, including spaces.

10m 50
Stringseasy

Count Vowels

Count vowels (a, e, i, o, u) regardless of letter case.

10m 50
Stringsmedium

Palindrome Check

Ignore case and non-alphanumeric characters, then detect whether the text is a palindrome.

18m 75
Stringseasy

Capitalize Words

Capitalize the first letter of every word in a sentence.

10m 50
Stringseasy

Remove Spaces

Remove all whitespace from a string.

10m 50
Stringsmedium

Character Frequency

Return an object counting how many times each character appears in a string.

18m 75
Stringsmedium

Longest Word

Return the longest word in a sentence.

18m 75
Stringshard

String Compression

Compress consecutive repeated characters, e.g. 'aaabcc' → 'a3b1c2'. Only compress runs of length 1+.

30m 120
Stringsmedium

Anagram Checker

Return true if two strings are anagrams of each other, ignoring case and spaces.

18m 75
Arrayseasy

Find Maximum

Return the largest number in an array without sorting the input.

10m 50
Arrayseasy

Find Minimum

Return the smallest number in an array.

10m 50
Arrayseasy

Sum Array

Return the sum of all numbers in an array.

10m 50
Arrayseasy

Average Array

Return the average of the numbers in an array, or 0 for an empty array.

10m 50
Arrayseasy

Remove Duplicates

Return a new array containing each value once, preserving first-seen order.

10m 50
Arraysmedium

Second Largest

Return the second largest distinct value in an array of numbers.

18m 75
Arrayseasy

Reverse Array

Return a new array with the elements in reverse order, without mutating the input.

10m 50
Arraysmedium

Flatten an Array

Flatten an arbitrarily nested array into one flat array.

18m 75
Arraysmedium

Chunk Array

Split an array into chunks of a given size, with the last chunk possibly smaller.

18m 75
Arraysmedium

Rotate Array

Rotate an array to the right by k positions.

18m 75
Arraysmedium

Array Intersection

Return the values that appear in both arrays, without duplicates.

18m 75
Arraysmedium

Array Difference

Return the values in the first array that do not appear in the second.

18m 75
Arraysmedium

Unique Values by Key

Given an array of objects, return one object per distinct value of a given key, keeping the first occurrence.

18m 75
Functionseasy

Calculator Function

Write calculate(a, b, operator) supporting "+", "-", "*", "/".

10m 50
Functionseasy

Callback Exercise

Write applyOperation(a, b, callback) that calls callback with a and b and returns the result.

10m 50
Functionsmedium

Higher-Order Function

Write withCallCount(fn) returning a wrapped function that tracks how many times it has been called via a .calls property.

18m 75
Functionsmedium

Function Composition

Write compose(...fns) returning a function that applies the given functions right-to-left.

18m 75
Functionsmedium

Custom Map

Reimplement Array.prototype.map as myMap(array, callback) without using the built-in .map.

18m 75
Functionsmedium

Custom Filter

Reimplement Array.prototype.filter as myFilter(array, predicate) without using the built-in .filter.

18m 75
Functionshard

Custom Reduce

Reimplement Array.prototype.reduce as myReduce(array, reducer, initialValue) without using the built-in .reduce.

30m 120
Objectseasy

Object Property Counter

Return the number of own properties on an object.

10m 50
Objectsmedium

Group Users by Role

Group an array of users into an object keyed by their role.

18m 75
Objectseasy

Merge Objects

Merge two objects into a new one; properties in the second override the first.

10m 50
Objectsmedium

Deep Property Lookup

Write getPath(obj, "a.b.c") that safely reads a dot-separated nested path, returning undefined if any part is missing.

18m 75
Objectsmedium

Transform API Data

Given raw API-shaped records { id, first_name, last_name }, return { id, fullName } objects.

18m 75
Objectshard

Inventory Calculator

Given an array of { name, price, quantity } items, return the total inventory value.

30m 120
Algorithmseasy

FizzBuzz

Return "Fizz" for multiples of 3, "Buzz" for multiples of 5, "FizzBuzz" for both, else the number.

10m 50
Algorithmseasy

Factorial

Return n! (the product of all positive integers up to n). 0! is 1.

10m 50
Algorithmsmedium

Fibonacci

Return the nth Fibonacci number (0-indexed: fib(0) = 0, fib(1) = 1).

18m 75
Algorithmsmedium

Prime Checker

Return true if a number is prime.

18m 75
Algorithmshard

Binary Search

Return the index of a target in a sorted array, or -1 if not found, using binary search.

30m 120
Algorithmseasy

Linear Search

Return the index of the first occurrence of a target value, or -1 if not found.

10m 50
Algorithmsmedium

Bubble Sort

Implement bubble sort: repeatedly swap adjacent out-of-order elements until the array is sorted ascending.

18m 75
Algorithmsmedium

Frequency Counter Pattern

Using the frequency counter pattern (not nested loops), return true if two arrays contain the same values with the same frequency, regardless of order.

18m 75
Algorithmsmedium

Two Sum

Return the indices of the two numbers that add up to a target, using a single pass (not nested loops).

18m 75
Algorithmsmedium

Missing Number

Given an array containing n distinct numbers from 0 to n, return the one number missing from the range.

18m 75
Modern JavaScripteasy

Destructuring Challenge

Write summarizeUser(user) that destructures name and a defaulted role ('learner') and returns a summary string.

10m 50
Modern JavaScripteasy

Spread / Rest Challenge

Write sum(...numbers) using rest parameters to add any number of arguments.

10m 50
Modern JavaScripteasy

Optional Chaining

Write getCity(user) that safely returns user.address.city, or undefined if address is missing, using optional chaining.

10m 50
Modern JavaScriptmedium

Closures Challenge

Write makeCounter(start) returning { increment, decrement, value } that all share one private counter.

18m 75
Modern JavaScripthard

Implement Memoize

Cache a pure function's results by its arguments so repeated calls avoid repeated work.

30m 120
Modern JavaScripthard

Implement Debounce

Return a debounced wrapper that delays calling fn until calls have stopped for `delay` ms.

30m 120
Modern JavaScripthard

Implement Throttle

Return a throttled wrapper that calls fn at most once per `interval` ms, running immediately on the first call.

30m 120
Asynceasy

Promise Chain

Write doubleThenAddOne(value) that wraps value in a Promise, doubles it, then adds one, using .then() chaining.

10m 50
Asyncmedium

Promise.all Aggregation

Write sumResolved(promises) that awaits every Promise in the array concurrently and returns their sum.

18m 75
Asyncmedium

Sequential Fetching

Write fetchSequential(ids, fetcher) that awaits fetcher(id) for each id one at a time, in order, returning the results array.

18m 75
Asynchard

Parallel Fetching

Write fetchParallel(ids, fetcher) that starts every fetcher(id) call concurrently and returns results in the original id order.

30m 120
Asynchard

Async Retry

Write retry(fn, attempts) that calls fn() (which returns a Promise), retrying on rejection up to `attempts` total tries before finally rejecting.

30m 120
Asyncmedium

Fetch Error Handling

Write safeFetchJSON(fetchImpl, url) that awaits fetchImpl(url), throws if response.ok is false, and otherwise returns the parsed JSON.

18m 75
Asynchard

Timeout Wrapper

Write withTimeout(promise, ms) that resolves/rejects with the original promise, or rejects with an Error if it takes longer than ms.

30m 120
DOMeasy

Counter Logic

Write createCounter(start) returning { increment, decrement, value } — the state logic behind a UI counter button.

10m 50
DOMeasy

Character Counter Logic

Write charsRemaining(text, limit) returning how many characters remain before a max-length limit, never negative.

10m 50
DOMeasy

Toggle State

Write toggleClassList(classes, className) that adds className if absent, or removes it if present, returning the new array.

10m 50
DOMmedium

Form Validation Logic

Write validateSignupForm({ email, password }) returning an errors object with a message per invalid field (email must contain @, password must be 8+ characters).

18m 75
DOMmedium

Dynamic List Reducer

Write applyListAction(items, action) supporting {type:'add',item} and {type:'remove',id} — the state logic behind a dynamic UI list.

18m 75
DOMmedium

Search Filter

Write searchItems(items, query) returning items whose name includes the query, case-insensitively.

18m 75
DOMmedium

Event Delegation Resolver

Write resolveDelegatedTarget(items, clickedId) returning the item whose id matches clickedId, or null — the lookup behind a delegated click handler.

18m 75
Debuggingeasy

Repair the Total

Fix the misspelled identifiers so the function returns a total.

10m 50