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")