Untitled

 avatar
unknown
javascript
4 years ago
2.0 kB
41
Indexable
// All arguments must be BigInts. Return value is a BigInt or a thrown RangeError
const bigH = (n, a, b) => {
  if (n < 0n || a < 0n || b < 0n) {
    throw Error('Can only hyperoperate on non-negative integers')
  }

  // [n, a, b, i result]
  let stack = [[n, a, b, 1n, a]]
  while (true) {
    // in some ways, stack overflows are the greatest base cases of all
    if (stack.length > 1000) {
      throw RangeError('stack')
    }

    let base_result = undefined;

    let [n, a, b, i, result] = stack[stack.length - 1]
    
    // successor operator
    if (n === 0n) {
      // Ignore `a`
      base_result = b + 1n
      
    // addition
    } else if (n === 1n) {
      base_result = a + b

    // multiplication
    } else if (n === 2n) {
      base_result = a * b

    // exponentiation
    } else if (n === 3n) {
      base_result = a ** b

    // n >= 4, time for some handy base cases

    } else if (a === 0n) {
      // Fun fact:
      base_result = b % 2n === 0n ? 1n : 0n

    } else if (a === 1n) {
      // 1^...^b = 1 for all finite b
      base_result = 1n

    // a >= 2

    } else if (b === 0n) {
      // a^0 = 1 for all a >= 2
      base_result = 1n

    } else if (b === 1n) {
      // a^...^1 = a for all a >= 2
      base_result = a

    // b >= 2

    } else if (a === 2n && b === 2n) {
      // Another fun fact
      base_result = 4n

      // check termination condition of loop
      // which isn't really a base case
    } else if (i === b) {
      base_result = result
    }


    if (base_result !== undefined) {
      stack.pop()

      // if we're in outermost stack frame, return
      if (stack.length == 0) {
        return base_result
      }

      // otherwise save result into previous stack frame
      stack[stack.length - 1][4] = base_result
    } else {

      // if we didn't hit a base case, increment i and push a stack frame
      stack[stack.length - 1][3] += 1n
      stack.push([n - 1n, a, result, 1n, a])
    }
  }
}
Editor is loading...