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

Updated version for the homework.

parent e78b7911
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
  <component name="ProjectKey">
    <option name="state" value="project://e2804f05-5315-4fc6-a121-c522a6c26470" />
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/out" />
  </component>
</project>
 No newline at end of file
+32 −21
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p1;

/**
 * Attempts to approximate the number of distinct elements seen so far.
 * AMaintains an approximate count of the number of distinct elements seen so far.
 */
public abstract class DistinctCounter {
    // FIELDS
    final private Byte[] state;

    /**
     * The memory associated with the counter.
     */
    protected final FixedBitArray mem;

    // METHODS

@@ -14,48 +18,55 @@ public abstract class DistinctCounter {
    /**
     * This constructor cannot be used.
     */
    private DistinctCounter() { state = null; }
    private DistinctCounter() {mem = null;}

    /**
     * Constructs an object backed by a given memory size.
     * @param stateSize The size of the memory backing, in number of integers.
     * Constructs an DistinctCounter with a given size of memory.
     *
     * @param memBits The number of bits of memory available to the counter.
     */
    public DistinctCounter(int stateSize) {
        state = new Byte[stateSize];
    public DistinctCounter(int memBits) {
        mem = new FixedBitArray(memBits);
    }

    /**
     * Creates a DistinctCounter object from a given initial state.
     * @param initialState The output of a call to {@link #currentState()} on some DistinctCounter object.
     * Sets the memory of this DistinctCounter object to <code>initialMem</code>.
     *
     * @param initialMem The memory to set for this object.
     * It should be in the same format as the output of a call to {@link #currentState()}
     * for some DistinctCounter object.
     */
    public DistinctCounter(Byte[] initialState) {
        state = new Byte[initialState.length];
        System.arraycopy(initialState, 0, state, 0, initialState.length);
    public void setMem(FixedBitArray initialMem) {
        if (mem.len != initialMem.len)
            throw new IllegalArgumentException(
                "Trying to set memory with an incompatible argument.");
        else {
            // copy initialMem bits to this object
            mem.bits.clear();
            mem.bits.xor(initialMem.bits);
        }
    }

    // ... OPERATIONAL

    /**
     * Log a new element that is seen.
     * Note a new element that is seen.
     *
     * @param newElement The element that was seen.
     */
    abstract void saw(String newElement);

    /**
     *
     * @return A guess of the number of distinct elements that were seen.
     */
    abstract Integer numDistinct();

    // ... INFORMATIONAL

    /**
     * outputs the current state of the DistinctCounter
     * */
    public Byte[] currentState() {
        return state;
    }

    // NESTED CLASSES
    public static class NotYetImplemented extends RuntimeException {
     */
    final public FixedBitArray currentState() {
        return mem;
    }
}
+114 −0
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p1;

import java.util.BitSet;

/**
 * Implements aan array of bits whose size cannot be changed.
 */
public class FixedBitArray {
  // FIELDS
  /**
   * The length, in bits, of this array.
   */
  public final int len;
  /**
   * The bits stored in this array.
   */
  final BitSet bits;

  // METHODS

  /**
   * Constructs an object that handles <code>theLen</code> bits.
   *
   * @param theLen The number of bits that the object can handle.
   */
  public FixedBitArray(int theLen) {
    len = theLen;
    bits = new BitSet(len);
  }

  public FixedBitArray(byte[] bytes) {
    len = bytes.length;
    bits = BitSet.valueOf(bytes);
  }

  /**
   * @param bitIndex The index at which the array is being queried.
   * @return The bit at the array index <code>bitIndex</code>.
   */
  public boolean get(int bitIndex) {
    confirmIndex(bitIndex);
    return bits.get(bitIndex);
  }

  /**
   * Sets the bit at index <code>bitIndex</code> to true.
   *
   * @param bitIndex The index to set true.
   */
  public void set(int bitIndex) {
    confirmIndex(bitIndex);
    bits.set(bitIndex);
  }

  /**
   * Clears the bit at index <code>bitIndex</code> to true.
   *
   * @param bitIndex The index to set true.
   */
  public void clear(int bitIndex) {
    confirmIndex(bitIndex);
    bits.clear(bitIndex);
  }

  /**
   * Flips the parity of the bit at index <code>bitIndex</code>
   *
   * @param bitIndex The index of the bit in the array to flip.
   */
  public void flip(int bitIndex) {
    confirmIndex(bitIndex);
    bits.flip(bitIndex);
  }

  /**
   * @return A byte array corresponding to memory of this object
   */
  public byte[] toByteArray() {
    rectifyBits();
    return bits.toByteArray();
  }

  /**
   * @param bytes The contents of the new array.
   * @return A FixedBitArray whose contents are <code>bytes</code>
   */
  static public FixedBitArray valueOf(byte[] bytes) {
    return new FixedBitArray(bytes);
  }

  @Override
  public String toString() {
    return "[" + len + " bits]: " + bits.toString();
  }

  /**
   * Confirms that <code>bitIndex</code> is within the dynamic range of indices
   * handled by this array, returning normally if confirmation succeeds.
   *
   * @param bitIndex The index to check.
   * @throws ArrayIndexOutOfBoundsException if <bode>bitIndex</bode> is out of
   * range for this array.
   */
  private void confirmIndex(int bitIndex) {
    if (bitIndex < 0 || bitIndex >= len) {throw new ArrayIndexOutOfBoundsException(bitIndex);}
  }

  /**
   * Make sure there are no bits outside the dynamic range of the array.
   */
  private void rectifyBits() {
    bits.set(len, bits.size(), false);
  }
}
+16 −10
Original line number Diff line number Diff line
@@ -2,31 +2,37 @@ package edu.bu.ec504.hw1p1;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main {
    // constants
    static final int stateSize = 10; // the number of bytes in the myDistinctCounter object
    static final int memSize = 10; // the number of bits backing the counter

    /**
     * Run {@link myDistinctCounter} through the test strings provided, and report its results.
     * @param testStrings The strings to run by the {@link myDistinctCounter}.
     * Run {@link MyDistinctCounter} through the test strings provided, and report its results.
     * @param testStrings The strings to run by the {@link MyDistinctCounter}.
     */
    static void test(ArrayList<String> testStrings) {
        // Show the counter my test strings
        myDistinctCounter tester = new myDistinctCounter(stateSize);
        MyDistinctCounter tester = new MyDistinctCounter(memSize);
        Set<String> verifier = new HashSet<>();

        for (String test: testStrings) {
            tester.saw(test);
            verifier.add(test);
        }

        // Record the counter's state
        Byte[] savedState = tester.currentState();
        System.out.println("Counter state is: "+ Arrays.toString(savedState));
        FixedBitArray savedState = tester.currentState();
        System.out.println("Counter state is: "+ savedState);

        // Output the prediction
        myDistinctCounter newFoo = new myDistinctCounter(savedState);
        System.out.println("# of distinct strings: "+newFoo.numDistinct());
        // Output the guess
        MyDistinctCounter newFoo = new MyDistinctCounter(memSize);
        newFoo.setMem(savedState);
        System.out.println("guessed # of distinct strings: "+newFoo.numDistinct());
        System.out.println(" actual # of distinct strings: "+verifier.size());
    }

    /**
+10 −10
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p1;

public class myDistinctCounter extends DistinctCounter {
public class MyDistinctCounter extends DistinctCounter {

  /**
   * @inheritDoc
   */
  public myDistinctCounter(int stateSize) {
    super(stateSize);
  public MyDistinctCounter(int memBits) {
    super(memBits);
    throw new NotYetImplemented();  // replace this with your code!
  }

  /**
   * @inheritDoc
   */
  public myDistinctCounter(Byte[] initialState) {
    super(initialState);
  @Override
  void saw(String newElement) {
    throw new NotYetImplemented();  // replace this with your code!
  }

@@ -22,15 +22,15 @@ public class myDistinctCounter extends DistinctCounter {
   * @inheritDoc
   */
  @Override
  void saw(String newElement) {
  Integer numDistinct() {
    throw new NotYetImplemented();  // replace this with your code!
  }

  // NESTED CLASSES

  /**
   * @inheritDoc
   * A runtime exception indicating that a method has not yet been implemented.
   */
  @Override
  Integer numDistinct() {
    throw new NotYetImplemented();  // replace this with your code!
  public static class NotYetImplemented extends RuntimeException {
  }
}