Commit ec29f039 authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

Merge branch 'pipeline' into 'master'

pipeline setup

See merge request !1
parents 013efb7d efee33a2
Loading
Loading
Loading
Loading

ci_cd/.gitlab-ci.yml

0 → 100644
+10 −0
Original line number Diff line number Diff line
stages:
  - prebuild
  - compile
  - test

include:
  - local: 'ci_cd/problem3.yml'   # FullInteger

default:
  timeout: 5m

ci_cd/problem3.yml

0 → 100644
+49 −0
Original line number Diff line number Diff line
prebuild_problem_3:
  stage: prebuild
  script:
    - |
      # Check if source files exist
      if [ ! -f "FullInteger.cpp" ]; then
        echo "FullInteger.cpp does not exist";
        exit 1;
      fi
    - git clone https://agile.bu.edu/gitlab/configs/ec330/homeworks/homeworkthree.git hw3
  artifacts:
    paths:
      - hw3/
  rules:
    - if: '$CI_COMMIT_REF_NAME == "problem3"'
  tags: [c++-17]

compile_problem_3:
  stage: compile
  needs:
    - job: prebuild_problem_3
      artifacts: true
  script:
    - ls -l hw3/tests/
    - cp FullInteger.cpp hw3/tests/
    - cd hw3/tests
    - make problem3
  artifacts:
    paths:
      - hw3/
  rules:
    - if: '$CI_COMMIT_REF_NAME == "problem3"'
  tags: [c++-17]

exec_problem_3:
  stage: test
  needs:
    - job: compile_problem_3
      artifacts: true
  script:
    - cd hw3/tests
    - ./problem3
  artifacts:
    paths:
      - hw3/
  rules:
    - if: '$CI_COMMIT_REF_NAME == "problem3"'
  tags: [c++-17]

tests/BigNum.cpp

0 → 100644
+191 −0
Original line number Diff line number Diff line
//
// Created by Ari Trachtenberg on 1/30/17.
//

#include <sstream>
#include <memory>
#include "../include/BigNum.h"

// IMPLEMENTATION

BigNum::BigNum(const string &num) {
    bool leading = true; // used to ignore leading zeroes
    for (int ii = 0; ii < num.length(); ii++)
        if (leading && num[ii] == '0')
            continue;
        else {
            leading = false;
            digits.insert(digits.begin(), num[ii] - '0');
        }
}

BigNum::BigNum(const unsigned long num) {
    stringstream ss; ss<<num;
    *this=BigNum(ss.str());
}


BigNum::BigNum(const BigNum& otherNum):digits(otherNum.digits) {
}

BigNum& BigNum::operator=(const BigNum& otherNum) {
    digits = otherNum.digits;
    return *this;
}

BigNum& BigNum::operator+=(const BigNum& addor) {
    BigNum first, second; // second always has at least as many digits as first
    const unique_ptr<BigNum> result(new BigNum("0"));
    if (digits.size() > addor.digits.size()) {
        first = addor;
        second = *this;
    } else {
        first = *this;
        second = addor;
    }

    int ii;
    int carry = 0;
    for (ii = 0; ii < first.digits.size(); ii++) {
        const int sum = first.digits[ii] + second.digits[ii];
        result->digits.push_back((sum + carry) % base);
        if (sum + carry > (base - 1)) {
            carry = 1;
        } else {
            carry = 0;
        }
    }

    // finish up with the larger number
    for (; ii < second.digits.size(); ii++)
        if (carry) {
            const int dig = (second.digits[ii] + carry);
            result->digits.push_back(dig % base);
            carry = (dig > (base - 1) ? dig / base : 0);
        } else
            result->digits.push_back(second.digits[ii]);
    if (carry)
        result->digits.push_back(carry);

    *this = *result;
    return *this;
}

BigNum &BigNum::operator*=(const int cc) {
    // multiplies by small number cc
    int carry = 0;
    const unique_ptr<BigNum> result(new BigNum());
    
    for (const int digit : digits) {
        const int prod = digit * cc + carry;
        result->digits.push_back(prod % base);
        if (prod > (base - 1))
            carry = prod / base;
        else
            carry = 0;
    }

    while (carry) {
        result->digits.push_back(carry % base);
        carry /= base;
    }

    *this=*result;
    return *this;
}

BigNum &BigNum::operator*=(const BigNum& multiplicator) {
    const unique_ptr<BigNum> sum(new BigNum());
    for (int ii = 0; ii < multiplicator.digits.size(); ii++) {
        BigNum smallProd = *this * multiplicator.digits[ii];
        smallProd << ii;
        *sum += smallProd;
    }
    *this = *sum;
    return *this;
}

BigNum &BigNum::operator/=(const BigNum& divisor) {
    // pretty naive algorithm that is easy to implement
    const unique_ptr<BigNum> guess(new BigNum());
    for (int ii = digits.size() - 1; ii >= 0; ii--) {
        int dig;
        BigNum trial("");
        for (dig = 9; dig > 0; dig--) {
            BigNum num("1");
            num << ii;
            trial = (num * dig);
            if ((*guess + trial) * divisor <= *this)
                break;
        }
        if (dig != 0)
            *guess = *guess + trial;
    }
    if (guess->digits.size() == 1 && guess->digits[0] == 0)
        guess->digits.pop_back(); // make it the empty representation
    *this = *guess;
    return *this;
}

bool BigNum::operator==(const BigNum& otherNum) const {
    if (digits.size() != otherNum.digits.size()) {
        return false;
    }
    for (int ii = 0; ii < digits.size(); ii++)
        if (digits[ii] != otherNum.digits[ii])
            return false;
    return true;
}

bool BigNum::operator<=(const BigNum& otherNum) const {
    if (digits.size() > otherNum.digits.size())
        return false;
    if (digits.size() < otherNum.digits.size())
        return true;
    // same number of digits
    for (int ii = digits.size() - 1; ii >= 0; ii--)
        if (digits[ii] < otherNum.digits[ii])
            return true;
        else if (digits[ii] > otherNum.digits[ii])
            return false;
    return true; // they are equal
}

void BigNum::operator<<(const int cc) {
    digits.insert(digits.begin(), cc, 0);
}

BigNum BigNum::operator*(const int cc) const {
    BigNum *result = new BigNum(*this);
    *result *= cc;
    return *result;
}

BigNum BigNum::operator+(const BigNum &addor) const {
    BigNum result(*this);
    result += addor;
    return result;
}

BigNum BigNum::operator*(const BigNum& multiplicator) const {
    BigNum result(*this);
    result *= multiplicator;
    return result;
}

BigNum BigNum::operator/(const BigNum& divisor) const {
    BigNum result(*this);
    result /= divisor;
    return result;
}

// friends and helpers
std::ostream & operator<<(std::ostream& stream, const BigNum& num) {
    if (num.digits.size() == 0)
        stream << "[0]";
    else
        for (int ii = num.digits.size() - 1; ii >= 0; ii--)
            stream << num.digits[ii];
    return stream;
}

tests/BigNum.h

0 → 100644
+111 −0
Original line number Diff line number Diff line
//
// Created by Ari Trachtenberg on 1/30/17.
//

#ifndef HW1_BIGNUM_H
#define HW1_BIGNUM_H


// Written by Prof. Ari Trachtenberg for EC330
#include <vector>
#include <string>
using namespace std;

/**
 * A class to represent arbitrarily large non-negative integers.
 */
class BigNum {
public:

    // CONSTRUCTORS
    
    /**
     * Constructs a bigNum from a given non-negative int
     */
    BigNum(unsigned long num);
    
    /**
     * Constructs a bigNum from a given string.
     * @param num contains only characters 0-9 and represents a positive integer >= 0
     */
    explicit BigNum(const string &num = "");
    
    /**
     * Constructs a copy of {@code otherNum}
     */
    BigNum(const BigNum& otherNum);

    // OPERATORS
    /**
     * @return true iff this bigNum is exactly numerically equal to otherNum
     */
    bool operator==(const BigNum& otherNum) const;

    /**
     * 
     * @param otherNum
     * @return true iff this number is numerically less than or equal to other number
     */
    bool operator<=(const BigNum& otherNum) const;

    /**
     * This bigNum becomes the same as otherNum
     * @return the (new) version of this bigNum
     */
    BigNum& operator=(const BigNum& otherNum);

    /**
     * @return the [index]-th least-significant digit of the number
     */
    int operator[](const size_t index) const { return digits.at(index); }
    
    /**
     * 
     * @return The number of significant digits in the number
     */
    [[nodiscard]] size_t numDigits() const { return digits.size(); }

    /**
     * Arithmetic
     */
    BigNum operator+(const BigNum& addor) const;
    BigNum operator*(const BigNum& multiplicator) const;
    BigNum operator/(const BigNum& divisor) const;

    /**
     * Optimized multiplication of a bigNum by an int
     * @param cc > 0 is assumed
     * @return the product of this number and cc
     */
    BigNum operator*(int cc) const;

    /**
     * ARITHMETIC ASSIGNMENT OPERATORS
     */
    BigNum& operator+=(const BigNum& addor);
    BigNum& operator*=(int cc);
    BigNum& operator*=(const BigNum& multiplicator);
    BigNum& operator/=(const BigNum& divisor);

protected:
    vector<int> digits; /** stores the digits of the current number */

    /**
 * @param cc > 0
 * @return shifts the number to the left cc digits;
 *         equivalent to multiplying the current number by base^cc
 */
    void operator<<(int cc);

private:
    // Constants
    constexpr static int base = 10; // the base of the number

    // FRIENDS
    /**
     * Prints a human-readable version of bigNum [num]
     * onto a given output stream
     */
    friend std::ostream & operator<<(std::ostream& stream, const BigNum& num);
};
#endif //HW1_BIGNUM_H

tests/FullInteger.h

0 → 100644
+64 −0
Original line number Diff line number Diff line
//
// Created by Ari on 2/22/26.
//

#ifndef HW3_ADMIN_FULLINTEGER_H
#define HW3_ADMIN_FULLINTEGER_H
#include <initializer_list>

#include "IntegerP.h"
#include "IntegerPP.h"

/**
 * Represents a positive Integer of arbitrary precision, together with comparison and sorting capabilities.
 */
class FullInteger: public IntegerPP {
  public:
    /**
     * All modeled after {@link IntegerPP}.
     */
    FullInteger() = default;
    FullInteger(unsigned long n) : IntegerPP(n) {}
    FullInteger(std::initializer_list<int> pBasis) : IntegerPP(pBasis) {}
    FullInteger(const IntegerP& other) : IntegerPP(other) {}
    explicit FullInteger(const BigNum& num) : IntegerPP(num) {}
    FullInteger operator+(const FullInteger &addor) const { return IntegerPP::operator+(addor); }
    FullInteger& operator=(const FullInteger& rhs) { IntegerPP::operator=(rhs); return *this; }
    // new methods
    /**
     * @param other The {@link FullInteger} to which we are comparing.
     * @return true iff this {@link FullInteger} is less than or equal to {@code other}.
     */
    bool operator<=(const FullInteger &other) const;

    /**
     * Sorts the given vector of FullIntegers in place based on {@link operator<=}.  The
     * FullIntegers must not have a single prime factor greater than {@largestPrimeFactor},
     * and functioning is unspecified if they do.
     * @param largestPrimeFactor The largest prime factor of the FullIntegers provided.
     * @param nums A vector of FullIntegers, none of whom have a prime factor greater than {@code largestPrimeFactor}.
     *
     * @example:
     *  vector<FullInteger> nums = {3,1,4,1,5,9};
     *  FullInteger::limitedSort(nums,5);
     *    transforms nums into the array {1,1,3,4,5,9}
     *  But FullInteger::limitedSort(nums,3) has unspecified execution because not all elements
     *    of the array have prime factors <= 3.
     */
    static void limitedSort(vector<FullInteger>& nums, int largestPrimeFactor);

    // ... derived methods
    /**
     * @param other The {@link FullInteger} to which we are comparing.
     * @return true iff this {@link FullInteger} is less than {@code other}.
     */
    bool operator<(const FullInteger &other) const { return operator<=(other) && !operator==(other); }

    /**
     * @param other The {@link FullInteger} to which we are comparing.
     * @return true iff this {@link FullInteger} is greater than {@code other}.
     */
    bool operator>(const FullInteger &other) const { return !operator<=(other); }
};

#endif //HW3_ADMIN_FULLINTEGER_H
 No newline at end of file
Loading