Permutation class for demonstrating usage of enumerator

Helpful script writing tricks and HowTo's
User avatar
FredOoo
Posts: 186
Joined: 07 May 2019, 21:58
Location: Paris

Permutation class for demonstrating usage of enumerator

Post by FredOoo » 19 Jun 2019, 04:04

Code: Select all

#SingleInstance force
#Persistent

;;Permutation class for demonstrating usage of enumerator
;Doc:    https://www.autohotkey.com/docs/commands/For.htm

for key, value in new Permutation( ["AA", "BB", "CC", "DD"] )
    print( key ":`t" flat( value ) )

;==========================================================


class Permutation {
    __new( Data ) {
        this.Data    := Data
        this.lenData := Data.length()
        this.maxK    := this.factorial(this.lenData)
        this.Choice  := []
        loop % this.lenData
            this.Choice.push(1)
            ; if the input is A, B, C, D (when you take one, it is removed)
            ; Choice [1,1,1,1] means you take the first four times -> A, B, C, D
            ; Choice [3,3,1,1] the third twice and the first twice -> C, D, A, B
    }
    _newEnum() {
        return this
    }
    next( byRef key, byRef value ) {
        static iK := 0 ; iK for index of keys
        if !iK {
            iK++
            key   := iK
            value := this.permute() ; first permute = input array
            return 1 ; continue
        }
        iK++
        while iK <= this.maxK {
            for i in this.Choice {
                ; build a choice of items
                if (this.Choice[i] = i)
                    this.Choice[i] := 1
                else {
                    this.Choice[i] += 1
                    break
                }
            }
            key   := iK
            value := this.permute()
            return 1 ; continue
        }
        return 0 ; end
    }
    permute() {
        D := []
        for k,v in this.Data
            D.push( v )
        P := []
        ;for k,v in this.Choice   ;| for a more understandable view,
        ;    P.insertAt( 1, v )   ;| display choice
        ;P.push( "`t" )           ;|
        loop % this.lenData {
            i := this.lenData-a_Index+1 ; index from end
            P.push( D[this.Choice[i]] )
            D.removeAt( this.Choice[i] )
        }
        return P
    }
    factorial( n ){
        if n=0
            return 1
        return % n*this.factorial(n-1)
    }
}


flat( liste, sep:=", " ){
    ; transform array to a flat line
    for index in liste
        txt .= liste[index] sep
    return rTrim( txt, sep)
}

print( text ){
    ; who wants 24 msgBox ?
    static stdOut := 0
    if !stdOut {
        dllCall("AllocConsole")
        stdOut := fileOpen("*", "w `n")
    }
    stdOut.writeLine( text )
    stdOut.read(0) ;flush
}

Code: Select all

1:      AA, BB, CC, DD
2:      AA, BB, DD, CC
3:      AA, CC, BB, DD
4:      AA, CC, DD, BB
5:      AA, DD, BB, CC
6:      AA, DD, CC, BB
7:      BB, AA, CC, DD
8:      BB, AA, DD, CC
9:      BB, CC, AA, DD
10:     BB, CC, DD, AA
11:     BB, DD, AA, CC
12:     BB, DD, CC, AA
13:     CC, AA, BB, DD
14:     CC, AA, DD, BB
15:     CC, BB, AA, DD
16:     CC, BB, DD, AA
17:     CC, DD, AA, BB
18:     CC, DD, BB, AA
19:     DD, AA, BB, CC
20:     DD, AA, CC, BB
21:     DD, BB, AA, CC
22:     DD, BB, CC, AA
23:     DD, CC, AA, BB
24:     DD, CC, BB, AA
Last edited by FredOoo on 20 Jun 2019, 02:21, edited 1 time in total.
(Alan Turing) « What would be the point of saying that A = B if it was really the same thing? »
(Albert Camus) « Misnaming things is to add to the misfortunes of the world. »

Return to “Tutorials (v1)”