FAQ: Code Challenges: Intermediate JavaScript - squareNums()

Hey cirufly,

Thanks for your message. Are you on a career path?

Feels like we might be at similar levels on Javascript. If you want to connect on Discord give me a shout. I’ve only just worked out how to use it, but it’s quite good for getting a bit of community going.

If not, no problem and all the best with your coding!!

1 Like

Hey, I’m on full-Stack path, currently 14% and about to start the Mixed messages project. It would be really nice to share and learn with someone else.
Discord: Ciru#2203
Feel free to text me if you want.

I’m so confused… This is what I wrote and it wasn’t working:

const numbers = [2, 7, 9, 171, 52, 33, 14]
const toSquare = num => num * num

const squareNums = (arr) => { 
  arr.map(toSquare);
};

console.log(squareNums(numbers));
//prints undefined

This is the solution the exercise help gave me. Spoiler alert here! :warning:

const squareNums = arr => 
  arr.map(toSquare);

The only difference is the brackets… can anyone explain to me when should I use this sytax instead of mine here? I used the same syntax for the declineEverything exercise and it worked out fine, but here it should be written without the parethesis (arr) and brackets {} :confounded:

The return, undefined is a result of the squareNums function not having a return. Insert a ‘return’ at the front of the line,

return arr.map(...)

or alternatively, write the function the same way you did toSquare so it returns implicitly.

1 Like

interesting! thanks a lot!
This javaScript course has gotten confusing and extremely hard!

1 Like

It only gets harder if we try to learn too much in one session. Make it a habit to go back over every unit and redo exercises, review the learning narrative, read up on the topic (MDN is top notch) and play with the concepts in a sandbox such as REPL.it. Stick to the basics until you can do it in your sleep so you get the feeling of success and get your mind used to solving problems. Be sure you are 100% on early concepts before pressing too far forward. This is not a race. Build a strong foundation from the start. It takes time, review and practice to gain confidence.

Jargon and technical terms tend to come out of every corner which only adds to the confusion. Keep the documentation readily at hand and read it multiple times. Eventually this will be walk in the park, but only if you put in the work and time.

2 Likes

Thanks for the tip! I was thinking about that, that it would be a good idea to work on hundreds of exercises before moving on. The MDN documentation sometimes is confusing to me, I know is a great resource but I often have to google things out :stuck_out_tongue:
I was never good at math mostly because of my lack of will! (as one teacher once put it :rofl:)

1 Like

what is this REPL thing? I googled it but I read something about Python and not javaScript

www. repl.it

Register (it’s free) and then ‘Start new REPL’, choosing ‘JavaScript’ as the language. This will open up a blank sandbox with an editor and a console. Write your code in the editor then Run it. The editor autosaves so your work will never be lost.

The name of the site is a play on the acronym. REPL is a common term that describes how computers actually work. They are always waiting for a next instruction.

Read -> Evaluate -> Print -> Loop

This will appear in many introductory computer courses.

Try out this:
const squareNums = numbers => numbers.map(toSquare);

Sometimes simplicity is the key

What I found confusing is that you can use various syntax methods with arr.map. Noting the comments above, here is my solution using various approaches to calling arr.map using functional expressions (see 1a and 1b approach) and functional declaration.

// squareNums() using .map
// This example shows three different .map approaches
const numbers = [2, 7, 9, 171, 52, 33, 14];

// functional expression to square numbers
const toSquare = num => num * num;

// 1a. Using functional expression approach
const squareNums = arrNum => arrNum.map(toSquare);

/* if you include curly brackets {}after the arrow, you need to explicitly write return to return anything from the function. If the only statement in your function is a return statement, then you can remove both the return and brackets as shown in 1a. above. */

// 1b. Using a functional expresson with brackets {}
// Notice you have to return toSquare(e) with each element
const squareNums1b = (arrNum) => arrNum.map(e => {return toSquare(e)});

// 2. Using a fuction declaration approach
function squareNumF(arrNum) {
return arrNum.map(toSquare);
} // end function

// 3. Using an anonymous function approach
// e = element of array
const cubeNums = arrNum => arrNum.map(e => e * e * e);

let sqNum = squareNums(numbers);
console.log(numbers); // [ 2, 7, 9, 171, 52, 33, 14 ]
console.log(sqNum); // [ 4, 49, 81, 29241, 2704, 1089, 196 ]

let sqNum1b = squareNums1b(numbers);
console.log(sqNum1b); // [ 4, 49, 81, 29241, 2704, 1089, 196 ]

let sqNumF = squareNumF(numbers);
console.log(sqNumF); // [ 4, 49, 81, 29241, 2704, 1089, 196 ]

let cubedArr = cubeNums(numbers);
console.log(cubedArr);
// [ 8, 343, 729, 5000211, 140608, 35937, 2744 ]

The same could said of any higher order function such as iterator methods. The simplest view, while abstract, is the simplest form:

Array.map(callback)

That description shows everything we need to map an array. We can drop in any valid function to act as the callback, or we can write a function of that name.

const callback = x => x ** 2;
const numbers = [2, 7, 9, 171, 52, 33, 14];
console.log(numbers.map(callback))
[ 4, 49, 81, 29241, 2704, 1089, 196 ]

It doesn’t make a lot of sense having a utility function like the above callback in global scope unless there is every likelihood it will be called from somewhere else in the program. It fits better in function scenario, as one of your examples demonstrates.

const mapSquares = arr => {
  const f = x => x ** 2;
  return arr.map(f);
}
const numbers = [2, 7, 9, 171, 52, 33, 14];
console.log(mapSquares(numbers))
[ 4, 49, 81, 29241, 2704, 1089, 196 ]

Off topic

Interesting numbers, 33 and 14. So happens our local recycling depot prefers bags with exactly 200 cans in them. After draining and removing the tab, I store them in a tray that holds 28 cans. Those then get dumped in the bag and a stroke gets added to what will eventually be a house with a stroke through it, for 7 strokes. 7 times 28 is 14 squared. Throw in four more cans, add 4 ticks and we have 200.

Back in the school days I used to bet for a jug if I could guess the outcome of their computation. Without boring you on the details, the correct solution if they followed instructions was always 1089.


This is a completely different programming language, on purpose. Watch the steps, and don’t worry about the code.

>>> def fn(x):
	if len(str(x)) != 3: raise ValueError
	y = int(str(x)[::-1])           #  reverse digits
	z = abs(y - x)                  #  absolute difference
	return int(str(z)[::-1]) + z    #  sum with reverse digits

>>>
>>> for x in range(100, 1000):
	a, b, c = list(str(x))          # capture the digits
	if abs(int(c) - int(a)) < 2: continue
	print(f'{fn(x)}', end=',')      # only valid outcomes

	
1089,1089,1089, #  ..., 640 times
>>> 

As we said, if instructions are followed. We have 90 possible 0 outcomes where the first digit matches the last, and 170 of 198 if they differ by only 1. That accounts for the missing 260. Figured out this puzzle, yet?

Hint: You really need to do this one on paper to appreciate it.

Thanks mtf!

Regarding the 3-digit 1089 outcome problem. Code looks like Python.
Here is my thoughts:

  1. When the 1st = 3rd digit, then reversed – original = 0 (e.g., 343 – 343 = 0)

  2. When the 1st – 3rd digit = abs(1), then reversed – original = 99, only a two-digit number (e.g., 433 – 334 = 99; 99 + 99 = 198); hence, code has to add a zero as the third digit, so 3-digit numbers are used in subtraction 990 – 099 = 891, then 891 + 198 = 1089. I don’t see in your code instruction where a zero is added as the 1st or 3rd digit (e.g., a = 0, c = 0) when a – c = abs(1).

  3. When the 1st – 3rd digit = abs(2), then reversed – original is always a 3-digit difference (e.g., 543 – 345 = 198; 891 – 198 = 693; 693 + 396 = 1089)

  4. Same holds true for all 3-digit numbers where the 1st – 3rd > abs(2)
    (e.g. 642 – 246 = 396; 693 – 396 = 297; 792 – 297 = 1089)

Best Regards, Bear . . .

1 Like

Very good work. The algorithm itself has three possible outcomes; the puzzle, with constraints always has one.

Good spot on the language. And you let the code tell you what it was doing. You were able to infer the role of scalar distance. Two things can be n meters apart regardless of direction.

Aside

Did you work this out on paper, with the constraints?

  • 3 digits
  • distance greater than unity for first and last digit
  • subtraction before addition

Dumb question. I meant did you actually do this on paper? It’s a bar gag. Napkins are the general norm.

Think of a three digit number.
Got it? Okay, write it down on the napkin but don’t let me see it.
It’s for sure a three digit number?
Are first and last digits more than one unit apart?
Reverse the number.
Subtract the smaller from the other.
Add the reverse of the outcome to the outcome.

I stress paper because that is where our creativity can test our wherewithal, or brilliance, so to speak. It’s an old puzzle, so it’s no surprise paper and pencil was involved. Computer algos like above just make it boring. Go out and have some fun! (But, wear your mask.)

Yes, I first wrote out instructions of your code, then I worked through a few examples on paper to understand the 0 and 198 result. Then I ran the entire data set (100 … 999) using MS-Excel so I could see the pattern of results. I found it interesting that there are 90, 0 results, 170, 198 results, and 640, 1089 results. At first I thought there should be 180 (90 * 2) 198 results; however, I could see the pattern of 198 results occurs only half as much from 900 … 999 (e.g., 180 - 10 = 170).
Thanks! Enjoy your July 4th holiday. Best Regards, Bear . . .

1 Like

Since you are learning JS, then we might as well explore this within that language context.

const fn = x => {
  if (x < 100 || x > 999) throw Error ('Value Error')
  const y = parseInt([...x.toString(10)].reverse().join(''), 10)
  const z = Math.abs(y - x)
  return parseInt([...z.toString(10)].reverse().join(''), 10) + z
}

for (let x = 100; x < 1000; x++) {
  const [a, b, c] = [...x.toString(10)]
  if (Math.abs(parseInt(c, 10) - parseInt(a, 10)) < 2) continue
  console.log(`${a}${b}${c}, ${fn(x)}`)
}

It is not a direct port from the Python, and may use some techniques and constructs you are not familiar with. TBH, the Python was easier for you to disseminate. This is not far off, though in achieving the same goal.

Notes:

  • We use x.toString(10) to show that x is a base 10 number . JS actually defaults to this, but we cannot be too implicit in our documentation. Adding that radix lets me avoid saying any more about it.

  • JavaScript, or rather ES6 let’s us express strings as arrays using the spread operator.

    […‘string’]

    becomes,

    [ ‘s’, ‘t’, ‘r’, ‘i’, ‘n’, ‘g’ ]

  • parseInt() also takes a radix, that we again set to base 10, the default, but explicitly.

Once we’re clear in terms of knowing the radix, it is fair and safe to remove all those '10’s. The code will still work the same. It knocks out 18 bytes of code overhead, but it also says, ‘implicit’.

1 Like

I am using the following code:

// Write your code here:

const squareNums = var => var.map(toSquare)

console.log(squareNums(numbers));

The only difference from the solution is that the solution uses the variable ‘arr’ instead of “var”, but for some reason it says my code is incorrect. Any ideas on why?

var is a reserved word in JavaScript. We should not use reserved words as variable names.

Lexical grammar - JavaScript | MDN

1 Like

const numbers = [2, 7, 9, 171, 52, 33, 14];

/*This is an arrow function with only one parameter (num) and a single line of code ( num * num). */

const toSquare = num => num * num

/*

Here’s another arrow function where we can notice:

  1. the code line is arr.map(toSquare)

  2. toSquare is a function passed as an argument.

  3. .map() takes an argument of a callback function and returns a new array

*/

const squareNums = arr => arr.map(toSquare)

What should I put into the console.log() to print the output?

You did assign the output to squareNums so that would be a sure bet.

console.log(squareNums)

// [ 4, 49, 81, 29241, 2704, 1089, 196 ]