01-edu · JS Piscine102 exercises

DATA

how-2-js primitives declarations mutability more-or-less returns last-first-kiss concat-str change dog-years circular biggie-smalls method-man abs min-max sign is physics collections block-chain

LOOP

repeat elementary index-of slicer keep-cut cut-corners reverser unbreakable chunky nasa molecules-cells get triangle pyramid flat find-expression sums

FIND

its-a-match letter-space-number vowel-dots same-amount ion-out greedy-url group-price valid-ip

RAID 1

crossword

TIME

dr-strange date-is get-some-time rebecca-black match-cron count-leap-years day-of-the-year sunny-sunday unicode-technical-report-35

CALL ME MAYBE

using-map using-filter using-reduce long-words for-each mapper filter reduce quantifiers sweet-curry has-city flow currify

DOM

get-them-all build-brick-and-break harder-bigger-bolder-stronger pimp-my-style fifty-shades-of-cold keycodes-symphony mouse-trap pick-and-click gossip-grid where-do-we-go

RAID 2

sortable

OBJECT

invert pick-omit fusion manipulate-values manipulate-keys manipulate-entries curry-entries deep-copy replica pronoun neuron flagger

ASYNC

debounce throttle interpolation keep-trying-or-giveup get-json is-winner gougle-search all series race
DATA

how-2-js

How 2 JS

Instructions

Welcome to the JS piscine 👋.

First you will have to learn to execute JavaScript.

JavaScript can run in different runtime environments. What you can do with JavaScript will greatly depend on the runtime. Even different web browsers (Chrome, Firefox, Safari etc) count as different runtime environments.

We'll start by running JavaScript in your browser, so you don't need to install anything to get started.

Some common JavaScript runtime environments:

  • Web browsers
  • Node.js
  • Deno

Let's make a hello world. First we create the JavaScript file

$ echo "console.log('Hello World')" > how-2-js.js

To run JavaScript in your browser, you can import it into a HTML page:

$ echo '<script type="module" src="how-2-js.js"></script>' > index.html

Let's create a simple web server:

$ &>/dev/null python3 -m http.server &

Now open your browser at the specified port. You'll use an appropriate command for your system:

  • Linux: xdg-open
  • macOS: open
  • Windows: start
xdg-open 'http://localhost:8000'

You can now open your web browser console. From Google Chrome, press Command+Option+J (Mac) or Control+Shift+J (Windows, Linux, ChromeOS), and you should see your hello world.

The console is a handy place to test your code.

You are all set. If you want to re-execute your script, just refresh.

Create a repository named ((ROOT)) which will hold all your solutions for this piscine. Add your 2 generated files to it.

We'll start slow for now... 🐢

DATA

primitives

Primitives

Instructions

Create a constant variable for each of the following primitive types:

  • str for string
  • num for number
  • bool for boolean
  • undef for undefined

Notions

  • Primitives and operators
  • Variables
DATA

declarations

Declarations

Instructions

Create the following constant variables:

  • escapeStr: a string which contains the following special characters: `, \, /, " and '.
  • arr: an array containing the values 4 and '2'.
  • obj: an object containing primitive values:
    • str: with a string value.
    • num: with a number value.
    • bool: with a boolean value.
    • undef: with a undefined value.
  • nested: an object containing:
    • arr: an array of 3 values: 4, undefined and '2'.
    • obj: an object with 3 properties
      • str with a string value.
      • num with a number value.
      • bool with a boolean value.

nested, arr and obj must be frozen, so that their elements or properties cannot be changed.

Notions

  • Primitive and Operators
  • Variables
  • Data Structures
  • Freeze
DATA

mutability

Mutability

Instructions

Create three copies of the person object named clone1, clone2 and samePerson.

Increase the age of person by one, and set its country to 'FR'.

You must find a way to keep the original values of clone1 and clone2. The values of samePerson should change when person is changed.

Notions

  • Set
  • Get
  • Data Structures

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const person = {
  name: 'Rick',
  age: 77,
  country: 'US',
}
DATA

more-or-less

More Or Less

Instructions

Create 4 functions:

  • more that takes 1 argument and adds 1 to it.
  • less that takes 1 argument and subtracts 1 from it.
  • add that takes 2 arguments and adds them together.
  • sub that takes 2 arguments and subtracts the second argument from the first.

All the functions must return the result of the operations specified above.

Each function should be defined with the exact number of parameters needed.

Notions

  • Functions
  • Primitives and Operators
DATA

returns

Returns

Instructions

Create the following functions:

  • id that takes one argument and returns it.
  • getLength that takes an array or a string and returns its length.

Notions

  • Functions
  • Data Structures
  • Get
DATA

last-first-kiss

Last First Kiss

Instructions

Create 3 functions:

  • first: that takes an array or a string and returns its first element or character.

  • last: that takes an array or a string and return its last element or character.

  • kiss: that takes an array or string, and returns an array of 2 elements. The returned array should contain the last and first elements or characters, in that order.

Notions

  • Data Structures.js
  • Get.js
DATA

concat-str

Concat Str

Instructions

Create a function named concatStr which takes 2 arguments and concatenates them.

Notions

  • Functions.js
  • Primitive and Operators.js
DATA

change

Change

Instructions

Create 2 functions:

  • get: a function that takes a key and returns the corresponding value from the sourceObject.

  • set: a function that takes a key and a value. Update the value for the corresponding property of the sourceObject and return the value.

Notions

  • Functions
  • Data Structures
  • Get
  • Set

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const sourceObject = {
  num: 42,
  bool: true,
  str: 'some text',
  log: console.log,
}
DATA

dog-years

Dog Years

Instructions

Someone once said that a human year is equal to 7 dog years.

Create a function named dogYears, that accepts the name of a planet, and the age of the dog in seconds. Your function should return the age of the dog on that planet in dog years.

  • earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31,557,600 seconds.
  • mercury: orbital period 0.2408467 Earth years.
  • venus: orbital period 0.61519726 Earth years.
  • mars: orbital period 1.8808158 Earth years.
  • jupiter: orbital period 11.862615 Earth years.
  • saturn: orbital period 29.447498 Earth years.
  • uranus: orbital period 84.016846 Earth years.
  • neptune: orbital period 164.79132 Earth years.

If you were told that a dog was 1,000,000,000 seconds old, you should calculate that the dog would be 221.82 Earth-years old.

You will have to format the number so that the result is rounded like the example above.

DATA

circular

Circular

Instructions

Create an object named circular that has a property named circular with itself as the value.

Notions

  • Data Structures
  • Get
  • Sets
DATA

biggie-smalls

Biggie Smalls

Instructions

Create 2 variables:

  • smalls with the smallest possible number value.
  • biggie with the greatest possible number value.

Notions

  • Number
DATA

method-man

Method Man

Instructions

Write 5 functions:

  • words: that takes a string, splits it by spaces, and returns an array of those substrings.
  • sentence: that takes an array of strings, and joins them with spaces to return a single string.
  • yell: that takes a string and returns it in upper case.
  • whisper: that takes a string and returns it in lower case, surrounded by *.
  • capitalize: that takes a string and transforms it so that the first character is upper case, and the subsequent characters are lower case.

Notions

  • Methods
DATA

abs

Abs

Instructions

Create a function named isPositive that takes a number as a argument, returning true if the number is strictly positive, and false otherwise.

Create a function named abs that takes a number as an argument and returns its absolute value. You must make your own implementation. You must not use Math.abs().

Notions

  • Functions
  • Ternary
  • Math.abs

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Math.abs = undefined
DATA

min-max

Min Max

Instructions

Create a function named max that takes 2 number arguments and returns the largest of the two.

You must not just use Math.max, make your own.

Create a function named min which is the same as max, but returns the lowest.

You must not just use Math.min, make your own.

Notions

  • Functions
  • Ternary
  • Math.min
  • Math.max

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Math.min = Math.max = undefined
DATA

sign

Sign

Instructions

Create a function named sign that takes one number argument; returning 1 if the number is positive, -1 if the number is negative and 0 if the number is exactly 0.

You must not just use Math.sign, make your own.

Create a function named sameSign that takes 2 numbers as arguments and returns true if they both have the same sign, or false otherwise.

Notions

  • Functions
  • If-else
  • Math.sign

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Math.sign = undefined
DATA

is

Is

Instructions

Add new function properties to the is object to check value types. Each function should take one argument, and return a boolean.

  • is.num: value is a number.
  • is.nan: value is NaN.
  • is.str: value is a string.
  • is.bool: value is a boolean.
  • is.undef: value is undefined.
  • is.def: value is defined.
  • is.arr: value is an array.
  • is.obj: value is a simple object or null objects.
  • is.fun: value is a function.
  • is.truthy: value is truthy.
  • is.falsy: value is falsy.

Examples

console.log(is.num(5))
// output: true

console.log(is.num('ciao'))
// output: false

Notions

  • Primitives and operators
  • typeof
  • Truthy
  • Falsy

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const is = {}
DATA

physics

physics

Instructions

Isaac Newton has forgotten his laws of physics and needs your help to animate an object on his game.

He must use the Second Law of Motion that states, "when the forces acting on an object are unbalanced, the object will accelerate."

This acceleration is dependent upon the force that acts upon the object and the object's mass.

So he wants to know what the acceleration of that object is, depending on its properties:

  • mass of xx
  • Δv of xx
  • Δt of xx
  • force of xx
  • distance xx
  • time xx

Create a function named getAcceleration that calculates the acceleration of a given object. For example:

{
  f: 10,
  m: 5,
  Δv: 100,
  Δt: 50,
  t:1,
  d: 10
}

If it is not possible to calculate it, it must return the string "impossible".

Formulas

a = F/m
a = Δv/Δt
a = 2d/t^2

a = acceleration
m = mass
F = force
Δv = final velocity - initial velocity
Δt = final time - initial time
d = distance
t = time

Quote

"Truth is ever to be found in simplicity, and not in the multiplicity and confusion of things."

Isaac Newton

DATA

collections

Collections

Instructions

Write a bunch of functions which converts data from one type to another:

  • arrToSet: from Array to Set.
  • arrToStr: from Array to string.
  • setToArr: from Set to Array.
  • setToStr: from Set to string.
  • strToArr: from string to Array.
  • strToSet: from string to Set.
  • mapToObj: from Map to Object.
  • objToArr: from Object to Array.
  • objToMap: from Object to Map.
  • arrToObj: from Array to Object.
  • strToObj: from string to Object.

Finally, write a function named superTypeOf that unlike typeof returns a specific values for advanced types like Map and Set.

Examples

const str = 'hello'
const arr = [1, 2, 1, 3]
const obj = { x: 45, y: 75, radius: 24 }
const set = new Set()
const map = new Map()
set.add(1)
set.add(2)
set.add(1)
set.add(3)
map.set('a', 1)
map.set('b', 2)
map.set(3, 'c')
map.set(4, 'd')

arrToSet(arr) // -> Set { 1, 2, 3 }
arrToStr(arr) // -> '1213'
setToArr(set) // -> [1, 2, 3]
setToStr(set) // -> '123'
strToArr(str) // -> ['h', 'e', 'l', 'l', 'o']
strToSet(str) // -> Set { 'h', 'e', 'l', 'o' }
mapToObj(map) // -> { a: 1, b: 2, '3': 'c', '4': 'd' }
objToArr(obj) // -> [45, 75, 24]
objToMap(obj) // -> Map { 'x' => 45, 'y' => 75, 'radius' => 24 }
arrToObj(arr) // -> { '0': 1, '1': 2, '2': 1, '3': 3 }
strToObj(str) // -> { '0': 'h', '1': 'e', '2': 'l', '3': 'l', '4': 'o' }

superTypeOf(map) //         -> 'Map'
superTypeOf(set) //         -> 'Set'
superTypeOf(obj) //         -> 'Object'
superTypeOf(str) //         -> 'String'
superTypeOf(666) //         -> 'Number'
superTypeOf(NaN) //         -> 'Number'
superTypeOf(arr) //         -> 'Array'
superTypeOf(null) //        -> 'null'
superTypeOf(undefined) //   -> 'undefined'
superTypeOf(superTypeOf) // -> 'Function'

Notions

  • typeof
  • Spread syntax
  • Map
  • Set
  • Object.fromEntries
  • Object.entries
DATA

block-chain

Block Chain

Instructions

Create a function named blockChain that creates a block in your very own block chain. It takes 2 arguments:

  • data: any valid JSON data.
  • prev: the previous block, if no block are given it should use the genesis block: { index: 0, hash: '0' }.

A block must have the following properties:

  • index
  • hash: a computed hash using the hashCode function provided. You will need to pass it a concatenation of the block's index, the previous block's hash and the block's stringified data.
  • data: any valid object.
  • prev: the previous block.
  • chain: a function that accepts data as an argument, and creates the next block with it.

Examples

const first = blockChain({ a: 1 })
console.log(first.index) //           -> 1
console.log(first.data) //            -> { a: 1 }
console.log(first.prev) //            -> { index: 0, hash: "0" }
console.log(first.hash) //            -> '1103f27'
console.log(hashCode('10{"a":1}')) // -> '1103f27'

const second = first.chain({ hello: 'world' })
console.log(second.hash) //                           -> '18drvvc'
console.log(hashCode('21103f27{"hello":"world"}')) // -> '18drvvc'

const chain = second
  .chain({ value: 4455 })
  .chain({ some: 'data' })
  .chain({ cool: 'stuff' })

const fork = second
  .chain({ value: 335 })
  .chain({ some: 'data' })
  .chain({ cool: 'stuff' })

console.log(chain.hash) //  -> '1qr3qfs'
console.log(fork.hash) //   -> '1x9gsc1'
console.log(chain.index) // -> 5
console.log(fork.index) //  -> 5

Notions

  • JSON.stringify

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const hashCode = str =>
  (
    [...str].reduce((h, c) => (h = (h << 5) - h + c.charCodeAt(0)) & h, 0) >>> 0
  ).toString(36)
LOOP

repeat

Repeat

Instructions

Create a function named repeat that takes a string and a number as arguments, and returns the string repeated as many times as the number describes. It should function like String.repeat(), but of course you must make your own.

Notions

  • String.repeat
  • Loops
  • Recursion

Code provided

The provided code will be added to your solution, and does not need to be submitted.

String.prototype.repeat = undefined
LOOP

elementary

Elementary

Instructions

Create 3 functions which each take (a, b) as arguments:

  • multiply that acts like the * operator, without using it.
  • divide that acts like the integer division operator /, without using it.
  • modulo that acts like the % operator, without using it.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Math.imul = undefined
eval = undefined
LOOP

index-of

Index Of

Instructions

Create 3 functions which accept an array to be searched, and a value to be matched.

  • indexOf: which returns the index of the first occurrence. It also accepts an optional index from where the search should begin. If the value was not found, -1 is returned.
  • lastIndexOf: which works just like your indexOf function, but returns the index of the last occurrence.
  • includes: which returns true if the value was found in the array, and false otherwise.

Of course you must not use any of Array.indexOf(), Array.lastIndexOf() or Array.includes().

Notions

  • Array.indexOf
  • Array.lastIndexOf
  • Array.includes

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.indexOf = undefined
Array.prototype.lastIndexOf = undefined
Array.prototype.includes = undefined
LOOP

slicer

Slicer

Instructions

Create a function named slice that works like Array.slice() and String.slice().

It takes 3 arguments:

  • string or array to process.
  • starting index.
  • optional ending index.

Notions

  • Array.slice

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.slice = undefined
String.prototype.slice = undefined
LOOP

keep-cut

Keep Cut

Instructions

Create some functions, which each take a string as an argument:

  • cutFirst: returns the string with the first 2 characters removed.

  • cutLast returns the string with the last 2 characters removed.

  • cutFirstLast returns the string with the first 2 characters and the last 2 characters removed.

  • keepFirst returns only the first 2 characters.

  • keepLast returns only the last 2 characters.

  • keepFirstLast returns the first 2 characters, and the last 2 characters.

Notions

  • Array.slice
LOOP

cut-corners

Cut Corners

Instructions

Create some functions which behave like JavaScript's Math rounding functions:

  • round: which behaves similar to Math.round().
  • ceil: which behaves similar to Math.ceil().
  • floor: which behaves similar to Math.floor().
  • trunc: which behaves similar to Math.trunc().

Some restrictions apply:

  • You may not use strings conversion to do it
  • No bitwise operator
  • No % operator

Usage

const nums = [3.7, -3.7, 3.1, -3.1]
console.log(nums.map(round))
console.log(nums.map(floor))
console.log(nums.map(trunc))
console.log(nums.map(ceil))

Output:

[ 4, -4, 3, -3 ]
[ 3, -4, 3, -4 ]
[ 3, -3, 3, -3 ]
[ 4, -3, 4, -3 ]

Notions

  • Math

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Math.round = Math.ceil = Math.floor = Math.trunc = undefined
LOOP

reverser

Reverser

Instructions

Create a function named reverse which accepts an array or a string. It should work like Array.reverse(), and of course you cannot use that.

Notions

  • devdocs.io/javascript/global_objects/array/reverse

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.reverse = undefined
LOOP

unbreakable

Unbreakable

Instructions

Implement 2 functions:

  • split that works like String.split, but takes the string as its first argument.

  • join that works like Array.join, but take the array as its first argument.

Notions

  • Array.join
  • String.split

Code provided

The provided code will be added to your solution, and does not need to be submitted.

String.prototype.split = undefined
String.prototype.match = undefined
RegExp.prototype.exec = undefined
Array.prototype.join = undefined
LOOP

chunky

Chunky

Instructions

Create a function named chunk which accepts an array and an integer representing a size.

Your function will chunk the array into sub-arrays, and return an array with each sub-array as its elements. The length of each sub-array is denoted by the size argument.

If the array cannot be split evenly, the last sub-array will contain the remaining elements.

LOOP

nasa

Nasa

Instructions

Create a function named nasa that takes a number N as an argument and returns a string with all numbers from 1 to N separated by spaces. There are three exceptions:

  • Convert numbers which are divisible by 3 to "NA".
  • Convert numbers which are divisible by 5 to "SA".
  • Convert numbers which are divisible by 3 and 5 to "NASA".

Notions

  • Loops
  • Recursion
LOOP

molecules-cells

Molecules Cells

Instructions

Create two functions which accept a string, and return a string:

  • RNA: that converts a DNA strand into its compliment RNA strand.
  • DNA: that converts an RNA strand into its compliment DNA strand.

Compliments:

DNA | RNA
 G  -  C
 C  -  G
 T  -  A
 A  -  U

Each strand must be represented as upper case string, without spaces, eg: "ATCG" is a valid DNA strand.

LOOP

get

Get

Instructions

Create a function named get which takes two arguments:

  • src: an object.
  • path: a string representing a path.

Your function will return the value at the given path in the src object.

Example:

const src = { nested: { key: 'peekaboo' } }
const path = 'nested.key'
get(src, path) // -> 'peekaboo'
LOOP

triangle

Triangle

Instructions

Create a function named triangle that takes a string and a number as arguments. Your function will return a string representing a triangle.

The string will denote the characters which construct the triangle, and the number denotes its height.

Example

  • * character and depth of 5:
*
**
***
****
*****

No new line in last line

Notions

  • Loops
  • Recursion
LOOP

pyramid

Pyramid

Instructions

Create a function named pyramid which works just like your triangle function. But, it should be pyramid shaped.

Output example

  • * character and depth of 5 :
    *
   ***
  *****
 *******
*********

No new line in last line

Notions

  • Loops
  • Recursion
LOOP

flat

Flat

Instructions

Create a function named flat that works like Array.flat(), except its first argument is the array.

Notions

  • Flat

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.flat = undefined
LOOP

find-expression

Find Expression

Instructions

Create a function named findExpression that takes a number as parameter and returns a string.

  • 2 constant variables will be made available to your function: add4 and mul2.
  • Your goal is to try to find a sequence, starting from the number 1, and repeatedly either adding 4 or multiplying by 2, to produce the number given as a parameter.
  • If the number can not be reached you should return undefined

For example, for the number 8, you must first multiply by 2 twice, and then add 4. Your function should return something like: 1 *2 *2 +4.

Notions

  • Loops
  • Recursion

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const add4 = '+4'
const mul2 = '*2'
LOOP

sums

Sums

Instructions

Create a function named sums that accepts a number and returns its partitions.

A partition is a group of numbers, where the sum of the partition is equal to the number argument. Duplicate partitions are not allowed. [1, 2] and [2, 1] are considered duplicates. The array of partitions must be sorted.

Example:

sums(4) // [ [1, 1, 1, 1], [1, 1, 2], [1, 3], [2, 2] ]
FIND

its-a-match

Its A Match

Instructions

Have you ever pondered the etymology of grep?

Create 4 regular expression variables:

  • normal: matches with the expression 'hi'.

  • begin: matches with the expression 'hi', only when it is at the beginning.

  • end: matches with the expression 'hi', only when it is at the end.

  • beginEnd: matches with the expression 'hi', only when it is exactly hi.

Notions

  • RegEx Anchors
FIND

letter-space-number

Letter Space Number

Instructions

Create a function named letterSpaceNumber that accepts a string; returning an array with every instance of a letter, followed by a space, followed by a number, only if that number has only one digit, and is not followed by any letter.

Examples

console.log(letterSpaceNumber('example 1, example 20'))
// output: ['e 1']

Notions

  • RegEx Shorthand Character Sets
FIND

vowel-dots

Vowel Dots

Instructions

Create a function named vowelDots that receives a string. Your function should return a new string with a . after every vowel.

Your RegEx should be stored in a variable named vowels.

a, e, i, o and u are considered as vowels here.

Notions

  • RegEx Character Sets
FIND

same-amount

Same Amount

Instructions

Create a function named sameAmount, that takes three arguments: a string, and 2 regular expressions. Your function should return a boolean.

The objective is to confirm that the regular expressions match the string the same number of times.

Notions

  • Using regular expressions in JavaScript
FIND

ion-out

Ion Out

Instructions

Create a function named ionOut, that receives a string and returns an array with every word containing 'ion' following a 't'. The words should be returned without the 'ion' part.

Notions

  • Learn RegEx Lookarounds
FIND

greedy-url

Greedy Url

Instructions

Create 3 functions, which accept a string which we'll refer to as the dataSet. Your function should return an array of strings.

  • getURL: returns all URLs present in the dataSet.
  • greedyQuery: returns URLs from the dataSet, with at least 3 query parameters.
  • notSoGreedy: returns URLs from the dataSet, with at least 2, but not more then 3 query parameters.

Example dataSet:

qqq http:// qqqq q qqqqq https://something.com/hello qqqqqqq qhttp://example.com/hello?you=something&something=you

Only http and https URLs are valid. You can search for greedy quantifiers for help.

Notions

  • Learn RegEx
FIND

group-price

Group Price

Instructions

Create a function named groupPrice, that can find prices in a given string.

Your function will return 2D array with the full price breakdown.

If there is no match, your function should return an empty array.

Example

Given price of USD12.31:

[["USD12.31", "12", "31"]]
FIND

valid-ip

Valid Ip

Instructions

Create a function named findIP, that returns an array of valid IP addresses from a given string. These addresses may or may not have a port.

For the IP part, the syntax will be as follows, where x is a number from 0-255. Values with leading zeros are not valid:

x.x.x.x

Don't forget to learn about the syntax of ports. But remember, the maximum TCP port number is 65,535.

For this task, you only need to concern yourself with <host> and <port>. Don't worry about <scheme> or anything else.

Notions

  • Learn RegEx
RAID 1

crossword

crossword

Instructions

Create the function crosswordSolver that is able to solve an empty crossword puzzle. The function must be submitted in a file named crosswordSolver.js.

The function takes two arguments:

  1. an empty puzzle, passed as a string and
  2. a list of words to fill in the puzzle (no double words allowed)

The function must print on the console a string representing the puzzle filled with the input words.

The empty puzzle will be a string with the following rules:

  • each character will be either a number, a . or a \n;
  • a number represents the number of words starting from the specific position and a . represents a space that does not need to be filled.

If the puzzle or list of words provided as inputs does not guarantee a unique solution, or any other conditions stated above are not met, the function must print 'Error'.

Examples

const emptyPuzzle = `2001
0..0
1000
0..0`
const words = ['casa', 'alan', 'ciao', 'anta']

crosswordSolver(emptyPuzzle, words)

/* output:
`casa
i..l
anta
o..n`
*/
TIME

dr-strange

Dr Strange

Instructions

You will create two functions: addWeek and timeTravel.

You have been given a mission to create a new sense of time. Normally a week has 7 days right? Well, that is about to change.

Weeks will instead have 14 days.

Let me explain; this new week will have 14 days, from Monday to Sunday, then secondMonday to secondSunday.

Your purpose is to create a new function named addWeek, that takes a Date as an argument. Your function should return the weekday as a string, according to our new 14-day week format. The epoch of our new 14-day week is 0001-01-01, and that was a Monday.

What is an epoch?

Now imagine you have an appointment with your doctor, and you have to wait for some hours, but you do not want to wait. So you decide that you need to create a new function named timeTravel, that allows you to change the time according to your needs.

Your function will take an object as an argument, and return a Date. You can see the timeTravel example below to understand the structure of the object argument.

Your objective is to use the information from the object to modify the time of the Date before returning it.

Example

addWeek(new Date('0001-01-01')) // Output: Monday
addWeek(new Date('0001-01-02')) // Output: Tuesday
addWeek(new Date('0001-01-07')) // Output: Sunday
addWeek(new Date('0001-01-08')) // Output: secondMonday
addWeek(new Date('0001-01-09')) // Output: secondTuesday

// timeTravel({ date, hour, minute, second })

timeTravel({
  date: new Date('2020-05-29 23:25:22'),
  hour: 21,
  minute: 22,
  second: 22,
}).toString()

// Output: Fri May 29 2020 21:22:22 GMT+0100 (Western European Summer Time)
TIME

date-is

Date Is

Instructions

Create the following functions:

  • isValid: accepts a Date, and returns false if the Date is invalid.
  • isAfter: accepts two Date arguments, and returns true if the first is greater then the second.
  • isBefore: accepts two Date arguments, and returns true if the second is greater than the first.
  • isFuture: accepts a Date, and returns true if the Date is valid, and is after than the present date.
  • isPast: accepts a Date, and returns true if the Date is valid, and is before the present date.

Notions

  • date-fns: isValid
  • date-fns: isAfter
  • date-fns: isBefore
  • date-fns: isFuture
  • date-fns: isPast
TIME

get-some-time

Get Some Time

Instructions

Create a function named firstDayWeek, which accepts a specific week in a given year:

  • number: representing a week of the year (between 1 and 53).
  • string: representing a year.

Your function should return a string representing the date of the first day of that specific week in the format dd-mm-yyyy.

Week 1 is in all cases, the week which contains the 1st of January.

The first day of a week is a Monday.

If the start of the week is in the previous year, then your function should return the first day of the specified year.

TIME

rebecca-black

Rebecca Black

Instructions

Create the following functions which accept a Date:

  • isFriday: returns true if the Date is a Friday.
  • isWeekend: returns true if the Date is a weekend day.
  • isLeapYear: returns true if the year of the Date is a leap year.
  • isLastDayOfMonth: returns true if the Date represents the last day of the month.

Notions

  • date-fns: isWeekend
  • date-fns: isAfter
  • date-fns: isLastDayOfMonth
TIME

match-cron

Match Cron

Instructions

Create a function named matchCron, which accepts a valid cron string, and a valid Date. Your function should return true if the pattern matches the Date.

You only need to implement numbers and *. Other complex patterns are not required.

Only valid patterns will be tested.

Example

matchCron('9 * * * *', new Date('2020-05-30 18:09:00')) // -> true
matchCron('9 * * * *', new Date('2020-05-30 19:09:00')) // -> true
matchCron('9 * * * *', new Date('2020-05-30 19:21:00')) // -> false
//         | | | | |
//         | | | | +- Day of the Week   (range: 1-7, 1 is Monday)
//         | | | +--- Month of the Year (range: 1-12)
//         | | +----- Day of the Month  (range: 1-31)
//         | +------- Hour              (range: 0-23)
//         +--------- Minute            (range: 0-59)

Notions

  • crontab.guru
  • Date
TIME

count-leap-years

Count Leap Years

Instructions

Create a function named countLeapYears which accepts a Date. Your function should return the number of leap years to have taken place since the year 1.

TIME

day-of-the-year

Day Of The Year

Instructions

Create a function named dayOfTheYear which accepts a Date. Your function should return the number of days since the first day of that year.

TIME

sunny-sunday

Sunny Sunday

Instructions

Let's eliminate Sundays by taking them out of the calendar, making a week only six days long, from "Monday" to "Saturday".

Create a function called sunnySunday that takes a Date as an argument and returns the weekday as a string.

01/01/0001 is a Monday.

TIME

unicode-technical-report-35

Unicode Technical Report 35

Subject

Create a function named format which accepts a valid Date and a format string. Your function should return a correctly formatted string.

Your function must handle:

  • y
  • yyyy
  • G
  • GGGG
  • M
  • MM
  • MMM
  • MMMM
  • d
  • dd
  • E
  • EEEE
  • h
  • hh
  • m
  • mm
  • s
  • ss
  • H
  • HH
  • a

Example

const d = new Date('7 January 1985, 3:08:19')

format(d, 'HH(mm)ss [dd] <MMM>') // -> '03(08)19 [07] <Jan>'

Notions

  • Unicode Date Field Symbol Table
CALL ME MAYBE

using-map

Using Map

Instructions

Create the following functions:

Your solutions must use map.

Cities Only

citiesOnly: accepts an array of objects and returns an array of strings from the city key.

citiesOnly([
  {
    city: 'Los Angeles',
    temperature: '  101 °F   ',
  },
  {
    city: 'San Francisco',
    temperature: ' 84 ° F   ',
  },
]) // -> ['Los Angeles', 'San Francisco']

Upper Casing States

upperCasingStates: accepts an array of strings, and returns a new array of strings. The returned array will be the same as the argument, except the first letter of every word must be capitalized.

upperCasingStates(['alabama', 'new jersey']) // -> ['Alabama', 'New Jersey']

Fahrenheit to Celsius

fahrenheitToCelsius: accepts an array of fahrenheit temperatures as strings, and returns an array of strings converted to celsius. Round down the result.

fahrenheitToCelsius(['68°F', '59°F', '25°F']) // -> ['20°C', '15°C', '-4°C']

Trim Temp

trimTemp: accepts an array of objects, and returns a new array of objects with the same structure. The temperature strings must have their spaces removed in the new array.

trimTemp([
  { city: 'Los Angeles', temperature: '  101 °F   ' },
  { city: 'San Francisco', temperature: ' 84 ° F   ' },
]) /* -> [
  { city: 'Los Angeles', temperature: '101°F' },
  { city: 'San Francisco', temperature: '84°F' },
] */

Temp Forecasts

tempForecasts: accepts an array of objects, and returns an array of formatted strings. See the example below:

tempForecasts([
  {
    city: 'Pasadena',
    temperature: ' 101 °F',
    state: 'california',
    region: 'West',
  },
]) // -> ['38°Celsius in Pasadena, California']

Notions

  • Array.prototype.map
CALL ME MAYBE

using-filter

Using Filter

Instructions

Create the following functions:

Your solutions must use filter.

  • filterShortStateName: accepts an array of strings, and returns only those strings which contain less than 7 characters.

  • filterStartVowel: accepts an array of strings, and returns only those that start with any vowel (a,e,i,o,u).

  • filter5Vowels: accepts an array of strings, and returns only those which contain at least 5 of any vowels (a,e,i,o,u).

  • filter1DistinctVowel: accepts an array of strings, and returns only those which contain only one distinct vowel (a,e,i,o,u). For example, "Alabama" contains only 1 distinct vowel "a".

  • multiFilter: accepts an array of objects, and returns only those which:

    • the key capital contains at least 8 characters.
    • the key name does not start with a vowel.
    • the key tag has at least one vowel.
    • the key region is not "South"

Notions

  • Array.prototype.filter
CALL ME MAYBE

using-reduce

Using Reduce

Instructions

Create the following functions:

Your solutions must use reduce.

  • adder: accepts an array of numbers, and returns the sum as a number.

  • sumOrMul: accepts an array of numbers and adds or multiplies its elements depending on whether the element is odd or even. Even = multiply. Odd = add.

  • funcExec: accepts an array of functions and executes them using reduce, returning the result.

Each function may accept an optional argument, which should be the initial value for the function's execution.

Example:

sumOrMul([1, 2, 3, 5, 8], 5) // (((((5 + 1) * 2) + 3) + 5) * 8) -> 160

Notions

  • Array.prototype.reduce
CALL ME MAYBE

long-words

Long Words

Instructions

Create three functions, which each accept an array as an argument.

  • longWords: returns true if every element of the array is a string with at least 5 characters.

  • oneLongWord: returns true if at least one element of the array is a string with 10 or more characters.

  • noLongWords: returns true if there are no elements in the array which is a string with at least 7 characters.

Notions

  • Array.prototype.every
  • Array.prototype.some
CALL ME MAYBE

for-each

For Each

Instructions

Create a function named forEach which takes an array as the first argument, a function as the second argument, and that works like the Array.prototype.forEach method.

Notions

  • Array.prototype.forEach

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.forEach = undefined
CALL ME MAYBE

mapper

Mapper

Instructions

  • Create a map function that takes an array as the first argument, a function as second, and that works like the method .map

  • Create a flatMap function that takes an array as the first argument, a function as second, and that works like the method .flatMap

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.map = undefined
Array.prototype.flatMap = undefined
Array.prototype.flat = undefined

Notions

  • devdocs.io/javascript/global_objects/array/map
  • devdocs.io/javascript/global_objects/array/flatmap
CALL ME MAYBE

filter

Filter

Instructions

Create the following functions, which each take an array as the first argument, and a function as the second argument.

  • filter: that works like the [].filter method.

  • reject: that works like the reject function from lodash.

  • partition: that works like the partition function from lodash.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.filter = undefined

Notions

  • devdocs.io/javascript/global_objects/array/filter
  • lodash.com/docs/4.17.15#reject
  • lodash.com/docs/4.17.15#partition
CALL ME MAYBE

reduce

Reduce

Instructions

Create four functions:

  • fold that receives an array, a function and an accumulator, in this order, and applies the function in the elements of the array starting on the left.

  • foldRight that receives an array, a function and an accumulator, in this order, and applies the function in the elements of the array starting on the right.

  • reduce that works just like the method [].reduce when you don't specify an accumulator. The arguments should be an array and a function. The starting value of your accumulator must be the first value of the array. If your array is less than 1 argument you should throw an error.

  • reduceRight like reduce, from the last value to the first

Example:

const adder = (a, b) => a + b
fold([1, 2, 3], adder, 2) // returns 8 (2 + 1 + 2 + 3)
foldRight([1, 2, 3], adder, 2) // returns 8 (2 + 3 + 2 + 1)
reduce([1, 2, 3], adder) // returns 6 (1 + 2 + 3)
reduceRight([1, 2, 3], adder) // returns 6 (3 + 2 + 1)

The use of [].reduce and [].reduceRight is forbidden for this exercise.

Notions

  • devdocs.io/javascript/global_objects/array/reduce

Code provided

all code provided will be added to your solution and doesn't need to be submited.

Array.prototype.reduce = undefined
Array.prototype.reduceRight = undefined
CALL ME MAYBE

quantifiers

Quantifiers

Instructions

Create these functions which receive an array and a function each. Each element will return true if

  • every: every element in the array respects the condition of the function.
  • some: that returns true if at least one element in the array respects the condition of the function.
  • none: that returns true if none of the elements in the array respects the condition of the function.

The use of [].every and [].some is forbidden for this exercise.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Array.prototype.some = Array.prototype.every = undefined

Notions

  • devdocs.io/javascript/global_objects/array/some
  • devdocs.io/javascript/global_objects/array/every
CALL ME MAYBE

sweet-curry

Sweet Curry

Instructions

Create the following functions with the "currying" process. Those functions should accept only one argument each.

  • mult2: that multiplies two numbers.
  • add3: that adds three numbers.
  • sub4: that subtracts four numbers in the given order: first number minus second number etc.

Notions

  • stackoverflow.com/questions/36314/what-is-currying
CALL ME MAYBE

has-city

Has City

Instructions

Create a function hasCity that takes a string called country and an array of strings, which are cities of that country, which returns a new function. The new function takes a string, called city, as a parameter and which determines whether the array contains that string or not.

If it does, it should return the string <city> is a city from <country>, otherwise <city> is not a city from <country>.

CALL ME MAYBE

flow

Flow

Instructions

Create the function named flow that will act like the _.flow([funcs]) from lodash.

Example

const square = (nbr) => nbr * nbr
const add2Numbers = (nbr1, nbr2) => nbr1 + nbr2

const flowedFunctions = flow([add2Numbers, square])
flowedFunctions(2, 3) // -> 25

Notions

  • lodash.com/docs/4.17.15#flow
CALL ME MAYBE

currify

Currify

Instructions

Create the function currify that will curry any functions put as argument.

example:

const mult2 = (el1, el2) => el1 * el2
console.log(mult2(2, 2)) // result expected 4

const mult2Curried = currify(mult2)

console.log(mult2Curried(2)(2)) // result expected 4
// (same result, with a function that has technically only one argument)

Notions

  • stackoverflow.com/questions/36314/what-is-currying
CALL ME MAYBE

DOM

README not found in repo.

CALL ME MAYBE

get-them-all

Get them all

Instructions

You've been attributed the task to find the main architect of the Tower of Pisa before he achieves his plans, avoiding us nowadays all those lame pictures of people pretending to stop it from falling.

You arrive at the architects' chamber to find him, but all you have in front of you is a bunch of unknown people. Step by step, with the limited details you have, gather information and figure out by elimination who he is.

Launch the provided HTML file in the browser to begin your investigation.
On top of the webpage, each of the four buttons fires a function:

  • Write the body of the getArchitects function, which returns an array containing 2 arrays of HTML elements:

    • the first array contains the architects, all corresponding to a <a> tag
    • the second array contains all the non-architects people
  • Write the body of the getClassical function, which returns an array containing 2 arrays of HTML elements:

    • the first array contains the architects belonging to the classical class
    • the second array contains the non-classical architects
  • Write the body of the getActive function, which returns an array containing 2 arrays of HTML elements:

    • the first array contains the classical architects who are active in their class
    • the second array contains the non-active classical architects
  • Write the body of the getBonannoPisano function, which returns an array containing:

    • the HTML element of the architect you're looking for, whose id is BonannoPisano
    • an array which contains all the remaining HTML elements of active classical architects

From now on, don't forget to export all the expected functions, so that they can be imported to be tested
> export const getArchitects = () => {...}

Notions

  • HTML Element
  • getElementsByTagName()
  • getElementsByClassName()
  • getElementById()
  • querySelectorAll() / querySelector()
  • ...and bit of CSS that could help with the :not pseudo class

Files

You only need to create & submit the JS file get-them-all.js ; we're providing you the following files to download (click right and save link) & test locally:

  • the HTML file get-them-all.html to open in the browser, which includes:

    • the JS script running some code, and which will also allow to run yours
    • some CSS pre-styled classes: feel free to use those as they are, or modify them
    • the import of the data
  • the data file get-them-all.data.js used to generate content in the HTML

  • feel free to use the CSS file get-them-all.data.css as it is or you can also modify it.

CALL ME MAYBE

build-brick-and-break

Build brick and break

Instructions

Today, your mission is to build a 3-column brick tower, maintain it and finally break it.

  • Create a function build which will create and display the amount of bricks passed as argument:

    • each brick has to be created as a div and added to the page at a regular interval of 100ms.
    • each brick will receive a unique id property, like the following:
    <div id="brick-1"></div>
    
    • each brick in the middle column has to be set with the custom data attribute foundation, receiving the value true.
  • Each one of the two emojis in the top-right corner fires a function on click:

    • 🔨: triggers the function repair. Write the body of that function. It receives any number of ids. For each id, it retrieves the HTML element, and sets the repaired custom attribute to in progress if it is a brick situated in the middle column, and true if not.
    • 🧨: triggers the destroy function. Write the body of that function. It removes the current last brick in the tower.

Files

You only need to create & submit the JS file build-brick-and-break.js, We're providing you the following file to download and test locally:

  • the HTML file build-brick-and-break.html can be opened in the browser, which includes:

    • the JS script running some code, and which will enable you to run your code.
  • feel free to use the CSS file build-brick-and-break.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • createElement
  • append
  • Element
  • setInterval / clearInterval
  • hasAttribute
  • dataset / data-*
  • remove
CALL ME MAYBE

harder-bigger-bolder-stronger

Harder, bigger, bolder, stronger

Instructions

Being stuck at home, bored, desperate and coming up with a lot of weird ideas, a friend asks you to develop a tool to measure his ocular skills. One of those Monoyer charts that ophthalmologists use.

Generate a board where each new letter is harder, bigger, bolder and stronger.

Write the function generateLetters which creates 120 div elements, each containing a letter randomly picked through the uppercase alphabet, and whose style properties have to be increased:

  • each letter's font-size has to grow from 11 to 130 pixels.
  • font-weight has to be 300 for the first third of the letters, 400 for the second third, and 600 for the last third.

Files

You only need to create & submit the JS file harder-bigger-bolder-stronger.js. We're providing you the following file to download and test locally:

  • the HTML file harder-bigger-bolder-stronger.html to open in the browser, which includes:

    • the JS script running some code, and which will enable you to run yours.
  • feel free to use the CSS file harder-bigger-bolder-stronger.data.css as it is or you can also modify it.

Notions

  • createElement
  • append
  • style
  • textContent
CALL ME MAYBE

pimp-my-style

Pimp my style

Instructions

Check out that button on the HTML page:

<button class="button">pimp my style</div>

For now, it's only a lonely, basic and sad element. let's pimp it up.

On each click on the page, a function pimp is triggered. Write the body of that function so that the button's class is altered:

  • From the data file provided, add each of the styles array elements as classes, in order.
  • When the end of the array is reached, remove the classes in a LIFO fashion.
  • While removing classes, toggle the unpimp class on. And toggle it off again while adding classes.

Example for a styles array with only 3 classes:

["one", "two", "three"]
Page load --> <button class="button"></button>

...adding
Click 1 --> <button class="button one"></button>
Click 2 --> <button class="button one two"></button>

...toggling `unpimp`
Click 3 --> <button class="button one two three unpimp"></button>

...and removing backwards
Click 4 --> <button class="button one two unpimp"></button>
Click 5 --> <button class="button one unpimp"></button>
Click 6 --> <button class="button"></button>

Files

You only need to create & submit the JS file pimp-my-style.js. We're providing you the following files to download and test locally.:

  • the HTML file pimp-my-style.html to open in the browser, which includes:

    • the JS script running some code, and which will enable you to run yours.
  • the data file pimp-my-style.data.js from which you can import styles.

  • feel free to use the CSS file pimp-my-style.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • classList: add(), remove(), toggle()
CALL ME MAYBE

fifty-shades-of-cold

Fifty shades of cold

Instructions

You've been asked to freshen up a webpage, by displaying shades of cold colors.

Check the colors array provided in the data file below.

Write the generateClasses function. It creates a <style> tag inside the <head>. It should generate one class for each color in the colors array, which sets the background attribute like so:

.blue {
  background: blue;
}

Write the generateColdShades function which creates a <div> for each color of the colors array, whose name contains aqua, blue, turquoise, green, cyan, navy or purple. Each <div> must have the corresponding generated class and display the name of the color, like following:

<div class="blue">blue</div>

The function choseShade is triggered when clicking on a div. Write the body of this function. It accepts the shade of the clicked element as an argument, and replaces all the classes of all the other elements by the chosen shade.

Files

You only need to create & submit the JS file fifty-shades-of-cold.js, we're providing you the following files to download and test locally:

  • the HTML file fifty-shades-of-cold.html to open in the browser, which includes:

    • the JS script running some code, and which will enable you to run yours
  • the data file fifty-shades-of-cold.data.js from which you can import colors.

  • feel free to use the CSS file fifty-shades-of-cold.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • head tag
  • style tag
  • className
  • classList: contains(), replace()
CALL ME MAYBE

keycodes-symphony

Keycodes symphony

Instructions

Like an inspired Beethoven who's about to write his Moonlight Sonata, you're about to compose a colorful symphony of letters with your keyboard.

Write the function compose:

  • Make it fire every time a key is pressed.
  • Create a new div with the class note when a letter of the lowercase alphabet is pressed. It should have a unique background color generated using the key of the event. It should also display the corresponding pressed character.
  • When Backspace is pressed, delete the last note.
  • When Escape is pressed, clear all the notes.

Files

You only need to create & submit the JS file keycodes-symphony.js; we're providing you the following file to download to test locally:

  • the HTML file keycodes-symphony.html to open in the browser, which includes:

    • the JS script which will allow to run your code.
  • feel free to use the CSS file keycodes-symphony.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • Keyboard event: keydown, key
CALL ME MAYBE

mouse-trap

Mouse trap

Instructions

Develop a trap to capture the elements when the mouse is getting too close to the center of the page.

Create the following functions:

  • createCircle: make it fire on every click on the page, and create a div at the position of the mouse on the screen, setting its background to white and its class to circle.

  • moveCircle: make it fire when the mouse moves, and get the last circle created and makes it move along with the mouse.

  • setBox: which creates a box with the class box in the center of the page. When a circle is entirely inside that box, it has to be purple (use the CSS global variable var(--purple) as its background). Once a circle enters the box, it is trapped inside and cannot escape.

Hint: Be careful, a circle cannot overlap the box which has walls of 1px. It has to be trapped strictly inside.

Provided files

Files

You only need to create & submit the JS file mouse-trap.js, we're providing you the following files to download and test locally:

  • the HTML file mouse-trap.html to open in the browser, which includes:

    • the JS script which will enable you to run your code.
  • feel free to use the CSS file mouse-trap.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • addEventListener
  • removeEventListener
  • Mouse event
  • click
  • mousemove
  • clientX
  • clientY
  • getBoundingClientRect
CALL ME MAYBE

pick-and-click

Pick & click

Instructions

Today, you're going to create your own color picker.

Write the function pick which turns the screen into a hsl color picker. It will vary the hue and luminosity according to the position of the mouse.

The background color of the body will change based on the position of the mouse on the screen.

  • The X axis will vary the hue value between 0 and 360.
  • The Y axis will vary the luminosity value between 0 and 100.

You'll need to display these three values:

  • The full hsl value in a div, which has the class hsl in the middle of the screen.
  • The hue value in a div with the class hue and text in the top right corner of the screen.
  • The luminosity value will be displayed in the bottom left corner of the screen, in a div with the class luminosity and text.

When the mouse is clicked, the value of the hsl will need to be copied to the clipboard.

Two SVG lines with ids axisX and axisY will need to follow the cursor, like really long cross hairs.

  • the axisX attributes x1 and x2 need to be set to the X position of the cursor.
  • the axisY attributes y1 and y2 need to be set to the Y position of the cursor.

The formatting of a hsl value: hsl(45, 50%, 35%).

Use Math.round() to round the values.

Files

You only need to create & submit the JS file pick-and-click.js; we're providing you the following file to download and test locally:

  • the HTML file pick-and-click.html to open in the browser, which includes:

    • the JS script which will enable you to run your code.
  • feel free to use the CSS file pick-and-click.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • Copy event
  • Mouse move event
  • SVG
  • createElementNS
  • setAttribute
  • Take a look at the HSL section
CALL ME MAYBE

gossip-grid

Gossip grid

Instructions

Create the function grid which displays all the gossips, provided in the data file below, as cards on a grid (in the same order).

They will each be represented as a div with the gossip class.

The first gossip card must be a form. It will need a textarea, and a submit button with the text "Share gossip!". It will add new gossip to the list.

Create 3 type="range" inputs with the class range, all wrapped in a div with the class ranges.

  • id="width": that controls the width of cards from 200 to 800 pixels.
  • id="fontSize": that controls the font size from 20 to 40 pixels.
  • id="background": that control the background lightness from 20% to 75%.

Use hsl for colors

Files

You only need to create & submit the JS file gossip-grid.js; we're providing you the following files to download and test locally:

  • the HTML file gossip-grid.html to open in the browser, which includes:

    • the JS script which will enable you to run your code.
  • the data file gossip-grid.data.js from which you can import gossips.

  • feel free to use the CSS file gossip-grid.data.css as it is or you can also modify it.

Expected result

You can see an example of the expected result here

Notions

  • form
  • input
  • text
  • range
CALL ME MAYBE

where-do-we-go

Where do we go?

Instructions

Where will you go on your next holiday?

Let's make a page to index your options, so that next time you ask yourself that question, you'll be ready with some ideas.

Create a function named explore, which creates a page displaying the list of places provided in the data file below.

  • Sort the places from north to south, so that the northern-most place is first.
  • Display a fullscreen-size <section> for each place. Use the pics hosted in the ./where-do-we-go_images folder below. Set the background attribute with the corresponding image URL. The URL has to be formatted like so: ./where-do-we-go_images/name-of-the-place.jpg.
  • Display a location indicator as an <a> tag in the middle of the screen. It should:
    • have the class location
    • display the name and coordinates of the current place, as text strings separated by \n
    • set the text color as color
    • update the name, coordinates and color on scroll, at the point when the next image reaches the middle of the screen height
    • make the href attribute open a new tab redirecting to a Google Maps URL with the coordinates of the place currently displayed
  • Display a compass as a div tag, indicating the latitude direction which:
    • has the class direction
    • displays N for North if the user is scrolling up
    • displays S for South if he's scrolling down

Files

You only need to create & submit the JS file where-do-we-go.js; we're providing you the following files to download and test locally:

  • the HTML file where-do-we-go.html to open in the browser, which includes:

    • the JS script which will enable you to run your code
  • the data file where-do-we-go.data.js from which you can import places

  • feel free to use the CSS file where-do-we-go.data.css as it is or you can also modify it.

  • you can get the images to be used in this compressed folder or you can get them in the where-do-we-go_images folder from the public URL. Example: `https://public.01-edu.org/subjects/where-do-we-go/where-do-we-go_images/arlit.jpg

Expected result

You can see an example of the expected result here

Notions

  • Scroll event
  • window
  • innerHeight
  • scrollY
  • pageYOffset
  • Take a look at the DMS coordinates system
RAID 2

sortable

Sortable

Instructions

You are a villain and your dream is to get rid of those annoying, yoga-pant-wearing, weird masked superheroes. You never understood why some of them are considered to be superheroes, just because they are rich. Others annoy you with their philosophical speeches.

We've found confidential information about those superheroes.

Your task is to build a web page to organize all the data about those smartypants. All that data can be found here in all.json.

You must write all of the code from scratch. You are not allowed to rely on any frameworks or libraries like React, Vue, Svelte etc.

Fetching the data

In order to get the information, you should use fetch. When you use fetch in JS, it always returns a Promise. We will look more deeply into that later on. For now, take a look at this:

// This function is called only after the data has been fetched, and parsed.
const loadData = (heroes) => {
  console.log(heroes);
};

// Request the file with fetch, and the data will be downloaded to your browser cache.
fetch("https://rawcdn.githack.com/akabab/superhero-api/0.2.0/api/all.json")
  .then((response) => response.json()) // parse the response from JSON
  .then(loadData); // .then will call the `loadData` function with the JSON value.

Display

Not all the information is valuable at a glance, so we will only show some of the fields in a <table> element. The necessary data will be:

  • Icon (.images.xs, should be displayed as images and not as a string)
  • Name (.name)
  • Full Name (.biography.fullName)
  • Powerstats (each entry of .powerstats)
  • Race (.appearance.race)
  • Gender (.appearance.gender)
  • Height (.appearance.height)
  • Weight (.appearance.weight)
  • Place Of Birth (.biography.placeOfBirth)
  • Alignment (.biography.alignment)

The information must be displayed in multiple pages. Use a <select> input to chose the page size from 10, 20,50, 100 or all results.

The default page size selected option must be 20.

Search

It must be possible to filter information by searching the name as a string. For example, searching "man" should find all superheros with "man" in their name.

The search should be interactive. In other words, the results should be filtered after every keystroke. So we don't need a "search" button.

Sort

It will be valuable to sort the information in the table by any of its columns. Results should be sortable alphabetically or numerically.

  • Initially all rows should be sorted by the column name by ascending order.
  • The first click on a column heading will sort the table by the data in that column in ascending order.
  • Consecutive clicks on a column heading will toggle between ascending and descending.
  • Some of the columns are composed of strings, but represent numerical values. For example, when the weight column is sorted in ascending order, then "78 kg" must be displayed before "100 kg".
  • Missing values should always be sorted last, irrespective of ascending or descending.

When dealing with heroes, speed is critical. All operations must be performed quickly, without slowing the browser down.

Bonus

Additional features will be critical to your success. Here's a few which will give you a bigger boost:

  • Specify the field that the search applies to.
  • Custom search operators
    • include
    • exclude
    • fuzzy
    • equal, not equal, greater than and lesser than for numbers (including weight and height).
  • Detail view. Clicking a hero from the list will show all the details and large image.
  • A slick design. Spend some time improving the look and feel by playing around with CSS. Have fun with it.
  • Modify the URL with the search term, so that if you copy and paste the URL in a different tab, it will display the same column filters. If you have implemented detail view, the state of which hero is displayed should also form part of the URL.
OBJECT

invert

Invert

Instructions

Create a function named invert which takes an object and returns a new one with its keys and values inverted.

Notions

  • object
OBJECT

pick-omit

Pick Omit

Instructions

Create two functions which takes an object and a string or array of strings. They should return a new object which:

  • pick: contains only those keys which appear in the string or array of strings.
  • omit: contains only those keys which do not match the string, or do not appear in the array of strings.

Those functions are pure and must not modify the given object It should ignore properties from the prototype chain

Notions

  • object
OBJECT

fusion

Fusion

Instructions

The objective of this exercise is to merge objects into a new object depending on the values type.

Create a function named fusion that:

  • For array types, you will concatenate them.
fusion({ arr: [1, "2"] }, { arr: [2] }); // -> { arr: [ 1, '2', 2 ] }
fusion({ arr: [], arr1: [5] },{ arr: [10, 3], arr1: [15, 3], arr2: ["7", "1"] }); // ->{ arr: [ 10, 3 ], arr1: [ 5, 15, 3 ], arr2: [ '7', '1' ] }
  • For strings, you must concatenate them with a space.
fusion({ str: "salem" }, { str: "alem" }); // -> { str: 'salem alem' }
fusion({ str: "salem" }, { str: "" }); // -> { str: 'salem ' }
  • If they are numbers, you must add them.
fusion({ a: 10, b: 8, c: 1 }, { a: 10, b: 2 }); // -> { a: 20, b: 10, c: 1 }
  • If it is an object, you must join them recursively.
fusion({ a: 1, b: { c: "Salem" } }, { a: 10, x: [], b: { c: "alem" } }); // -> { a: 11, x: [], b: { c: 'Salem alem' } }
fusion( { a: { b: [3, 2], c: { d: 8 } } },{ a: { b: [0, 3, 1], c: { d: 3 } } }); // -> { a: { b: [ 3, 2, 0, 3, 1 ], c: { d: 11 } } }
  • In case of type mismatch you must replace it with the value of the second object (if it exists).
fusion({ a: "hello", b: [] }, { a: 4 }); // -> { a: 4, b: [] }
OBJECT

manipulate-values

Manipulate Values

Instructions

Let's buy groceries.

You have a grocery cart with some items you need. The item's name is the key, and the value will represent nutrition facts per 100 grams.

Create 3 functions that work like the .filter, .map and .reduce array methods, for the values in your grocery cart object. You can see their function names and how they work in the examples.

Examples

const nutrients = { carbohydrates: 12, protein: 20, fat: 5 }

console.log(filterValues(nutrients, (nutrient) => nutrient <= 12))
// output: { carbohydrates: 12, fat: 5 }

console.log(mapValues(nutrients, (v) => v+1))
// output: { carbohydrates: 13, protein: 21, fat: 6 }

console.log(reduceValues(nutrients, (acc, cr) => acc + cr))
// output: 37

You will have a small database to help you with the groceries.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

// small database with nutrition facts, per 100 grams
// In this exercise this is used for testing purposes only
// prettier-ignore
const nutritionDB = {
    tomato:  { calories: 18,  protein: 0.9,   carbs: 3.9,   sugar: 2.6, fiber: 1.2, fat: 0.2   },
    vinegar: { calories: 20,  protein: 0.04,  carbs: 0.6,   sugar: 0.4, fiber: 0,   fat: 0     },
    oil:     { calories: 48,  protein: 0,     carbs: 0,     sugar: 123, fiber: 0,   fat: 151   },
    onion:   { calories: 0,   protein: 1,     carbs: 9,     sugar: 0,   fiber: 0,   fat: 0     },
    garlic:  { calories: 149, protein: 6.4,   carbs: 33,    sugar: 1,   fiber: 2.1, fat: 0.5   },
    paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1,   fiber: 0,   fat: 12.89 },
    sugar:   { calories: 387, protein: 0,     carbs: 100,   sugar: 100, fiber: 0,   fat: 0     },
    orange:  { calories: 49,  protein: 0.9,   carbs: 13,    sugar: 9,   fiber: 0.2, fat: 0.1   },
  }

Notions

  • filter
  • map
  • reduce
  • entries
  • fromEntries
OBJECT

manipulate-keys

Manipulate Keys

Instructions

I do not want onions. I want oranges.

Create 3 functions that works like the .filter, .map and .reduce array methods, but for the keys of your grocery cart. You can see their names and how they work in the examples.

Examples

const nutrients = { carbohydrates: 12, protein: 20, fat: 5 }

console.log(filterKeys(nutrients, (key) => /protein/.test(key)))
// output: { protein: 20 }

console.log(mapKeys(nutrients, (k) => `-${k}`))
// output: { -carbohydrates: 12, -protein: 20, -fat: 5 }

console.log(reduceKeys(nutrients, (acc, cr) =>acc.concat(', ', cr)))
// output: carbohydrates, protein, fat

Code provided

The provided code will be added to your solution, and does not need to be submitted.

// small database with nutrition facts, per 100 grams
// prettier-ignore
const nutritionDB = {
  tomato:  { calories: 18,  protein: 0.9,   carbs: 3.9,   sugar: 2.6, fiber: 1.2, fat: 0.2   },
  vinegar: { calories: 20,  protein: 0.04,  carbs: 0.6,   sugar: 0.4, fiber: 0,   fat: 0     },
  oil:     { calories: 48,  protein: 0,     carbs: 0,     sugar: 123, fiber: 0,   fat: 151   },
  onion:   { calories: 0,   protein: 1,     carbs: 9,     sugar: 0,   fiber: 0,   fat: 0     },
  garlic:  { calories: 149, protein: 6.4,   carbs: 33,    sugar: 1,   fiber: 2.1, fat: 0.5   },
  paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1,   fiber: 0,   fat: 12.89 },
  sugar:   { calories: 387, protein: 0,     carbs: 100,   sugar: 100, fiber: 0,   fat: 0     },
  orange:  { calories: 49,  protein: 0.9,   carbs: 13,    sugar: 12,  fiber: 0.2, fat: 0.1   },
}

Notions

  • filter
  • map
  • reduce
  • entries
  • fromEntries
OBJECT

manipulate-entries

Manipulate Entries

Instructions

Create 3 functions which work like the .filter, .map and .reduce array methods, but for the entries in the grocery cart.

  • filterEntries: filters using both key and value, passed as an array ([k, v]).
  • mapEntries: changes the key, the value or both, passed as an array ([k, v]).
  • reduceEntries: reduces the entries passing keys and values as an array ([k, v]).

Create 3 additional functions that use your previously created functions and take an object as input:

  • totalCalories: that will return the total calories of a cart.
  • lowCarbs: that leaves only those items of the cart which have less than 50 grams of carbs after calculating the total amount.
  • cartTotal: that will give you the right amount of calories, proteins and so on for each item in your grocery cart.

Think about the shape of Object.entries()

Code provided

The provided code will be added to your solution, and does not need to be submitted.

// small database with nutrition facts, per 100 grams
// prettier-ignore
const nutritionDB = {
  tomato:  { calories: 18,  protein: 0.9,   carbs: 3.9,   sugar: 2.6, fiber: 1.2, fat: 0.2   },
  vinegar: { calories: 20,  protein: 0.04,  carbs: 0.6,   sugar: 0.4, fiber: 0,   fat: 0     },
  oil:     { calories: 48,  protein: 0,     carbs: 0,     sugar: 123, fiber: 0,   fat: 151   },
  onion:   { calories: 0,   protein: 1,     carbs: 9,     sugar: 0,   fiber: 0,   fat: 0     },
  garlic:  { calories: 149, protein: 6.4,   carbs: 33,    sugar: 1,   fiber: 2.1, fat: 0.5   },
  paprika: { calories: 282, protein: 14.14, carbs: 53.99, sugar: 1,   fiber: 0,   fat: 12.89 },
  sugar:   { calories: 387, protein: 0,     carbs: 100,   sugar: 100, fiber: 0,   fat: 0     },
  orange:  { calories: 49,  protein: 0.9,   carbs: 13,    sugar: 9,   fiber: 0.2, fat: 0.1   },
}

Usage

Here is a possible script to test your functions:

The value for each item in groceriesCart is the number of grams

const groceriesCart = { orange: 500, oil: 20, sugar: 480 }

console.log('Total calories:')
console.log(totalCalories(groceriesCart))
console.log('Items with low carbs:')
console.log(lowCarbs(groceriesCart))
console.log('Total cart nutritional facts:')
console.log(cartTotal(groceriesCart))

And its output:

Total calories:
2112.2
Items with low carbs:
{ oil: 20 }
Total cart nutritional facts:
{
  orange: {
    calories: 245,
    protein: 4.5,
    carbs: 65,
    sugar: 45,
    fiber: 1,
    fat: 0.5
  },
  oil: {
    calories: 9.6,
    protein: 0,
    carbs: 0,
    sugar: 24.6,
    fiber: 0,
    fat: 30.2
  },
  sugar: {
    calories: 1857.6,
    protein: 0,
    carbs: 480,
    sugar: 480,
    fiber: 0,
    fat: 0
  }
}

Notions

  • filter
  • map
  • reduce
  • entries
  • fromentries
OBJECT

curry-entries

Curry Entries

Instructions

You're going to create some curry functions, to apply to the object's entries.

Create defaultCurry, which curries two objects. It mergers the objects together. If the key exists in both objects, the value from the second object override the value from the first object.

defaultCurry({
  http: 403,
  connection: 'close',
  contentType: 'multipart/form-data',
})({
  http: 200,
  connection: 'open',
  requestMethod: 'GET'
})
// output
{
    http: 200,
    connection: 'open',
    contentType: 'multipart/form-data',
    requestMethod: 'GET'
}

Create mapCurry, which replicates function .map (but for an object). The first entry is the function, and the second entry is the object.

mapCurry(([k, v]) => [`${k}_force`, v])(personnel)
// output
{
  lukeSkywalker_force: { id: 5,  pilotingScore: 98, shootingScore: 56, isForceUser: true  },
  sabineWren_force:    { id: 82, pilotingScore: 73, shootingScore: 99, isForceUser: false },
  zebOrellios_force:   { id: 22, pilotingScore: 20, shootingScore: 59, isForceUser: false },
  ezraBridger_force:   { id: 15, pilotingScore: 43, shootingScore: 67, isForceUser: true  },
  calebDume_force:     { id: 11, pilotingScore: 71, shootingScore: 85, isForceUser: true  },
}

Create reduceCurry, which replicates the .reduce method (but from an object). The first entry is the function, and the second is the object and initial value).

reduceCurry((acc, [k, v]) => (acc += v))({ a: 1, b: 2, c: 3 }, 0)
// output
6

Create filterCurry which replicates the .filter method (but for an object). The first entry is the function, and the second is an object.

filterCurry(([k, v]) => typeof v === 'string' || k === 'arr')({
  str: 'string',
  nbr: 1,
  arr: [1, 2],
})
// output
{ str: 'string', arr: [1, 2] }

Using each curry function create the following functions with a parameter personnel:

  • reduceScore: that will return the total value of the scores of the people who use the force. (this function can have one additional parameter).
  • filterForce: that will return the force users with shootingScores equal to or higher than 80.
  • mapAverage: that will return a new object with the property averageScore, that is the average of the scores for each person.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

// prettier-ignore
const personnel = {
  lukeSkywalker: { id: 5,  pilotingScore: 98, shootingScore: 56, isForceUser: true  },
  sabineWren:    { id: 82, pilotingScore: 73, shootingScore: 99, isForceUser: false },
  zebOrellios:   { id: 22, pilotingScore: 20, shootingScore: 59, isForceUser: false },
  ezraBridger:   { id: 15, pilotingScore: 43, shootingScore: 67, isForceUser: true  },
  calebDume:     { id: 11, pilotingScore: 71, shootingScore: 85, isForceUser: true  },
}

Notions

  • filter
  • map
  • reduce
  • entries
  • fromentries
  • stackoverflow what-is-currying?
OBJECT

deep-copy

Deep Copy

Instructions

Create a function named deepCopy that copies objects and arrays recursively.

Notions

  • devdocs.io/javascript-object
OBJECT

replica

Replica

Instructions

Create a function named replica that allows you to deep assign the values of all properties from one or more objects to a target object.

Watch out for shallow copies.

Notions

  • data-structures
OBJECT

pronoun

Pronoun

Instructions

Create a function named pronoun that accepts a string as its parameter. This function should return an object where each key is a personal pronoun found in the string. The value of each key should be a sub-object containing:

  • a word array, which includes the first word that follows each occurrence of the pronoun (excluding other pronouns)
  • a count property, indicating how many times the pronoun appears in the string.

Note: If the word that follows a pronoun is also a pronoun, it should be ignored and not included in the word array.

Pronouns:

  • i
  • you
  • he
  • she
  • it
  • they
  • we

Example

const ex = 'Using Array Destructuring, you you can iterate through objects easily.'

{ you: { word: [ 'can' ], count: 2 } }

const ex = 'If he you want to buy something you have to pay.'

{
  he: { word: [], count: 1}
  you: { word: [ 'want', 'have' ], count: 2 }
}

OBJECT

neuron

Neuron

Instructions

Create a function named neuron, that enables your AI/bot to learn to mutate data into a more usable shape. You can see how it works from the example.

Example

neuron([
  'Questions: what is ounces? - Response: Ounce, unit of weight in the avoirdupois system',
  'Questions: what is ounces? - Response: equal to 1/16 pound (437 1/2 grains)',
  'Questions: what is Mud dauber - Response: Mud dauber is a name commonly applied to a number of wasps',
  'Orders: shutdown! - Response: Yes Sr!',
  'Orders: Quote something! - Response: Pursue what catches your heart, not what catches your eyes.'
])

// output
{
  questions: {
    what_is_ounces: { question: 'what is ounces?', responses: [
        'Ounce, unit of weight in the avoirdupois system',
        'equal to 1/16 pound (437 1/2 grains)'
    ] },
    what_is_mud_dauber: { question: 'what is Mud dauber', responses: [
        'Mud dauber is a name commonly applied to a number of wasps'
    ] }
  },
  orders: {
    shutdown: { order: 'shutdown!', responses: ['Yes Sr!'] },
    quote_something: { order: 'Quote something!', responses: [
        'Pursue what catches your heart, not what catches your eyes.'
    ] }
  }
}
OBJECT

flagger

Flagger

Instructions

Create a function named flags that receives an object and returns the specific aliases and descriptions from the properties of that object.

The help flag:

  • Must be present in the output by default.
  • When not present in the input, it should return the description of all flags.
  • When present in the input, it specifies the descriptions of the flags that are passed to help. (ex: help: ['divide'])

Example:

{
  multiply: 'multiply the values',
  divide: 'divides the values',
  help: ['divide']
}

and outputs :

{
  alias: { h: 'help', m: 'multiply', d: 'divide'}
  description: '-d, --divide: divides the values',
}
ASYNC

debounce

Debounce

Instructions

Create two functions that will work like _.debounce from lodash.

  • debounce: don't worry about the options.
  • opDebounce: implement the leading options.

Notions

  • lodash debounce
  • css-tricks.com debounce
ASYNC

throttle

Throttle

Instructions

Create two functions that will work like _.throttle from lodash.

  • throttle: don't worry about the options.
  • opThrottle: implement the trailing and leading options.

Notions

  • lodash throttle
  • css-tricks throttle
  • stackoverflow about lodash debounce
ASYNC

interpolation

Interpolation

Instructions

Create a function named interpolation that takes an object with 5 properties: step, start, end, callback and duration.

This function must interpolate points from the start position to the end position (not including the end position). The number of points depends on the number of steps.

For each interpolation point, you must call the callback function with an array of the two points [x, y]:

  • x: distance
  • y: point

There should be a delay between each callback invocation of duration / step, so that the final call happens after duration.

Example

step = 5
start = 0
end = 1
duration = 10

   t
   |
10 |_______________. <- execute callback([0.8, 10])
   |               |
   |               |
 8 |___________.   |
   |           |   |
   |           |   |
 6 |_______.   |   |
   |       |   |   |
   |       |   |   |
 4 |___.   |   |   |
   |   |   |   |   |
   |   |   |   |   |
 2 .   |   |   |   |
   |   |   |   |   |
   |___|___|___|___|___d
   0  0.2 0.4 0.6 0.8

Notions

  • setTimeout & setInterval
ASYNC

keep-trying-or-giveup

Keep Trying Or Giveup

Instructions

Create a retry function, that takes 2 arguments:

  • count: indicates maximum number of retries.
  • callback: an async function that will be invoked for every attempt.

retry returns a function that invokes the callback function. That function passes its arguments to callback, and returns the value from callback.

The function returned by retry must catch errors from callback. After that function has caught count errors, it must throw an Error.

if count is 3, callback will be invoked at most 4 times, the initial call plus 3 retries.

Create function named timeout, that takes 2 arguments:

  • delay: indicates maximum wait time.
  • callback: an asynchronous function that will be invoked.

timeout returns a function that invokes and returns the value from callback. The function must pass its arguments to callback. If callback does not resolve before delay, your function returns Error('timeout').

Notions

  • Promises
  • setTimeout
  • Promise.race
ASYNC

get-json

Get Json

Instructions

In this exercise, we will focus on building complex async flows with promises.

Create a function named getJSON with two parameters:

  • path: a URL called by your function.
  • params: optional query parameters that will be appended to the path.

getJSON must construct a valid url with the path and stringified params, and use fetch to fulfil the request.

If the response is not OK, getJSON must throw an error using the response status text.

The response body must then be read and parsed from JSON.

The parsed object contains one of those 2 properties:

  • "data": the actual data to return.
  • "error": the error message to throw.

Notions

  • Promise.js
  • Using fetch
  • URL search params
  • JSON
ASYNC

is-winner

Is Winner

Instructions

Create a function named isWinner which accepts a string representing the name of a country. It should use the winners "API" to return a resolved Promise with an appropriate string.

The strings which can be returned are listed below. You'll need to replace "Country" with the country named which is passed to isWinner:

  • "Country never was a winner": The country has never won a FIFA world cup.

  • "Country is not what we are looking for because of the continent": The country is not from the european continent.

  • "Country is not what we are looking for because of the number of times it was champion": The country won the FIFA world cup fewer than 3 times.

  • "Country won the FIFA World Cup in <years> winning by <results>": with the following format:

    • <years>: "1000, 1004, 1008"
    • <results>: "4-3, 5-2, 1-0"

Code provided

The provided code will be added to your solution, and does not need to be submitted.

const db = (() => {
  //countries that won the FIFA World Cup
  const countries = [
    { id: 1, name: 'Brazil', continent: 'South America' },
    { id: 2, name: 'Germany', continent: 'Europe' },
    { id: 3, name: 'Italy', continent: 'Europe' },
    { id: 4, name: 'Argentina', continent: 'South America' },
    { id: 5, name: 'France', continent: 'Europe' },
    { id: 6, name: 'Uruguay', continent: 'South America' },
    { id: 7, name: 'England', continent: 'Europe' },
    { id: 8, name: 'Spain', continent: 'Europe' },
  ]

  //Information about the wins
  const results = [
    { id: 1, countryId: 6, year: 1930, score: '4-2' },
    { id: 2, countryId: 3, year: 1934, score: '2-1' },
    { id: 3, countryId: 3, year: 1938, score: '4-2' },
    { id: 4, countryId: 6, year: 1950, score: '2-1' },
    { id: 5, countryId: 2, year: 1954, score: '3-2' },
    { id: 6, countryId: 1, year: 1958, score: '5-2' },
    { id: 7, countryId: 1, year: 1962, score: '3-1' },
    { id: 8, countryId: 7, year: 1966, score: '4-2' },
    { id: 9, countryId: 1, year: 1970, score: '4-1' },
    { id: 10, countryId: 2, year: 1974, score: '2-1' },
    { id: 11, countryId: 4, year: 1978, score: '3-1' },
    { id: 12, countryId: 3, year: 1982, score: '3-1' },
    { id: 13, countryId: 4, year: 1986, score: '3-2' },
    { id: 14, countryId: 2, year: 1990, score: '1-0' },
    { id: 15, countryId: 1, year: 1994, score: '3-2p' },
    { id: 16, countryId: 5, year: 1998, score: '3-0' },
    { id: 17, countryId: 1, year: 2002, score: '2-0' },
    { id: 18, countryId: 3, year: 2006, score: '5-3p' },
    { id: 19, countryId: 8, year: 2010, score: '1-0' },
    { id: 20, countryId: 2, year: 2014, score: '1-0' },
    { id: 21, countryId: 5, year: 2018, score: '4-2' },
  ]

  return {
    //returns the information of the country
    getWinner: async (countryName) => {
      const match = countries.find((country) => country.name === countryName)
      if (!match) throw Error('Country Not Found')
      return match
    },
    //returns the information of the wins of that country
    getResults: async (countryId) => {
      const match = results.filter((result) => result.countryId === countryId)
      if (!match.length) throw Error('Results Not Found')
      return match
    },
    addCountry: (country) => countries.push(country),
    addResults: (result) => results.push(result),
  }
})()
ASYNC

gougle-search

Gougle Search

Instructions

Create a function named queryServers that takes 2 arguments:

  • serverName: a string of the name of the server.
  • q: a string of the query given by the user.

You need to construct 2 urls which should work like this:

queryServers('pouet', 'hello+world')
// return the fastest of those 2 calls:
// -> getJSON('/pouet?q=hello+world')
// -> getJSON('/pouet_backup?q=hello+world')

Create a function named: gougleSearch that takes a single query argument (q). It must invoke queryServers concurrently on 3 servers:

  • "web"
  • "image"
  • "video"

You must return the value from each server in an object using the server name as key.

A timeout of 80milliseconds must be set for the whole operation, if it is not complete within 80 milliseconds, then you must return Error('timeout').

Code provided

The provided code will be added to your solution, and does not need to be submitted.

// fake `getJSON` function
let getJSON = async (url) => url

Notions

  • Promise.race
  • Promise.all
ASYNC

all

All

Instructions

Create a function named all that works like Promise.all but with objects (instead of arrays).

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Promise.all = undefined

Notions

  • Promise.js
  • Promise.all
ASYNC

series

Series

Instructions

Create a function named series that takes an array of async functions. It must execute them in series and return the results in order.

Notions

  • Promise
ASYNC

race

Race

Instructions

Create two functions:

  • race: that works like Promise.race.
  • some: that takes an array of promises or values, and count number. It should return the first count resolved values. Empty arrays or a count of 0 return a promise resolving to undefined.

Code provided

The provided code will be added to your solution, and does not need to be submitted.

Promise.race = undefined

Notions

  • Promise
  • Promise.race