function isPrime(n: number): boolean {
  if (n === 2) {
    return true;
  }
  if (n < 2 || n % 2 === 0) {
    return false;
  }
  for (var i = 3; i <= Math.sqrt(n); i += 2) {
    if (n % i === 0) {
      return false;
    }
  }
  return true;
}

function* primes(): Generator<number> {
  let i = 0;
  while (true) {
    if (!isPrime(i)) {
      i++;
      continue;
    }
    yield i++;
  }
}

for (let prime of primes()) {
  console.log("prime", prime);
  if (prime > 1000) {
    break;
  }
}

export class Rational {
  constructor(public numerator: number, public denominator: number) {
    if (denominator < 0) {
      this.numerator = numerator * -1;
      this.denominator = denominator;
    }
  }

  add(rational: Rational): Rational {
    /* The sum of two rational numbers `r₁ = a₁/b₁` and `r₂ = a₂/b₂`
     * is `r₁ + r₂ = a₁/b₁ + a₂/b₂ = (a₁ * b₂ + a₂ * b₁) / (b₁ * b₂)`. */
    return new Rational(
      this.numerator * rational.denominator +
        this.denominator * rational.numerator,
      rational.numerator * rational.denominator
    );
  }

  sub(rational: Rational): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  mul(rational: Rational): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  div(rational: Rational): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  abs(): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  exprational(amount: number): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  expreal(amount: number): Rational {
    throw new Error("Remove this statement and implement this function");
  }

  reduce(): Rational {
    throw new Error("Remove this statement and implement this function");
  }
}
