Checking if an integer permutation is cyclic in JavaMax heap in JavaPermutation of given stringPermutation...

Boss asked me to sign a resignation paper without a date on it along with my new contract

Was Opportunity's last message to Earth "My battery is low and it's getting dark"?

Why don't you get burned by the wood benches in a sauna?

Manager has noticed coworker's excessive breaks. Should I warn him?

Dot product with a constant

Can I combine Divination spells with Arcane Eye?

Question: "Are you hungry?" Answer: "I feel like eating."

How can guns be countered by melee combat without raw-ability or exceptional explanations?

What is formjacking?

What does it mean when an external ID field follows a DML Statement?

Is it common to refer to someone as "Prof. Dr. [LastName]"?

Why would you use 2 alternate layout buttons instead of 1, when only one can be selected at once

How to know if I am a 'Real Developer'

What is an explicit bijection in combinatorics?

What does @ mean in a hostname in DNS configuration?

How do I handle a blinded enemy which wants to attack someone it's sure is there?

Is it possible to detect 100% of SQLi with a simple regex?

Why do we interpret the accelerated expansion of the universe as the proof for the existence of dark energy?

When distributing a Linux kernel driver as source code, what's the difference between Proprietary and GPL license?

Spells that would be effective against a Modern Day army but would NOT destroy a fantasy one

How can I make my enemies feel real and make combat more engaging?

Have the UK Conservatives lost the working majority and if so, what does this mean?

Why is Bernie Sanders maximum accepted donation on actblue $5600?

3D buried view in Tikz



Checking if an integer permutation is cyclic in Java


Max heap in JavaPermutation of given stringPermutation algorithmRandom permutation of int[] and ArrayList<Integer>Heap's algorithm - integer permutationQuerying Facebook for details of a user's OAuth tokenImplementation of stackFinding Kth Permutation SequenceFinding the middle permutationCyclic Rotation













3












$begingroup$


A an integer permutation array[] is said to be cyclic if and only if we can choose an arbitrary element at position i, move it to the array[i]'s position, move the array[i]'s element to array[array[i]]'s position, and finally end up to the ith position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:



package net.coderodde.math;

import java.util.Objects;

/**
* This class checks that a given permutation consists of a single cycle
* covering the entire sequence. The idea is that if the input array is
* {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
* On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
* only one permutation cycle.
*
* @author Rodion "rodde" Efremov
* @version 1.6 (Feb 22, 2019)
*/
public class PermutationCyclicity {

private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
"array[%d] = %d, array.length = %d";

public boolean isCyclic(int[] array) {
check(array);
int nextNumber = array[array[0]];
int visitedNumbers = 1;

while (nextNumber != array[0]) {
nextNumber = array[nextNumber];
visitedNumbers++;
}

return visitedNumbers == array.length;
}

private void check(int[] array) {
checkArrayHasLength(array);
checkArrayContentsWithinBounds(array);
checkArrayElements(array);
}

private void checkArrayHasLength(int[] array) {
Objects.requireNonNull(array, "The input array is null.");

if (array.length == 0) {
throw new IllegalArgumentException("The array has length zero.");
}
}

private void checkArrayContentsWithinBounds(int[] array) {
for (int i = 0; i < array.length; i++) {
int num = array[i];

if (num < 0 || num >= array.length) {
String exceptionMessage =
String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
i,
num,
array.length);

throw new IllegalArgumentException(exceptionMessage);
}
}
}

private void checkArrayElements(int[] array) {
int[] counts = new int[array.length];

for (int i : array) {
if (++counts[i] > 1) {
throw new IllegalArgumentException(
"The value " + i + " appears more than once.");
}
}
}

public static void main(String[] args) {
PermutationCyclicity pc = new PermutationCyclicity();
System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));

try {
pc.isCyclic(new int[] { 1, 0, 1 });
} catch (Exception ex) {
System.out.println(ex.getMessage());
}

try {
pc.isCyclic(new int[] { 1 });
} catch (Exception ex) {
System.out.println(ex.getLocalizedMessage());
}

System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
}
}


Critique request



I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.










share|improve this question









$endgroup$

















    3












    $begingroup$


    A an integer permutation array[] is said to be cyclic if and only if we can choose an arbitrary element at position i, move it to the array[i]'s position, move the array[i]'s element to array[array[i]]'s position, and finally end up to the ith position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:



    package net.coderodde.math;

    import java.util.Objects;

    /**
    * This class checks that a given permutation consists of a single cycle
    * covering the entire sequence. The idea is that if the input array is
    * {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
    * On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
    * only one permutation cycle.
    *
    * @author Rodion "rodde" Efremov
    * @version 1.6 (Feb 22, 2019)
    */
    public class PermutationCyclicity {

    private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
    "array[%d] = %d, array.length = %d";

    public boolean isCyclic(int[] array) {
    check(array);
    int nextNumber = array[array[0]];
    int visitedNumbers = 1;

    while (nextNumber != array[0]) {
    nextNumber = array[nextNumber];
    visitedNumbers++;
    }

    return visitedNumbers == array.length;
    }

    private void check(int[] array) {
    checkArrayHasLength(array);
    checkArrayContentsWithinBounds(array);
    checkArrayElements(array);
    }

    private void checkArrayHasLength(int[] array) {
    Objects.requireNonNull(array, "The input array is null.");

    if (array.length == 0) {
    throw new IllegalArgumentException("The array has length zero.");
    }
    }

    private void checkArrayContentsWithinBounds(int[] array) {
    for (int i = 0; i < array.length; i++) {
    int num = array[i];

    if (num < 0 || num >= array.length) {
    String exceptionMessage =
    String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
    i,
    num,
    array.length);

    throw new IllegalArgumentException(exceptionMessage);
    }
    }
    }

    private void checkArrayElements(int[] array) {
    int[] counts = new int[array.length];

    for (int i : array) {
    if (++counts[i] > 1) {
    throw new IllegalArgumentException(
    "The value " + i + " appears more than once.");
    }
    }
    }

    public static void main(String[] args) {
    PermutationCyclicity pc = new PermutationCyclicity();
    System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));

    try {
    pc.isCyclic(new int[] { 1, 0, 1 });
    } catch (Exception ex) {
    System.out.println(ex.getMessage());
    }

    try {
    pc.isCyclic(new int[] { 1 });
    } catch (Exception ex) {
    System.out.println(ex.getLocalizedMessage());
    }

    System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
    }
    }


    Critique request



    I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.










    share|improve this question









    $endgroup$















      3












      3








      3





      $begingroup$


      A an integer permutation array[] is said to be cyclic if and only if we can choose an arbitrary element at position i, move it to the array[i]'s position, move the array[i]'s element to array[array[i]]'s position, and finally end up to the ith position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:



      package net.coderodde.math;

      import java.util.Objects;

      /**
      * This class checks that a given permutation consists of a single cycle
      * covering the entire sequence. The idea is that if the input array is
      * {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
      * On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
      * only one permutation cycle.
      *
      * @author Rodion "rodde" Efremov
      * @version 1.6 (Feb 22, 2019)
      */
      public class PermutationCyclicity {

      private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
      "array[%d] = %d, array.length = %d";

      public boolean isCyclic(int[] array) {
      check(array);
      int nextNumber = array[array[0]];
      int visitedNumbers = 1;

      while (nextNumber != array[0]) {
      nextNumber = array[nextNumber];
      visitedNumbers++;
      }

      return visitedNumbers == array.length;
      }

      private void check(int[] array) {
      checkArrayHasLength(array);
      checkArrayContentsWithinBounds(array);
      checkArrayElements(array);
      }

      private void checkArrayHasLength(int[] array) {
      Objects.requireNonNull(array, "The input array is null.");

      if (array.length == 0) {
      throw new IllegalArgumentException("The array has length zero.");
      }
      }

      private void checkArrayContentsWithinBounds(int[] array) {
      for (int i = 0; i < array.length; i++) {
      int num = array[i];

      if (num < 0 || num >= array.length) {
      String exceptionMessage =
      String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
      i,
      num,
      array.length);

      throw new IllegalArgumentException(exceptionMessage);
      }
      }
      }

      private void checkArrayElements(int[] array) {
      int[] counts = new int[array.length];

      for (int i : array) {
      if (++counts[i] > 1) {
      throw new IllegalArgumentException(
      "The value " + i + " appears more than once.");
      }
      }
      }

      public static void main(String[] args) {
      PermutationCyclicity pc = new PermutationCyclicity();
      System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));

      try {
      pc.isCyclic(new int[] { 1, 0, 1 });
      } catch (Exception ex) {
      System.out.println(ex.getMessage());
      }

      try {
      pc.isCyclic(new int[] { 1 });
      } catch (Exception ex) {
      System.out.println(ex.getLocalizedMessage());
      }

      System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
      }
      }


      Critique request



      I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.










      share|improve this question









      $endgroup$




      A an integer permutation array[] is said to be cyclic if and only if we can choose an arbitrary element at position i, move it to the array[i]'s position, move the array[i]'s element to array[array[i]]'s position, and finally end up to the ith position. For example, $langle 1, 2, 0 rangle$ is cyclic, whereas $langle 1, 0, 2 rangle$ is not since if we start from 2, we sill end up in an infinite loop. My attempt is as follows:



      package net.coderodde.math;

      import java.util.Objects;

      /**
      * This class checks that a given permutation consists of a single cycle
      * covering the entire sequence. The idea is that if the input array is
      * {@code 1, 0, 2}, it returns {@code false} since 2 is in its correct position.
      * On the other hand, {@code 1, 2, 0} returns {@code true} since it consists of
      * only one permutation cycle.
      *
      * @author Rodion "rodde" Efremov
      * @version 1.6 (Feb 22, 2019)
      */
      public class PermutationCyclicity {

      private static final String NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT =
      "array[%d] = %d, array.length = %d";

      public boolean isCyclic(int[] array) {
      check(array);
      int nextNumber = array[array[0]];
      int visitedNumbers = 1;

      while (nextNumber != array[0]) {
      nextNumber = array[nextNumber];
      visitedNumbers++;
      }

      return visitedNumbers == array.length;
      }

      private void check(int[] array) {
      checkArrayHasLength(array);
      checkArrayContentsWithinBounds(array);
      checkArrayElements(array);
      }

      private void checkArrayHasLength(int[] array) {
      Objects.requireNonNull(array, "The input array is null.");

      if (array.length == 0) {
      throw new IllegalArgumentException("The array has length zero.");
      }
      }

      private void checkArrayContentsWithinBounds(int[] array) {
      for (int i = 0; i < array.length; i++) {
      int num = array[i];

      if (num < 0 || num >= array.length) {
      String exceptionMessage =
      String.format(NUMBER_OUT_OF_BOUNDS_EXCEPTION_FORMAT,
      i,
      num,
      array.length);

      throw new IllegalArgumentException(exceptionMessage);
      }
      }
      }

      private void checkArrayElements(int[] array) {
      int[] counts = new int[array.length];

      for (int i : array) {
      if (++counts[i] > 1) {
      throw new IllegalArgumentException(
      "The value " + i + " appears more than once.");
      }
      }
      }

      public static void main(String[] args) {
      PermutationCyclicity pc = new PermutationCyclicity();
      System.out.println(pc.isCyclic(new int[] { 1, 2, 3, 0 }));

      try {
      pc.isCyclic(new int[] { 1, 0, 1 });
      } catch (Exception ex) {
      System.out.println(ex.getMessage());
      }

      try {
      pc.isCyclic(new int[] { 1 });
      } catch (Exception ex) {
      System.out.println(ex.getLocalizedMessage());
      }

      System.out.println(pc.isCyclic(new int[] { 1, 0, 2 }));
      }
      }


      Critique request



      I would like to hear comments regarding exception throwing and naming conventions, yet feel free to tell me anything that comes to mind.







      java algorithm array combinatorics






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 2 hours ago









      coderoddecoderodde

      15.9k638127




      15.9k638127






















          3 Answers
          3






          active

          oldest

          votes


















          3












          $begingroup$

          Here




          int nextNumber = array[array[0]];
          int visitedNumbers = 1;

          while (nextNumber != array[0]) {
          nextNumber = array[nextNumber];
          visitedNumbers++;
          }



          you determine the length of the orbit starting array[0]. If you start at 0 instead then some array lookups are saved, and I find it easier to understand:



          int nextNumber = array[0];
          int visitedNumbers = 1;

          while (nextNumber != 0) {
          nextNumber = array[nextNumber];
          visitedNumbers++;
          }


          And with a do-while loop the initial array lookup can be made part of the loop:



          int currentNumber = 0;
          int visitedNumbers = 0;

          do {
          currentNumber = array[currentNumber];
          visitedNumbers++;
          } while (currentNumber != 0);




          Further suggestions:



          Checking for duplicate array elements is not necessary if you limit the number of iterations:



          int currentNumber = 0;
          int visitedNumbers = 0;

          do {
          currentNumber = array[currentNumber];
          visitedNumbers++;
          } while (visitedNumbers <= array.length && currentNumber != 0);


          This saves one array traversal and the additional storage in checkArrayElements(). The only downside is that calling the function with an invalid permutation now possibly returns false instead of throwing an error.



          Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.






          share|improve this answer











          $endgroup$





















            2












            $begingroup$

            For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength, checkArrayContentsWithinBounds and checkArrayElements are private, return void and throw an IllegalArgumentException.



            Null Checking



            The method checkArrayHasLength checks for null, but checkArrayElements doesn`t.



            So the method checkArrayElements is dependent on checkArrayHasLength in the method check and you can't call them in an different order without to get your personalized exception message.



            checkArrayHasLength(null); // personalized error message


            checkArrayElements(null); // non personalized error message


            Naming



            After I looked into checkArrayHasLength I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty would be better.



            The name checkArrayElements is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce would be better.



            Type Embedded in Name




            Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.




            Each method includes Array, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..

            New method names could be: checkIsNotEmpty, checkElementsWithinBounds and checkAllElementsOccurNotMoreThanOnce.





            Make it more Abstract



            As already mention you have three methods that are private, but they could be public to.



            Rename PermutationCyclicity



            If we rename PermutationCyclicity to Permutation it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean instead of void and for that I would suggest to rename again all methods with an is or are prefix instead of check.



            As a Utility-Class



            class Permutations {

            public boolean isCyclic(int[] array) {
            check(array);
            int nextNumber = array[array[0]];
            int visitedNumbers = 1;

            while (nextNumber != array[0]) {
            nextNumber = array[nextNumber];
            visitedNumbers++;
            }

            return visitedNumbers == array.length;
            }

            private void check(int[] array) {
            if (isNotEmpty(array))
            throw new IllegalArgumentException("The array has length zero.");
            if (areAllElementsWithinBounds(array))
            throw new IllegalArgumentException("Argument contains elements that are not in the bound");
            if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
            throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
            }

            public boolean isNotEmpty(int[] array) {* ... *}

            public boolean areAllElementsWithinBounds(int[] array) {* ... *}

            public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}

            }


            As a Value-Object



            class Permutation {

            private int[] values;

            public Permutation(int[] values) {
            this.values = Objects.requireNonNull(values, "The argument is null.");
            }

            public boolean isCyclic() {
            check();
            int nextNumber = values[values[0]];
            int visitedNumbers = 1;

            while (nextNumber != values[0]) {
            nextNumber = values[nextNumber];
            visitedNumbers++;
            }

            return visitedNumbers == values.length;
            }

            private void check() {
            if (isNotEmpty())
            throw new IllegalArgumentException("The array has length zero.");

            if (areAllElementsWithinBounds())
            throw new IllegalArgumentException("Argument contains elements that are not in the bound");

            if (isOccurrenceOfAllElementsNotMoreThanOnce())
            throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
            }

            public boolean isNotEmpty() {* ... *}

            public boolean areAllElementsWithinBounds() {* ... *}

            public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}

            }


            Does it need to Throw?



            I'm not if the method isCyclic needs to throw an IllegalArgumentException. From my feelings here a permutation can be cyclic or not - true or false. Additional if a client forgot to catch the IllegalArgumentException, he will never get to know the reason.



            If you want to make sure the client should get always the reason use not a RuntimeException, because they don't have to be checked.



            A other way would to use an algebraic data type. The Either can be used to get a result or an error message.



            Or just simply return false and the client has to find the reason:



            class Permutation {

            private int[] values;

            public Permutation(int[] values) {
            this.values = Objects.requireNonNull(values, "The argument is null.");
            }

            public boolean isCyclic() {
            if (isEmpty()
            && areAllElementsAreNotWithinBounds()
            && isOccurrenceOfAllElementsMoreThanOnce())
            return false;

            // ..

            return visitedNumbers == values.length;
            }

            public boolean isEmpty() {* ... *}

            public boolean areAllElementsAreNotWithinBounds() {* ... *}

            public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}

            }


            public static void main(String[] args) {
            Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});

            if (permutation.isCyclic())
            System.out.println("nice");
            else {
            if (!permutation.areAllElementsWithinBounds())
            System.out.println("not all elements are in bound");
            // ..
            }
            }





            share|improve this answer











            $endgroup$













            • $begingroup$
              There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
              $endgroup$
              – Martin R
              7 mins ago










            • $begingroup$
              @MartinR psst.. Already fixed it. Thanks
              $endgroup$
              – Roman
              5 mins ago










            • $begingroup$
              Check again: Unless I am mistaken, it still says if (array is valid) { return false }
              $endgroup$
              – Martin R
              4 mins ago



















            1












            $begingroup$

            I would prefer checkArrayValidity over the generic check and PermutationCyclicityChecker checker over PermutationCyclicity as the class implements functionality, not state.



            Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).






            share|improve this answer









            $endgroup$













              Your Answer





              StackExchange.ifUsing("editor", function () {
              return StackExchange.using("mathjaxEditing", function () {
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              });
              });
              }, "mathjax-editing");

              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "196"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: false,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214013%2fchecking-if-an-integer-permutation-is-cyclic-in-java%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              3












              $begingroup$

              Here




              int nextNumber = array[array[0]];
              int visitedNumbers = 1;

              while (nextNumber != array[0]) {
              nextNumber = array[nextNumber];
              visitedNumbers++;
              }



              you determine the length of the orbit starting array[0]. If you start at 0 instead then some array lookups are saved, and I find it easier to understand:



              int nextNumber = array[0];
              int visitedNumbers = 1;

              while (nextNumber != 0) {
              nextNumber = array[nextNumber];
              visitedNumbers++;
              }


              And with a do-while loop the initial array lookup can be made part of the loop:



              int currentNumber = 0;
              int visitedNumbers = 0;

              do {
              currentNumber = array[currentNumber];
              visitedNumbers++;
              } while (currentNumber != 0);




              Further suggestions:



              Checking for duplicate array elements is not necessary if you limit the number of iterations:



              int currentNumber = 0;
              int visitedNumbers = 0;

              do {
              currentNumber = array[currentNumber];
              visitedNumbers++;
              } while (visitedNumbers <= array.length && currentNumber != 0);


              This saves one array traversal and the additional storage in checkArrayElements(). The only downside is that calling the function with an invalid permutation now possibly returns false instead of throwing an error.



              Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.






              share|improve this answer











              $endgroup$


















                3












                $begingroup$

                Here




                int nextNumber = array[array[0]];
                int visitedNumbers = 1;

                while (nextNumber != array[0]) {
                nextNumber = array[nextNumber];
                visitedNumbers++;
                }



                you determine the length of the orbit starting array[0]. If you start at 0 instead then some array lookups are saved, and I find it easier to understand:



                int nextNumber = array[0];
                int visitedNumbers = 1;

                while (nextNumber != 0) {
                nextNumber = array[nextNumber];
                visitedNumbers++;
                }


                And with a do-while loop the initial array lookup can be made part of the loop:



                int currentNumber = 0;
                int visitedNumbers = 0;

                do {
                currentNumber = array[currentNumber];
                visitedNumbers++;
                } while (currentNumber != 0);




                Further suggestions:



                Checking for duplicate array elements is not necessary if you limit the number of iterations:



                int currentNumber = 0;
                int visitedNumbers = 0;

                do {
                currentNumber = array[currentNumber];
                visitedNumbers++;
                } while (visitedNumbers <= array.length && currentNumber != 0);


                This saves one array traversal and the additional storage in checkArrayElements(). The only downside is that calling the function with an invalid permutation now possibly returns false instead of throwing an error.



                Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.






                share|improve this answer











                $endgroup$
















                  3












                  3








                  3





                  $begingroup$

                  Here




                  int nextNumber = array[array[0]];
                  int visitedNumbers = 1;

                  while (nextNumber != array[0]) {
                  nextNumber = array[nextNumber];
                  visitedNumbers++;
                  }



                  you determine the length of the orbit starting array[0]. If you start at 0 instead then some array lookups are saved, and I find it easier to understand:



                  int nextNumber = array[0];
                  int visitedNumbers = 1;

                  while (nextNumber != 0) {
                  nextNumber = array[nextNumber];
                  visitedNumbers++;
                  }


                  And with a do-while loop the initial array lookup can be made part of the loop:



                  int currentNumber = 0;
                  int visitedNumbers = 0;

                  do {
                  currentNumber = array[currentNumber];
                  visitedNumbers++;
                  } while (currentNumber != 0);




                  Further suggestions:



                  Checking for duplicate array elements is not necessary if you limit the number of iterations:



                  int currentNumber = 0;
                  int visitedNumbers = 0;

                  do {
                  currentNumber = array[currentNumber];
                  visitedNumbers++;
                  } while (visitedNumbers <= array.length && currentNumber != 0);


                  This saves one array traversal and the additional storage in checkArrayElements(). The only downside is that calling the function with an invalid permutation now possibly returns false instead of throwing an error.



                  Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.






                  share|improve this answer











                  $endgroup$



                  Here




                  int nextNumber = array[array[0]];
                  int visitedNumbers = 1;

                  while (nextNumber != array[0]) {
                  nextNumber = array[nextNumber];
                  visitedNumbers++;
                  }



                  you determine the length of the orbit starting array[0]. If you start at 0 instead then some array lookups are saved, and I find it easier to understand:



                  int nextNumber = array[0];
                  int visitedNumbers = 1;

                  while (nextNumber != 0) {
                  nextNumber = array[nextNumber];
                  visitedNumbers++;
                  }


                  And with a do-while loop the initial array lookup can be made part of the loop:



                  int currentNumber = 0;
                  int visitedNumbers = 0;

                  do {
                  currentNumber = array[currentNumber];
                  visitedNumbers++;
                  } while (currentNumber != 0);




                  Further suggestions:



                  Checking for duplicate array elements is not necessary if you limit the number of iterations:



                  int currentNumber = 0;
                  int visitedNumbers = 0;

                  do {
                  currentNumber = array[currentNumber];
                  visitedNumbers++;
                  } while (visitedNumbers <= array.length && currentNumber != 0);


                  This saves one array traversal and the additional storage in checkArrayElements(). The only downside is that calling the function with an invalid permutation now possibly returns false instead of throwing an error.



                  Similarly, the “bounds check” can be made directly in that loop. That might be viewed as a violation of the “separation of concerns” principle, but saves one array traversal.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 41 mins ago

























                  answered 1 hour ago









                  Martin RMartin R

                  15.9k12364




                  15.9k12364

























                      2












                      $begingroup$

                      For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength, checkArrayContentsWithinBounds and checkArrayElements are private, return void and throw an IllegalArgumentException.



                      Null Checking



                      The method checkArrayHasLength checks for null, but checkArrayElements doesn`t.



                      So the method checkArrayElements is dependent on checkArrayHasLength in the method check and you can't call them in an different order without to get your personalized exception message.



                      checkArrayHasLength(null); // personalized error message


                      checkArrayElements(null); // non personalized error message


                      Naming



                      After I looked into checkArrayHasLength I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty would be better.



                      The name checkArrayElements is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce would be better.



                      Type Embedded in Name




                      Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.




                      Each method includes Array, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..

                      New method names could be: checkIsNotEmpty, checkElementsWithinBounds and checkAllElementsOccurNotMoreThanOnce.





                      Make it more Abstract



                      As already mention you have three methods that are private, but they could be public to.



                      Rename PermutationCyclicity



                      If we rename PermutationCyclicity to Permutation it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean instead of void and for that I would suggest to rename again all methods with an is or are prefix instead of check.



                      As a Utility-Class



                      class Permutations {

                      public boolean isCyclic(int[] array) {
                      check(array);
                      int nextNumber = array[array[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != array[0]) {
                      nextNumber = array[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == array.length;
                      }

                      private void check(int[] array) {
                      if (isNotEmpty(array))
                      throw new IllegalArgumentException("The array has length zero.");
                      if (areAllElementsWithinBounds(array))
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");
                      if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty(int[] array) {* ... *}

                      public boolean areAllElementsWithinBounds(int[] array) {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}

                      }


                      As a Value-Object



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      check();
                      int nextNumber = values[values[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != values[0]) {
                      nextNumber = values[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == values.length;
                      }

                      private void check() {
                      if (isNotEmpty())
                      throw new IllegalArgumentException("The array has length zero.");

                      if (areAllElementsWithinBounds())
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");

                      if (isOccurrenceOfAllElementsNotMoreThanOnce())
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty() {* ... *}

                      public boolean areAllElementsWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}

                      }


                      Does it need to Throw?



                      I'm not if the method isCyclic needs to throw an IllegalArgumentException. From my feelings here a permutation can be cyclic or not - true or false. Additional if a client forgot to catch the IllegalArgumentException, he will never get to know the reason.



                      If you want to make sure the client should get always the reason use not a RuntimeException, because they don't have to be checked.



                      A other way would to use an algebraic data type. The Either can be used to get a result or an error message.



                      Or just simply return false and the client has to find the reason:



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      if (isEmpty()
                      && areAllElementsAreNotWithinBounds()
                      && isOccurrenceOfAllElementsMoreThanOnce())
                      return false;

                      // ..

                      return visitedNumbers == values.length;
                      }

                      public boolean isEmpty() {* ... *}

                      public boolean areAllElementsAreNotWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}

                      }


                      public static void main(String[] args) {
                      Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});

                      if (permutation.isCyclic())
                      System.out.println("nice");
                      else {
                      if (!permutation.areAllElementsWithinBounds())
                      System.out.println("not all elements are in bound");
                      // ..
                      }
                      }





                      share|improve this answer











                      $endgroup$













                      • $begingroup$
                        There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                        $endgroup$
                        – Martin R
                        7 mins ago










                      • $begingroup$
                        @MartinR psst.. Already fixed it. Thanks
                        $endgroup$
                        – Roman
                        5 mins ago










                      • $begingroup$
                        Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                        $endgroup$
                        – Martin R
                        4 mins ago
















                      2












                      $begingroup$

                      For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength, checkArrayContentsWithinBounds and checkArrayElements are private, return void and throw an IllegalArgumentException.



                      Null Checking



                      The method checkArrayHasLength checks for null, but checkArrayElements doesn`t.



                      So the method checkArrayElements is dependent on checkArrayHasLength in the method check and you can't call them in an different order without to get your personalized exception message.



                      checkArrayHasLength(null); // personalized error message


                      checkArrayElements(null); // non personalized error message


                      Naming



                      After I looked into checkArrayHasLength I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty would be better.



                      The name checkArrayElements is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce would be better.



                      Type Embedded in Name




                      Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.




                      Each method includes Array, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..

                      New method names could be: checkIsNotEmpty, checkElementsWithinBounds and checkAllElementsOccurNotMoreThanOnce.





                      Make it more Abstract



                      As already mention you have three methods that are private, but they could be public to.



                      Rename PermutationCyclicity



                      If we rename PermutationCyclicity to Permutation it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean instead of void and for that I would suggest to rename again all methods with an is or are prefix instead of check.



                      As a Utility-Class



                      class Permutations {

                      public boolean isCyclic(int[] array) {
                      check(array);
                      int nextNumber = array[array[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != array[0]) {
                      nextNumber = array[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == array.length;
                      }

                      private void check(int[] array) {
                      if (isNotEmpty(array))
                      throw new IllegalArgumentException("The array has length zero.");
                      if (areAllElementsWithinBounds(array))
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");
                      if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty(int[] array) {* ... *}

                      public boolean areAllElementsWithinBounds(int[] array) {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}

                      }


                      As a Value-Object



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      check();
                      int nextNumber = values[values[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != values[0]) {
                      nextNumber = values[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == values.length;
                      }

                      private void check() {
                      if (isNotEmpty())
                      throw new IllegalArgumentException("The array has length zero.");

                      if (areAllElementsWithinBounds())
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");

                      if (isOccurrenceOfAllElementsNotMoreThanOnce())
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty() {* ... *}

                      public boolean areAllElementsWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}

                      }


                      Does it need to Throw?



                      I'm not if the method isCyclic needs to throw an IllegalArgumentException. From my feelings here a permutation can be cyclic or not - true or false. Additional if a client forgot to catch the IllegalArgumentException, he will never get to know the reason.



                      If you want to make sure the client should get always the reason use not a RuntimeException, because they don't have to be checked.



                      A other way would to use an algebraic data type. The Either can be used to get a result or an error message.



                      Or just simply return false and the client has to find the reason:



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      if (isEmpty()
                      && areAllElementsAreNotWithinBounds()
                      && isOccurrenceOfAllElementsMoreThanOnce())
                      return false;

                      // ..

                      return visitedNumbers == values.length;
                      }

                      public boolean isEmpty() {* ... *}

                      public boolean areAllElementsAreNotWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}

                      }


                      public static void main(String[] args) {
                      Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});

                      if (permutation.isCyclic())
                      System.out.println("nice");
                      else {
                      if (!permutation.areAllElementsWithinBounds())
                      System.out.println("not all elements are in bound");
                      // ..
                      }
                      }





                      share|improve this answer











                      $endgroup$













                      • $begingroup$
                        There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                        $endgroup$
                        – Martin R
                        7 mins ago










                      • $begingroup$
                        @MartinR psst.. Already fixed it. Thanks
                        $endgroup$
                        – Roman
                        5 mins ago










                      • $begingroup$
                        Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                        $endgroup$
                        – Martin R
                        4 mins ago














                      2












                      2








                      2





                      $begingroup$

                      For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength, checkArrayContentsWithinBounds and checkArrayElements are private, return void and throw an IllegalArgumentException.



                      Null Checking



                      The method checkArrayHasLength checks for null, but checkArrayElements doesn`t.



                      So the method checkArrayElements is dependent on checkArrayHasLength in the method check and you can't call them in an different order without to get your personalized exception message.



                      checkArrayHasLength(null); // personalized error message


                      checkArrayElements(null); // non personalized error message


                      Naming



                      After I looked into checkArrayHasLength I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty would be better.



                      The name checkArrayElements is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce would be better.



                      Type Embedded in Name




                      Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.




                      Each method includes Array, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..

                      New method names could be: checkIsNotEmpty, checkElementsWithinBounds and checkAllElementsOccurNotMoreThanOnce.





                      Make it more Abstract



                      As already mention you have three methods that are private, but they could be public to.



                      Rename PermutationCyclicity



                      If we rename PermutationCyclicity to Permutation it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean instead of void and for that I would suggest to rename again all methods with an is or are prefix instead of check.



                      As a Utility-Class



                      class Permutations {

                      public boolean isCyclic(int[] array) {
                      check(array);
                      int nextNumber = array[array[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != array[0]) {
                      nextNumber = array[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == array.length;
                      }

                      private void check(int[] array) {
                      if (isNotEmpty(array))
                      throw new IllegalArgumentException("The array has length zero.");
                      if (areAllElementsWithinBounds(array))
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");
                      if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty(int[] array) {* ... *}

                      public boolean areAllElementsWithinBounds(int[] array) {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}

                      }


                      As a Value-Object



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      check();
                      int nextNumber = values[values[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != values[0]) {
                      nextNumber = values[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == values.length;
                      }

                      private void check() {
                      if (isNotEmpty())
                      throw new IllegalArgumentException("The array has length zero.");

                      if (areAllElementsWithinBounds())
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");

                      if (isOccurrenceOfAllElementsNotMoreThanOnce())
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty() {* ... *}

                      public boolean areAllElementsWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}

                      }


                      Does it need to Throw?



                      I'm not if the method isCyclic needs to throw an IllegalArgumentException. From my feelings here a permutation can be cyclic or not - true or false. Additional if a client forgot to catch the IllegalArgumentException, he will never get to know the reason.



                      If you want to make sure the client should get always the reason use not a RuntimeException, because they don't have to be checked.



                      A other way would to use an algebraic data type. The Either can be used to get a result or an error message.



                      Or just simply return false and the client has to find the reason:



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      if (isEmpty()
                      && areAllElementsAreNotWithinBounds()
                      && isOccurrenceOfAllElementsMoreThanOnce())
                      return false;

                      // ..

                      return visitedNumbers == values.length;
                      }

                      public boolean isEmpty() {* ... *}

                      public boolean areAllElementsAreNotWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}

                      }


                      public static void main(String[] args) {
                      Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});

                      if (permutation.isCyclic())
                      System.out.println("nice");
                      else {
                      if (!permutation.areAllElementsWithinBounds())
                      System.out.println("not all elements are in bound");
                      // ..
                      }
                      }





                      share|improve this answer











                      $endgroup$



                      For the task to check if a permutation is cyclic, the code works perfect. But we have no reusable code because it works only for these task, since the methods checkArrayHasLength, checkArrayContentsWithinBounds and checkArrayElements are private, return void and throw an IllegalArgumentException.



                      Null Checking



                      The method checkArrayHasLength checks for null, but checkArrayElements doesn`t.



                      So the method checkArrayElements is dependent on checkArrayHasLength in the method check and you can't call them in an different order without to get your personalized exception message.



                      checkArrayHasLength(null); // personalized error message


                      checkArrayElements(null); // non personalized error message


                      Naming



                      After I looked into checkArrayHasLength I understand, that it means it checks if an array is not empty. For me, maybe because I'm not a native English speaker, the name checkArrayIsNotEmpty would be better.



                      The name checkArrayElements is in my eyes useless. This name could use every method that do some validation on an array. I think the name checkAllArrayElementsOccurNotMoreThanOnce would be better.



                      Type Embedded in Name




                      Avoid placing types in method names; it's not only redundant, but it forces you to change the name if the type changes.




                      Each method includes Array, which is redundant because the parameter list already includes the datatype. If you want to switch from an array to a list you need to rename all methods and it could be possible to forget one method..

                      New method names could be: checkIsNotEmpty, checkElementsWithinBounds and checkAllElementsOccurNotMoreThanOnce.





                      Make it more Abstract



                      As already mention you have three methods that are private, but they could be public to.



                      Rename PermutationCyclicity



                      If we rename PermutationCyclicity to Permutation it would make sense to have methods that check for the length, the bounds and the number of occurrence of elements. These methods could now return a boolean instead of void and for that I would suggest to rename again all methods with an is or are prefix instead of check.



                      As a Utility-Class



                      class Permutations {

                      public boolean isCyclic(int[] array) {
                      check(array);
                      int nextNumber = array[array[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != array[0]) {
                      nextNumber = array[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == array.length;
                      }

                      private void check(int[] array) {
                      if (isNotEmpty(array))
                      throw new IllegalArgumentException("The array has length zero.");
                      if (areAllElementsWithinBounds(array))
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");
                      if (isOccurrenceOfAllElementsNotMoreThanOnce(array))
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty(int[] array) {* ... *}

                      public boolean areAllElementsWithinBounds(int[] array) {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce(int[] array) {* ... *}

                      }


                      As a Value-Object



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      check();
                      int nextNumber = values[values[0]];
                      int visitedNumbers = 1;

                      while (nextNumber != values[0]) {
                      nextNumber = values[nextNumber];
                      visitedNumbers++;
                      }

                      return visitedNumbers == values.length;
                      }

                      private void check() {
                      if (isNotEmpty())
                      throw new IllegalArgumentException("The array has length zero.");

                      if (areAllElementsWithinBounds())
                      throw new IllegalArgumentException("Argument contains elements that are not in the bound");

                      if (isOccurrenceOfAllElementsNotMoreThanOnce())
                      throw new IllegalArgumentException("Argument contains elements that occurs multiple times");
                      }

                      public boolean isNotEmpty() {* ... *}

                      public boolean areAllElementsWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsNotMoreThanOnce() {* ... *}

                      }


                      Does it need to Throw?



                      I'm not if the method isCyclic needs to throw an IllegalArgumentException. From my feelings here a permutation can be cyclic or not - true or false. Additional if a client forgot to catch the IllegalArgumentException, he will never get to know the reason.



                      If you want to make sure the client should get always the reason use not a RuntimeException, because they don't have to be checked.



                      A other way would to use an algebraic data type. The Either can be used to get a result or an error message.



                      Or just simply return false and the client has to find the reason:



                      class Permutation {

                      private int[] values;

                      public Permutation(int[] values) {
                      this.values = Objects.requireNonNull(values, "The argument is null.");
                      }

                      public boolean isCyclic() {
                      if (isEmpty()
                      && areAllElementsAreNotWithinBounds()
                      && isOccurrenceOfAllElementsMoreThanOnce())
                      return false;

                      // ..

                      return visitedNumbers == values.length;
                      }

                      public boolean isEmpty() {* ... *}

                      public boolean areAllElementsAreNotWithinBounds() {* ... *}

                      public boolean isOccurrenceOfAllElementsMoreThanOnce() {* ... *}

                      }


                      public static void main(String[] args) {
                      Permutation permutation = new Permutation(new int[] {1, 2, 3, 0});

                      if (permutation.isCyclic())
                      System.out.println("nice");
                      else {
                      if (!permutation.areAllElementsWithinBounds())
                      System.out.println("not all elements are in bound");
                      // ..
                      }
                      }






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 1 min ago

























                      answered 13 mins ago









                      RomanRoman

                      671214




                      671214












                      • $begingroup$
                        There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                        $endgroup$
                        – Martin R
                        7 mins ago










                      • $begingroup$
                        @MartinR psst.. Already fixed it. Thanks
                        $endgroup$
                        – Roman
                        5 mins ago










                      • $begingroup$
                        Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                        $endgroup$
                        – Martin R
                        4 mins ago


















                      • $begingroup$
                        There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                        $endgroup$
                        – Martin R
                        7 mins ago










                      • $begingroup$
                        @MartinR psst.. Already fixed it. Thanks
                        $endgroup$
                        – Roman
                        5 mins ago










                      • $begingroup$
                        Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                        $endgroup$
                        – Martin R
                        4 mins ago
















                      $begingroup$
                      There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                      $endgroup$
                      – Martin R
                      7 mins ago




                      $begingroup$
                      There seems to be some negation missing in your last isCyclic() function: It returns false if the array represents a valid permutation.
                      $endgroup$
                      – Martin R
                      7 mins ago












                      $begingroup$
                      @MartinR psst.. Already fixed it. Thanks
                      $endgroup$
                      – Roman
                      5 mins ago




                      $begingroup$
                      @MartinR psst.. Already fixed it. Thanks
                      $endgroup$
                      – Roman
                      5 mins ago












                      $begingroup$
                      Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                      $endgroup$
                      – Martin R
                      4 mins ago




                      $begingroup$
                      Check again: Unless I am mistaken, it still says if (array is valid) { return false }
                      $endgroup$
                      – Martin R
                      4 mins ago











                      1












                      $begingroup$

                      I would prefer checkArrayValidity over the generic check and PermutationCyclicityChecker checker over PermutationCyclicity as the class implements functionality, not state.



                      Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).






                      share|improve this answer









                      $endgroup$


















                        1












                        $begingroup$

                        I would prefer checkArrayValidity over the generic check and PermutationCyclicityChecker checker over PermutationCyclicity as the class implements functionality, not state.



                        Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).






                        share|improve this answer









                        $endgroup$
















                          1












                          1








                          1





                          $begingroup$

                          I would prefer checkArrayValidity over the generic check and PermutationCyclicityChecker checker over PermutationCyclicity as the class implements functionality, not state.



                          Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).






                          share|improve this answer









                          $endgroup$



                          I would prefer checkArrayValidity over the generic check and PermutationCyclicityChecker checker over PermutationCyclicity as the class implements functionality, not state.



                          Maybe move exception message formatting to dedicated exception classes and unify the message format in all cases (one provides indexes where error occurs, the other just the offending value).







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 21 mins ago









                          TorbenPutkonenTorbenPutkonen

                          21117




                          21117






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Code Review Stack Exchange!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              Use MathJax to format equations. MathJax reference.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214013%2fchecking-if-an-integer-permutation-is-cyclic-in-java%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Szabolcs (Ungheria) Altri progetti | Menu di navigazione48°10′14.56″N 21°29′33.14″E /...

                              Discografia di Klaus Schulze Indice Album in studio | Album dal vivo | Singoli | Antologie | Colonne...

                              How to make inet_server_addr() return localhost in spite of ::1/128RETURN NEXT in Postgres FunctionConnect to...