Add solution directories for exercises

This commit is contained in:
thatblindgeye 2022-02-20 14:07:44 -05:00
parent 1971712fde
commit fb1a2db8d7
26 changed files with 600 additions and 0 deletions

View file

@ -0,0 +1,5 @@
const helloWorld = function () {
return 'Hello, World!';
};
module.exports = helloWorld;

View file

@ -0,0 +1,7 @@
const helloWorld = require('./helloWorld-solution');
describe('Hello World', function () {
test('says "Hello, World!"', function () {
expect(helloWorld()).toEqual('Hello, World!');
});
});

View file

@ -0,0 +1,10 @@
const repeatString = function (word, times) {
if (times < 0) return 'ERROR';
let string = '';
for (let i = 0; i < times; i++) {
string += word;
}
return string;
};
module.exports = repeatString;

View file

@ -0,0 +1,41 @@
const repeatString = require('./repeatString-solution');
describe('repeatString', () => {
test('repeats the string', () => {
expect(repeatString('hey', 3)).toEqual('heyheyhey');
});
test.skip('repeats the string many times', () => {
expect(repeatString('hey', 10)).toEqual(
'heyheyheyheyheyheyheyheyheyhey'
);
});
test.skip('repeats the string 1 times', () => {
expect(repeatString('hey', 1)).toEqual('hey');
});
test.skip('repeats the string 0 times', () => {
expect(repeatString('hey', 0)).toEqual('');
});
test.skip('returns ERROR with negative numbers', () => {
expect(repeatString('hey', -1)).toEqual('ERROR');
});
test.skip('repeats the string a random amount of times', function () {
/*The number is generated by using Math.random to get a value from between
0 to 1, when this is multiplied by 1000 and rounded down with Math.floor it
equals a number between 0 to 999 (this number will change everytime you run
the test).*/
// DO NOT use Math.floor(Math.random() * 1000) in your code,
// this test generates a random number, then passes it into your code with a function parameter.
// If this doesn't make sense, you should go read about functions here: https://www.theodinproject.com/paths/foundations/courses/foundations/lessons/fundamentals-part-3
const number = Math.floor(Math.random() * 1000);
/*The .match(/((hey))/g).length is a regex that will count the number of heys
in the result, which if your function works correctly will equal the number that
was randomaly generated. */
expect(repeatString('hey', number).match(/((hey))/g).length).toEqual(
number
);
});
test.skip('works with blank strings', () => {
expect(repeatString('', 10)).toEqual('');
});
});

View file

@ -0,0 +1,5 @@
const reverseString = function (string) {
return string.split('').reverse().join('');
};
module.exports = reverseString;

View file

@ -0,0 +1,18 @@
const reverseString = require('./reverseString-solution');
describe('reverseString', () => {
test('reverses single word', () => {
expect(reverseString('hello')).toEqual('olleh');
});
test.skip('reverses multiple words', () => {
expect(reverseString('hello there')).toEqual('ereht olleh');
});
test.skip('works with numbers and punctuation', () => {
expect(reverseString('123! abc!')).toEqual('!cba !321');
});
test.skip('works with blank strings', () => {
expect(reverseString('')).toEqual('');
});
});

View file

@ -0,0 +1,31 @@
// we have 2 solutions here, an easier one and a more advanced one.
// The easiest way to get an array of all of the arguments that are passed to a function
// is using the rest operator. If this is unfamiliar to you look it up!
const removeFromArray = function (...args) {
// the very first item in our list of arguments is the array, we pull it out with args[0]
const array = args[0];
// create a new empty array
const newArray = [];
// use forEach to go through the array
array.forEach((item) => {
// push every element into the new array
// UNLESS it is included in the function arguments
// so we create a new array with every item, except those that should be removed
if (!args.includes(item)) {
newArray.push(item);
}
});
// and return that array
return newArray;
};
// A simpler, but more advanced way to do it is to use the 'filter' function,
// which basically does what we did with the forEach above.
// var removeFromArray = function(...args) {
// const array = args[0]
// return array.filter(val => !args.includes(val))
// }
//
module.exports = removeFromArray;

View file

@ -0,0 +1,28 @@
const removeFromArray = require('./removeFromArray-solution');
describe('removeFromArray', () => {
test('removes a single value', () => {
expect(removeFromArray([1, 2, 3, 4], 3)).toEqual([1, 2, 4]);
});
test.skip('removes multiple values', () => {
expect(removeFromArray([1, 2, 3, 4], 3, 2)).toEqual([1, 4]);
});
test.skip('ignores non present values', () => {
expect(removeFromArray([1, 2, 3, 4], 7, 'tacos')).toEqual([1, 2, 3, 4]);
});
test.skip('ignores non present values, but still works', () => {
expect(removeFromArray([1, 2, 3, 4], 7, 2)).toEqual([1, 3, 4]);
});
test.skip('can remove all values', () => {
expect(removeFromArray([1, 2, 3, 4], 1, 2, 3, 4)).toEqual([]);
});
test.skip('works with strings', () => {
expect(removeFromArray(['hey', 2, 3, 'ho'], 'hey', 3)).toEqual([
2,
'ho',
]);
});
test.skip('only removes same type', () => {
expect(removeFromArray([1, 2, 3], '1', 3)).toEqual([1, 2]);
});
});

View file

@ -0,0 +1,16 @@
const sumAll = function (min, max) {
if (!Number.isInteger(min) || !Number.isInteger(max)) return 'ERROR';
if (min < 0 || max < 0) return 'ERROR';
if (min > max) {
const temp = min;
min = max;
max = temp;
}
let sum = 0;
for (let i = min; i < max + 1; i++) {
sum += i;
}
return sum;
};
module.exports = sumAll;

View file

@ -0,0 +1,22 @@
const sumAll = require('./sumAll-solution');
describe('sumAll', () => {
test('sums numbers within the range', () => {
expect(sumAll(1, 4)).toEqual(10);
});
test.skip('works with large numbers', () => {
expect(sumAll(1, 4000)).toEqual(8002000);
});
test.skip('works with larger number first', () => {
expect(sumAll(123, 1)).toEqual(7626);
});
test.skip('returns ERROR with negative numbers', () => {
expect(sumAll(-10, 4)).toEqual('ERROR');
});
test.skip('returns ERROR with non-number parameters', () => {
expect(sumAll(10, '90')).toEqual('ERROR');
});
test.skip('returns ERROR with non-number parameters', () => {
expect(sumAll(10, [90, 1])).toEqual('ERROR');
});
});

View file

@ -0,0 +1,5 @@
const leapYears = function (year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
};
module.exports = leapYears;

View file

@ -0,0 +1,22 @@
const leapYears = require('./leapYears-solution');
describe('leapYears', () => {
test('works with non century years', () => {
expect(leapYears(1996)).toBe(true);
});
test.skip('works with non century years', () => {
expect(leapYears(1997)).toBe(false);
});
test.skip('works with ridiculously futuristic non century years', () => {
expect(leapYears(34992)).toBe(true);
});
test.skip('works with century years', () => {
expect(leapYears(1900)).toBe(false);
});
test.skip('works with century years', () => {
expect(leapYears(1600)).toBe(true);
});
test.skip('works with century years', () => {
expect(leapYears(700)).toBe(false);
});
});

View file

@ -0,0 +1,12 @@
const ftoc = function (f) {
return Math.round((f - 32) * (5 / 9) * 10) / 10;
};
const ctof = function (c) {
return Math.round(((c * 9) / 5 + 32) * 10) / 10;
};
module.exports = {
ftoc,
ctof,
};

View file

@ -0,0 +1,25 @@
const { ftoc, ctof } = require('./tempConversion-solution');
describe('ftoc', () => {
test('works', () => {
expect(ftoc(32)).toEqual(0);
});
test.skip('rounds to 1 decimal', () => {
expect(ftoc(100)).toEqual(37.8);
});
test.skip('works with negatives', () => {
expect(ftoc(-100)).toEqual(-73.3);
});
});
describe('ctof', () => {
test.skip('works', () => {
expect(ctof(0)).toEqual(32);
});
test.skip('rounds to 1 decimal', () => {
expect(ctof(73.2)).toEqual(163.8);
});
test.skip('works with negatives', () => {
expect(ctof(-10)).toEqual(14);
});
});

View file

@ -0,0 +1,48 @@
const add = function (a, b) {
return a + b;
};
const subtract = function (a, b) {
return a - b;
};
const sum = function (array) {
return array.reduce((total, current) => total + current, 0);
};
const multiply = function (array) {
return array.length
? array.reduce((accumulator, nextItem) => accumulator * nextItem)
: 0;
};
const power = function (a, b) {
return Math.pow(a, b);
};
const factorial = function (n) {
if (n === 0) return 1;
let product = 1;
for (let i = n; i > 0; i--) {
product *= i;
}
return product;
};
// This is another implementation of Factorial that uses recursion
// THANKS to @ThirtyThreeB!
const recursiveFactorial = function (n) {
if (n === 0) {
return 1;
}
return n * recursiveFactorial(n - 1);
};
module.exports = {
add,
subtract,
sum,
multiply,
power,
factorial,
};

View file

@ -0,0 +1,77 @@
const calculator = require('./calculator-solution');
describe('add', () => {
test('adds 0 and 0', () => {
expect(calculator.add(0, 0)).toBe(0);
});
test.skip('adds 2 and 2', () => {
expect(calculator.add(2, 2)).toBe(4);
});
test.skip('adds positive numbers', () => {
expect(calculator.add(2, 6)).toBe(8);
});
});
describe('subtract', () => {
test.skip('subtracts numbers', () => {
expect(calculator.subtract(10, 4)).toBe(6);
});
});
describe('sum', () => {
test.skip('computes the sum of an empty array', () => {
expect(calculator.sum([])).toBe(0);
});
test.skip('computes the sum of an array of one number', () => {
expect(calculator.sum([7])).toBe(7);
});
test.skip('computes the sum of an array of two numbers', () => {
expect(calculator.sum([7, 11])).toBe(18);
});
test.skip('computes the sum of an array of many numbers', () => {
expect(calculator.sum([1, 3, 5, 7, 9])).toBe(25);
});
});
describe('multiply', () => {
test.skip('multiplies two numbers', () => {
expect(calculator.multiply([2, 4])).toBe(8);
});
test.skip('multiplies several numbers', () => {
expect(calculator.multiply([2, 4, 6, 8, 10, 12, 14])).toBe(645120);
});
});
describe('power', () => {
test.skip('raises one number to the power of another number', () => {
expect(calculator.power(4, 3)).toBe(64); // 4 to third power is 64
});
});
describe('factorial', () => {
test.skip('computes the factorial of 0', () => {
expect(calculator.factorial(0)).toBe(1); // 0! = 1
});
test.skip('computes the factorial of 1', () => {
expect(calculator.factorial(1)).toBe(1);
});
test.skip('computes the factorial of 2', () => {
expect(calculator.factorial(2)).toBe(2);
});
test.skip('computes the factorial of 5', () => {
expect(calculator.factorial(5)).toBe(120);
});
test.skip('computes the factorial of 10', () => {
expect(calculator.factorial(10)).toBe(3628800);
});
});

View file

@ -0,0 +1,6 @@
const palindromes = function (string) {
processedString = string.toLowerCase().replace(/[^a-z]/g, '');
return processedString.split('').reverse().join('') == processedString;
};
module.exports = palindromes;

View file

@ -0,0 +1,24 @@
const palindromes = require('./palindromes-solution');
describe('palindromes', () => {
test('works with single words', () => {
expect(palindromes('racecar')).toBe(true);
});
test.skip('works with punctuation ', () => {
expect(palindromes('racecar!')).toBe(true);
});
test.skip('works with upper-case letters ', () => {
expect(palindromes('Racecar!')).toBe(true);
});
test.skip('works with multiple words', () => {
expect(palindromes('A car, a man, a maraca.')).toBe(true);
});
test.skip('works with multiple words', () => {
expect(
palindromes('Animal loots foliated detail of stool lamina.')
).toBe(true);
});
test.skip("doesn't just always return true", () => {
expect(palindromes('ZZZZ car, a man, a maraca.')).toBe(false);
});
});

View file

@ -0,0 +1,14 @@
const fibonacci = function (count) {
if (count < 0) return 'OOPS';
if (count === 0) return 0;
let a = 0;
let b = 1;
for (let i = 1; i < count; i++) {
const temp = b;
b = a + b;
a = temp;
}
return b;
};
module.exports = fibonacci;

View file

@ -0,0 +1,31 @@
const fibonacci = require('./fibonacci-solution');
describe('fibonacci', () => {
test('4th fibonacci number is 3', () => {
expect(fibonacci(4)).toBe(3);
});
test.skip('6th fibonacci number is 8', () => {
expect(fibonacci(6)).toBe(8);
});
test.skip('10th fibonacci number is 55', () => {
expect(fibonacci(10)).toBe(55);
});
test.skip('15th fibonacci number is 610', () => {
expect(fibonacci(15)).toBe(610);
});
test.skip('25th fibonacci number is 75025', () => {
expect(fibonacci(25)).toBe(75025);
});
test.skip("doesn't accept negatives", () => {
expect(fibonacci(-25)).toBe('OOPS');
});
test.skip('DOES accept strings', () => {
expect(fibonacci('1')).toBe(1);
});
test.skip('DOES accept strings', () => {
expect(fibonacci('2')).toBe(1);
});
test.skip('DOES accept strings', () => {
expect(fibonacci('8')).toBe(21);
});
});

View file

@ -0,0 +1,5 @@
const getTheTitles = function (array) {
return array.map((book) => book.title);
};
module.exports = getTheTitles;

View file

@ -0,0 +1,18 @@
const getTheTitles = require('./getTheTitles-solution');
describe('getTheTitles', () => {
const books = [
{
title: 'Book',
author: 'Name',
},
{
title: 'Book2',
author: 'Name2',
},
];
test('gets titles', () => {
expect(getTheTitles(books)).toEqual(['Book', 'Book2']);
});
});

View file

@ -0,0 +1,19 @@
const findTheOldest = function (array) {
return array.reduce((oldest, currentPerson) => {
const oldestAge = getAge(oldest.yearOfBirth, oldest.yearOfDeath);
const currentAge = getAge(
currentPerson.yearOfBirth,
currentPerson.yearOfDeath
);
return oldestAge < currentAge ? currentPerson : oldest;
});
};
const getAge = function (birth, death) {
if (!death) {
death = new Date().getFullYear();
}
return death - birth;
};
module.exports = findTheOldest;

View file

@ -0,0 +1,62 @@
const findTheOldest = require('./findTheOldest-solution');
describe('findTheOldest', () => {
test('finds the oldest person!', () => {
const people = [
{
name: 'Carly',
yearOfBirth: 1942,
yearOfDeath: 1970,
},
{
name: 'Ray',
yearOfBirth: 1962,
yearOfDeath: 2011,
},
{
name: 'Jane',
yearOfBirth: 1912,
yearOfDeath: 1941,
},
];
expect(findTheOldest(people).name).toBe('Ray');
});
test.skip('finds the oldest person if someone is still living', () => {
const people = [
{
name: 'Carly',
yearOfBirth: 2018,
},
{
name: 'Ray',
yearOfBirth: 1962,
yearOfDeath: 2011,
},
{
name: 'Jane',
yearOfBirth: 1912,
yearOfDeath: 1941,
},
];
expect(findTheOldest(people).name).toBe('Ray');
});
test.skip('finds the oldest person if the OLDEST is still living', () => {
const people = [
{
name: 'Carly',
yearOfBirth: 1066,
},
{
name: 'Ray',
yearOfBirth: 1962,
yearOfDeath: 2011,
},
{
name: 'Jane',
yearOfBirth: 1912,
yearOfDeath: 1941,
},
];
expect(findTheOldest(people).name).toBe('Carly');
});
});

View file

@ -0,0 +1,26 @@
const caesar = function (string, shift) {
return string
.split('')
.map((char) => shiftChar(char, shift))
.join('');
};
const codeSet = (code) => (code < 97 ? 65 : 97);
// this function is just a fancy way of doing % so that it works with negative numbers
// see this link for details:
// https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
const mod = (n, m) => ((n % m) + m) % m;
const shiftChar = (char, shift) => {
const code = char.charCodeAt();
if ((code >= 65 && code <= 90) || (code >= 97 && code <= 122)) {
return String.fromCharCode(
mod(code + shift - codeSet(code), 26) + codeSet(code)
);
}
return char;
};
module.exports = caesar;

View file

@ -0,0 +1,23 @@
const caesar = require('./caesar-solution');
test('works with single letters', () => {
expect(caesar('A', 1)).toBe('B');
});
test.skip('works with words', () => {
expect(caesar('Aaa', 1)).toBe('Bbb');
});
test.skip('works with phrases', () => {
expect(caesar('Hello, World!', 5)).toBe('Mjqqt, Btwqi!');
});
test.skip('works with negative shift', () => {
expect(caesar('Mjqqt, Btwqi!', -5)).toBe('Hello, World!');
});
test.skip('wraps', () => {
expect(caesar('Z', 1)).toBe('A');
});
test.skip('works with large shift factors', () => {
expect(caesar('Hello, World!', 75)).toBe('Ebiil, Tloia!');
});
test.skip('works with large negative shift factors', () => {
expect(caesar('Hello, World!', -29)).toBe('Ebiil, Tloia!');
});