Commit 1dd1d6c7 authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

fixed ci_cd file name

parent d4244710
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ compile_problem_2b:
    - job: prebuild_problem_2b
      artifacts: true
  script:
    - cp binPrime.cpp hw1/tests/
    - cp IntegerP.cpp binPrime.cpp hw1/tests/
    - cd hw1/tests
    - make problem2b
  artifacts:

tests/IntegerP.cpp

deleted100644 → 0
+0 −171
Original line number Diff line number Diff line
#include <sstream>

#include "IntegerP.h"

#include <iostream>
#include <cmath>
#include <climits>

using namespace std;

// helpers
/**
 * @return true iff n is prime
 */
bool isPrime(const int n) {
  if (n <= 1)
    return false;

  for (int i = 2; i * i <= n; i++) {
    if (n % i == 0) {
      return false;
    }
  }

  return true;
}

/**
 * @return The i-th prime, starting with i-thPrime(0)==2.
 */
unsigned int ithPrime(const size_t ii) {
  static auto memoized = vector<unsigned int>();
  if (memoized.size()>ii && memoized[ii]!=0u) // i.e., already memoized
    return memoized[ii];

  int prime=2;
  size_t ii_search=ii;
  while (ii_search!=0) {
    if (isPrime(++prime))
      ii_search--;
  }

  memoized.resize(ii+1);
  memoized[ii]=prime;
  return prime;
}

/**
 * @return {@code v[i]} if {@code i} is within the range of {@code v}, or, {@code def} otherwise.
 * @thanks ChatGPT
 */
template <typename T>
T getOrDef(const std::vector<T>& v, std::size_t i, T def = T{}) {
  return i < v.size() ? v[i] : def;
}

/**
 * Computes a positive integer power of an integer, using square-and-multiply.
 * @param base The base.
 * @param exp The exponent
 * @return base ^ exp
 * @requires exp>=0
 * @thanks ChatGPT
 */
long ipow(int base, int exp) {
  long result = 1;

  while (exp > 0) {
    if (exp & 1)
      result *= base;
    base *= base;
    exp >>= 1;
  }

  return result;
}

IntegerP::IntegerP(unsigned long lnum) {
  int ii=-1;
  while (lnum>1) {
    ii++;
    if (lnum % ithPrime(ii)==0) {
      if (_primePowers.size()<=(size_t) ii) // make sure that space is allocated
        _primePowers.resize(ii+1);
      _primePowers[ii]++;
      lnum/=ithPrime(ii);
      ii--;
    }
  }
}
IntegerP::IntegerP(const initializer_list<int> pBasis):_primePowers(pBasis) {
}
IntegerP::IntegerP():IntegerP(1) {
}
// IntegerP IntegerP::operator+(const IntegerP &addend) {
//
// }
// IntegerP IntegerP::operator-(const IntegerP &subtrahend) {
// }
IntegerP IntegerP::operator*(const IntegerP &multiplicand) const {
  const auto numIndices = static_cast<int>(max(_primePowers.size(),multiplicand._primePowers.size()));
  IntegerP result;
  for (int ii=0; ii<numIndices; ii++) {
    result._primePowers.push_back(
      getOrDef(_primePowers,ii,0) +
        getOrDef(multiplicand._primePowers,ii,0)
        );
  }
  return result;
}
IntegerP IntegerP::operator/(const IntegerP &divisor) const {
  const auto numIndices = static_cast<int>(max(_primePowers.size(),divisor._primePowers.size()));
  IntegerP result;
  int max_index=0; // the maximum significant index
  for (int ii=0; ii<numIndices; ii++) {
    result._primePowers.push_back(
      getOrDef(_primePowers,ii,0) -
        getOrDef(divisor._primePowers,ii,0)
        );
    if (result._primePowers[ii]!=0)
      max_index=ii;
  }
  // trim the result
  result._primePowers.resize(max_index+1);

  return result;
}

bool IntegerP::operator==(const IntegerP &other) const {
  return _primePowers==other._primePowers;
}

long IntegerP::trunc() const {
  // check size by comparing logs to log(LONG_MAX)
  double log_sum=0; // the log base e of this number
  for (size_t ii=0; ii<_primePowers.size(); ii++)
    log_sum+=log(ithPrime(ii))*_primePowers[ii];
  if (log_sum > log(LONG_MAX))
    return LONG_MAX;

  // size is ok
  long result=1;
  for (size_t ii=0; ii<_primePowers.size(); ii++)
    result*=ipow((int) ithPrime(ii),_primePowers[ii]);
  return result;
}

bool IntegerP::divisibleBy(const IntegerP &divisor) const {
  const IntegerP result = operator/(divisor);
  for (const int exp:result._primePowers)
    if (exp<0)
      return false;
  return true;
}
std::string IntegerP::toString() const {
  ostringstream result;

  if (_primePowers.empty() || (_primePowers.size()==1 && _primePowers[0]==0))
    result << "1";
  else {
    for (size_t ii=0; ii<_primePowers.size(); ii++)
      if (_primePowers[ii]!=0) {
        result << ithPrime(ii);
        if (_primePowers[ii]!=1)
          result <<  "^" << _primePowers[ii];
        if (ii<_primePowers.size()-1)
          result << " * ";
      }
  }
  return result.str();
}