# Introduction to (Web) Programming

## Program 3: conditionals and loops

### Due date: Thursday, February 21 at 1:30pm

#### General instructions

• Before proceeding - read this entire document thoroughly!
• Use only the JavaScript operations and commands we have described thus far in class.
• 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

#### The problems themselves.

1. 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"
"Cool!!"``````
2. 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``````
3. 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``````
4. 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.)

5. 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"``````
6. 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('')
""
"*****"``````
7. 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``````
8. 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``````
9. 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``````
10. (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``````

#### Challenge problems

• 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?"
"hellno"
"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``````

#### Restrictions and requirements

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``````