Pythoncode bij NIM

Deel 1

# Nim
# Invoer: NimSet
# Uitvoer: PeriodeDD en StartDD

import math

def BerekenVolgendeVerlies(NimSet, NimVerlies):
    L = len(NimVerlies)
    LaatsteVerlies = NimVerlies[L-1]
    VolgendeVerlies = LaatsteVerlies
    OK = True
    while OK == True:
        VolgendeVerlies += 1
        OK = False
        for i in NimSet:
            if (VolgendeVerlies > i) & (VolgendeVerlies-i in NimVerlies):
            OK = True
    return VolgendeVerlies

def CheckPeriodeDD(PeriodeDD, NimDD, StartDDLen, M):
    PeriodeLen = 0
    for v in PeriodeDD:
        PeriodeLen += v
    num = math.ceil(M / PeriodeLen)
    if num < 2:
        num = 2
    NimDDLen = len(NimDD)
    PeriodeDDLen = len(PeriodeDD)
    #print(StartDDLen, PeriodeDDLen, NimDDLen, M, num)
    if NimDDLen < StartDDLen + num * PeriodeDDLen:
        return False
    ok = 0
    for n in range(num):
        for p in range(PeriodeDDLen):
            if PeriodeDD[p] == NimDD[StartDDLen + p + n*PeriodeDDLen]:
                ok += 1
    return ok == num * PeriodeDDLen

NimVerlies = [1]
NimDD = []
NimWinst = [] # Wordt niet gebruikt
NimRemise = [] # Wordt met deze settings niet gebruikt
# Voorbeelden van NimSet
NimSet = [1, 8, 15, 16]
NimSet = [1, 4, 9, 10]
NimSet = [1, 6, 9]
NimSet = [1, 4, 5, 10]
LenNimSet = len(NimSet)
M = NimSet[LenNimSet-1]
VolgendeVerlies = 1
LaatsteVerlies = 1
while VolgendeVerlies < 2*M:
    VolgendeVerlies = BerekenVolgendeVerlies(NimSet, NimVerlies)
    NimDD.append(VolgendeVerlies - LaatsteVerlies)
    NimVerlies.append(VolgendeVerlies)
    LaatsteVerlies = VolgendeVerlies
PeriodeGevonden = False
while not PeriodeGevonden:
    VolgendeVerlies = BerekenVolgendeVerlies(NimSet, NimVerlies)
    NimDD.append(VolgendeVerlies - LaatsteVerlies)
    NimVerlies.append(VolgendeVerlies)
    LaatsteVerlies = VolgendeVerlies
    NimDDLen = len(NimDD)
    StartDD = []
    StartDDLen = 0
    PeriodeDD = []
    PeriodeDDLen = 0
    while (not PeriodeGevonden) & (StartDDLen + 2 * PeriodeDDLen < NimDDLen) & (NimDDLen - StartDDLen >= 4):
        while (not PeriodeGevonden) & (StartDDLen + 2 * PeriodeDDLen < NimDDLen):
            PeriodeDD.append(NimDD[StartDDLen + PeriodeDDLen])
            PeriodeDDLen += 1
            PeriodeGevonden = CheckPeriodeDD(PeriodeDD, NimDD, StartDDLen, M)
        if not PeriodeGevonden:
            StartDD.append(NimDD[StartDDLen])
            StartDDLen += 1
            PeriodeDD = []
            PeriodeDDLen = 0
if StartDDLen > 0:
    print(NimSet, ":", PeriodeDD, "Start", StartDD)
else:
    print(NimSet, ":", PeriodeDD)
print("Ready")

Deel 2

# Nim
# Invoer: MM
# Uitvoer: PeriodeDD en StartDD voor alle (unieke) NimSet met M <= MM

import math
import numpy

def BerekenVolgendeVerlies(NimSet, NimVerlies):
    L = len(NimVerlies)
    LaatsteVerlies = NimVerlies[L-1]
    VolgendeVerlies = LaatsteVerlies
    OK = True
    while OK == True:
        VolgendeVerlies += 1
        OK = False
        for i in NimSet:
            if (VolgendeVerlies > i) & (VolgendeVerlies-i in NimVerlies):
                OK = True
    return VolgendeVerlies

def CheckPeriodeDD(PeriodeDD, NimDD, StartDDLen, M):
    PeriodeLen = 0
    for v in PeriodeDD:
        PeriodeLen += v
    num = math.ceil(M / PeriodeLen)
    if num < 2:
        num = 2
    NimDDLen = len(NimDD)
    PeriodeDDLen = len(PeriodeDD)
    #print(StartDDLen, PeriodeDDLen, NimDDLen, M, num)
    if NimDDLen < StartDDLen + num * PeriodeDDLen:
        return False
    ok = 0
    for n in range(num):
        for p in range(PeriodeDDLen):
            if PeriodeDD[p] == NimDD[StartDDLen + p + n*PeriodeDDLen]:
                ok += 1
    return ok == num * PeriodeDDLen

def BerekenNimPeriode(NimSet):
    NimVerlies = [1]
    NimDD = []
    LenNimSet = len(NimSet)
    M = NimSet[LenNimSet-1]
    VolgendeVerlies = 1
    LaatsteVerlies = 1
    while VolgendeVerlies < 2*M:
        VolgendeVerlies = BerekenVolgendeVerlies(NimSet, NimVerlies)
        NimDD.append(VolgendeVerlies - LaatsteVerlies)
        NimVerlies.append(VolgendeVerlies)
        LaatsteVerlies = VolgendeVerlies
    PeriodeGevonden = False
    while not PeriodeGevonden:
        VolgendeVerlies = BerekenVolgendeVerlies(NimSet, NimVerlies)
        NimDD.append(VolgendeVerlies - LaatsteVerlies)
        NimVerlies.append(VolgendeVerlies)
        LaatsteVerlies = VolgendeVerlies
        NimDDLen = len(NimDD)
        StartDD = []
        StartDDLen = 0
        PeriodeDD = []
        PeriodeDDLen = 0
        while (not PeriodeGevonden) & (StartDDLen + 2 * PeriodeDDLen < NimDDLen) & (NimDDLen - StartDDLen >= 4):
            while (not PeriodeGevonden) & (StartDDLen + 2 * PeriodeDDLen < NimDDLen):
                PeriodeDD.append(NimDD[StartDDLen + PeriodeDDLen])
                PeriodeDDLen += 1
                PeriodeGevonden = CheckPeriodeDD(PeriodeDD, NimDD, StartDDLen, M)
            if not PeriodeGevonden:
                StartDD.append(NimDD[StartDDLen])
                StartDDLen += 1
                PeriodeDD = []
                PeriodeDDLen = 0
    if StartDDLen > 0:
    return [PeriodeDD, StartDD]
    else:
    return [PeriodeDD]

MM = 10
PS_Set = []
kM = numpy.power(2,MM)
cnt = 0
for k in range(kM):
    NimSet = [1]
    c = 2
    while k > 0:
        if k % 2 == 1:
            NimSet.append(c)
        k = k // 2
        c += 1
    PS = BerekenNimPeriode(NimSet)
    PeriodeLen = 0
    for p in PS[0]:
        PeriodeLen += p
    if not PS in PS_Set:
        cnt += 1
        if len(PS) == 2:
            print(cnt, NimSet, ": (", PeriodeLen, ")", PS[0], "Start:", PS[1])
        else:
            print(cnt, NimSet, ": (", PeriodeLen, ")", PS[0])
        PS_Set.append(PS)
print("Ready")

Deel 3

# Nim
# De gebruikte procedures staan hier boven
# Uitvoer: uitsluitend de NimSet met langste periode per M

MM = 19
PS_Set = []
kM = numpy.power(2,MM)
cnt = 0
M0 = 0
PeriodeLenMax = 0
for k in range(kM):
    NimSet = [1]
    c = 2
    while k > 0:
        if k % 2 == 1:
            NimSet.append(c)
        k = k // 2
        c += 1
    NimSetLen = len(NimSet)
    M = NimSet[NimSetLen - 1]
    if M > M0:
        if PeriodeLenMax > 0:
            print(M0, NimSetMax, PeriodeLenMax, PSMax)
        M0 = M
        PeriodeLenMax = 0
    PS = BerekenNimPeriode(NimSet)
    PeriodeLen = 0
    for p in PS[0]:
        PeriodeLen += p
    if PeriodeLen > PeriodeLenMax:
        PeriodeLenMax = PeriodeLen
        NimSetMax = NimSet
        PSMax = PS[0]
print(M, NimSetMax, PeriodeLenMax, PSMax)
print("Ready")

Deel 4

# Nim
# De gebruikte procedures staan hier boven
# Uitvoer: uitsluitend NimSets met start groter dan 0

MM = 10
PS_Set = []
kM = numpy.power(2,MM)
cnt = 0
M0 = 0
PeriodeLenMax = 0
for k in range(kM):
    NimSet = [1]
    c = 2
    while k > 0:
        if k % 2 == 1:
            NimSet.append(c)
        k = k // 2
        c += 1
    NimSetLen = len(NimSet)
    PS = BerekenNimPeriode(NimSet)
    if len(PS) > 1:
        PeriodeLen = 0
        for p in PS[0]:
            PeriodeLen += p
        StartLen = 0
        for p in PS[1]:
            StartLen += p
        print(NimSet, PeriodeLen, StartLen, PS[0], PS[1])
print("Ready")