Python programmatuur bij Dobbelstenen vakantieuitdaging

Python programMatUur bij DoBbelstENen vAkantieuitdaGing

# Programma 1: Versie van Flippo die de oplossing ook weergeeft
import time
import math
from itertools import permutations 

def vereenvoudig(u):
    if u[1] < 0:
        u[0] = -u[0]
        u[1] = -u[1]
    g = math.gcd(u[0],u[1])
    if g < 0:
        g = -g
    if g == 0:
        return ([0,0])
    else:
        return ([u[0]//g,u[1]//g])

def fplus(u,v):
    return vereenvoudig([u[0]*v[1]+u[1]*v[0],u[1]*v[1]])

def fmin(u,v):
    return vereenvoudig([u[0]*v[1]-u[1]*v[0],u[1]*v[1]])

def fmaal(u,v):
    return vereenvoudig([u[0]*v[0],u[1]*v[1]])

def fdeel(u,v):
    return vereenvoudig([u[0]*v[1],u[1]*v[0]])

def fop(u,v,op):
    if op == 0:
        return fplus(u,v)
    if op == 1:
        return fmin(u,v)
    if op == 2:
        return fmaal(u,v)
    if op == 3:
        return fdeel(u,v)

t0 = time.process_time()

Q = [3,3,11,25,24]
OPS = ["+", "-", "x", ":"]
a = Q[0]
b = Q[1]
c = Q[2]
d = Q[3]
r = Q[4]
perms = permutations([a,b,c,d])
# disc = (a-b)*(a-c)*(a-d)*(b-c)*(b-d)*(c-d)
lipe = list(perms)
lipe.sort()
print(len(lipe))
print(lipe)
for elt in lipe:
    for u1 in range(4):
        r1 = fop([elt[0],1],[elt[1],1],u1)
        for u2 in range(4):
            r2a = fop(r1,[elt[2],1],u2)
            r2b = fop([elt[2],1],r1,u2)
            r2c = fop([elt[2],1],[elt[3],1],u2)
            for u3 in range(4):
                r3a = fop(r2a,[elt[3],1],u3)
                r3b = fop(r2b,[elt[3],1],u3)
                r3c = fop([elt[3],1],r2a,u3)
                r3d = fop([elt[3],1],r2b,u3)
                r3e = fop(r1,r2c,u3)
                if (r3a[0] == r) & (r3a[1] == 1):
                    #print(r1, r2a, r3a, "(", "(", elt[0], OPS[u1], elt[1], ")", OPS[u2], elt[2], ")", OPS[u3], elt[3])
                    print("(", "(", elt[0], OPS[u1], elt[1], ")", OPS[u2], elt[2], ")", OPS[u3], elt[3])
                if (r3b[0] == r) & (r3b[1] == 1):
                    #print(r1, r2b, r3b, "(", elt[2], OPS[u2], "(", elt[0], OPS[u1], elt[1], ")", ")", OPS[u3], elt[3])
                    print("(", elt[2], OPS[u2], "(", elt[0], OPS[u1], elt[1], ")", ")", OPS[u3], elt[3])
                if (r3c[0] == r) & (r3c[1] == 1):
                    #print(r1, r2a, r3c, elt[3], OPS[u3], "(", "(", elt[0], OPS[u1], elt[1], ")", OPS[u2], elt[2], ")")
                    print(elt[3], OPS[u3], "(", "(", elt[0], OPS[u1], elt[1], ")", OPS[u2], elt[2], ")")
                if (r3d[0] == r) & (r3d[1] == 1):
                    #print(r1, r2b, r3d, elt[3], OPS[u3], "(", elt[2], OPS[u2], "(", elt[0], OPS[u1], elt[1], ")", ")")
                    print(elt[3], OPS[u3], "(", elt[2], OPS[u2], "(", elt[0], OPS[u1], elt[1], ")", ")")
                if (r3e[0] == r) & (r3e[1] == 1):
                    #print(r1, r2c, r3e, "(", elt[0], OPS[u1], elt[1], ")", OPS[u3], "(", elt[2], OPS[u2], elt[3], ")")
                    print("(", elt[0], OPS[u1], elt[1], ")", OPS[u3], "(", elt[2], OPS[u2], elt[3], ")")
t1 = time.process_time()
print("Aantal secondes rekentijd", t1-t0)

 

# Programma 2: Hiermee kunnen voor specifieke sets dobbelstenen
# de berekeningen worden uitgevoerd.

import time
import math
from itertools import permutations 

def vereenvoudig(u):
    g = math.gcd(u[0],u[1])
    if g == 0:
        return ([0,0])
    else:
        return ([u[0]//g,u[1]//g])

def fplus(u,v):
    return vereenvoudig([u[0]*v[1]+u[1]*v[0],u[1]*v[1]])

def fmin(u,v):
    return vereenvoudig([abs(u[0]*v[1]-u[1]*v[0]),u[1]*v[1]])

def fmaal(u,v):
    return vereenvoudig([u[0]*v[0],u[1]*v[1]])

def fdeel(u,v):
    return vereenvoudig([u[0]*v[1],u[1]*v[0]])

def fop(u,v,op):
    if op == 0:
        return fplus(u,v)
    if op == 1:
        return fmin(u,v)
    if op == 2:
        return fmaal(u,v)
    if op == 3:
        return fdeel(u,v)

def flippo(Q):
    a = Q[0]
    b = Q[1]
    c = Q[2]
    d = Q[3]
    r = Q[4]
    perms = permutations([a,b,c,d]) 
    # disc = (a-b)*(a-c)*(a-d)*(b-c)*(b-d)*(c-d)
    lipe = list(perms)
    lipe.sort()
    ok = 0
    for elt in lipe:
        if ok == 0:
            for u1 in range(4):
                r1 = fop([elt[0],1],[elt[1],1],u1)
                for u2 in range(4):
                    r2a = fop([elt[2],1],r1,u2)
                    r2b = fop(r1,[elt[2],1],u2)
                    r2c = fop([elt[2],1],[elt[3],1],u2)
                    for u3 in range(4):
                        r3a = fop([elt[3],1],r2a,u3)
                        r3b = fop([elt[3],1],r2b,u3)
                        r3c = fop(r2a,[elt[3],1],u3)
                        r3d = fop(r2b,[elt[3],1],u3)
                        r3e = fop(r1,r2c,u3)
                        if (r3a[0] == r) & (r3a[1] == 1):
                            ok += 1
                        if (r3b[0] == r) & (r3b[1] == 1):
                            ok += 1
                        if (r3c[0] == r) & (r3c[1] == 1):
                            ok += 1
                        if (r3d[0] == r) & (r3d[1] == 1):
                            ok += 1
                        if (r3e[0] == r) & (r3e[1] == 1):
                            ok += 1
    return ok

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (1, 2, 3, 4, 5, 6)
Dobbelsteen3 = (1, 2, 3, 4, 5, 6)
Dobbelsteen4 = (1, 2, 3, 4, 5, 6)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (7, 8, 9, 10, 11, 12)
Dobbelsteen3 = (13, 14, 15, 16, 17, 18)
Dobbelsteen4 = (19, 20, 21, 22, 23, 24)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (2, 4, 6, 8, 10, 12)
Dobbelsteen3 = (3, 6, 9, 12, 15, 18)
Dobbelsteen4 = (4, 8, 12, 16, 20, 24)

# Oplossing van Lance Bakker
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 10)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (9, 11, 12, 13, 14, 15)

# Oplossing van Casper de With
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 7, 8)
Dobbelsteen3 = (2, 3, 4, 5, 6, 9)
Dobbelsteen4 = (10, 11, 12, 14, 15, 18)

print(Dobbelsteen1, Dobbelsteen2, Dobbelsteen3, Dobbelsteen4, ":")

t0 = time.process_time()
niet_geslaagd = 0
for n in range(1,101):
    if n % 10 == 0: print (n, "% gedaan")
    for a1 in Dobbelsteen1:
        for a2 in Dobbelsteen2:
            for a3 in Dobbelsteen3:
                for a4 in Dobbelsteen4:
                    Q = [a1,a2,a3,a4,n]
                    f = flippo(Q)
                    if f == 0:
                        niet_geslaagd +=1
t1 = time.process_time()
print(round(100-niet_geslaagd/1296,2),"% door", \
      Dobbelsteen1, Dobbelsteen2, Dobbelsteen3, Dobbelsteen4)
T = t1-t0
M = math.floor(T / 60)
print("Rekentijd:", M, "minuten", T - 60*M, "seconden")

 

# Programma 3: Het kan echter veel sneller.

import time
import math
from itertools import permutations 

def vereenvoudig(u):
    g = math.gcd(u[0],u[1])
    if g == 0:
        return ([0,0])
    else:
        return ([u[0]//g,u[1]//g])

def fplus(u,v):
    return vereenvoudig([u[0]*v[1]+u[1]*v[0],u[1]*v[1]])

def fmin(u,v):
    return vereenvoudig([abs(u[0]*v[1]-u[1]*v[0]),u[1]*v[1]])

def fmaal(u,v):
    return vereenvoudig([u[0]*v[0],u[1]*v[1]])

def fdeel(u,v):
    return vereenvoudig([u[0]*v[1],u[1]*v[0]])

def fop(u,v,op):
    if op == 0:
        return fplus(u,v)
    if op == 1:
        return fmin(u,v)
    if op == 2:
        return fmaal(u,v)
    if op == 3:
        return fdeel(u,v)

def flippo(Q):
    a = Q[0]
    b = Q[1]
    c = Q[2]
    d = Q[3]
    S = []
    perms = permutations([a,b,c,d]) 
    lipe = list(perms)
    lipe.sort()
    for elt in lipe:
        for u1 in range(4):
            r1 = fop([elt[0],1],[elt[1],1],u1)
            for u2 in range(4):
                r2a = fop([elt[2],1],r1,u2)
                r2b = fop(r1,[elt[2],1],u2)
                r2c = fop([elt[2],1],[elt[3],1],u2)
                for u3 in range(4):
                    r3a = fop([elt[3],1],r2a,u3)
                    r3b = fop([elt[3],1],r2b,u3)
                    r3c = fop(r2a,[elt[3],1],u3)
                    r3d = fop(r2b,[elt[3],1],u3)
                    r3e = fop(r1,r2c,u3)
                    if (r3a[0] not in S) & (r3a[0] < 101) & (r3a[0] > 0) & (r3a[1] == 1):
                        S.append(r3a[0])
                    if (r3b[0] not in S) & (r3b[0] < 101) & (r3b[0] > 0) & (r3b[1] == 1):
                        S.append(r3b[0])
                    if (r3c[0] not in S) & (r3c[0] < 101) & (r3c[0] > 0) & (r3c[1] == 1):
                        S.append(r3c[0])
                    if (r3d[0] not in S) & (r3d[0] < 101) & (r3d[0] > 0) & (r3d[1] == 1):
                        S.append(r3d[0])
                    if (r3e[0] not in S) & (r3e[0] < 101) & (r3e[0] > 0) & (r3e[1] == 1):
                        S.append(r3e[0])
    return len(S)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (1, 2, 3, 4, 5, 6)
Dobbelsteen3 = (1, 2, 3, 4, 5, 6)
Dobbelsteen4 = (1, 2, 3, 4, 5, 6)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (7, 8, 9, 10, 11, 12)
Dobbelsteen3 = (13, 14, 15, 16, 17, 18)
Dobbelsteen4 = (19, 20, 21, 22, 23, 24)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (2, 4, 6, 8, 10, 12)
Dobbelsteen3 = (3, 6, 9, 12, 15, 18)
Dobbelsteen4 = (4, 8, 12, 16, 20, 24)

# Oplossing van Lance Bakker
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 10)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (9, 11, 12, 13, 14, 15)

# Oplossing van Casper de With
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 7, 8)
Dobbelsteen3 = (2, 3, 4, 5, 6, 9)
Dobbelsteen4 = (10, 11, 12, 14, 15, 18)

t0 = time.process_time()
geslaagd = 0
for a1 in Dobbelsteen1:
    for a2 in Dobbelsteen2:
        for a3 in Dobbelsteen3:
            for a4 in Dobbelsteen4:
                Q = [a1,a2,a3,a4]
                f = flippo(Q)
                geslaagd += f
t1 = time.process_time()
print(round(geslaagd/1296,2),"% door", \
      Dobbelsteen1, Dobbelsteen2, Dobbelsteen3, Dobbelsteen4)
T = t1-t0
M = math.floor(T / 60)
print("Rekentijd:", M, "minuten", T - 60*M, "seconden")

Conform de ideeen van Casper wordt hieronder een database aangemaakt met records die twee getallen bevatten $(N, C)$, waarbij $N=g^3 \star a + g^2 \star b + g \star c + d$ en $C$ is het aantal oplossingen in de range $[1 \ldots 100]$ voor het viertal $(a,b,c,d)$. Maar er kunnen nog een aantal slimmigheden worden toegevoegd:

  1. $1\le a\le b\le c\le d$. Dus niet alle mogelijkheden hoeven opgeslagen te worden. Door slim uitlezen hoeft alleen $C$ opgeslagen te worden.
  2. De formule van $(a,b,c,d)$ naar $N$ is als volgt: $C_2(n) = \frac{1}{2}n(n+1)$, $C_3(n)=\frac{1}{6}n(n+1)(n+2)$ en $C_4(n)=\frac{1}{24}n(n+1)(n+2)(n+3).$ $N=a+C_2(b)+C_3(c)+C_4(d)$.
# Programma 4: Berekening om externe data te creeren. 
# Zie beschrijving hier boven en programma 7.
# Op mijn computer kostte de berekening 22 minuten. Maar ik bereken alle combinaties
# t/m 40. In principe volstaat 24. Dat scheelt aanzienlijk, ook qua opslag!
# Let op: De constante DIR moet mogelijk worden aangepast.
import time
import math
from itertools import permutations 

def Line_To_Num(line, T):
    S = data.split(",")
    for s in S:
        if s not in ["", "\n"]:
            T.append(int(s))
    return 

def vereenvoudig(u):
    g = math.gcd(u[0],u[1])
    if g == 0:
        return ([0,0])
    else:
        return ([u[0]//g,u[1]//g])

def fplus(u,v):
    return vereenvoudig([u[0]*v[1]+u[1]*v[0],u[1]*v[1]])

def fmin(u,v):
    return vereenvoudig([abs(u[0]*v[1]-u[1]*v[0]),u[1]*v[1]])

def fmaal(u,v):
    return vereenvoudig([u[0]*v[0],u[1]*v[1]])

def fdeel(u,v):
    return vereenvoudig([u[0]*v[1],u[1]*v[0]])

def fop(u,v,op):
    if op == 0:
        return fplus(u,v)
    if op == 1:
        return fmin(u,v)
    if op == 2:
        return fmaal(u,v)
    if op == 3:
        return fdeel(u,v)

def flippo(Q):
    a = Q[0]
    b = Q[1]
    c = Q[2]
    d = Q[3]
    S = []
    perms = permutations([a,b,c,d]) 
    lipe = list(perms)
    lipe.sort()
    for elt in lipe:
        for u1 in range(4):
            r1 = fop([elt[0],1],[elt[1],1],u1)
            for u2 in range(4):
                r2a = fop([elt[2],1],r1,u2)
                r2b = fop(r1,[elt[2],1],u2)
                r2c = fop([elt[2],1],[elt[3],1],u2)
                for u3 in range(4):
                    r3a = fop([elt[3],1],r2a,u3)
                    r3b = fop([elt[3],1],r2b,u3)
                    r3c = fop(r2a,[elt[3],1],u3)
                    r3d = fop(r2b,[elt[3],1],u3)
                    r3e = fop(r1,r2c,u3)
                    if (r3a[0] not in S) & (r3a[0] < 101) & (r3a[0] > 0) & (r3a[1] == 1):
                        S.append(r3a[0])
                    if (r3b[0] not in S) & (r3b[0] < 101) & (r3b[0] > 0) & (r3b[1] == 1):
                        S.append(r3b[0])
                    if (r3c[0] not in S) & (r3c[0] < 101) & (r3c[0] > 0) & (r3c[1] == 1):
                        S.append(r3c[0])
                    if (r3d[0] not in S) & (r3d[0] < 101) & (r3d[0] > 0) & (r3d[1] == 1):
                        S.append(r3d[0])
                    if (r3e[0] not in S) & (r3e[0] < 101) & (r3e[0] > 0) & (r3e[1] == 1):
                        S.append(r3e[0])
    return len(S)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (1, 2, 3, 4, 5, 6)
Dobbelsteen3 = (1, 2, 3, 4, 5, 6)
Dobbelsteen4 = (1, 2, 3, 4, 5, 6)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (7, 8, 9, 10, 11, 12)
Dobbelsteen3 = (13, 14, 15, 16, 17, 18)
Dobbelsteen4 = (19, 20, 21, 22, 23, 24)

Dobbelsteen1 = (1, 2, 3, 4, 5, 6)
Dobbelsteen2 = (2, 4, 6, 8, 10, 12)
Dobbelsteen3 = (3, 6, 9, 12, 15, 18)
Dobbelsteen4 = (4, 8, 12, 16, 20, 24)

# Oplossing van Lance Bakker
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 10)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (9, 11, 12, 13, 14, 15)

# Oplossing van Casper de With
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 7, 8)
Dobbelsteen3 = (2, 3, 4, 5, 6, 9)
Dobbelsteen4 = (10, 11, 12, 14, 15, 18)

#DIR = "/home/matcos/Documenten/Pythagoras/Python/Jaargang 59/59 Dobbelstenen/"
DIR = "./"
DATA = "DobbelCombinaties.txt"
dfout = DIR+DATA
fout = open(dfout, "w")
t0 = time.process_time()
GOAL = 40
OLDT = 0
cnt = 0
for b1 in range(GOAL):
    a1 = b1 + 1
    for b2 in range(a1):
        a2 = b2 + 1
        for b3 in range(a2):
            a3 = b3 + 1
            for b4 in range(a3):
                a4 = b4 + 1
                Q = [a4,a3,a2,a1]
                f = flippo(Q)
                fout.write(str(f))
                fout.write(",")
                cnt += 1
                if cnt % 25 == 0:
                    fout.write("\n")
    T = math.floor(100*a1*a1*a1*a1/(GOAL*GOAL*GOAL*GOAL))
    if T > OLDT:
        OLDT = T
        print(T, "% gedaan")
fout.close()
CC = []
t1 = time.process_time()
T = math.floor(100*(t1-t0))
M = math.floor(T / 6000)
print("Rekentijd:", M, "minuten", T/100 - 60*M, "seconden")
dfin = DIR+DATA
fin = open(dfin, "r")
data = fin.readline()
ld = len(data)
while ld > 0:
    Line_To_Num(data,CC)
    data = fin.readline()
    ld = len(data)
print(len(CC))

 

# Programma 5: Berekening met externe data, die relatief snel is te berekenen.
# Externe data staat eveneens op de site, maar kan ook met programma 4 worden 
# gegenereerd.
# In dit programma heb ik geprobeerd om een nog beter resultaat te vinden.
# Let op: De constante DIR moet mogelijk worden aangepast.
import time
import math

def C2(n):
    return math.floor(n*(n+1)/2)
def C3(n):
    return math.floor(n*(n+1)*(n+2)/6)
def C4(n):
    return math.floor(n*(n+1)*(n+2)*(n+3)/24)

def NC(a,b,c,d):
    return a-1 + C2(b-1) + C3(c-1) + C4(d-1)
def NX(N):
    d = 0
    while C4(d) <= N:
        d += 1
    d -= 1
    c = 0
    while C3(c) <= N - C4(d):
        c += 1
    c -= 1
    b = 0
    while C2(b) <= N - C4(d) - C3(c):
        b += 1
    b -= 1
    a = N - C4(d) - C3(c) - C2(b)
    return (a+1,b+1,c+1,d+1)

CC = []
#DIR = "/home/matcos/Documenten/Pythagoras/Python/Jaargang 59/59 Dobbelstenen/"
DIR = "./"
DATA = "DobbelCombinaties.txt"
dfin = DIR+DATA
fin = open(dfin, "r")
data = fin.readline()
ld = len(data)
while ld > 0:
    Line_To_Num(data,CC)
    data = fin.readline()
    ld = len(data)
lcc = len(CC)
print("Inlezen geslaagd,",lcc,"combinaties.")
maxCC = 0
M = []
for i in range(lcc):
    c = CC[i]
    if c == maxCC:
        M.append(i)
    if c > maxCC:
        maxCC = c
        M = [i]
print ("Maximum",maxCC, "voor:")
for m in M:
    print (NX(m))
for k in range(5):
    print (maxCC-1-k, "voor:")
    for i in range(lcc):
        c = CC[i]
        if c == maxCC-1-k:
            print (NX(i))
print("Ready")

 

# Programma 6: Berekening met externe data, die relatief snel is te berekenen.
# Externe data staat eveneens op de site (zie: [Documenten], maar moet dan nog als .txt 
# opgeslagen worden (zonder opmaak). 
# De data kan ook met programma 4 worden gegenereerd.
# Let op: De constante DIR moet mogelijk worden aangepast.
import time
import math
import random

def C2(n):
    return math.floor(n*(n+1)/2)
def C3(n):
    return math.floor(n*(n+1)*(n+2)/6)
def C4(n):
    return math.floor(n*(n+1)*(n+2)*(n+3)/24)

def NC(a,b,c,d):
    return a-1 + C2(b-1) + C3(c-1) + C4(d-1)
def NX(N):
    d = 0
    while C4(d) <= N:
        d += 1
    d -= 1
    c = 0
    while C3(c) <= N - C4(d):
        c += 1
    c -= 1
    b = 0
    while C2(b) <= N - C4(d) - C3(c):
        b += 1
    b -= 1
    a = N - C4(d) - C3(c) - C2(b)
    return (a+1,b+1,c+1,d+1)

def CNTset(D):
    sum = 0
    D1 = (D[0],D[1],D[2],D[3],D[4],D[5])
    D2 = (D[6],D[7],D[8],D[9],D[10],D[11])
    D3 = (D[12],D[13],D[14],D[15],D[16],D[17])
    D4 = (D[18],D[19],D[20],D[21],D[22],D[23])
    for a in D1:
        for b in D2:
            for c in D3:
                for d in D4:
                    S = [a,b,c,d]
                    S.sort()
                    IX = NC(S[0], S[1], S[2], S[3])
                    sum += CC[IX]
    return sum

DD = [
[2, 2, 2, 2, 2, 2,  3, 3, 3, 3, 3, 3,  6, 6, 6, 6, 6, 6,  22, 22, 22, 22, 22, 22],
[1, 2, 3, 4, 5, 6,  1, 2, 3, 4, 5, 6,  1, 2, 3, 4, 5, 6,  1, 2, 3, 4, 5, 6],
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,  19, 20, 21, 22, 23, 24],
[9, 10, 11, 13, 14, 15,   2, 3, 4, 5, 6, 8,  2, 3, 4, 7, 10, 12,  2, 3, 4, 5, 6, 8],
[9, 10, 12, 14, 16, 18,   2, 3, 4, 5, 6, 7,  2, 4, 6, 8, 10, 12,  3, 4, 5, 6, 7, 8],
[9, 11, 12, 13, 14, 15,   2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 10,   2, 3, 4, 5, 7, 8], 
[9, 11, 12, 13, 14, 16,   2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 10,   2, 3, 4, 5, 7, 6],
[9, 11, 12, 13, 14, 22,   2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 10,   2, 3, 4, 5, 7, 8],
[9, 11, 12, 14, 15, 18,   2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 10],
[9, 11, 13, 14, 15, 18,   2, 3, 4, 5, 6, 7,  2, 3, 4, 8, 10, 12,  2, 3, 4, 5, 6, 8],
[9, 11, 13, 14, 15, 18,   2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 10,   2, 3, 4, 5, 7, 8],
[9, 11, 13, 14, 15, 19,   2, 3, 4, 5, 6, 7,  2, 3, 4, 8, 10, 12,  2, 3, 4, 5, 6, 8],
[10, 11, 12, 13, 14, 15,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 8,    2, 3, 4, 5, 7, 9],
[10, 11, 12, 13, 14, 15,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 9],
[10, 11, 12, 14, 15, 16,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 10],
[10, 11, 12, 14, 15, 18,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 9],
[10, 11, 12, 14, 16, 18,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 9],
[10, 12, 13, 14, 15, 18,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 7, 8,    2, 3, 4, 5, 6, 10],
[11, 12, 13, 14, 15, 18,  2, 3, 4, 5, 6, 7,  2, 3, 4, 5, 6, 10,   2, 3, 4, 5, 7, 8]
     ]
#DD = []
# Oplossing van Casper de With (64.4282 %)
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 9)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (10, 11, 12, 14, 15, 18)

# Oplossing van Lance Bakker (64.4360 %)
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 10)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (9, 11, 12, 13, 14, 15)

# Oplossing van Daan de Groot (64.4491 %)
Dobbelsteen1 = (2, 3, 4, 5, 6, 7)
Dobbelsteen2 = (2, 3, 4, 5, 6, 10)
Dobbelsteen3 = (2, 3, 4, 5, 7, 8)
Dobbelsteen4 = (11, 12, 13, 14, 15, 18)

CC = []
#DIR = "/home/matcos/Documenten/Pythagoras/Python/Jaargang 59/59 Dobbelstenen/"
DIR = "./"
DATA = "DobbelCombinaties.txt"
dfin = DIR+DATA
fin = open(dfin, "r")
data = fin.readline()
ld = len(data)
while ld > 0:
    Line_To_Num(data,CC)
    data = fin.readline()
    ld = len(data)
lcc = len(CC)
print("Inlezen geslaagd,",lcc,"combinaties.")

for D in DD:
    sum = CNTset(D)
    D1 = (D[0],D[1],D[2],D[3],D[4],D[5])
    D2 = (D[6],D[7],D[8],D[9],D[10],D[11])
    D3 = (D[12],D[13],D[14],D[15],D[16],D[17])
    D4 = (D[18],D[19],D[20],D[21],D[22],D[23])
    DS = [D1,D2,D3,D4]
    DS.sort()
    [D1,D2,D3,D4] = DS
    print(sum, round(sum/1296,4),"% door\n   ", D1, D2, D3, D4)
N = 1000
for j in range(20):
    D = [9, 11, 12, 14, 18, 22, 2, 3, 4, 5, 6, 8, 2, 3, 4, 5, 6, 11, 2, 3, 4, 5, 7, 9 ]
    maxd = CNTset(D)
    Dmax = []
    for d in D:
        Dmax.append(d)
    for i in range(N):
        for z in range(3):
            k = random.randint(0, 47)
            if k > 23:
                k -= 24
                if D[k] > 1:
                    D[k] -= 1
                while k > 0:
                    if D[k] == D[k-1]:
                        D[k-1] -= 1
                    k -= 1
            else:
                D[k] += 1
                while k < 23:
                    if D[k] == D[k+1]:
                        D[k+1] += 1
                    k += 1
        r = CNTset(D)
        if r >= maxd-81:
            maxd = r
            Dmax = []
            for d in D:
                Dmax.append(d)
        else:
            D = []
            for d in Dmax:
                D.append(d)
    if maxd/1296 > 64.4:
        print (j, round(maxd/1296,4),"%", Dmax)
print("Ready")

 

# Programma 7: Experiment om met combinaties te werken.
import math
def C2(n):
    return math.floor(n*(n+1)/2)
def C3(n):
    return math.floor(n*(n+1)*(n+2)/6)
def C4(n):
    return math.floor(n*(n+1)*(n+2)*(n+3)/24)

def NC(a,b,c,d):
    return a-1 + C2(b-1) + C3(c-1) + C4(d-1)
    
t0 = time.process_time()
GOAL = 40
cnt = 0
for b1 in range(GOAL):
    a1 = b1 + 1
    for b2 in range(a1):
        a2 = b2 + 1
        for b3 in range(a2):
            a3 = b3 + 1
            for b4 in range(a3):
                a4 = b4 + 1
                cnt += 1
    print(a1, math.floor(100*a1*a1*a1*a1/(GOAL*GOAL*GOAL*GOAL)), "% gedaan", cnt)
t1 = time.process_time()
GOAL = 4
cnt = 0
for b1 in range(GOAL):
    a1 = b1 + 1
    for b2 in range(a1):
        a2 = b2 + 1
        for b3 in range(a2):
            a3 = b3 + 1
            for b4 in range(a3):
                a4 = b4 + 1
                print(a4,a3,a2,a1,NC(a4,a3,a2,a1), cnt)
                cnt += 1
    print(a1, math.floor(100*a1*a1*a1*a1/(GOAL*GOAL*GOAL*GOAL)), "% gedaan", cnt)