Custom shuffle algorithm












0















I know there is an efficient shuffling algorithm called Fisher Yates I believe but I try to build a custom one (out of stubbornness).



I am trying to generate a new random number in the right range, than use it to determine a new random place in a copied array. And then store this random number to NOT use it twice.
My method does not work. Would someone care to give me some enlightment?



public int shuffled(int numbers) {
int rand;
int copyNumbers = new int[numbers.length];
int usedRand = new int[numbers.length];


for (int i = 0; i < numbers.length; i++) {
rand = new Random().nextInt(numbers.length + 1);
if ((i != rand) && (usedRand[i]!=rand)) {
copyNumbers[rand] = numbers[i];
usedRand[i]=rand;
}
}
numbers = copyNumbers;
return numbers;
}









share|improve this question

























  • What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

    – dnsiv
    Nov 21 '18 at 10:08











  • I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

    – Dovendyr
    Nov 21 '18 at 10:29






  • 1





    Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

    – dnsiv
    Nov 21 '18 at 10:50











  • The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

    – dnsiv
    Nov 21 '18 at 10:52


















0















I know there is an efficient shuffling algorithm called Fisher Yates I believe but I try to build a custom one (out of stubbornness).



I am trying to generate a new random number in the right range, than use it to determine a new random place in a copied array. And then store this random number to NOT use it twice.
My method does not work. Would someone care to give me some enlightment?



public int shuffled(int numbers) {
int rand;
int copyNumbers = new int[numbers.length];
int usedRand = new int[numbers.length];


for (int i = 0; i < numbers.length; i++) {
rand = new Random().nextInt(numbers.length + 1);
if ((i != rand) && (usedRand[i]!=rand)) {
copyNumbers[rand] = numbers[i];
usedRand[i]=rand;
}
}
numbers = copyNumbers;
return numbers;
}









share|improve this question

























  • What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

    – dnsiv
    Nov 21 '18 at 10:08











  • I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

    – Dovendyr
    Nov 21 '18 at 10:29






  • 1





    Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

    – dnsiv
    Nov 21 '18 at 10:50











  • The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

    – dnsiv
    Nov 21 '18 at 10:52
















0












0








0








I know there is an efficient shuffling algorithm called Fisher Yates I believe but I try to build a custom one (out of stubbornness).



I am trying to generate a new random number in the right range, than use it to determine a new random place in a copied array. And then store this random number to NOT use it twice.
My method does not work. Would someone care to give me some enlightment?



public int shuffled(int numbers) {
int rand;
int copyNumbers = new int[numbers.length];
int usedRand = new int[numbers.length];


for (int i = 0; i < numbers.length; i++) {
rand = new Random().nextInt(numbers.length + 1);
if ((i != rand) && (usedRand[i]!=rand)) {
copyNumbers[rand] = numbers[i];
usedRand[i]=rand;
}
}
numbers = copyNumbers;
return numbers;
}









share|improve this question
















I know there is an efficient shuffling algorithm called Fisher Yates I believe but I try to build a custom one (out of stubbornness).



I am trying to generate a new random number in the right range, than use it to determine a new random place in a copied array. And then store this random number to NOT use it twice.
My method does not work. Would someone care to give me some enlightment?



public int shuffled(int numbers) {
int rand;
int copyNumbers = new int[numbers.length];
int usedRand = new int[numbers.length];


for (int i = 0; i < numbers.length; i++) {
rand = new Random().nextInt(numbers.length + 1);
if ((i != rand) && (usedRand[i]!=rand)) {
copyNumbers[rand] = numbers[i];
usedRand[i]=rand;
}
}
numbers = copyNumbers;
return numbers;
}






arrays shuffle






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 4 '18 at 5:37









Cœur

19k9113155




19k9113155










asked Nov 21 '18 at 10:03









DovendyrDovendyr

52




52













  • What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

    – dnsiv
    Nov 21 '18 at 10:08











  • I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

    – Dovendyr
    Nov 21 '18 at 10:29






  • 1





    Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

    – dnsiv
    Nov 21 '18 at 10:50











  • The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

    – dnsiv
    Nov 21 '18 at 10:52





















  • What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

    – dnsiv
    Nov 21 '18 at 10:08











  • I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

    – Dovendyr
    Nov 21 '18 at 10:29






  • 1





    Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

    – dnsiv
    Nov 21 '18 at 10:50











  • The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

    – dnsiv
    Nov 21 '18 at 10:52



















What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

– dnsiv
Nov 21 '18 at 10:08





What does not work? even Random should follow a certain structure. If you really want to use a random value, you should mix in some real random variables, like time, date etc.

– dnsiv
Nov 21 '18 at 10:08













I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

– Dovendyr
Nov 21 '18 at 10:29





I don't get a properly shuffled array. This is a school project so they do not look that close if our shuffling is "real" random. But of course I take any avice.

– Dovendyr
Nov 21 '18 at 10:29




1




1





Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

– dnsiv
Nov 21 '18 at 10:50





Right now I see 2 possible errors. The first one is rand = new Random().nextInt(numbers.length+1); You need a random number from 0 to numbers.length-1, since arrays start with indexing at 0, but right now you will get a random number from 1 to numbers.length. You should get an IndexOutOfBoundsException this way.

– dnsiv
Nov 21 '18 at 10:50













The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

– dnsiv
Nov 21 '18 at 10:52







The second possible error lies in this phrase (usedRand[i] != rand). You're just comparing the current entry (i) in usedRand with the current random value, if that entry already used this random number. But this way, you wont be able to access one entry a second time. You need to create a second for loop, which iterates through all entries of usedRand and compares their values with the current random number

– dnsiv
Nov 21 '18 at 10:52














1 Answer
1






active

oldest

votes


















0














As I already pointed the errors out in the comments. Here is possible implementation of shuffle(). I commented the code based on my modifications.
If you happen to have questions, please feel free to ask!



public static void main(String args) {
//sample values
int numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

//First call of recursive function
int x = shuffled(numbers, null, null, false, 0);

//Print out values
for (int i = 0; i < x.length; i++) {
System.out.print(x[i] + "|");
}
}

public static int shuffled(int numbers, int usedRand, int copyNumbers, boolean newRandomValue, int current) {

//Initialisation
int rand = -1;
int start = 0;

//If function hasn't been called before, initialise.
if (usedRand == null) {
usedRand = new int[numbers.length];
Arrays.fill(usedRand, -1);
}
if (copyNumbers == null) {
copyNumbers = new int[numbers.length];
}

//If function has been called recursively, reassign the start-Integer for for-loop
if (newRandomValue) {
start = current;
}

//Iterate over numbers-array with <start> as start-index
for (int i = start; i < numbers.length; i++) {
/*
new Random().nextInt(numbers.length+1 ) gets a random number between 0 and numbers.length + 1
In our example, numbers.length+1 is 20. So we will get a random number between 0 and 20.
But we want to get random values between -1 and 19, so
new Random().nextInt(numbers.length+1 ) --> values between 0 to 20
rand = new Random().nextInt(numbers.length+1 ) -1 --> values between -1 to 19
*/
rand = new Random().nextInt(numbers.length+1 ) -1;

//Iterate through usedRand array and compare if current rand value has already been used yet.
for (int j = 0; j < usedRand.length; j++) {
if (usedRand[j] == rand) {
/*
If current rand value has already been used, recursively call shuffle again with the current index i
as new start-index
*/
return shuffled(numbers, usedRand, copyNumbers, true, i);
}
}
copyNumbers[rand] = numbers[i];
usedRand[i] = rand;
}
numbers = copyNumbers;
return numbers;
}





share|improve this answer























    Your Answer






    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: "1"
    };
    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: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    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%2fstackoverflow.com%2fquestions%2f53409543%2fcustom-shuffle-algorithm%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    As I already pointed the errors out in the comments. Here is possible implementation of shuffle(). I commented the code based on my modifications.
    If you happen to have questions, please feel free to ask!



    public static void main(String args) {
    //sample values
    int numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

    //First call of recursive function
    int x = shuffled(numbers, null, null, false, 0);

    //Print out values
    for (int i = 0; i < x.length; i++) {
    System.out.print(x[i] + "|");
    }
    }

    public static int shuffled(int numbers, int usedRand, int copyNumbers, boolean newRandomValue, int current) {

    //Initialisation
    int rand = -1;
    int start = 0;

    //If function hasn't been called before, initialise.
    if (usedRand == null) {
    usedRand = new int[numbers.length];
    Arrays.fill(usedRand, -1);
    }
    if (copyNumbers == null) {
    copyNumbers = new int[numbers.length];
    }

    //If function has been called recursively, reassign the start-Integer for for-loop
    if (newRandomValue) {
    start = current;
    }

    //Iterate over numbers-array with <start> as start-index
    for (int i = start; i < numbers.length; i++) {
    /*
    new Random().nextInt(numbers.length+1 ) gets a random number between 0 and numbers.length + 1
    In our example, numbers.length+1 is 20. So we will get a random number between 0 and 20.
    But we want to get random values between -1 and 19, so
    new Random().nextInt(numbers.length+1 ) --> values between 0 to 20
    rand = new Random().nextInt(numbers.length+1 ) -1 --> values between -1 to 19
    */
    rand = new Random().nextInt(numbers.length+1 ) -1;

    //Iterate through usedRand array and compare if current rand value has already been used yet.
    for (int j = 0; j < usedRand.length; j++) {
    if (usedRand[j] == rand) {
    /*
    If current rand value has already been used, recursively call shuffle again with the current index i
    as new start-index
    */
    return shuffled(numbers, usedRand, copyNumbers, true, i);
    }
    }
    copyNumbers[rand] = numbers[i];
    usedRand[i] = rand;
    }
    numbers = copyNumbers;
    return numbers;
    }





    share|improve this answer




























      0














      As I already pointed the errors out in the comments. Here is possible implementation of shuffle(). I commented the code based on my modifications.
      If you happen to have questions, please feel free to ask!



      public static void main(String args) {
      //sample values
      int numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

      //First call of recursive function
      int x = shuffled(numbers, null, null, false, 0);

      //Print out values
      for (int i = 0; i < x.length; i++) {
      System.out.print(x[i] + "|");
      }
      }

      public static int shuffled(int numbers, int usedRand, int copyNumbers, boolean newRandomValue, int current) {

      //Initialisation
      int rand = -1;
      int start = 0;

      //If function hasn't been called before, initialise.
      if (usedRand == null) {
      usedRand = new int[numbers.length];
      Arrays.fill(usedRand, -1);
      }
      if (copyNumbers == null) {
      copyNumbers = new int[numbers.length];
      }

      //If function has been called recursively, reassign the start-Integer for for-loop
      if (newRandomValue) {
      start = current;
      }

      //Iterate over numbers-array with <start> as start-index
      for (int i = start; i < numbers.length; i++) {
      /*
      new Random().nextInt(numbers.length+1 ) gets a random number between 0 and numbers.length + 1
      In our example, numbers.length+1 is 20. So we will get a random number between 0 and 20.
      But we want to get random values between -1 and 19, so
      new Random().nextInt(numbers.length+1 ) --> values between 0 to 20
      rand = new Random().nextInt(numbers.length+1 ) -1 --> values between -1 to 19
      */
      rand = new Random().nextInt(numbers.length+1 ) -1;

      //Iterate through usedRand array and compare if current rand value has already been used yet.
      for (int j = 0; j < usedRand.length; j++) {
      if (usedRand[j] == rand) {
      /*
      If current rand value has already been used, recursively call shuffle again with the current index i
      as new start-index
      */
      return shuffled(numbers, usedRand, copyNumbers, true, i);
      }
      }
      copyNumbers[rand] = numbers[i];
      usedRand[i] = rand;
      }
      numbers = copyNumbers;
      return numbers;
      }





      share|improve this answer


























        0












        0








        0







        As I already pointed the errors out in the comments. Here is possible implementation of shuffle(). I commented the code based on my modifications.
        If you happen to have questions, please feel free to ask!



        public static void main(String args) {
        //sample values
        int numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

        //First call of recursive function
        int x = shuffled(numbers, null, null, false, 0);

        //Print out values
        for (int i = 0; i < x.length; i++) {
        System.out.print(x[i] + "|");
        }
        }

        public static int shuffled(int numbers, int usedRand, int copyNumbers, boolean newRandomValue, int current) {

        //Initialisation
        int rand = -1;
        int start = 0;

        //If function hasn't been called before, initialise.
        if (usedRand == null) {
        usedRand = new int[numbers.length];
        Arrays.fill(usedRand, -1);
        }
        if (copyNumbers == null) {
        copyNumbers = new int[numbers.length];
        }

        //If function has been called recursively, reassign the start-Integer for for-loop
        if (newRandomValue) {
        start = current;
        }

        //Iterate over numbers-array with <start> as start-index
        for (int i = start; i < numbers.length; i++) {
        /*
        new Random().nextInt(numbers.length+1 ) gets a random number between 0 and numbers.length + 1
        In our example, numbers.length+1 is 20. So we will get a random number between 0 and 20.
        But we want to get random values between -1 and 19, so
        new Random().nextInt(numbers.length+1 ) --> values between 0 to 20
        rand = new Random().nextInt(numbers.length+1 ) -1 --> values between -1 to 19
        */
        rand = new Random().nextInt(numbers.length+1 ) -1;

        //Iterate through usedRand array and compare if current rand value has already been used yet.
        for (int j = 0; j < usedRand.length; j++) {
        if (usedRand[j] == rand) {
        /*
        If current rand value has already been used, recursively call shuffle again with the current index i
        as new start-index
        */
        return shuffled(numbers, usedRand, copyNumbers, true, i);
        }
        }
        copyNumbers[rand] = numbers[i];
        usedRand[i] = rand;
        }
        numbers = copyNumbers;
        return numbers;
        }





        share|improve this answer













        As I already pointed the errors out in the comments. Here is possible implementation of shuffle(). I commented the code based on my modifications.
        If you happen to have questions, please feel free to ask!



        public static void main(String args) {
        //sample values
        int numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18};

        //First call of recursive function
        int x = shuffled(numbers, null, null, false, 0);

        //Print out values
        for (int i = 0; i < x.length; i++) {
        System.out.print(x[i] + "|");
        }
        }

        public static int shuffled(int numbers, int usedRand, int copyNumbers, boolean newRandomValue, int current) {

        //Initialisation
        int rand = -1;
        int start = 0;

        //If function hasn't been called before, initialise.
        if (usedRand == null) {
        usedRand = new int[numbers.length];
        Arrays.fill(usedRand, -1);
        }
        if (copyNumbers == null) {
        copyNumbers = new int[numbers.length];
        }

        //If function has been called recursively, reassign the start-Integer for for-loop
        if (newRandomValue) {
        start = current;
        }

        //Iterate over numbers-array with <start> as start-index
        for (int i = start; i < numbers.length; i++) {
        /*
        new Random().nextInt(numbers.length+1 ) gets a random number between 0 and numbers.length + 1
        In our example, numbers.length+1 is 20. So we will get a random number between 0 and 20.
        But we want to get random values between -1 and 19, so
        new Random().nextInt(numbers.length+1 ) --> values between 0 to 20
        rand = new Random().nextInt(numbers.length+1 ) -1 --> values between -1 to 19
        */
        rand = new Random().nextInt(numbers.length+1 ) -1;

        //Iterate through usedRand array and compare if current rand value has already been used yet.
        for (int j = 0; j < usedRand.length; j++) {
        if (usedRand[j] == rand) {
        /*
        If current rand value has already been used, recursively call shuffle again with the current index i
        as new start-index
        */
        return shuffled(numbers, usedRand, copyNumbers, true, i);
        }
        }
        copyNumbers[rand] = numbers[i];
        usedRand[i] = rand;
        }
        numbers = copyNumbers;
        return numbers;
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 11:35









        dnsivdnsiv

        347117




        347117
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • 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.


            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%2fstackoverflow.com%2fquestions%2f53409543%2fcustom-shuffle-algorithm%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

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)