2
votes

I need help how to make сlass extension implementation work in different cases.

During the training, I completed next task:

*Decrementing Carousel is a container, accepting int elements. DecrementingCarousel has a maximum capacity, specified via the constructor. When created, DecrementingCarousel is in accumulating state: you may add elements via the addElement method and can produce a CarouselRun object via the run method. Once the run method is called, DecrementingCarousel is in running state: it refuses adding more elements. The CarouselRun allows to iterate over elements of the carousel decrementing them one by one with the next method. The next returns the value of the current element.
Then it decreases the current element by one and switches to the next element.

The CarouselRun iterates over elements in the order of their insertion. When an element is decreased to zero, the CarouselRun will skip it in further iterations. When there are no more elements available for decrementing, the CarouselRun returns -1.

The CarouselRun also has the isFinished method, which indicates, if the carousel has run out of the lements to decrement.

Specification Details DecrementingCarousel has two public methods:

boolean addElement(int element) - adds an element. If element is negative or zero, do not add the element. If container is full, do not add the element. If the run method was called to create a CarouselRun, do not add the element. If element is added successfully, return true. Return false otherwise. CarouselRun run() - returns a CarouselRun to iterate over the elements. If the run method has already been called earlier, it must return null: DecrementingCarousel may generate only one CarouselRun object.

CarouselRun has two public methods:

int next() - returns the current value of the current element, then decreases the current element by one and switches to the next element in insertion order. Skips zero elements. When there is no more elements to decrease, returns -1.

boolean isFinished() - when there is no more elements to decrease, returns true. Otherwise, returns false.

Examples

Empty case:

CarouselRun run = new DecrementingCarousel(7).run();
System.out.println(run.isFinished()); //true
System.out.println(run.next()); //-1

Regular case:

DecrementingCarousel carousel = new DecrementingCarousel(7);

carousel.addElement(2);
carousel.addElement(3);
carousel.addElement(1);

CarouselRun run = carousel.run();

System.out.println(run.isFinished()); //false

System.out.println(run.next()); //2
System.out.println(run.next()); //3
System.out.println(run.next()); //1

System.out.println(run.next()); //1
System.out.println(run.next()); //2

System.out.println(run.next()); //1

System.out.println(run.isFinished()); //true
System.out.println(run.next()); //-1

My implementation

DecrementingCarousel

public class DecrementingCarousel {
    int i = 0;
    int R = 0;
    public static int [] array;

    public DecrementingCarousel(int capacity) {
        array = new int[capacity];
    }

    public boolean addElement(int element){

        if (element>0&&R==0){
            if (i>=array.length){
                return false;            }
            else {
                array[i] = element;
                i++;}
            return true;
        } else {return false;}
    }

    public CarouselRun run(){
        R++;

        if (R == 1){
       return new CarouselRun();}
        else {return null;}

    }
}

CarouselRun

public class CarouselRun {
    public int[] arr = DecrementingCarousel.array.clone();
    int position = -1;
    int lvl=0;
    int index =0;
public int next() {
    if (allNegative(arr)) {return -1;}
    position++;

    if (position==arr.length||(position%arr.length==0&&position!=0))
    {         lvl++;        }

    CheckMinus();

    if(position-arr.length*lvl>=arr.length){ lvl++;}

    CheckMinus();

    if (lvl>=max(arr)){return -1;}

    return arr[position-arr.length*lvl]-lvl;
}

    public boolean isFinished() {

        if (max(arr)==0){return true;}
        return lvl >= max(arr) - 1 && position - arr.length * lvl >= index;
    }
    public void CheckMinus(){
        if (arr[position-arr.length*lvl]-lvl<=0){
            for (int i = position-arr.length*lvl; i < arr.length; i++){

                if (arr[i]-lvl<=0){position++;}
                else {break;}
            }
        }
    }
    public int max(int []values){

        int result = 0;
        for (int i = 0; i < values.length; i++) {
            int value = values[i];
            if (value >= result) {
                result = value;
                index = i;
            }
        }
        return result;
    }
    public static boolean allNegative (int[] array) {
        for (int j : array) {
            if (j > 0) return false;
        }
        return true;
    }
}

In new exercise I need to extend DecrementingCarousel. I need to implement HalvingCarousel. This subclass must halve elements instead of decrementing it by one. Note that you need to apply regular integer division, discarding the remainder. For example, 5 / 2 = 2.

Examples

Empty case:

CarouselRun run = new HalvingCarousel(7).run();
System.out.println(run.isFinished()); //true
System.out.println(run.next()); //-1

Regular case:

DecrementingCarousel carousel = new HalvingCarousel(7);

carousel.addElement(20);
carousel.addElement(30);
carousel.addElement(10);

CarouselRun run = carousel.run();

System.out.println(run.isFinished()); //false

System.out.println(run.next()); //20
System.out.println(run.next()); //30
System.out.println(run.next()); //10

System.out.println(run.next()); //10
System.out.println(run.next()); //15
System.out.println(run.next()); //5

System.out.println(run.next()); //5
System.out.println(run.next()); //7
System.out.println(run.next()); //2

System.out.println(run.next()); //2
System.out.println(run.next()); //3
System.out.println(run.next()); //1

System.out.println(run.next()); //1
System.out.println(run.next()); //1

System.out.println(run.isFinished()); //true
System.out.println(run.next()); //-1

Another

HalvingCarousel carousel = new HalvingCarousel(6);

        carousel.addElement(7);
        carousel.addElement(2);
        carousel.addElement(100);
        carousel.addElement(3);
        carousel.addElement(1);
        carousel.addElement(4);
        CarouselRun run = carousel.run();

        System.out.println(run.next());// 7
        System.out.println(run.next());// 2
        System.out.println(run.next());// 100
        System.out.println(run.next());// 3
        System.out.println(run.next());// 1
        System.out.println(run.next());// 4

        System.out.println(run.next());// 3
        System.out.println(run.next());// 1
        System.out.println(run.next());// 50
        System.out.println(run.next());// 1
        System.out.println(run.next());// 2

        System.out.println(run.next());// 1
        System.out.println(run.next());// 25
        System.out.println(run.next());// 1

        System.out.println(run.next());// 12

        System.out.println(run.next());// 6
        System.out.println(run.next());// 3
        System.out.println(run.next());// 1

        System.out.println(run.next());// -1
        System.out.println(run.isFinished()); //true

The default extended class looks like this

public class HalvingCarousel extends DecrementingCarousel {
    public HalvingCarousel(final int capacity) {
        super(capacity);    }
}

Methods of DecrementingCarousel(addElement and run) is still working so i did not change it.

I decided to change the CarouselRun methods to solve a new problem and this is what I got. It works with new task but not with old one. And on the task it is required that it works in both cases Decrementing and Halving. I need help how to make it work in both cases.

My code works with Halving.

public class CarouselRun {
    public int[] arr = DecrementingCarousel.array.clone();
    int position = -1;
    int lvl=0;
    int maxLVL =0;
    int index =0;
    public int next() {
        if (allNegative(arr)) {return -1;}
        maxLVL();
        index(arr);

        position++;

        if (position==arr.length||(position%arr.length==0&&position!=0))
        {         lvl++;        }

        CheckMinus();

        if(position-arr.length*lvl>=arr.length){ lvl++;}

        CheckMinus();

        if (lvl>=maxLVL){return -1;}

        CheckHalving();

        if(position>index+arr.length*lvl&&maxLVL-1==lvl){return -1;}

        if(lvl>0){

            int valueOrig = arr[position-arr.length*lvl];

            for (int i = lvl; i > 0; i--){
                valueOrig = valueOrig/2;

            }
            return valueOrig;
        }

        return arr[position-arr.length*lvl]-lvl;
    }

    public boolean isFinished() {

        if (max(arr)==0){return true;}
        if ((lvl>=maxLVL-1&&position-arr.length*lvl>=index)||(lvl>maxLVL-1&&position-arr.length*lvl==0)||(lvl>maxLVL-1&&position-arr.length*lvl==1)){return true;}
        else {return false;}
    }
    public void CheckMinus(){
        if (lvl>0){

            if ((arr[position-arr.length*lvl])/(lvl*2)<=0){
                for (int i = position-arr.length*lvl; i < arr.length; i++){

                    if ((arr[position-arr.length*lvl])/(lvl*2)<=0){position++;}
                    else {break;}
                }
            }
        }
        else{
            if (arr[position-arr.length*lvl]-lvl<=0){
                for (int i = position-arr.length*lvl; i < arr.length; i++){

                    if (arr[i]-lvl<=0){position++;}
                    else {break;}
                }
            }
        }
    }

    public void CheckHalving(){
        if(lvl>0) {
            for (int j = position - arr.length * lvl; j < arr.length; j++) {
                int kek = arr[position - arr.length * lvl];

                for (int i = lvl; i > 0; i--) {
                    kek = kek / 2;
                }
                if (kek <= 0) {
                    position++;
                }
            }
        }
    }
    public int max(int []values){

        int result = 0;
        for (int value : values) {
            if (value >= result) {
                result = value;

            }
        }
        return result;
    }
    public void index(int []values){

        for (int j = 0; j < values.length; j++) {

            int value = values[j];

            for (int i = maxLVL-1; i > 0; i--) {
                value = value / 2;

            }
            if (value == 1) {

                index = j;

            }

        }
    }


    public void maxLVL(){

        if(position==-1){
            int a = max(arr);

            for(int i = a; i >=1; i=i/2){
                maxLVL++;
            }
        }
    }

    public static boolean allNegative (int[] array) {
        for (int j : array) {
            if (j > 0) return false;
        }
        return true;
    }
}
1

1 Answers

1
votes

It might be better if you were to implement the next() method to the DecreasingCarousel method. Then you could override the next() method in the HalvingCarousel.

A much less elegant method that doesn't require you to rewrite your code though would be if you were to include a check for wich class is used in the .run() method and pass it onto the CarouselRun. The check would look like this:

public boolean checkClass(){
   return getClass()==DecrementingCarousel.class;
}

This returns true if the object is an instance of the "original" class and false if it is part of a subclass or an unrelated class.

This however is not how subclasses are supposed to be used.