LMU ☀️ CMSI 185
COMPUTER PROGRAMMING
HOMEWORK #4 PARTIAL ANSWERS

Of course there are many ways to write these functions. But even if you got 100% on this assignment, you should still read my answers and think about how they are similar to or different from, and are better than or worse than, your own.

cmsi185-hw4.js
function countOfNegatives(values) {
  if (!Array.isArray(values)) {
    throw "not an array"
  }
  let count = 0
  for (const value of values) {
    if (["number", "bigint"].includes(typeof value) && value < 0) {
      count++
    }
  }
  return count
}

function occurrences(word, desired) {
  let count = 0
  for (const character of word) {
    if (character === desired) {
      count++
    }
  }
  return count
}

function randomBetween(x, y) {
  return Math.random() * (y - x) + x
}

function acronym(phrase) {
  return phrase
    .toLowerCase()
    .split(/\s+/)
    .map(word => word[0])
    .join("")
}

function isPrime(n) {
  if (!Number.isSafeInteger(n) || n <= 0) {
    throw `${n} is not a positive, safe integer`
  } else if (n === 2 || n === 3) {
    return true
  } else if (n === 1 || n % 2 === 0 || n % 3 === 0) {
    return false
  }
  for (let k = 5, w = 2; k * k <= n; k += w, w = 6 - w) {
    if (n % k === 0) {
      return false
    }
  }
  return true
}

function median(x, y, z) {
  if ([x, y, z].some(n => isNaN(n) || typeof n !== "number")) {
    throw "At least one of the values is not a number"
  }
  return [x, y, z].sort((a, b) => a - b)[1]
}

function sumOfEvenSquares(values) {
  const even = n => n % 2 === 0
  const square = n => n ** 2
  const sum = (x, y) => x + y
  return values
    .filter(even)
    .map(square)
    .reduce(sum, 0)
}

function insideSubstring(s, t) {
  const [shorter, longer] = s.length < t.length ? [s, t] : [t, s]
  return longer.includes(shorter) &&
    !longer.startsWith(shorter) &&
    !longer.endsWith(shorter)
}

class Point {
  constructor(latitude, longitude) {
    if (isNaN(latitude) || isNaN(longitude)) {
      throw "Latitude and longitude must be numeric"
    }
    if (Math.abs(latitude) > 90 || Math.abs(longitude) > 180) {
      throw "Latitude outside -90..90 or longitude outside -180..180"
    }
    this.latitude = latitude
    this.longitude = longitude
  }
  inArcticCircle() {
    return this.latitude > 66.5625
  }
  inAntarcticCircle() {
    return this.latitude < -66.5625
  }
  inTropics() {
    return this.latitude <= 23.437 && this.latitude >= -23.437
  }
  antipode() {
    return new Point(
      -this.latitude,
      this.longitude > 0 ? this.longitude - 180 : this.longitude + 180
    )
  }
}

function makeSequenceGenerator(operation, startValue) {
  let currentValue = startValue
  return () => {
    const returnValue = currentValue
    currentValue = operation(currentValue)
    return returnValue
  }
}

function powerArray(a) {
  if (!Array.isArray(a)) {
    throw "An Array is required"
  }
  const power = [[]]
  for (const x of a) {
    for (const element of power.slice()) {
      power.push([...element, x])
    }
  }
  return power
}

function collatzSteps(n) {
  if (!Number.isInteger(n) || n <= 0 || n > 1000000000000) {
    throw "Need a positive integer"
  }
  let steps = 0
  while (n > 1) {
    n = n % 2 === 0 ? n / 2 : 3 * n + 1
    steps++
  }
  return steps
}