In this TDD set, you'll learn some problem solving strategies that you'll be using for the rest of your programming career!
- Clone this repo.
- Navigate your terminal to your local repo folder.
- In your terminal, run
npm install
. - In your terminal, run
npm test
. - Notice that only the first test will run. This is due to the
describe.only
inscript.test.js
. When you are ready to move on the the next problem, remove.only
from the current test and change the next test todescribe.only
. - Edit
script.js
until you are passing all test cases! - Press
Control+C
orq
in your terminal to close the Jest process once you are done testing.
The rest of these instructions is categorized into some common strategies used not only to tackle TDD problems, but also to write code in general! While this list is certainly not exhaustive, you'll find that these techniques are used again and again no matter where you go.
An example solution is provided in script.js
for the first prompt of each strategy. Use that code as a reference as you complete the rest of the prompts!
Do them in order!
A guard is a conditional usually placed at the beginning of a function that prevents the rest of the function from being run if certain conditions are not met. These are used often to help avoid errors. A function can have more than one guard.
multiplyNumbers(a: any, b: any)
returns the product of a
and b
unless either of the parameters is not a number, in which case the string "error"
is returned.
multiplyNumbers(3, 6); // >>> 18
multiplyNumbers("not a number", 6); // >>> "error"
vote(age: number)
returns "Who would you like to vote for?"
if the given age
is at least 18; otherwise it returns "You must be 18 or older to vote."
vote(49); // >>> "Who would you like to vote for?"
vote(12); // >>> "You must be 18 or older to vote."
concatenateStrings(a: any, b: any)
returns the two given strings concatenated together unless either a
or b
is not a string, in which case the string "error"
is returned.
concatenateStrings("hello", "world"); // >>> "helloworld"
concatenateStrings("hello", 15); // >>> "error"
An accumulator variable is used to keep track of information as a program executes, usually in the context of a loop.
sumArray(number[])
returns the sum of the given array. The sum of an empty array is 0. You can assume that only arrays of numbers will be passed in.
sumArray([]); // >>> 0
sumArray([1]); // >>> 1
sumArray([1, 1]); // >>> 2
sumArray([10, 9, 28, 173, -23]); // >>> 197
sumToN(n: number)
returns the sum of all integers from 1 to n
. If n
is 0 or negative, then 0
is returned. You can assume that n
is an integer.
Use a loop!
sumToN(-2); // >>> 0
sumToN(8); // >>> 36
sumToN(23); // >>> 276
factorial(n: number)
returns the product of all integers from 1 to n
. If n
is 0, then 1
is returned. If n
is negative or not an integer, then the string "error"
is returned.
factorial(-1919): // >>> "error"
factorial("10"); // >>> "error"
factorial(8); // >>> 40320
The accumulator doesn't have to be a number! You can build arrays or strings as well.
buildNArray(n: number)
returns an array of all integers from 1 to n
. If n
is 0 or negative, then an empty array is returned. If n
is not an integer, then the string "error"
is returned.
buildNArray(-555); // >>> []
buildNArray(2.38); // >>> "error"
buildNArray(3); // [1, 2, 3]
We've seen conditional statements used as guard clauses, but they can also go inside a loop! We don't always want to update an accumulator variable.
findMax(number[])
returns the greatest number in a given array of numbers. If the array is empty, then -Infinity
is returned.
findMax([]); // >>> -Infinity
findMax([-10, 234, 568, 29, 7]); // >>> 568
findMax([3, 3, 3]); // >>> 3
findLongestString(string[])
returns the longest string in a given array of strings. If the array is empty, then an empty string is returned.
findLongestString([]); // >>> ""
findLongestString(["a", "bc", "def", "gh"]); // >>> "def"
countPresent(attendance: boolean[])
receives an array of booleans that represent whether or not students in a class are present (true
= present), and returns the number of students that are present.
countPresent([]); // >>> 0
countPresent([true, true, false, false, true]); // >>> 3
In DNA strings, the symbols A
and T
are complements of each other, and C
and G
are complements. getDnaComplement(dna: string)
receives one side of the DNA strand and returns the complementary string.
getDnaComplement(""); // >>> ""
getDnaComplement("ATAT"); // >>> "TATA"
getDnaComplement("GTCA"); // >>> "CAGT";
Almost all of the functions we've seen so far return something at the very end. Sometimes we get the answer we want before we finish iterating. For these next problems, think about what to return and when to return!
isSongInPlaylist(song: string, playlist: string[])
returns whether the given song can be found in the given playlist. You can assume that the song will be nonempty.
isSongInPlaylist("Chasing Pavements", [
"Just Smile",
"Burn Options",
"Chasing Pavements",
"Industrial Now",
]); // >>> true
isSongInPlaylist("24K Power", [
"Stubborn Love",
"Electric Heart",
"All I Want",
]); // >>> false
isAllEven(number[])
returns whether or not the given array of integers is all even. You can assume that the array will be nonempty.
isAllEven([2, 4, 6, 8, 10]); // >>> true
isAllEven([2, 4, 9, 6, 8]); // >>> false
You can loop inside a loop, and you can have arrays of arrays! This is actually super common, so make sure you understand the solution code for the following prompt.
makeBoard
takes two arguments:
cols
: number - how many columns the board will haverows
: number - how many rows the board will have
makeBoard
will return a 2D array filled with "-"
according to the given dimensions.
makeBoard(3, 4);
/* >>>
[
["-", "-", "-"],
["-", "-", "-"],
["-", "-", "-"],
["-", "-", "-"]
]
*/
evenAndOdd(number[])
takes an array of numbers and returns a new array that contains two smaller arrays. The first element in the returned array should be an array with all of the even numbers from the original array. The second element in the returned array should be an array with all of the odd numbers from the original array.
evenAndOdd([1, 2, 3, 4, 5, 6]); // >>> [[ 2, 4, 6 ], [ 1, 3, 5 ]]
evenAndOdd([10, 8, 6, 4, 2]); // >>> [[10, 8, 6, 4, 2], []]
Use a combination of the techniques you've learned to solve the following practice problems!
exponentiate(b: integer, p: integer)
returns b
raised to the p
th power. Do not use the exponent operator (**
).
exponentiate(2, 3); // >>> 8
onlyOdds(number)
returns the sum of all odd numbers between 1 and the given number.
If it receives an argument less than 1, it should return 0.
onlyOdds(11); // >>> 36
bacteriaTime(current: number, target: number)
returns the number of minutes required for the number of bacteria to grow from current
to a number >= target
. The number of bacteria doubles every 20 minutes, and you can assume that current
will be a positive integer. If target
is smaller than current
, return the string "target must be larger than current"
.
bacteriaTime(10, 120); // >>> 80
getAverage(number[])
returns the average (mean) of all the numbers in the given array. If the array is empty, then null
should be returned.
getAverage([]); // >>> null
getAverage([10, 23, 18, -5, 28, 10]); // >>> 14
countCoins(coins: string[])
takes an array of strings that represent coins. Return the total value in cents of the array.
- P = 1 cent, N = 5 cents, D = 10 cents, Q = 25 cents
countCoins(["Q", "Q", "D", "N", "N", "P", "Q"]); // >>> 96
getPairs(number)
returns an array of all possible pairs of integers between 1 and the given number. If the given number is not a positive integer, then the string "error"
is returned.
getPairs("pair"); // >>> "error"
getPairs(4); // >>> [[ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 2 ], [ 2, 3 ], [ 2, 4 ], [ 3, 3 ], [ 3, 4 ], [ 4, 4 ]]