- Before proceeding - read this entire document
*thoroughly*! - Work on your own.
- Use only the JavaScript operations and commands we have described thus far in class.
- Download unzip the starter archive.
- Write all your code in the file
`hw3.js`

. - Replace
`(YOUR NAME)`

with*your name*in the comment near the top of`hw3.js`

. - Run
`hw3-demo.html`

in your browser to experiment with my solution. - Run
`hw3.html`

in your browser to test your solution. - Any written (i.e., non-programming) answers must be in the form of
`//`

comments. - Fill in all the areas of the supplied file marked by
`...`

. Remove the ellipses once you are finished with that part of the assignment. - Submit your work by uploading your
`hw3.js`

file via MySLC

Complete the function

`padEven(s)`

so that it returns string`s`

if`s`

consists of an even number of characters (i.e., its length is an even number) or returns`s`

with an exclamation point (`!`

) appended

if the length is odd. Use an`if`

statement*without*an`else`

. Examples:`> padEven('Cool') "Cool" > padEven('Cool!') "Cool!!"`

Complete

`threeify(n)`

so that it returns`n`

divided by 3 if`n`

is divisible by 3 and`n`

times 3 if`n`

is not divisible by 3. You can assume`n`

is a number. Use an`if`

-`else`

statement. Examples:`> threeify(15) 5 > threeify(7) 21`

Complete

`seasonToNumber(season)`

so that it returns the number corresponding to the specified string`season`

(1 for`Winter`

, 2 for`Spring`

, etc.). Returns`NaN`

if`season`

is not one of the four seasons.*Case insensitive*. Use a*multiway conditional*. Examples:`> seasonToNumber('winter') 1 > seasonToNumber('SPRING') 2 > seasonToNumber('Fall') 4 > isNaN(seasonToNumber('magicvember')) true`

Complete

`middleText`

so that it returns the string that is in the (lexicographic) middle of the three specified strings`s1`

,`s2`

, and`s3`

.*Case sensitive*. Examples:`> middleText('alpha', 'beta', 'gamma') "beta" > middleText('alpha', 'Beta', 'gamma') "alpha" > middleText('alpha', 'Beta', 'GAMMA') "GAMMA"`

*Note*: there is nothing particular about this function that makes it work only for strings. (It should work on numbers, too, though I will only test it on strings.)Complete

`categorize(m)`

so that it returns a string of length four categorizing number`m`

. The first character of the returned string indicates whether`m`

is a true number (i.e., not`NaN`

), if so, it is`'y'`

otherwise`'n'`

. The second character is either`'n'`

,`'+'`

,`'0'`

, or`'-'`

where`'n'`

again indicates`NaN`

,`'+'`

means the number is positive,`'-'`

that it is negative, and`'0'`

that it is zero. The third character is again`'n'`

if`m`

is`NaN`

, otherwise`'I'`

for`Infinity`

or`'F'`

for finite. The final character is`'n'`

if`NaN`

,`'?'`

if infinite,`'i'`

if`m`

is a finite integer, or`'f'`

if`m`

is finite, but not an integer (if it is “fractional”). Use*nested*`if`

s. Examples:`> categorize(4103) "y+Fi" > categorize(-Infinity) "y-I?" categorize('hello') "nnnn" categorize(-3.14) "y-Ff"`

Complete

`mask(s)`

so that it returns a string consisting of the`'*'`

symbol concatenated for the entire length of input string. Use a`while`

loop. Examples:`> mask('') "" > mask('hello') "*****"`

Complete

`sumSquares(n)`

so that it returns the sum of the squares of the integers from 1 through`n`

(inclusive). Use a`while`

loop. Example:`> sumSquares(4) // 1*1 + 2*2 + 3*3 + 4*4 30`

Complete

`snakeEyes()`

so that it repeatedly simulates rolling two six-sided dice until they “land as snake eyes” - meaning the sum of the dice is 2. Return the number of rolls required to arrive at snake eyes. In a comment, explain whether the loop you use is*definite*or*indefinite*. Your code should call the function`randomRange`

which has been supplied for you.

The last two problems involve the

*factors*of positive integers. Recall that`m`

is a*factor*of`n`

if`m`

divides into`n`

without any remainder. For example, the factors of 36 are: 1, 2, 3, 4, 6, 9, 12, 18 and 36 itself. We say that factors of a number that are neither 1 nor the number itself are*nontrivial factors*. A number is*perfect*if it is the sum of all its factors other than itself. (Perfect numbers are quite fascinating!)We can easily test if a number

`d`

is a factor of a number`q`

by using the remainder operator and comparing the result to zero:`> 36 % 12 === 0 // 12 is a factor of 36 true > 36 % 11 === 0 // 11 is not a factor of 36 false`

Complete

`isPerfect(n)`

so that it returns`true`

if`n`

is a perfect number and returns`false`

otherwise. Examples:`> isPerfect(6) // 6 = 1 + 2 + 3 true > isPerfect(15) // 15's factors are 1, 3, and 5 false`

(

*Challenging*.) Complete`factors(start, stop)`

so that it returns a string representation of all the nontrivial factors of each number between`start`

(inclusive) and`stop`

(exclusive). Use*nested*`while`

loops. The string should consist of one line for each number from`start`

to`stop`

. Each line should consist of the number whose factors are being presented, followed by a colon, followed by all its notrivial factors with two spaces between each factor. Example:`> console.log(factors(10, 15)) 10: 2 5 11: 12: 2 3 4 6 13: 14: 2 7`

Modify

`padEven`

so that it takes a second argument that represents the character to be appended (rather than it always being`'!'`

. Examples:`> padEven('hello', '?') "hello?" > padEven('hellno', '?') "hellno" > padEven('hi?', '*') "hi?*"`

Modify

`sumSquares`

so that it takes a second*and*third argument as in`sumSquares(n,start,step)`

so that it now returns the sum of`n`

squares starting at`start`

and going up by`step`

numbers at a time. Examples:`> sumSquares(4, 1, 1) // as before 30 > sumSquares(5, 3, 2) // 3*3 + 5*5 + 7*7 + 9*9 + 11*11 285`

Modify

`factors`

so that it takes a third argument, a Boolean value called`skipPrimes`

. If`skipPrimes`

is false, it works as before. But if`skipPrimes`

is true then`factors`

should return a string with lines only corresponding to numbers that have at least one nontrivial factor (i.e., only to*composite*numbers - numbers that are not*prime*). Examples:`> console.log(factors(10, 15, false)) 10: 2 5 11: 12: 2 3 4 6 13: 14: 2 7 > console.log(factors(10, 15, true)) 10: 2 5 12: 2 3 4 6 14: 2 7`

All of your functions should return a value. Make sure that your functions have a single return statement as the last statement within the body of the function. Keep the `return`

simple: just return a variable.

Your code should *not* use `prompt`

, `confirm`

or `alert`

.

For numbers, you can use the standard five arithmetic operations:

`+ - * / %`

the six arithmetic comparison operations:

`=== !== < > <= >=`

and `isNan`

and `isFinite`

. (`randomRange`

uses `Math.floor`

and `Math.random`

but you should not need either.)

For Booleans you can use the literals `true`

and `false`

and the three standard Boolean operators:

`! && ||`

For strings, you can use:

`=== !== < > <= >= .length .toLowerCase .toUpperCase`

You should not need the `typeof`

operator (except, possibly, for the `categorize`

problem).

Remember, `\n`

is the character than when displayed (either using `alert`

or `console.log`

) indicates that the next characters should appear on a *new line*.

You may use the short hand modifiers for assignments:

```
x++; // shorthand for x = x + 1;
x--; // shorthand for x = x - 1;
x += y; // shorthand for x = x + y; (works for strings, too)
x -= y; // shorthand for x = x - y;
x *= y; // shorthand for x = x * y;
```

To experiment more directly with my solutions, you can open up on a console while viewing this page and try examples such as:

```
> padEven('hello')
"hello!"
> sumSquares(4)
30
```