arraysbashuniq

Using Bash to Generate Lotto Numbers


I've got a simple bash script that generates the following:

These are your winning lottery numbers: 
 27  6   29  17  15  47
 19  16  33  15  20  14
 29  34  48  19  33  40

Here is the code for it:

#!/bin/bash

tickets="$1"

function get_tickets { printf "How many tickets are you going to get? "; read tickets;}

function gen_numbers { printf "\nThese are your winning lottery numbers: \n"; 

    for ((z=1 ; z<=tickets ; z++)); do
         for ((i=0; i<6; i++ )); do 
            x=`echo $[ 1 + $[ RANDOM % 49 ]]`; 
            printf "\t $x"; 
         done;
         printf "\n" 
    done; 
    printf "\n"; }


############################
if [[ -z $tickets ]]  ; then
    get_tickets
    gen_numbers
else
    gen_numbers
fi

My question is, does anyone know how to modify it to prevent duplicate numbers on each row from appearing? I am guess I'd use uniq, and an array, but am not sure how that would look. Any advice would be appreciated; thanks!


Solution

  • To avoid duplicates by row use an array to mark the used values. Here is a modified version of your script:

    for ((z = 1; z<=tickets ; z++)); do
         i=0
         used=( 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 )
         for (( ; i<6;  )); do 
            x=`echo $[ 1 + $[ RANDOM % 49 ]]`; 
            if [ ${used[$x]} -eq 0 ]
            then
                printf "\t $x"; 
                i=$((i + 1))
                used[$x]=1
            fi
         done;
         printf "\n" 
    done; 
    printf "\n"; }
    

    EDIT: Explanation.

    The idea is very simple, we use the array to mark those values already used.

    Initially all the elements (50 elements that corresponds to the values [0, 49]) of the array are set to zero, i.e. all the numbers are available.

    For each random number x we check if that number is available (used[x] = 0), if so we increase the counter i and mark that value (used[x] = 1) to avoid repetitions.

    If the value is already taken simply try again and again until an unused value is found.