Sign in to follow this  
Followers 0
kylomas

*** Challenge ***

11 posts in this topic

A recent thread having to do with poker piqued both my curiosity and stuborness. So I had to write something that would generate shuffled decks of cards.

Question - the shuffle routines that I have seen here all re-arrange 1 or more existing arrays. Why not dump the current array and re-generate it?

The attached routine can generate 1000 shuffled poker decks in appx. 1.5 secs (WinXP 2Ghz, 2GB, yes, a boat anchor)

;
; generate ubound($deck) decks of shuffled cards
;

#include <array.au3>

local $i,$j,$deck[1000][53],$st,$tt,$cdeck[53],$k,$card

$tt = timerinit()
for $i = 0 to ubound($deck,1) - 1                               ; generate ubound($deck) number of card decks
    for $k = 1 to 52                                            ; set dup checking deck
        $cdeck[$k] = $k
    Next
    $st = timerinit()
    for $j = 1 to 52                                            ; start generate deck of cards
        $card = random(1,52,1)                                  ; Seed?
        while $cdeck[$card] = 0                                 ; if $cdeck slot is 0 then we have used this card
            $card = random(1,52,1)
        Wend
        $deck[$i][$j] = $card                                   ; $cdeck slot was not 0 so use card and...
        $cdeck[$card] = 0                                       ; set $cdeck slot to 0
    Next                                                        ; end generate deck of cards
    $deck[$i][0] = round(timerdiff($st)/1000,5)
Next

consolewrite(@crlf & round(timerdiff($tt)/1000,5) & @crlf)

_arraydisplay($deck)

I don't give a damn about poker, just wanted to see if I could come up with something fast...

What do the "expert" think???

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hi, here are some stuff I did,

1. The For/Next filling loop of cdeck reduced to one time for an cdeck_init array and then (re)initialize cdeck with this init_array each turn

2. While/Wend changed to Do/Until with a shortened condition.

;
; generate ubound($deck) decks of shuffled cards
;

#include <array.au3>

Local $i, $j, $deck[1000][53], $st, $tt, $k, $card
Local $cdeck_init[53], $cdeck


$tt = TimerInit()

; array $cdeck_init will be use to init $cdeck before
For $k = 1 To 52 ; set dup checking deck
    $cdeck_init[$k] = $k
Next

For $i = 1 to 999 ; generate ubound($deck) number of card decks

    ; (re)initialization
    $cdeck = $cdeck_init

    For $j = 1 To 52 ; start generate deck of cards

        Do
            $card = Random(1, 52, 1) ; Seed?
        Until $cdeck[$card]

        $deck[$i][$j] = $card ; $cdeck slot was not 0 so use card and...

        $cdeck[$card] = 0 ; set $cdeck slot to 0
    Next ; end generate deck of cards

Next

ConsoleWrite(@CRLF & Round(TimerDiff($tt) / 1000, 5) & @CRLF)

;_arraydisplay($deck)

Incredible result!! I can hear the crowd yelling out loud on the street !!!

Hehe!!

Let's see what other will do!!

Edit: Added and changed some comments

Edited by hench

Share this post


Link to post
Share on other sites

hench,

cut .3 secs off, very good.

re-initing the dup checking deck with another array was TOO obvious, duh!

kylomas


Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

0.35315

2.6GHZ AMD Athlon 64 X2 5000+

2GB RAM

Original version runs at 0.9something

#include <Array.au3>

Global $deck[1000][52]
Global $cdeck[52]
Global $card
Global $diff

Global Const $upBound = UBound($deck, 1) - 1

Global Const $timer = TimerInit()

For $i = 0 To $upBound
    For $j = 0 To 51
        Do
            $card = Random(1, 52, 1)
        Until $cdeck[$card - 1] = 0

        $deck[$i][$j] = $card
    Next
Next

$diff = Round(TimerDiff($timer) / 1000, 5)

ConsoleWrite($diff & @CRLF)

_ArrayDisplay($deck)

NVM -- There's a bug. >:{ The Do loop doesn't give equal weight to all numbers. Some numbers will appear more than others. Back to the drawing board for me.

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

An alternative method that I believe is about 15% to 20% faster than the original.

I must say that I really enjoy little challenges like this one.

;
; generate ubound($deck) decks of shuffled cards
;

#include <array.au3>

Global $i, $j, $k, $deck[1000][52], $tt, $cdeck[52]
Global $FullDeck = "01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152"
$tt = TimerInit()
For $i = 0 To UBound($deck, 1) - 1 ; generate ubound($deck) number of card decks
    $cdeck = $FullDeck
    For $j = 51 To 0 Step -1
        $k = Random(0, $j, 1) * 2
        $deck[$i][$j] = StringMid($cdeck, $k + 1, 2)
        $cdeck = StringLeft($cdeck, $k) & StringTrimLeft($cdeck, $k + 2)
    Next
Next

ConsoleWrite(@CRLF & Round(TimerDiff($tt) / 1000, 5) & @CRLF)
_ArrayDisplay($deck)

"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to build bigger and better idiots. So far, the universe is winning."- Rick Cook

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

OK, this beats everything that has come before!

0.00317

Sorry, I forgot to loop it for 1000 times!!!!!

0.27682 -- average after five runs

Still ain't half bad.

#Tidy_Parameters=/tc 0 /kv 0 /reel
#AutoIt3Wrapper_Au3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d

#include <Array.au3>

Global Const $deck_size = 52 ; without jokers
Global Const $card_deck_init[52] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
Global $card_deck
Global $tmp
Global $rnd

Global Const  $timer = TimerInit()

For $j = 0 To 999
    $card_deck = $card_deck_init

    For $i = $deck_size - 1 To 1 Step -1
        $rnd = Random(0, $i, 1)

        $tmp = $card_deck[$i]
        $card_deck[$i] = $card_deck[$rnd]
        $card_deck[$rnd] = $tmp
    Next
Next

Global Const $acc = TimerDiff($timer)

ConsoleWrite("Time to complete 1000 runs is: " & Round(($acc / 1000), 5) & @LF)

Not guaranteed to be bug free.

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

DELETE!

Edited by guinness

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I got 0.00178 & 0.00061 with jaberwocky6669's new Script and Array.au3 is missing if people are wondering about the error.

Edited by guinness

_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 04/09/2015

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

It only seems to shuffle once though.

I only show the shuffled array once so that it won't impact speed but if you aren't worried about speed then put the _ArrayDisplay() inside of the loop.

This example will show you the array before and after the shuffle.

#Tidy_Parameters=/tc 0 /kv 0 /reel
#AutoIt3Wrapper_Au3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 6 -d

#include <Array.au3>

Global Const $deck_size = 52 ; without jokers
Global Const $card_deck_init[52] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
Global $card_deck
Global $tmp
Global $rnd

For $j = 0 To 10
    $card_deck = $card_deck_init

    _ArrayDisplay($card_deck, "Before the shuffle.")

    For $i = $deck_size - 1 To 1 Step -1
        $rnd = Random(0, $i, 1)

        $tmp = $card_deck[$i]
        $card_deck[$i] = $card_deck[$rnd]
        $card_deck[$rnd] = $tmp
    Next

    _ArrayDisplay($card_deck, "After the shuffle.")
Next

Wow, I made a dumb mistake, should be fixed now.

Edited by jaberwocky6669

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

#include <Array.au3>; used for array display

; Creat the deck
Global $ga_deck[52]
For $i = 0 To 51
    $ga_deck[$i] = $i + 1
Next

; globals for number of shuffles and shuffled deck array
Global $gi_numshuffles = 10
Global $ga_deckshuffled = $ga_deck

Global $gn_timer = TimerInit()

For $ishuffle = 1 To $gi_numshuffles
    $ga_deckshuffled = _Array_Random_Shuffle($ga_deckshuffled)
Next

; log timer diff
Global $gn_diff = TimerDiff($gn_timer) / 1000

ConsoleWrite($gi_numshuffles & " took: " & $gn_diff & " seconds." & @CRLF)
_ArrayDisplay($ga_deckshuffled)


Func _Array_Random_Shuffle($av_array, $i_lbound = 0)
    Local $i_ubound = UBound($av_array) - 1
    Local $icc, $s_temp, $i_random

    For $icc = $i_lbound To $i_ubound
        $s_temp = $av_array[$icc]
        $i_random = Random($i_lbound, $i_ubound, 1)
        $av_array[$icc] = $av_array[$i_random]
        $av_array[$i_random] = $s_temp
    Next

    Return $av_array
EndFunc

Edit:

I didn't notice jaberwocky's random shuffle, I've used this function ( _Array_Random_Shuffle ) for several years now, but his is very similar.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

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