Sign in to follow this  
Followers 0
anunes

Problem with a "Random algorithm"

10 posts in this topic

Hi, I'm working in a new program, what the program do is:

- It opens a .txt file with a list of names (something about 5 or 6 names);

- Read this names, and sort this names randomly on the week days, throughout all the days of the month, except weekends;

- But, if the name already gets a position, it just get a new position when all the names gone;

My problem is, how do I do the to sort the names randomly? How to do a "Random Algorithm"?

Thanks, and sorry about my english!

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Something like this might work. You'd have to setup a loop to load the results of Get_Names into an array of available dates. There might be an easier way to go about it, with so few names. This routine is tuned more for large lists.

#include<Array.au3>
Global $names_count = 6, $names[$names_count + 1] = ["", "John", "Mary", "Bill", "Pat", "Debbie", "Mortimer"]
Global $names_control[$names_count + 1], $names_random[$names_count + 1]

Get_Names()
_ArrayDisplay($names_random)
Exit

;-------------------------------------------------------------------------------
Func Get_Names()
    For $i=1 To $names_count
        $names_control[$i] = $i
    Next
    For $i = 1 To $names_count - 1
        $new = Random($i, $names_count, 1)
        $names_random[$i] = $names[$names_control[$new]]
        $names_control[$new] = $names_control[$i]
    Next
    $names_random[$names_count] = $names[$names_control[$names_count]]
EndFunc

Edit: moved loop to reset control array to be inside function

Edited by Spiff59

Share this post


Link to post
Share on other sites

anunes,

Have a look at this:

#include <Array.au3>

Global $aNames[6]
Global $aRandom[6]
Global $aSorted[6]

; Create dummy list of names
For $i = 0 To 5
    $aNames[$i] = Chr($i + 65)
Next

; Copy the names to another array - that way the original is untouched
$aSorted = $aNames
$iCount = 0

Do
; Transfer random names to the Random array
    $iRandomIndex = Random(0, UBound($aSorted) - 1, 1)
    $aRandom[$iCount] = $aSorted[$iRandomIndex]
; Delete that name from the array
    _ArrayDelete($aSorted, $iRandomIndex)
    $iCount +=1
    
Until $iCount = 5

; Add the final name - because Random will not work if both Min and Max = 0
$aRandom[5] = $aSorted[0]

; Show result
_ArrayDisplay($aRandom)

Ask if anything is unclear.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

anunes,

Have a look at this:

#include <Array.au3>

Global $aNames[6]
Global $aRandom[6]
Global $aSorted[6]

; Create dummy list of names
For $i = 0 To 5
    $aNames[$i] = Chr($i + 65)
Next

; Copy the names to another array - that way the original is untouched
$aSorted = $aNames
$iCount = 0

Do
; Transfer random names to the Random array
    $iRandomIndex = Random(0, UBound($aSorted) - 1, 1)
    $aRandom[$iCount] = $aSorted[$iRandomIndex]
; Delete that name from the array
    _ArrayDelete($aSorted, $iRandomIndex)
    $iCount +=1
    
Until $iCount = 5

; Add the final name - because Random will not work if both Min and Max = 0
$aRandom[5] = $aSorted[0]

; Show result
_ArrayDisplay($aRandom)

Ask if anything is unclear.

M23

M23, your program works fine when I executed the script, but, when I tried to change it, it's occours an error... here's the script

#include <Array.au3>

Global $aNames[6]
Global $aRandom[6]
Global $aSorted[6]
Dim $sSource

$sSource = FileOpenDialog("Abrir arquivo", @WorkingDir, "Arquivo texto (*.txt)")
$aNames = FileRead($sSource)

; Create dummy list of names
;~ For $i = 0 To 5
;~     $aNames[$i] = Chr($i + 65)
;~ Next

; Copy the names to another array - that way the original is untouched
$aSorted = $aNames
$iCount = 0

Do
; Transfer random names to the Random array
    $iRandomIndex = Random(0, UBound($aSorted) - 1, 1)
    $aRandom[$iCount] = $aSorted[$iRandomIndex]
; Delete that name from the array
    _ArrayDelete($aSorted, $iRandomIndex)
    $iCount +=1
    
Until $iCount = 5

; Add the final name - because Random will not work if both Min and Max = 0
$aRandom[5] = $aSorted[0]

; Show result
_ArrayDisplay($aRandom)

But, when the script read from the file, it doesn't create an array... So occours the error saying: "Subscript used with non-Array variable.:"

How can I try to fix it?

Edited by anunes

Share this post


Link to post
Share on other sites

anunes,

Try using FileReadToArray - AutoIt then creates the array for you. But beware - the first element in the array is the count, so you will either have to delete that element or adapt the script to not use it.

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

anunes,

Try using FileReadToArray - AutoIt then creates the array for you. But beware - the first element in the array is the count, so you will either have to delete that element or adapt the script to not use it.

M23

I adapt the script to not use that element. But, there's some way to create an array with the right size, without know previously your size?

Something like this:

- I have a list of names, but I don't know how much names there's in there...

So I use _FileReadToArray, get the first element and create an array with this size. Is it possible?

Share this post


Link to post
Share on other sites

anunes,

I assume your file is already in the form of:

name1 @CRLF
name2 @CRLF etc

All you need to do is to put these lines into your code (after making sure File.au3 is included!):

$sSource = FileOpenDialog("Abrir arquivo", @WorkingDir, "Arquivo texto (*.txt)")
_FileReadToArray($sSource, $aNames)

And AutoIt does it all for you! But remember the first element is the count!

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

anunes,

I assume your file is already in the form of:

name1 @CRLF
name2 @CRLF etc

All you need to do is to put these lines into your code (after making sure File.au3 is included!):

$sSource = FileOpenDialog("Abrir arquivo", @WorkingDir, "Arquivo texto (*.txt)")
_FileReadToArray($sSource, $aNames)

And AutoIt does it all for you! But remember the first element is the count!

M23

It's already done! Trying to complete the program, another doubt I'll continue in this topic!

Thanks M23

Share this post


Link to post
Share on other sites

It's already done! Trying to complete the program, another doubt I'll continue in this topic!

Thanks M23

My program is almost done, but need only one thing.

#include <Array.au3>
#include <File.au3>
#include <Excel.au3>
#include <Date.au3>

    $arquivoFonte = FileOpenDialog("Abrir arquivo", @WorkingDir, "Arquivo texto (*.txt)")
    $numeroLinhas = _FileCountLines($arquivoFonte)

    Global $vetorNomes[$numeroLinhas + 1]
    Global $vetorAleatorio[$numeroLinhas + 1]
    Global $vetorDistribuicao[$numeroLinhas + 1]
    Global $vetorNovo[$numeroLinhas]
    Global $vetorNovo2[$numeroLinhas]

    _FileReadToArray($arquivoFonte, $vetorNomes)

    ; Copia os nomes prum outro vetor - assim não mexe no vetor original
    ; Copy the names to another array - that way the original is untouched
    $vetorDistribuicao = $vetorNomes
    $i = 1
    Do

        ; Transfere nomes aleatórios para o vetor Aleatorio
        ; Transfer random names to the Random array
        $vetorNomesAleatorios = Random(1, UBound($vetorDistribuicao) - 1, 1)
        $vetorAleatorio[$i] = $vetorDistribuicao[$vetorNomesAleatorios]

        ; Deleta o nome que já foi escolhido do vetor
        ; Delete that name from the array
        _ArrayDelete($vetorDistribuicao, $vetorNomesAleatorios)
        $i = $i + 1

    Until $i = $numeroLinhas

    ; Adiciona o nome final - porque a função Random não funciona se o Min e o Max forem iguais a 0
    ; Add the final name - because Random will not work if both Min and Max = 0
    $vetorAleatorio[$numeroLinhas] = $vetorDistribuicao[1]

    ; Mostra o resultado
    ; Show result
;~  _ArrayDisplay($vetorAleatorio)
    
$i = 0
While $i < $numeroLinhas
    $vetorNovo[$i] = $vetorAleatorio[$i + 1]
    $i = $i + 1
WEnd


$x = 1
$arquivoExcel = _ExcelBookNew()
$dia = 1
$mes = 3
$ano = 2009
$diafinal = 31
$mesfinal = 12

While $mes <> $mesfinal Or $dia <> $diafinal + 1
    
    $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
    
    If $diadasemana = 1 Then
        $dia = $dia + 1
    ElseIf $diadasemana = 7 Then
        $dia = $dia + 2
    EndIf
    
    $data_checa = $ano & "/" & $mes & "/" & $dia
    If _DateIsValid($data_checa) = 0 Then
        $mes = $mes + 1
        $dia = 1
        $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
        If $diadasemana = 1 Then 
            $dia = 2
        ElseIf $diadasemana = 7 Then
            $dia = 3
        EndIf
    EndIf
    
    $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
    $data = $dia & "/ " & $mes & "/" & $ano
    _ExcelWriteCell($arquivoExcel, $data, $x, 1)
    _ExcelWriteCell($arquivoExcel, _DateDayOfWeek($diadasemana), $x, 2)
    _ExcelWriteArray($arquivoExcel, 1, 3, $vetorNovo, 1)
    
    $dia = $dia + 1
    $x = $x + 1
    
WEnd

Here's the code, it's just a simple test I was doing. Wath the program do is:

- It gets the file.txt with the names (one by line), randomize the list and write it on Execel;

But it just write 1 time the randomized list, wath I need is:

- Open the list and complete the dates with the names, it is, when the first randomized list finish to be writed, then it randomize again the same list an write, over and over again, until it complete the Excel date lines;

Sorry about the bad english, if you not understand something, please, ask, and correct me in PM!

Share this post


Link to post
Share on other sites

My program is almost done, but need only one thing.

#include <Array.au3>
#include <File.au3>
#include <Excel.au3>
#include <Date.au3>

    $arquivoFonte = FileOpenDialog("Abrir arquivo", @WorkingDir, "Arquivo texto (*.txt)")
    $numeroLinhas = _FileCountLines($arquivoFonte)

    Global $vetorNomes[$numeroLinhas + 1]
    Global $vetorAleatorio[$numeroLinhas + 1]
    Global $vetorDistribuicao[$numeroLinhas + 1]
    Global $vetorNovo[$numeroLinhas]
    Global $vetorNovo2[$numeroLinhas]

    _FileReadToArray($arquivoFonte, $vetorNomes)

    ; Copia os nomes prum outro vetor - assim não mexe no vetor original
    ; Copy the names to another array - that way the original is untouched
    $vetorDistribuicao = $vetorNomes
    $i = 1
    Do

        ; Transfere nomes aleatórios para o vetor Aleatorio
        ; Transfer random names to the Random array
        $vetorNomesAleatorios = Random(1, UBound($vetorDistribuicao) - 1, 1)
        $vetorAleatorio[$i] = $vetorDistribuicao[$vetorNomesAleatorios]

        ; Deleta o nome que já foi escolhido do vetor
        ; Delete that name from the array
        _ArrayDelete($vetorDistribuicao, $vetorNomesAleatorios)
        $i = $i + 1

    Until $i = $numeroLinhas

    ; Adiciona o nome final - porque a função Random não funciona se o Min e o Max forem iguais a 0
    ; Add the final name - because Random will not work if both Min and Max = 0
    $vetorAleatorio[$numeroLinhas] = $vetorDistribuicao[1]

    ; Mostra o resultado
    ; Show result
;~  _ArrayDisplay($vetorAleatorio)
    
$i = 0
While $i < $numeroLinhas
    $vetorNovo[$i] = $vetorAleatorio[$i + 1]
    $i = $i + 1
WEnd


$x = 1
$arquivoExcel = _ExcelBookNew()
$dia = 1
$mes = 3
$ano = 2009
$diafinal = 31
$mesfinal = 12

While $mes <> $mesfinal Or $dia <> $diafinal + 1
    
    $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
    
    If $diadasemana = 1 Then
        $dia = $dia + 1
    ElseIf $diadasemana = 7 Then
        $dia = $dia + 2
    EndIf
    
    $data_checa = $ano & "/" & $mes & "/" & $dia
    If _DateIsValid($data_checa) = 0 Then
        $mes = $mes + 1
        $dia = 1
        $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
        If $diadasemana = 1 Then 
            $dia = 2
        ElseIf $diadasemana = 7 Then
            $dia = 3
        EndIf
    EndIf
    
    $diadasemana = _DateToDayOfWeek($ano, $mes, $dia)
    $data = $dia & "/ " & $mes & "/" & $ano
    _ExcelWriteCell($arquivoExcel, $data, $x, 1)
    _ExcelWriteCell($arquivoExcel, _DateDayOfWeek($diadasemana), $x, 2)
    _ExcelWriteArray($arquivoExcel, 1, 3, $vetorNovo, 1)
    
    $dia = $dia + 1
    $x = $x + 1
    
WEnd

Here's the code, it's just a simple test I was doing. Wath the program do is:

- It gets the file.txt with the names (one by line), randomize the list and write it on Execel;

But it just write 1 time the randomized list, wath I need is:

- Open the list and complete the dates with the names, it is, when the first randomized list finish to be writed, then it randomize again the same list an write, over and over again, until it complete the Excel date lines;

Sorry about the bad english, if you not understand something, please, ask, and correct me in PM!

The problem was solved doing a simple loop. Thanks!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0