Skip to content

Instantly share code, notes, and snippets.

@alexhawkins
Last active September 28, 2023 12:25
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save alexhawkins/f275513a88119423c958 to your computer and use it in GitHub Desktop.
Save alexhawkins/f275513a88119423c958 to your computer and use it in GitHub Desktop.
Solutions for Eloquent Javascript Chapter 3, 4 Exercises (Functions, Arrays, Objects)
'use strict';
/****************************************
* Chapter 3 Exercises: Functions
*****************************************
#EXERCISE 1: Minimum
The previous chapter introduced the standard function Math.min that returns
its smallest argument. We can do that ourselves now. Write a function min that
takes two arguments and returns their minimum.
*/
var min = function(x, y) {
return (x <= y) ? x : y;
};
//tests
console.log(min(0, 10));
// → 0
console.log(min(0, -10));
// → -10
console.log(min(4, 4));
// → 4
/*
#EXCERCISE 2: Recursion
We’ve seen that % (the remainder operator) can be used to test whether a number
is even or odd by using % 2 to check whether it’s divisible by two. Here’s another
way to define whether a positive whole number is even or odd:
Zero is even.
One is odd.
For any other number N, its evenness is the same as N - 2.
Define a recursive function isEven corresponding to this description. The function
should accept a number parameter and return a Boolean.
Test it on 50 and 75. See how it behaves on -1. Why? Can you think of a way to fix this?*/
var isEven = function(num) {
num = Math.abs(num); //convert to absolute value to account for negative numbers
if (num === 0)
return true;
else if (num === 1)
return false;
else
return isEven(num - 2);
};
//tests
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → false
console.log(isEven(-10002));
// → true
/*
#EXERCISE 3: Bean Counting
You can get the Nth character, or letter, from a string by writing "string".charAt(N),
similar to how you get its length with "s".length. The returned value will be a string
containing only one character (for example, "b"). The first character has position zero,
which causes the last one to be found at position string.length - 1. In other words, a
two-character string has length 2, and its characters have positions 0 and 1.
Write a function countBs that takes a string as its only argument and returns a number
that indicates how many uppercase “B” characters are in the string.
Next, write a function called countChar that behaves like countBs, except it takes a
second argument that indicates the character that is to be counted (rather than counting
only uppercase "B" characters). Rewrite countBs to make use of this new function. */
var countBs = function(str) {
return str.match(/B/g).length;
};
var countChar = function(str, character) {
var matchExp = new RegExp(character, 'g');
return str.match(matchExp).length;
};
//the old fashioned way
var countChar2 = function(str, character) {
var count = 0;
for (var i = 0; i < str.length; i++) {
if (str[i] === character)
count++;
}
return count;
};
//tests
console.log(countBs('BBC'));
// → 2
console.log(countChar('kakkerlak', 'k'));
// → 4
console.log(countChar2('kakkekekkkkkkkekrlak', 'k'));
/****************************************
* Chapter 4 Exercises: Arrays and Objects
*****************************************
#EXERCISE 1: The sum of a range
The introduction of this book alluded to the following as a nice way to compute
the sum of a range of numbers: console.log(sum(range(1, 10)));
Write a range function that takes two arguments, start and end, and returns
an array containing all the numbers from start up to (and including) end.
Next, write a sum function that takes an array of numbers and returns the sum of
hese numbers. Run the previous program and see whether it does indeed return 55.
As a bonus assignment, modify your range function to take an optional third argument
that indicates the “step” value used to build up the array. If no step is given, the
array elements go up by increments of one, corresponding to the old behavior. The
function call range(1, 10, 2) should return [1, 3, 5, 7, 9]. Make sure it also
works with negative step values so that range(5, 2, -1) produces [5, 4, 3, 2].*/
var range = function(start, end, step) {
var arr = [];
for (var i = start; step > 1 || step === undefined ? i <= end : i >= end; step ? i = i + step : i++)
arr.push(i);
return arr;
};
var sum = function(arr) {
return arr.reduce(function(x, y) {
return x + y;
});
};
//tests
console.log(sum(range(1, 10)));
// → 55
console.log(range(1, 10));
// → [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(range(5, 2, -1));
// → [5, 4, 3, 2]
console.log(range(1, 10, 2));
// → [ 1, 3, 5, 7, 9 ]
/*EXERCISE 2: Reversing an Array
Arrays have a method reverse, which changes the array by inverting the order in
which its elements appear. For this exercise, write two functions, reverseArray
and reverseArrayInPlace. The first, reverseArray, takes an array as argument and
produces a new array that has the same elements in the inverse order. The second,
reverseArrayInPlace, does what the reverse method does: it modifies the array
given as argument in order to reverse its elements.
Thinking back to the notes about side effects and pure functions in the previous
chapter, which variant do you expect to be useful in more situations? Which one
is more efficient?*/
//using push
var reverseArray = function(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--)
newArr.push(arr[i]);
return newArr;
};
//swapping values
var reverseArrayInPlace = function(arr) {
var temp = 0;
for (var i = 0; i < arr.length / 2; i++) {
temp = arr[i];
arr[i] = arr[arr.length - i - 1];
arr[arr.length - i - 1] = temp;
}
};
//tests
console.log(reverseArray(['A', 'B', 'C']));
// → ["C", "B", "A"];
var arrayValue = [1, 2, 3, 4, 5, 6, 7, 8, 9];
reverseArrayInPlace(arrayValue);
console.log(arrayValue);
// → [ 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
@LucasRizzotto
Copy link

Hey man, the Chap 4 Ex #1 is incorrect. It doesn't work with the examples given in EloquentJS and it's supposed to. Negative steps don't work, and if the start number is bigger than the end number, the range also is not given.

I made one here (https://github.com/SexualPotatoes/Eloquent-JavaScript/blob/master/SumOfARange.js). The code is much longer than yours, probably not as well written, but works in all instances!

@LucasRizzotto
Copy link

Some other answers seem to be wrong as well. You got most of the logic down, but not all, the programs do not work as they should 100% !

@nlapier
Copy link

nlapier commented Feb 11, 2016

Hi All,

I used a different approach for reverseArrayInPlace, but it seems to work: https://gist.github.com/nlapier/eb394fe78ed28a25b1ed#file-gistfile1-txt

Let me know what you think!

@Eazybright
Copy link

nice work.......
this helped me alot

@AdelinaLipsa
Copy link

you are kind of cheating with Math.abs, the solution is fairly simple

@sleeptighthill
Copy link

var min = function(x, y) {
if (x <= y) return x;
else return y;
}

That is the simplest way I could write the Math.min function.

@sammiearchie77
Copy link

lol I just love developers haha Thank you so much for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment