Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

can this code be improved

Thread view: 
Print Guy - 17 Aug 2006 00:53 GMT
Hi all.

To most of you, what I have been working on is probably trivial and
easy, but it's taken me the good part of a week working 2 or 3 hrs a
day to finally figure out how to do what I needed to do.
Here in Canada, we have a lottery called 6-49.  You pick 6 numbers
between 1 and 49.  Those numbers are put on a ticket and there is a
draw twice a week.

I wanted to come up with a statistically solid way to pick my numbers
so I figured that if I were to pick 6 numbers 1,000,000 times and count
the number of times each number is selected, the top six would be good
numbers to bet on during the lottery.

With that being said, I thought I could write a Java program to do the
job.  It proved to be a bit more difficult than I thought it would be;
the hardest part being ensuring that each of the 6 numbers were unique.

Here is my code.  What I am hoping for is some constructive criticism
which could help me to make the code more efficient.

(Normally I would not comment my code so much, but I wanted you to see
what I was trying to accomplish)

package lotto;

import java.util.Arrays;
import java.util.Date;

import java.util.Random;

public class Sample {
    public static void main(String args[]) {
        Date today=new Date();
        System.out.println("Starting:" + today);
// the original array of 6 numbers picked
        int [] list = new int[6];
// the new array containing unique numbers only
        int[] newList = new int[6];
        int number = 0;
// this array is used to count the number of occurances (1-49)
        int [] BigList = new int[50];
// initialize BigList
        for ( int x=0;x<=BigList.length-1;x++)
            BigList[x]=0;
// do this whole thing a million times
        for (int y=1;y<=1000000;y++)    {
// initialize newList
            for (int t=0;t<=newList.length-1;t++)
                newList[t]=0;
// put 6 random numbers into an array
            for ( int z=0;z<6;z++) {
                Random rand = new Random() ;
                number=rand.nextInt(49) + 1;
                list[z]=number;
            }
            int count=0;
// what this loop does is check each member of "list" to see
// if it's a duplicate.  Copy the current element to the newList
// if it's not a duplicate.
            boolean dupLocated=false;
            for ( int b=0;b<=list.length-1;b++)
            {
                int chkNum=list[b];
                int temp = b;
                boolean found = false;
                for ( int a=0;a<=newList.length-1;a++)
                {
                    if ( newList[a] == chkNum)
                    {
                        found=true;
                        dupLocated=true;
                    }
                }
                if ( ! found )
                    newList[temp]=chkNum;
            }
// now that we have at least one duplicate, we need to replace
// the zero space holder with a new random number.  So
// to do that, we select a random number and then check to see
// if it is the array.  If it isn't then stick in in the list
otherwise, keep
// selecting and checking until we can put it in (usually takes one or
two
// iterations
            if ( dupLocated )
            {
                for (int x=0;x<=newList.length-1;x++)
                    if ( newList[x] == 0 )
                    {
                        boolean t=false;
                        while ( !t )
                        {
                            Random rand = new Random() ;
                            int number1=rand.nextInt(49) + 1;
                            int tt = 0;
                            for (int r=0;r<=newList.length-1;r++)
                                if ( newList[r] != 0 )
                                    if ( newList[r] == number1 )
                                        tt++;
                            if ( tt == 0 )
                            {
                                newList[x]=number1;
                                t=true;
                            }
                        }
                    }
            }
// so now we have a list of 6 unique numbers.  and we need to increment
// the value in BigList that corresponds to each of the six numbers.
            for (int j=0;j<=list.length-1;j++)
            {
                int idx=list[j];
                BigList[idx]++;
            }

        }
// now find the top six and create a new array called topSix
        int [] topSix = new int[6];
        for (int count=0;count<=topSix.length-1;count++)
        {
            int lIndex=0;
            int largest=BigList[0];
// compare each element of BigList with each "other" element
// of BigList (I created this algorithm on my own, or maybe I rememered
// it from somewhere.
            for (int x=0;x<=BigList.length-1;x++)
            {
                for ( int y=x+1;y<=BigList.length-2;y++)
                    if ( BigList[y] > largest )
                    {
                        largest=BigList[y];
                        BigList[y]=0;
                        lIndex=y;
                        topSix[count]=lIndex;
                    }

            }
        }
// now print out the list of topSix
        for (int i=0;i<=topSix.length-1;i++)
            System.out.println("Rank " + (i+1) + " number is " + topSix[i]);
        Date today2=new Date();
        System.out.println("Ending:" + today2);
    }
}

------------------------------------------------------------------------------
Sample output

Starting:Wed Aug 16 20:51:49 ADT 2006
Rank 1 number is 43
Rank 2 number is 48
Rank 3 number is 29
Rank 4 number is 30
Rank 5 number is 35
Rank 6 number is 46
Ending:Wed Aug 16 20:52:04 ADT 2006

15 seconds isn't too bad... but maybe it could be faster?
Andrew Thompson - 17 Aug 2006 01:05 GMT
> Hi all.
>
[quoted text clipped - 9 lines]
> the number of times each number is selected, the top six would be good
> numbers to bet on during the lottery.

I am no statistician, so this is more a question than a strategy,
but woul it not be just as valid to have a Vector of
'number of values in lottery' and simply remove any number
that comes up?

E.G.  start with a vector of 49 elements, if '35' is first
chosen, remove that element and choose randomly
from the the remaining 48 elements.

> public class Sample {
>     public static void main(String args[]) {
>         Date today=new Date();

And please change 'tab's to a couple of spaces before posting,
that line is this wide...
                              Date today=new Date();
..in my 'news client'.

Andrew T.
Print Guy - 17 Aug 2006 01:22 GMT
> > Hi all.
> >
[quoted text clipped - 29 lines]
>
> Andrew T.

Sorry man... eclipse did the "indentation"  all I did was copy and
paste into google.groups

Yeah.. the vector idea sounds good except that I haven't gotten that
far in my self-education process... I wanted to see if  I could
accomplish my goal with the tools and knowledge I currently have....
but... I like your idea and as soon as I get that far in my learning
process I will try to write something..
Stefan Ram - 17 Aug 2006 01:33 GMT
>Here in Canada, we have a lottery called 6-49.

 No, this lottery in fact is located here in Germany, and it's
 called "6 aus 49".

>I wanted to come up with a statistically solid way to pick my
>numbers so I figured that if I were to pick 6 numbers 1,000,000
>times and count the number of times each number is selected,
>the top six would be good numbers to bet on during the lottery.

 Actually the numbers are best, which are most rarely chosen
 by other players, because then the rates will be higher.

>Here is my code.  What I am hoping for is some constructive criticism
>which could help me to make the code more efficient.

 Destructive criticism is much more fun!

>Rank 1 number is 43

class NumericMapUtils
{ public static <D> void addTo
 ( final java.util.Map<D,java.lang.Integer> map, final D d, final int i )
 { map.put( d, i +( map.containsKey( d )? map.get( d ): 0 )); }}

public class Main
{ static final java.util.Random rand = new java.util.Random();
 public static void main( java.lang.String[] args )
 { final java.util.Map<java.lang.Integer,java.lang.Integer> map
   = new java.util.HashMap<java.lang.Integer,java.lang.Integer>( 50 );
   for( int i = 0; i < 1000; ++i )
   NumericMapUtils.<java.lang.Integer>addTo( map, rand.nextInt( 49 ), 1 );
   final java.util.SortedMap<java.lang.Integer,java.lang.Integer> sort
   = new java.util.TreeMap<java.lang.Integer,java.lang.Integer>();
   for( final java.lang.Integer i : map.keySet() )sort.put( -map.get( i ), i );
   int c = 0; for( final int i : sort.keySet() )
   { java.lang.System.out.println
     ( "Rank " +( c + 1 )+ " number is " + sort.get( i ));
     if( ++c >= 6 )break; }}}

Rank 1 number is 21
Rank 2 number is 14
Rank 3 number is 34
Rank 4 number is 15
Rank 5 number is 47
Rank 6 number is 20

 However, there is a small chance that »nextInt« will return
 the same number for 1000 times, so that the program would only
 output one number; but I tried to implement your general
 description.
Stefan Ram - 17 Aug 2006 02:10 GMT
>sort.put( -map.get( i ), i );

 This attempt to "invert" a map still has a bug: If two keys of
 the original map have the same value, one of them will be
 lost. The following solution uses a small "bias" added to
 each value, to make it different from every other value.
 (It might fail under some conditions.)

class NumericMapUtils
{ public static <D> void addTo
 ( final java.util.Map<D,java.lang.Integer> map, final D d, final int i )
 { map.put( d, i +( map.containsKey( d )? map.get( d ): 0 )); }}

public class Main
{ static final java.util.Random rand = new java.util.Random();
 public static void main( java.lang.String[] args )
 { final java.util.Map<java.lang.Integer,java.lang.Integer> map
   = new java.util.HashMap<java.lang.Integer,java.lang.Integer>( 50 );
   final int k = 1000; for( int i = 0; i < k; ++i )
   NumericMapUtils.<java.lang.Integer>addTo( map, rand.nextInt( 49 ), 1 );
   final java.util.SortedMap<java.lang.Double,java.lang.Integer> sort
   = new java.util.TreeMap<java.lang.Double,java.lang.Integer>();
   int j = 0; for( final java.lang.Integer i : map.keySet() )
   sort.put( -map.get( i )+ j++ * .8 / k, i );
   int c = 0; for( final java.lang.Double d : sort.keySet() )
   { java.lang.System.out.println
     ( "Rank " +( c + 1 )+ " number is " + sort.get( d ));
     if( ++c >= 6 )break; }}}

 A more clean solution might replace each key of the map
 "sort" by a ComparablePair of both the key and its value.

 I even have implemented such a beast

http://www.purl.org/stefan_ram/html/ram.jar/de/dclj/ram/type/pair/ComparablePair.html
Luke Webber - 17 Aug 2006 02:12 GMT
> Hi all.
>
[quoted text clipped - 19 lines]
> (Normally I would not comment my code so much, but I wanted you to see
> what I was trying to accomplish)
[snip]

If you're asking this just as a Java question, then there are certainly
things you can do to improve on it. But I have to point out that you're
not modelling the real world here. You'll mostly be testing for bias in
the Java random number generator, when you should really be testing for
bias in whatever process/equipment the lottery agency is using.

If they keep historical records for downloading (as our Australian
agency does), you'd be better served to download that and massage it.

Cheers,
Luke
Patricia Shanahan - 17 Aug 2006 06:15 GMT
> Hi all.
>
[quoted text clipped - 9 lines]
> the number of times each number is selected, the top six would be good
> numbers to bet on during the lottery.

You are assuming that any bias in the Java Random class also applies to
the lottery's random number generation method? I suspect it is using
genuinely random numbers, not just pseudo-random, and monitors them for
bias.

> With that being said, I thought I could write a Java program to do the
> job.  It proved to be a bit more difficult than I thought it would be;
> the hardest part being ensuring that each of the 6 numbers were unique.

Here is an alternative method for picking the 6 numbers.

There is a well-known linear time algorithm for shuffling an array, the
Fisher-Yates shuffle. On iteration i, the element with index i is
swapped with a randomly selected element between i and the end of the array.

There are two important loop invariants:

1. At the end of every iteration, the array contains a permutation
of its original contents.

2. After N iterations, the first N elements of the array are randomly
selected with equal probability.

In a normal shuffle, the number of iterations is equal to the size of
the array minus one, and all elements have been shuffled. (The last
iteration is not needed because it makes a random choice from one
element, and swaps that element with itself).

Why not run Fisher-Yates for 6 iterations, and then pick up the
first 6 elements of the array?

Patricia

  /**
   * Partially shuffle the elements of an int
   * array
   *
   * On completion, data contains a permutation of
   * its original contents, with the elements in
   * the first count spaces selected randomly.
   * There is no assurance of randomness for
   * elements data[count] and later, and many of
   * those elements may remain in their original
   * positions.
   *
   * @param data
   *          The array
   * @param count
   *          The number of elements to shuffle.
   *          If count is negative or greater than
   *          data.length, all elements are
   *          shuffled.
   * @param rand
   *          partialShuffle gets its random
   *          numbers from this generator.
   */
  public static void partialShuffle(int[] data, int count,
      Random rand) {
    if (count > data.length || count < 0) {
      count = data.length;
    }
    for (int i = 0; i < count; i++) {
      int pickIndex = rand.nextInt(data.length - i) + i;
      int temp = data[pickIndex];
      data[pickIndex] = data[i];
      data[i] = temp;
    }
  }
Daniel Dyer - 18 Aug 2006 01:32 GMT
> Why not run Fisher-Yates for 6 iterations, and then pick up the
> first 6 elements of the array?

OK, but if you are going to generate 6 random numbers between 1 and 49 in  
order to decide which elements to swap, why not just use those random  
numbers as your selected lottery numbers?

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Patricia Shanahan - 18 Aug 2006 03:21 GMT
>> Why not run Fisher-Yates for 6 iterations, and then pick up the
>> first 6 elements of the array?
>
> OK, but if you are going to generate 6 random numbers between 1 and 49
> in order to decide which elements to swap, why not just use those random
> numbers as your selected lottery numbers?

Because they may contain duplicates, and the OP wants unique numbers.

Patricia
Daniel Dyer - 18 Aug 2006 09:23 GMT
>>> Why not run Fisher-Yates for 6 iterations, and then pick up the
>>> first 6 elements of the array?
[quoted text clipped - 3 lines]
>
> Because they may contain duplicates, and the OP wants unique numbers.

Of course.  I guessed you'd have a good reason, thanks.

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

bugbear - 17 Aug 2006 10:04 GMT
> Hi all.
>
[quoted text clipped - 6 lines]
>
> I wanted to come up with a statistically solid way to pick my numbers

This requires analysis, not code.

  BugBear
AndrewMcDonagh - 17 Aug 2006 20:07 GMT
> Hi all.
>
[quoted text clipped - 16 lines]
> Here is my code.  What I am hoping for is some constructive criticism
> which could help me to make the code more efficient.

 snipped

ok, to be brutal - you have created a Procedural solution not an Object
Oriented solution.  Given that Java is aimed at being an OO language
(lets not get into an argument about what that is nor Java's flaws) it
would be good to see the solution using the tools and techniques from an
OO perspective.

That said, even if we stick with a procedural solution your current one
needs a lot of work to improve its readability (never mind logic changes
to remove unneeded loops, conditions or state)

HTH

Andrew...........

A simple starting point would be to turn comments into executable comments.

For example,

 // the original array of 6 numbers picked
 int [] list = new int[6];
 // the new array containing unique numbers only
 int[] newList = new int[6];
 // this array is used to count the number of occurances (1-49)
 int [] BigList = new int[50];

becomes something like...

 int [] originalPickedNumbers = new int[6];
 int [] uniqueNumbers = new int[6];
 int [] numberOfOccurancesCount = new int[50];

Another example would be for each of those comments blocks to become
method names and move the code they refer to, into these new methods.

for example....

public class Sample {

  public static void main(String args[]) {
    Date today = new Date();
    System.out.println("Starting:" + today);

    //the original array of 6 numbers picked
    int[] list = new int[6];
    //the new array containing unique numbers only
    int[] newList = new int[6];
    int number = 0;
    //this array is used to count the number of occurances (1-49)
    int[] BigList = new int[50];

    initializeBigList(BigList);
    //do this whole thing a million times
    for (int y = 1; y <= 1000000; y++) {
      initializeNewList(newList);
      put6RandomNumbersIntoAnArray(list);
      boolean dupLocated = copyAllUniqueNumbersIntoNewList(list, newList);

      if (dupLocated) {
        replaceAnyZeroSpaceHolderWithRandomNumber(newList);
      }

      incrementBigListValuesThatMatchEachOfTheSixNumbers(list, BigList);
    }

    int[] topSix = createNewListContainingOnlyTopSix(BigList);
    printListOfTopSix(topSix);
  }

  private static void printListOfTopSix(int[] topSix) {
    //now print out the list of topSix
    for (int i = 0; i <= topSix.length - 1; i++)
      System.out.println("Rank " + (i + 1) + " number is " + topSix[i]);
    Date today2 = new Date();
    System.out.println("Ending:" + today2);
  }

  private static int[] createNewListContainingOnlyTopSix(int[] BigList) {
    //now find the top six and create a new array called topSix
    int[] topSix = new int[6];
    for (int count = 0; count <= topSix.length - 1; count++) {
      int lIndex = 0;
      int largest = BigList[0];
      //compare each element of BigList with each "other" element
      //of BigList (I created this algorithm on my own, or maybe I
rememered
      //it from somewhere.
      for (int x = 0; x <= BigList.length - 1; x++) {
        for (int y = x + 1; y <= BigList.length - 2; y++)
          if (BigList[y] > largest) {
            largest = BigList[y];
            BigList[y] = 0;
            lIndex = y;
            topSix[count] = lIndex;
          }

      }
    }
    return topSix;
  }

  private static void
incrementBigListValuesThatMatchEachOfTheSixNumbers(int[] list, int[]
BigList) {
    //so now we have a list of 6 unique numbers. and we need to increment
    //the value in BigList that corresponds to each of the six numbers.
    for (int j = 0; j <= list.length - 1; j++) {
      int idx = list[j];
      BigList[idx]++;
    }
  }

  private static void replaceAnyZeroSpaceHolderWithRandomNumber(int[]
newList) {
    //now that we have at least one duplicate, we need to replace
    //the zero space holder with a new random number. So
    //to do that, we select a random number and then check to see
    //if it is the array. If it isn't then stick in in the list
    //otherwise, keep
    //selecting and checking until we can put it in (usually takes one
ortwo
    //iterations
    for (int x = 0; x <= newList.length - 1; x++)
      if (newList[x] == 0) {
        boolean t = false;
        while (!t) {
          Random rand = new Random();
          int number1 = rand.nextInt(49) + 1;
          int tt = 0;
          for (int r = 0; r <= newList.length - 1; r++)
            if (newList[r] != 0)
              if (newList[r] == number1)
                tt++;
          if (tt == 0) {
            newList[x] = number1;
            t = true;
          }
        }
      }
  }

  private static boolean copyAllUniqueNumbersIntoNewList(int[] list,
int[] newList) {
    //what this loop does is check each member of "list" to see
    //if it's a duplicate. Copy the current element to the newList
    //if it's not a duplicate.
    boolean dupLocated = false;
    for (int b = 0; b <= list.length - 1; b++) {
      int chkNum = list[b];
      int temp = b;
      boolean found = false;
      for (int a = 0; a <= newList.length - 1; a++) {
        if (newList[a] == chkNum) {
          found = true;
          dupLocated = true;
        }
      }
      if (!found)
        newList[temp] = chkNum;
    }
    return dupLocated;
  }

  private static void put6RandomNumbersIntoAnArray(int[] list) {
    int number;
    //put 6 random numbers into an array
    for (int z = 0; z < 6; z++) {
      Random rand = new Random();
      number = rand.nextInt(49) + 1;
      list[z] = number;
    }
  }

  private static void initializeNewList(int[] newList) {
    //initialize newList
    for (int t = 0; t <= newList.length - 1; t++)
      newList[t] = 0;
  }

  private static void initializeBigList(int[] BigList) {
    //initialize BigList
    for (int x = 0; x <= BigList.length - 1; x++)
      BigList[x] = 0;
  }
}
Print Guy - 17 Aug 2006 21:44 GMT
> > Hi all.
> >
[quoted text clipped - 28 lines]
> needs a lot of work to improve its readability (never mind logic changes
> to remove unneeded loops, conditions or state)

Brutal is good.  My background is procedural languages even though I do
some scripting and attempt to employ a OO design technique.

What you are suggesting here is great.  What I am really hoping for is
the implementation of my solution using classes and methods for objects
like

class bigListElement
   int element;
   int count;

   void insert()
   void delete()
   void display()

But I thought that if I started out using the stuff I knew about I
would eventually be able to refine my design to the point where it was
a true Object Oriented program, not a Java translation of a Cobol
program :-)

Thanks muchly for your help.... you and Patricia have given me alot to
think about.
AndrewMcDonagh - 17 Aug 2006 23:03 GMT
>>> Hi all.
>>>
[quoted text clipped - 34 lines]
> the implementation of my solution using classes and methods for objects
> like

Now that you have the first refactored version of your code, you can
start to look for duplication*.

Removing the duplication will create abstractions or behavior styled
methods. Once you have a number of these you should easily see that
there are logical groupings of the methods.

Once you see these groupings you can refactor further, by moving them
into their own class.

*duplication is not just code duplication - its also behavior or
algorithm duplication.

A quick review of the current design shows a number of Loops on lists,
doing something specific.

Each loop logic is the same.  Its the specifics that different.  These
specifics could either be extracted into a new class or the loop logic
called many times with different parameters for the loop to work on

for example...

we currently have.....

  private static void initializeNewList(int[] newList) {
    //initialize newList
    for (int t = 0; t <= newList.length - 1; t++)
      newList[t] = 0;
  }

  private static void initializeBigList(int[] BigList) {
    //initialize BigList
    for (int x = 0; x <= BigList.length - 1; x++)
      BigList[x] = 0;
  }

The duplication is obvious now we have these two methods.
And you should see that the only difference is the array being used.

so if we renamed one of the two methods above to 'initializeList(...)

we could simply call the same method twice, once with 'newList' and
another time with 'bigList'

as in....

 public static void main(String args[]) {
    Date today = new Date();
    System.out.println("Starting:" + today);
    //the original array of 6 numbers picked
    int[] list = new int[6];
    //the new array containing unique numbers only
    int[] newList = new int[6];
    int number = 0;
    //this array is used to count the number of occurances (1-49)
    int[] BigList = new int[50];

    initializeList(BigList);

    for (int y = 1; y <= 1000000; y++) {
      initializeList(newList);

    // snipped remaining...   
  }

  private static void initializeList(int[] list) {
    for (int x = 0; x <= list.length - 1; x++)
      list[x] = 0;
  }

> class bigListElement
>     int element;
[quoted text clipped - 8 lines]
> a true Object Oriented program, not a Java translation of a Cobol
> program :-)

Thats fine, but do keep in mind that its not a problem doing a
procedural approach per se.

The main problem comes should you need to use the solution in a program
where two different implementations of the Sample class could be chosen.

In other words, static functions don't support polymorphism, so a
program would not be able to accept/call a different version at runtime.

With your example, just moving the entire body of the 'main()' method
into an 'instance' method would allow the start of polymorphism to be
possible.

e.g.

class SampleRunner {

  public void main(String[] args) {

    Sample sample = new Sample();
    sample.prinoutTopSixRandomNumbers();
  }

}

class Sample {

  public void printoutTopSixRandomNumbers() {
    // insert code from your main() method here....
  }

}

> Thanks muchly for your help.... you and Patricia have given me alot to
> think about.

np - glad to help...
Luke Webber - 17 Aug 2006 22:27 GMT
[snip]
> A simple starting point would be to turn comments into executable comments.
>
[quoted text clipped - 12 lines]
>  int [] uniqueNumbers = new int[6];
>  int [] numberOfOccurancesCount = new int[50];

Say what? Let's skip the spelling mistake for a minute here and ask one
simple question. Why "numberOf" AND "Count"? I mean, I like meaningful
names, but I'd go insane trying to work with code like that.

[snip]
>   private static int[] createNewListContainingOnlyTopSix(int[] BigList) {
[snip]
>   private static void
> incrementBigListValuesThatMatchEachOfTheSixNumbers(int[] list, int[]
> BigList) {
[snip]
>   private static void replaceAnyZeroSpaceHolderWithRandomNumber(int[]
> newList) {
[snip]
>   private static boolean copyAllUniqueNumbersIntoNewList(int[] list,
> int[] newList) {
[snip]
>   private static void put6RandomNumbersIntoAnArray(int[] list) {

With the greatest respect, this is taking things WAY too far.

Luke
AndrewMcDonagh - 17 Aug 2006 22:42 GMT
> [snip]
>> A simple starting point would be to turn comments into executable
[quoted text clipped - 18 lines]
> simple question. Why "numberOf" AND "Count"? I mean, I like meaningful
> names, but I'd go insane trying to work with code like that.

I agree - but thats what the comments say the vars are ....

Once we rename them to be 'meaningful' i.e. get rid of the redundant
comment, we can start to look for other changes to the entire design.

The initial renaming is simply a starting point to make sure the usages
of the vars is more meaningful than 'list, biglist, newList'  who's
purpose is as clear as mud unless you constantly refer back to where
they are defined.

> [snip]
>>   private static int[] createNewListContainingOnlyTopSix(int[] BigList) {
[quoted text clipped - 10 lines]
> [snip]
>>   private static void put6RandomNumbersIntoAnArray(int[] list) {

> With the greatest respect, this is taking things WAY too far.

Why?  Because the method names are long?
I type them once and let Eclipse auto-complete from then on. Longer,
more descriptive names help reveal and have a better chance of staying
up to date than comments.

Besides, you missed the main part, its a starting point.

The aim of these small refactorings are not to keep the methods, but to
reveal the algorithm used by the main() method.

Now we can see what the algorithm is within a few lines of code. We
can't nor need to see the implementation of the algorithm.

Once we have this ability to see the algorithm we are better placed to
refactor it further or rewrite it entirely.

> Luke
Luke Webber - 18 Aug 2006 08:03 GMT
>>>  int [] originalPickedNumbers = new int[6];
>>>  int [] uniqueNumbers = new int[6];
[quoted text clipped - 5 lines]
>
> I agree - but thats what the comments say the vars are ....

So it's occurrenceCount or numOccurrences maybe, or even
numberOfOccurrences if you really must, but I'd prefer something a
little short, though still meaningful.

> Once we rename them to be 'meaningful' i.e. get rid of the redundant
> comment, we can start to look for other changes to the entire design.
[quoted text clipped - 3 lines]
> purpose is as clear as mud unless you constantly refer back to where
> they are defined.

True, no doubt. As we used to say in the "old days", "real programmers
can write FORTRAN in any language". <g>

>> [snip]
>>>   private static int[] createNewListContainingOnlyTopSix(int[]
[quoted text clipped - 16 lines]
> Why?  Because the method names are long?
> I type them once and let Eclipse auto-complete from then on.

Which doesn't work for variable names. And doesn't even work for methods
withing the current class unless you preface it with "this.", which is
still more typing. But it;s not just typing it in that concerns me. It's
/reading/ it as well. When the method names get that long, they actually
start to /lose/ meaning for me, because I kind of zone out on the
difference between "aReallyReallyLongNameThatGoesOnForever" and
"aReallyReallyLongNameThatGoesOnForeverAndADay". There is a happy middle
ground somewhere, where the names are meaningful, but not so long that
you have difficulty parsing them in your head.

For me, you don't have to be able to look at a method name and have it
tell you exactly what the method does. That's what documentation for. As
long as the method is sufficiently meaningful to give me a fairish idea
of its function, I'm frabjous.

> Longer,
> more descriptive names help reveal and have a better chance of staying
> up to date than comments.

And if you decide that you want to handle Powerball numbers and system 5
entries as well, then what? You have to change the method name AND ALL
CALLS TO IT, because it's no longer strictly six numbers?

And for that matter, why "IntoAnArray"? Your argument is an array, so
that tells the story right there.

> Besides, you missed the main part, its a starting point.

Ah, but when you tell a new programmer that "this is a starting point",
they're likely to take it even /further/, and you never know where he'll
end up <g>.

> The aim of these small refactorings are not to keep the methods, but to
> reveal the algorithm used by the main() method.
>
> Now we can see what the algorithm is within a few lines of code. We
> can't nor need to see the implementation of the algorithm.

That's what Javadoc is for, IMO. I'm pleased to note that there are no
examples if this level of verbosity in the standard libraries.

> Once we have this ability to see the algorithm we are better placed to
> refactor it further or rewrite it entirely.

Maybe. OTOH, as I've said before, once you start rewriting those
methods, you're going to have to change the names to reflect their new
function. But if they were at least slightly more generic, you wouldn't
need to.

Luke
Print Guy - 19 Aug 2006 01:14 GMT
So why are the result of your program so much differnent from the ones
by the responder from gmail.com

Starting:Fri Aug 18 21:07:14 ADT 2006
Rank 1 number is 44
Rank 2 number is 40
Rank 3 number is 48
Rank 4 number is 43
Rank 5 number is 47
Rank 6 number is 45
Ending:Fri Aug 18 21:07:28 ADT 2006

vs

[27, 28, 3, 19, 45, 15]

My (your) numbers were all in the 40's where the other ones were more
scattered.
Patricia Shanahan - 19 Aug 2006 04:01 GMT
> So why are the result of your program so much differnent from the ones
> by the responder from gmail.com
[quoted text clipped - 14 lines]
> My (your) numbers were all in the 40's where the other ones were more
> scattered.

Your method for finding the six most frequent numbers does not make
sense to me. Could you explain how it is supposed to work? Specifically,
why do you assign 0 to BigList[y] where you do? And why the three loops?

    // now find the top six and create a new array called topSix
    int[] topSix = new int[6];
    for (int count = 0; count <= topSix.length - 1; count++) {
      int lIndex = 0;
      int largest = BigList[0];
      // compare each element of BigList with each "other"
      // element
      // of BigList (I created this algorithm on my own, or maybe
      // I
      // rememered
      // it from somewhere.
      for (int x = 0; x <= BigList.length - 1; x++) {
        for (int y = x + 1; y <= BigList.length - 2; y++)
          if (BigList[y] > largest) {
            largest = BigList[y];
            BigList[y] = 0;
            lIndex = y;
            topSix[count] = lIndex;
          }

      }
    }

I would have done something like the following, except I've kept your
variable names to make the relationships clearer:

***** Warning! Warning! untested code ahead! ******

  int[] topSix = new int[6];
  for(int count = 0; count < topSix.length; count++){
    int lIndex = 0;
    int largest = BigList[0];
    for( int x = 1; x < BigList.length; x++){
      if(BigList[x] > largest){
        largest = BigList[x];
        lIndex = x;
      }
    }
    topSix[count] = lIndex;
    BigList[lIndex] = 0;
  }

only zeroing out a BigList element when I definitely commit to its index
being in the topSix.
Print Guy - 19 Aug 2006 20:52 GMT
> > So why are the result of your program so much differnent from the ones
> > by the responder from gmail.com
[quoted text clipped - 63 lines]
> only zeroing out a BigList element when I definitely commit to its index
> being in the topSix.

Well if each element of "BigList" contains the number of times it was
picked when I did 6 selections, 1 million times then
a)  I need the top six (outer most loop)
b)  I need to compare each number (inner loop number 1)
c)  with each other number (inner loop number 2)

Seems to me that topSix should now contain the top six picks but I
could be wrong..
Patricia Shanahan - 19 Aug 2006 22:08 GMT
>>> So why are the result of your program so much differnent from the ones
>>> by the responder from gmail.com
[quoted text clipped - 69 lines]
> b)  I need to compare each number (inner loop number 1)
> c)  with each other number (inner loop number 2)

Nope, you only need to compare each number to the best so far.

And you have not said why you zero out a value before you have committed
to putting its index in topSix.

> Seems to me that topSix should now contain the top six picks but I
> could be wrong..

Try separating it out into a method, and taking it for a test drive with
known data.

Patricia
Patricia Shanahan - 19 Aug 2006 23:12 GMT
...
> Seems to me that topSix should now contain the top six picks but I
> could be wrong..

I'm afraid you are wrong, and the apparent over-selection of the high
numbers is due to bugs in your top six selection.

I've written a simple test program comparing the two methods. Take a
look at it, and take it for a test drive:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class TopSixTest {

  public static void main(String[] args) {
    int[] data = new int[49];
    // Fixed seed for reproducibility
    Random rand = new Random(5);

    for (int i = 0; i < data.length; i++) {
      data[i] = 5;
    }
    System.out.println("data[i]==5");
    test(data);

    for (int i = 0; i < data.length; i++) {
      data[i] = i + 1;
    }
    System.out.println("data[i]==i+1");
    test(data);

    for (int i = 0; i < data.length; i++) {
      data[i] = 100 - i;
    }
    System.out.println("data[i]=100-i");
    test(data);

    testRandomData(rand);
    testRandomData(rand);
    testRandomData(rand);
  }

  /**
   * Test random permutation of numbers from 1000 through 1048
   *
   * @param rand
   */
  private static void testRandomData(Random rand) {
    int[] data = new int[49];
    List<Integer> dataList = new ArrayList<Integer>();
    for (int i = 0; i < data.length; i++) {
      dataList.add(new Integer(1000 + i));
    }
    Collections.shuffle(dataList, rand);
    for (int i = 0; i < data.length; i++) {
      data[i] = dataList.get(i).intValue();
    }
    System.out
        .println("Random permutation of 1000 through 1048");
    test(data);
    System.out.println("Actual positions of largest 6 elements");
    for (int i = 1048; i > 1042; i--) {
      System.out.printf("%d %d", i, dataList
          .indexOf(new Integer(i)));
      System.out.println();
    }
  }

  /**
   * Print the results of both methods on the input data
   *
   * @param data
   *          "BigList" data, a 49 element frequency array.
   */
  private static void test(int[] data) {
    int[] printsTop = printsVersion(data.clone());
    int[] patsTop = patsVersion(data.clone());
    for (int i = 0; i < 6; i++) {
      System.out.printf("%d Print's %d Pats's %d", i,
          printsTop[i], patsTop[i]);
      System.out.println();
    }
  }

  private static int[] printsVersion(int[] BigList) {
    int[] topSix = new int[6];
    for (int count = 0; count <= topSix.length - 1; count++) {
      int lIndex = 0;
      int largest = BigList[0];
      for (int x = 0; x <= BigList.length - 1; x++) {
        for (int y = x + 1; y <= BigList.length - 2; y++)
          if (BigList[y] > largest) {
            largest = BigList[y];
            BigList[y] = 0;
            lIndex = y;
            topSix[count] = lIndex;
          }

      }
    }
    return topSix;
  }

  private static int[] patsVersion(int[] BigList) {
    int[] topSix = new int[6];
    for (int count = 0; count < topSix.length; count++) {
      int lIndex = 0;
      int largest = BigList[0];
      for (int x = 1; x < BigList.length; x++) {
        if (BigList[x] > largest) {
          largest = BigList[x];
          lIndex = x;
        }
      }
      topSix[count] = lIndex;
      BigList[lIndex] = 0;
    }
    return topSix;
  }

}
Patricia Shanahan - 20 Aug 2006 04:13 GMT
> ...
>> Seems to me that topSix should now contain the top six picks but I
[quoted text clipped - 5 lines]
> I've written a simple test program comparing the two methods. Take a
> look at it, and take it for a test drive:
...
>   private static int[] patsVersion(int[] BigList) {
>     int[] topSix = new int[6];
[quoted text clipped - 9 lines]
>       topSix[count] = lIndex;
>       BigList[lIndex] = 0;

This line should be:

BigList[lIndex] = -1;

Zero is a possible count of the number of instances of a result. -1 is not.

>     }
>     return topSix;
>   }
>
> }
Daniel Dyer - 19 Aug 2006 20:01 GMT
> So why are the result of your program so much differnent from the ones
> by the responder from gmail.com
[quoted text clipped - 14 lines]
> My (your) numbers were all in the 40's where the other ones were more
> scattered.

While the first output does look suspicious, it could just be a freak  
occurrence.  Have you only run it once or does it favour high numbers over  
repeated runs?

This may not be the cause of the anomaly, but both programs make the  
mistake of creating a new Random object for each random number generated.  
You should only ever use one Random instance and instead make multiple  
calls to it.  Not only is it more efficient this way, it will avoid  
potential problems with the seeds of the instances being the same or very  
similar when they are used to generate only one number before being  
discarded.

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

jgrabell@gmail.com - 17 Aug 2006 23:49 GMT
import java.util.ArrayList;
import java.util.Random;
public class SixFourNine {
   ArrayList winningNumbers = null;
   public static int NUM_CHOICES = 6;
   public static int MAX_NUMBER = 49;
   int[][] simulationArray = new int[MAX_NUMBER][2];
   /** creates a new SixFourNine object**/
   public SixFourNine() {
       initializeSimulationArray();
   }
   /** initializes the array for storing the simulation **/
   public void initializeSimulationArray() {
       for (int i=0; i <MAX_NUMBER; i++) {
           simulationArray[i][0] = (i+1);
           simulationArray[i][1] = 0;
       }
   }
   /** default simulation -- 1 million trials **/
   public void runSimulation() {
       runSimulation(1000000);
   }
   /** simulation -- specify # trials **/
   public void runSimulation(int numTrials) {
       if (numTrials <= 0 ) return;
       Random rand = null;
       int number = 0;
       for (int i = 0; i < numTrials; i++ ){
           rand = new Random() ;
           number=rand.nextInt(MAX_NUMBER) + 1;
           simulationArray[number-1][1]++;
       }
   }
   /** get the winning numbers.  throws an exception if you have not
run a simulation **/
   public ArrayList getWinningNumbers() throws
SixFourNineSimulationNotRunException {
       if (simulationArray == null) throw new
SixFourNineSimulationNotRunException();
       winningNumbers = new ArrayList();
       for (int i = 0; i < NUM_CHOICES; i++) {
           Integer r = new Integer(findAndRemoveMax());
           winningNumbers.add(r);
       }
       initializeSimulationArray();
       return winningNumbers /*NOT A GUARANTEE*/;
   }
   /** finds the most picked number from the simulations, in the case
of a tie, largest number (index) wins **/
   private int findAndRemoveMax() {
       int max = 0;
       int count = 0;
       for (int i = 0; i < MAX_NUMBER; i++) {
           if (simulationArray[i][1] > count) {
               count = simulationArray[i][1] ;
               max = i;
           }
       }
       simulationArray[max][1] =0;
       return max+1;
   }
   /** program main **/
   public static void main(String[] args) {
       SixFourNine sfn = new SixFourNine();
       sfn.runSimulation(1000000);
       try {
           System.out.println(sfn.getWinningNumbers());
       } catch (SixFourNineSimulationNotRunException sfnnre) { // this
cannot happen in this example but we must catch;
           System.out.println("Sorry, there was a problem; you need to
run a simulation before you can guess the winning numbers!");
           System.exit(42);
       }
       System.exit(0);
   }
   public class SixFourNineSimulationNotRunException extends Exception
{};
}
Daniel Dyer - 18 Aug 2006 01:14 GMT
> Hi all.
>
[quoted text clipped - 9 lines]
> the number of times each number is selected, the top six would be good
> numbers to bet on during the lottery.

How do you mean "statistically solid"?  Unless you know of some flaw in  
the machine that picks the numbers, any set of six numbers is equally  
likely to come up as any other.  You may as well pick 1, 2, 3, 4, 5 and 6  
and be done with it.  Unless, as Stefan suggested, you want to maximise  
your winnings if you ever hit the jackpot, in which case you need data  
about how often each number is selected by other players.  In the absence  
of any hard data, I would guess that picking high numbers is the way to go  
as many people pick numbers that correspond to dates (birthdays,  
anniversaries etc.), which are all in the range 1-31.

> With that being said, I thought I could write a Java program to do the
> job.  It proved to be a bit more difficult than I thought it would be;
> the hardest part being ensuring that each of the 6 numbers were unique.

java.util.Random is not very good at generating statistically random  
numbers.  See Roedy Green's page  
(http://mindprod.com/jgloss/pseudorandom.html) for more details.  An  
improvement would be to use the SecureRandom class, which has a better  
distribution but is a bit slower.

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Print Guy - 18 Aug 2006 20:06 GMT
> How do you mean "statistically solid"?  Unless you know of some flaw in
> the machine that picks the numbers, any set of six numbers is equally
[quoted text clipped - 5 lines]
> as many people pick numbers that correspond to dates (birthdays,
> anniversaries etc.), which are all in the range 1-31.

I thought that picking 6 random numbers between 1 and 49 a million
times would be a reasonably good estimate of the real world odds.  I
guess I was wrong.

Actually, the odds are that if you roll a dice, you will get a 3 or 4
more than any other number so I was trying to sort of simulate that.
Patricia Shanahan - 18 Aug 2006 20:21 GMT
>> How do you mean "statistically solid"?  Unless you know of some flaw in
>> the machine that picks the numbers, any set of six numbers is equally
[quoted text clipped - 12 lines]
> Actually, the odds are that if you roll a dice, you will get a 3 or 4
> more than any other number so I was trying to sort of simulate that.

There is no one set of "real world" odds.

A single dice roll, a java.util.Random nextInt(), the numbers picked by
a lottery machine, are all approximations to the uniform probability
distribution, in which on each pick every number is exactly equally likely.

In each case, there may be bias due to the specific implementation.

A physical dice may not be perfectly fair, especially if it is at all
worn, or the person throwing it is skilled. As already pointed out,
there are defects in the java.util.Random implementation that may make
it not perfectly fair.

The lottery machine is probably the closest of them all to being exactly
uniform. A state lottery can afford to spend a lot more than the cost of
a dice on buying their machine and testing it for uniformity.

Patricia
Print Guy - 19 Aug 2006 00:06 GMT
> There is no one set of "real world" odds.
>
[quoted text clipped - 14 lines]
>
> Patricia

So how do they do it?  In the old days, there used to be 49 balls in a
tumbler, one would fall out, then another, then another, then another
until there were six.  In fact, I seem to recall seeing on TV some of
the televised American lotteries where the same methods were employed.
If you wanted to simulate that, you would need an array of 49 numbers,
then pick a number at random, drop that number out of the array, shrink
it by one and then pick 1 - 48, then 1-47 etc.   I guess the issue here
isn't the way that the picking is simulated, but the way that the
randomness is implemented.  Is there any computer language, or program
or whatever that is capable of true random number selection based on
"statistically proven techniques" or is everything we consider to be
random just a close approximation?
Patricia Shanahan - 19 Aug 2006 00:52 GMT
>> There is no one set of "real world" odds.
>>
[quoted text clipped - 27 lines]
> "statistically proven techniques" or is everything we consider to be
> random just a close approximation?

The algorithm I suggested, a truncated Fisher-Yates, essentially
simulates the ball dropping process. After N iterations, the first N
elements of the array contain the numbers that have been picked. The
remaining length-N elements contain the numbers that were in the
original array but have not yet been picked, and so can be picked in the
future.

However, its accuracy is dependent on the quality of the underlying
random number generator.

There are several approaches to getting random numbers.

The ball dropping machine, rolling dice, tossed coins, and spinning
roulette wheels all depend on physical processes that are designed so
that very small changes in the initial conditions can make large, hard
to predict, changes in the outcome.

The strongest sources of random numbers are really unpredictable
physical processes. For example, each atom of some isotope has a known
probability of decaying in any given time interval, but we have no way
of predicting which will decay when. The clicks of a Geiger counter are
as close to true randomness as we can get.

java.util.Random, and similar software random number generators, are
"pseudo-random". It takes a seed value, and does a repeated computation
on it to get the next seed. Selected bits of the seed are returned as
e.g. nextInt(). The results are designed to LOOK random, but the
complete sequence of results is fixed once the seed has been chosen.

Patricia
Daniel Dyer - 19 Aug 2006 19:13 GMT
> So how do they do it?  In the old days, there used to be 49 balls in a
> tumbler, one would fall out, then another, then another, then another
[quoted text clipped - 8 lines]
> "statistically proven techniques" or is everything we consider to be
> random just a close approximation?

I think you're right, the more important issue is the source of the  
randomness.  That's not to say that the question which you posed was not  
an interesting programming problem.  I think that Patricia's solution is  
particularly elegant (once I switched on my brain and understood why she  
was doing it that way).

This article  
(http://www.cigital.com/papers/download/developer_gambling.pdf) is an  
interesting story of how flaws in random number generation and shuffling  
algorithms allowed the authors to exploit an online poker site.

I'm not sure what you mean by "statistically proven techniques" for  
generating random numbers.  There are however several tests that can be  
applied to a sequence of numbers in order to obtain a measure of "how  
random" the sequence is (or more correctly, a measure of how confident we  
should be that the sequence is truly random, since the statistics don't  
actually *prove* anything about the sequence).  The most well-known of  
these tests is the Diehard suite (http://stat.fsu.edu/pub/diehard/).  
java.util.Random performs poorly on the Diehard suite, whereas  
java.security.SecureRandom performs well.  I would imagine that the  
revelant gaming authorities have tested the performace of the lottery  
machines, using Diehard or similar, before awarding a licence in order to  
satisfy themselves that the outcomes are sufficiently random.

People who are seriously interested in good quality, unpredictable random  
numbers (i.e. cryptographers and online gaming operators) will typically  
use hardware devices that extract entropy from physical processes such as  
radioactive decay or electronic noise.  The random bits from these devices  
(which are invariably slow) are often used as a seed for a PRNG with known  
statistical properties rather than relied upon in their own right.

A cheaper variation on this theme is to rely on sources of randomness that  
are already present in the computer hardware.  The Solaris kernel, for  
example, extracts entropy from I/O timings in order to provide random  
numbers via /dev/random.

Are you interested in lotteries just as a programming exercise or are you  
seriously hoping to find a way to beat the system?

If you are interested in this kind of thing, maybe you should consider  
other types of gambling (i.e. roulette, blackjack, poker).  For a start,  
the expected return on the lottery is abysmal (only about 50% of the money  
staked goes into the prize pool).  So you have to have a huge edge in  
order to overcome the inherent disadvantage of playing the game in the  
first place.  Blackjack on the other hand has an expected return of  
somewhere in the region of 99.4% (depending on the exact rules in use).  
In other words, if you play optimally (and it's not difficult to learn to  
do so), on average you will only lose 3 cents for every $5 you stake.  
This is still a losing proposition in the long-run, but you'd only need to  
find a slight edge to turn it around.  Traditionally professional gamblers  
found this edge by card-counting, but the casinos have since introduced  
measures to prevent this such as using more decks and a continous  
shuffling machine.

The book "Fortune's Formula", by William Poundstone, is a good read.  
Among other things, it discusses money-making systems that have been used  
for Roulette, Blackjack and the stock market and looks at the ideas behind  
them, dating back to Shannon's work on information theory in the 1940s.

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Luke Webber - 19 Aug 2006 00:29 GMT
> I thought that picking 6 random numbers between 1 and 49 a million
> times would be a reasonably good estimate of the real world odds.  I
> guess I was wrong.
>
> Actually, the odds are that if you roll a dice, you will get a 3 or 4
> more than any other number so I was trying to sort of simulate that.

That doesn't sound right. The statistical bias in dice generally kicks
in when you roll multiple dice. Because there are more ways to make a
seven than, for example, a twelve or a two.

Luke
Print Guy - 19 Aug 2006 01:21 GMT
> > I thought that picking 6 random numbers between 1 and 49 a million
> > times would be a reasonably good estimate of the real world odds.  I
[quoted text clipped - 8 lines]
>
> Luke
Agreed but if you roll one dice say 10 or 20 times, you are more apt to
get a 3 or 4 than any other number... let me see if I can find a link
to verify this...

And of course I can't find it... I'll search some more tomorrow.... I
like the way this thread turned out.... I got lots of good ideas and
now it's time to continue reading.... I wonder if Ruby can do this kind
of stuff ;-)  (**ducks***)
Print Guy - 19 Aug 2006 01:26 GMT
Apparently 4 is the best number of of 6

http://en.wikibooks.org/wiki/Image:Histogramofdice.png
Patricia Shanahan - 19 Aug 2006 02:37 GMT
> Apparently 4 is the best number of of 6
>
> http://en.wikibooks.org/wiki/Image:Histogramofdice.png

You are taking a single image badly out of context. See
http://en.wikibooks.org/wiki/Statistics:Displaying_Data/Histograms.
It is an example of a hypothetical set of dice rolls, for part of a
statistics course. As the page says "This could be the result of chance,
or it could represent an actual anomaly in the data and it is something
to take note of keep in mind.".

If I had been the person constructing the page, I would have used a
biased "dice" to ensure an interesting histogram.

Patricia
Patricia Shanahan - 19 Aug 2006 02:55 GMT
>>> I thought that picking 6 random numbers between 1 and 49 a million
>>> times would be a reasonably good estimate of the real world odds.  I
[quoted text clipped - 10 lines]
> get a 3 or 4 than any other number... let me see if I can find a link
> to verify this...

That may be a property of dice from some manufacturer, though they would
probably not stay in business long if people found out. However, I think
you may be confusing the single roll situation with the effect of adding
the results of a lot of rolls.

For example, if you roll two fair dice, there is only one combination,
a=6, b=6, that gives a 12. On the other hand, there are 6 ways of
getting a total of 7.

According to http://en.wikipedia.org/wiki/Loaded_dice, "There is some
controversy over whether manufacturing processes create genuinely "fair"
dice (dice that roll with even distributions over their number span).
Casino dice are legally required to be fair; those used by all others
hold no such requirement." Note that if dice were consistently and
measurably biased towards 4 there would be no controversy - it would be
easy to prove. For there to be a controversy, any bias must be tiny.

Also, http://en.wikipedia.org/wiki/Craps discusses craps strategy solely
in terms of the odds that would apply if the dice are fair. That
suggests that there is no common bias.

Patricia
David Segall - 19 Aug 2006 15:52 GMT
>Actually, the odds are that if you roll a dice, you will get a 3 or 4
>more than any other number
Not true. The chances of rolling any number are exactly one in six if
the dice has been perfectly made. It is true that for real physical
devices there will be a bias but it is unlikely that will be apparent
over the statistics available from Lotto draws. It is obviously
impossible for you to simulate that bias with any computer program.

[OT] 1 http://www.random.org/ offers a source of "true" random numbers
based on the noise you hear when your radio is not tuned to a station.

[OT] 2 A friend spent a week observing a roulette wheel in a casino
and decided he had located a bias. As soon as he started betting the
staff picked up the wheel he was at and dropped in a different one.
Print Guy - 19 Aug 2006 20:57 GMT
> >Actually, the odds are that if you roll a dice, you will get a 3 or 4
> >more than any other number
[quoted text clipped - 10 lines]
> and decided he had located a bias. As soon as he started betting the
> staff picked up the wheel he was at and dropped in a different one.

Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
more times... I don't have time to roll a dice that many times, but it
makes sense that it should apply no matter how many times you roll the
die as long as it is a large number of times.
Daniel Dyer - 19 Aug 2006 21:35 GMT
> Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
> a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
> more times... I don't have time to roll a dice that many times, but it
> makes sense that it should apply no matter how many times you roll the
> die as long as it is a large number of times.

If the odds are 1 in 6 for the first roll, wouldn't they be 1 in 6 for the  
second roll too?  And for the third roll, and so on.

Why do you think 4 and 5 are more likely?

Perhaps you are confusing a uniform distribution with a normal  
distribution (a.k.a "bell curve")?

Dan.

Signature

Daniel Dyer
http://www.dandyer.co.uk

Patricia Shanahan - 19 Aug 2006 22:26 GMT
>>> Actually, the odds are that if you roll a dice, you will get a 3 or 4
>>> more than any other number
[quoted text clipped - 16 lines]
> makes sense that it should apply no matter how many times you roll the
> die as long as it is a large number of times.

What is your definition of "odds"?

It seems clear that you are not following the frequency interpretation
of probability because in that approach the probability of a four on a
single rolls is defined to be the limit, as N tends to infinity, of the
proportion of fours in N rolls.

You seem to have different opinions about the proportion of fours in a
large number of rolls and the probability of a four on a single roll?

Patricia
David Segall - 20 Aug 2006 09:40 GMT
>Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
>a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
>more times... I don't have time to roll a dice that many times, but it
>makes sense that it should apply no matter how many times you roll the
>die as long as it is a large number of times.
If you agree that the odds are 1 in 6 for the first roll then the odds
must be 1 in 6 for the second roll since the dice has no way of
"knowing" that it has been rolled once already. That is still true for
the third roll right up to the 5000000th roll.

Incidentally, why did you decide that it was four or five that would
come up more often? Why not one or six?
Print Guy - 20 Aug 2006 14:22 GMT
> >Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
> >a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
[quoted text clipped - 8 lines]
> Incidentally, why did you decide that it was four or five that would
> come up more often? Why not one or six?

Experience?
Anyway this whole discussion has been fantastic.  But I didn't win last
night.  I used some of the programs we came up with in this thread
(including my original) and didn't come close to picking the right
numbers.. Even a piece of code that I found in the Horstman book didn't
pick the numbers... oh well
Patricia Shanahan - 20 Aug 2006 14:55 GMT
>>> Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
>>> a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
[quoted text clipped - 10 lines]
>
> Experience?

But you said you didn't have time to do the number of rolls at which you
expected the bias to show up?

> Anyway this whole discussion has been fantastic.  But I didn't win last
> night.  I used some of the programs we came up with in this thread
> (including my original) and didn't come close to picking the right
> numbers.. Even a piece of code that I found in the Horstman book didn't
> pick the numbers... oh well

Assuming a difference in probabilities of numbers may be one of the
worst strategies for picking lottery numbers.

The people running the lottery can monitor their own equipment for bias,
and they have far more data than you do. You only get to see the few
numbers from actual lottery runs. They get all the output, including as
many test runs as they feel like doing between lottery runs.

On the other hand, there may be enough people assuming a bias that the
numbers that happen to have shown up most in recent lottery runs are
particularly popular. If so, picking those numbers would increase the
risk that, in the extremely unlikely event of a win, you would have to
share the prize.

Almost any strategy you can think of for picking the number will be
chosen by others. There is one strategy, picking your numbers at random,
with equal probability, for which that doesn't matter.

Patricia
Print Guy - 20 Aug 2006 21:58 GMT
> >>> Yes, the odds are 1 in 6 if you roll a dice once.  But what if you roll
> >>> a 6 sided dice 5000000 times?  I still think that 4 or 5 will occur
[quoted text clipped - 39 lines]
>
> Patricia

20 rolls
1 = 4
2 = 4
3 = 3
4= 1
5=5
6=3

So I guess it would take more than 20 rolls before any kind of bias
would show up.

A while ago, I went back in "time" and wrote down all the winning
number combination for about 10 draws... if I remember correctly 14 was
a good number....
zero - 20 Aug 2006 16:58 GMT
>> >Yes, the odds are 1 in 6 if you roll a dice once.  But what if you
>> >roll a 6 sided dice 5000000 times?  I still think that 4 or 5 will
[quoted text clipped - 10 lines]
>
> Experience?

Seems to me like you're confusing Gaussian distributed values (for
example test scores, or people's heights) with truly random values (such
as lottery numbers - if the lottery is fair - or dice rolls).  For
people's heights its it indeed true that there will be more people of
say 1.8m (6') than people of 2.3m (7'5").  With dice however there is no
reason to assume that the number 4 is likely to come up more often than
the number 1.  Although it may be counterintuitive, rolling the number 6
5 times in a row is just as likely as rolling the (exact) sequence 5 2 4
5 3.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.