import string
letters = string.ascii_uppercase
global letters26
letters26 = [*letters]
#Generate all 26!/(26-5)! five letter orders.
#
#Returns a list of 26!/(26-5)! quintuples.
#Each quintuple has a unique order of five integers from 1-26.
def letterOrders():
#Each letter is a number
#Final list.
letter_orders = []
#Current order of five letters.
five_letters = []
for l1 in letters26 :
#Add the first letter.
five_letters.append(l1)
#Make a copy and remove that letter.
letters25 = letters26.copy()
letters25.remove(l1)
for l2 in letters25 :
#Add the second letter.
five_letters.append(l2)
#Make a copy and remove that letter.
letters24 = letters25.copy()
letters24.remove(l2)
for l3 in letters24 :
#Add the third letter.
five_letters.append(l3)
#Make a copy and remove that letter.
letters23 = letters24.copy()
letters23.remove(l3)
for l4 in letters23 :
#Add the fourth letter.
five_letters.append(l4)
#Make a copy and remove that letter.
letters22 = letters23.copy()
letters22.remove(l4)
for l5 in letters22 :
#Add the fifth letter.
five_letters.append(l5)
#Append quintuple to final list.
letter_orders.append(five_letters)
#Remove fifth letter for next fifth letter.
five_letters = five_letters[:-1]
#Remove fourth letter for next fourth letter.
five_letters = five_letters[:-1]
#Remove third letter for next third letter.
five_letters = five_letters[:-1]
#Remove second letter for next second letter.
five_letters = five_letters[:-1]
#Remove first letter for next first letter.
five_letters = five_letters[:-1]
return(letter_orders)
#Inputs slots and bounds list.
#Changes all bounds of [] to [lower, upper].
#Slot in slots with [single_letter] remain unchanged.
#Returns slots.
def updateBounds(slots):
bounds = []
#Look at all the slots with a single letter.
for slot in slots.keys():
bound = slots[slot]
if len(bound) == 1:
#Saves ordered pair of slot and letter.
bounds.append((slot, bound))
#Creates new, equal ranges for each slot between two letters in slots.
#For every index in length of bounds up to the second to last.
for i in range(0, len(bounds) - 1):
#Get the slot number and letter
slot_min = bounds[i][0]
bound_min = bounds[i][1][0]
slot_max = bounds[i+1][0]
bound_max = bounds[i+1][1][0]
#d is the number of slots between two current.
#If it is 0, there are no slots to fill.
d = slot_max - slot_min - 1
if d == 0:
pass
else:
#Divide number of letters by number of slots.
j = (ord(bound_max) - ord(bound_min) - 1) / (slot_max - slot_min - 1)
#Decimal carryover to keep lists as close to equal as possible.
carryover = 0
#For each slot between the current two,
for slot in range(slot_min+1, slot_max):
#The lower limit = (upper of previous slot) + 1.
lower = ord(slots[slot-1][-1]) + 1
#If it is the last slot to be filled, the upper limit = (lower of next slot) - 1.
if slot == slot_max - 1:
upper = ord(slots[slot_max][0]) - 1
#If not create upper from lower, range, and carryover.
#Update the carryover.
else:
upper = lower + round(j + carryover)-1
carryover += j - round(j + carryover)
#Update the slot.
slots[slot] = [chr(lower), chr(upper)]
return(slots)
#Inputs slots and bounds list, as well as a new letter.
#Replaces the appropriate slot's bounds with the new letter.
#Clears all other bounds.
#Returns either "Loss" or updated slots.
def updateSlots(slots, letter):
#Boolean to continue or not.
cont = False
#Look at all the slots with two bounds, no single letter.
for slot in slots.keys():
bound = slots[slot]
if len(bound) == 2:
#If the new letter fits in the bounds, place it there.
if bound[0]<= letter and letter <= bound[1]:
slots[slot] = [letter]
#Letter can fit, continue.
cont = True
#All other bounds should become blank.
else:
slots[slot] = []
#If after all slots no change, we cannot continue.
if cont == False:
return("Loss")
else:
return(slots)
letter_orders = letterOrders()
wins = 0
loss = 0
for lo in letter_orders:
#Initiate slots.
slots = {0 : ['@'],
1 : [],
2 : [],
3 : [],
4 : [],
5 : [],
6 : ['[']}
#For each letter in lo,
for i in range(5):
#Update bounds, try to fit letter in bounds.
slots = updateBounds(slots)
letter = lo[i]
slots = updateSlots(slots, letter)
#At any point, updateBounds could return "Loss".
if slots == "Loss" :
loss += 1
break
#If five loops are completed, win!
else :
if i == 4 :
wins += 1
print(wins, loss)
1948258 5945342
def printable(slots):
if slots == "Loss" :
return(slots)
else:
printable = ""
for i in range(1,6) :
v = list(slots.values())[i]
if v == []:
s = "__"
else:
s = v[0]
if len(v) == 2:
s = "[" + v[0]+ "," + v[1] + "]"
if i < 5 :
printable += s + "--"
else :
printable += s
return(printable)
#Random letter order.
lo = letter_orders[5432345]
print(lo)
#Initiate slots.
slots = {0 : ['@'],
1 : [],
2 : [],
3 : [],
4 : [],
5 : [],
6 : ['[']}
print(printable(slots))
#For each letter in lo,
for i in range(5):
print("")
print("")
#Update bounds, try to fit letter in bounds.
letter = lo[i]
print("Fit " + letter + " in slot bounds.")
slots = updateBounds(slots)
print(printable(slots))
letter = lo[i]
slots = updateSlots(slots, letter)
print(printable(slots))
#At any point, updateBounds could return "Loss".
if slots == "Loss" :
break
['R', 'X', 'H', 'V', 'T'] __--__--__--__--__ Fit R in slot bounds. [A,E]--[F,J]--[K,P]--[Q,U]--[V,Z] __--__--__--R--__ Fit X in slot bounds. [A,F]--[G,K]--[L,Q]--R--[S,Z] __--__--__--R--X Fit H in slot bounds. [A,F]--[G,K]--[L,Q]--R--X __--H--__--R--X Fit V in slot bounds. [A,G]--H--[I,Q]--R--X Loss