# iteration 18 debugged exhaustively and now prepares for exportation """ Instructions for use, with the following grid as an example. X 0 0 3 3 0 0 4 X 0 2 0 4 3 3 4 0 0 3 0 0 2 5 2 1 0 X 3 0 0 0 4 0 0 X The program first asks for the size of the puzzle. For example, if you are playing this 7 by 7, then you enter the integer 7 as the size of the puzzle. Remember, the border numbers are just constraints, and not actually part of the puzzle grid, which is why this is considered a 7 by 7 puzzle. The program then asks for the border numbers. These are the numbers on the outside of the grid. If a border number is blank, then enter 0. You must enter an integer of length 4 times the size of the puzzle. For example, you could enter 0033004244005000400032030300. The program lastly asks for any givens. They are entered as a 3 digit integer in which the first digit is the row number, the second is the column number, and the last is the value itself. Enter 000 when you are done entering givens. For example, you might enter 343, 612, and 741. The program will then run. If it is able to solve the puzzle, it will verify its answer, and if it is correct, it will display the time it took to solve the puzzle along with the completed grid. If the program makes an error, it will display as much of the grid that it completed, and notify that it made an error. This error could be either because of a bug in the code, of which there are several left, or because the given puzzle has no actual solution. Please see the bottom of the code for a recent history of additions and changes, along with the grids being used for testing. """ print("Algorithm starting...") import random import time import itertools import urllib.request with open(r"C:\Users\glsap\Downloads\readme.txt","w") as f: facade=("Printing and grid manipulation") def gridtotextfile(size,fullgrid): f.write(str(fullgrid)) f.write("\n") for i in range(size+2): for j in range(size+2): f.write(str(fullgrid[i][j])+"\t\t") f.write("\n") f.write("\n") def printgridfinal(size,fullgrid): for i in range(size+2): for j in range(size+2): print(str(fullgrid[i][j])+"\t\t",end="") print("\n\n") def printgrid(size,fullgrid): gridfilledblanks=duplicategrid(size,fullgrid) for i in range(size+2): # top border print(" "+str(gridfilledblanks[0][i])+"\t\t",end="") print("\n -",end="") for i in range(size): print("--------",end="") print("") for i in range(1,size+1): # middle chunk print("\t|",end="") for j in range(1,size+1): print("\t",end="") if type(gridfilledblanks[i][j])==list: if 1 in gridfilledblanks[i][j]: print("1",end="") else: print(" ",end="") if 2 in gridfilledblanks[i][j]: print("2",end="") else: print(" ",end="") if 3 in gridfilledblanks[i][j]: print("3",end="") else: print(" ",end="") print("\t",end="") print(" |") print(" "+str(gridfilledblanks[i][0]),end="") # left border print("\t|",end="") for j in range(1,size+1): print("\t",end="") if type(gridfilledblanks[i][j])==list: if 4 in gridfilledblanks[i][j]: print("4",end="") else: print(" ",end="") if 5 in gridfilledblanks[i][j]: print("5",end="") else: print(" ",end="") if 6 in gridfilledblanks[i][j]: print("6",end="") else: print(" ",end="") if type(gridfilledblanks[i][j])==int: print("",'\033[4m' + str(gridfilledblanks[i][j]) + '\033[0m',end="") print("\t",end="") print(" |",end="") print(" "+str(gridfilledblanks[i][size+1])) # right border print("\t|",end="") for j in range(1,size+1): print("\t",end="") if type(gridfilledblanks[i][j])==list: if 7 in gridfilledblanks[i][j]: print("7",end="") else: print(" ",end="") if 8 in gridfilledblanks[i][j]: print("8",end="") else: print(" ",end="") if 9 in gridfilledblanks[i][j]: print("9",end="") else: print(" ",end="") print("\t",end="") print(" |",end="") if i!=size: print("\n | ",end="") for i in range(size): print(" ",end="") print("|") else: print("\n -",end="") for i in range(size): print("--------",end="") print("") for i in range(size+2): # low border print(" "+str(gridfilledblanks[size+1][i])+"\t\t",end="") print("\n") def duplicategrid(size,fullgrid): duplicategrid=[] for i in range(size+2): duplicategrid.append([]) for i in range(size+2): for j in range(size+2): duplicategrid[i].append([]) for i in range(size+2): for j in range(size+2): duplicategrid[i][j]=fullgrid[i][j] return duplicategrid def noteinversion(nodesnotes,possiblevalueslist): possiblevalues=possiblevalueslist[:] for i in range(len(nodesnotes)): possiblevalues.remove(nodesnotes[i]) return possiblevalues def webscraper(length): inputgrids=[] for i in range(length): newgrid=[6] print("Scraping grid "+str(i+1)+" of "+str(length)) url = "https://www.puzzle-skyscrapers.com/?size=8" urllib.request.urlopen(url) request_url = urllib.request.urlopen(url) htmldump=str(request_url.read()) initial=htmldump.find("var Game = {}; var Puzzle = {};") consequence=htmldump.find("var loadedId = 0;") borderandgivens=htmldump[initial+45:consequence-4] commasplit=borderandgivens.find(",") if commasplit == -1: border=borderandgivens givens="null" else: border=borderandgivens[:commasplit] givens=borderandgivens[commasplit+1:] borderstring="" indexer=0 for j in range(23): if border[indexer]=="/": borderstring=borderstring+"0" indexer=indexer+1 else: borderstring=borderstring+border[indexer] indexer=indexer+2 if border[-1]!="/": borderstring=borderstring+border[-1] else: borderstring=borderstring+"0" borderstringordered=borderstring[0:6]+borderstring[18:24]+borderstring[6:12][::-1]+borderstring[12:18][::-1] newgrid.append(borderstringordered) if givens=="null": newgrid.append(0) else: givenscount=0 spacing=0 for indexer in range(len(givens)): if givens[indexer]=="0" or givens[indexer]=="1" or givens[indexer]=="2" or givens[indexer]=="3" or givens[indexer]=="4" or givens[indexer]=="5" or givens[indexer]=="6" or givens[indexer]=="7" or givens[indexer]=="8" or givens[indexer]=="9": hundredsplace=((spacing//6)+1)*100 tensplace=((spacing%6)+1)*10 if tensplace==0: tensplace=60 newgrid.append(hundredsplace+tensplace+int(givens[indexer])) givenscount=givenscount+1 spacing=spacing+1 elif givens[indexer]=="_": spacing=spacing+0 else: if givens[indexer]=="a": spacing=spacing+1 if givens[indexer]=="b": spacing=spacing+2 if givens[indexer]=="c": spacing=spacing+3 if givens[indexer]=="d": spacing=spacing+4 if givens[indexer]=="e": spacing=spacing+5 if givens[indexer]=="f": spacing=spacing+6 if givens[indexer]=="g": spacing=spacing+7 if givens[indexer]=="h": spacing=spacing+8 if givens[indexer]=="i": spacing=spacing+9 if givens[indexer]=="j": spacing=spacing+10 if givens[indexer]=="k": spacing=spacing+11 if givens[indexer]=="l": spacing=spacing+12 if givens[indexer]=="m": spacing=spacing+13 if givens[indexer]=="n": spacing=spacing+14 if givens[indexer]=="o": spacing=spacing+15 if givens[indexer]=="p": spacing=spacing+16 if givens[indexer]=="q": spacing=spacing+17 if givens[indexer]=="r": spacing=spacing+18 if givens[indexer]=="s": spacing=spacing+19 if givens[indexer]=="t": spacing=spacing+20 if givens[indexer]=="u": spacing=spacing+21 if givens[indexer]=="v": spacing=spacing+22 if givens[indexer]=="w": spacing=spacing+23 if givens[indexer]=="x": spacing=spacing+24 if givens[indexer]=="y": spacing=spacing+25 if givens[indexer]=="z": spacing=spacing+26 newgrid.insert(2,givenscount) inputgrids.append(newgrid) return inputgrids facade=("Simple functions") def cleannotes(size,fullgrid): for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list: fullgrid[i+1][j+1]=sorted(fullgrid[i+1][j+1]) fullgrid[i+1][j+1]=list(dict.fromkeys(fullgrid[i+1][j+1])) return fullgrid def updatenotes(size,fullgrid): for k in range(size): for i in range(size): for j in range(size): if fullgrid[i+1][j+1]==k+1: for l in range(size): if type(fullgrid[i+1][l+1])==list: fullgrid[i+1][l+1].append(k+1) for m in range(size): if type(fullgrid[m+1][j+1])==list: fullgrid[m+1][j+1].append(k+1) def updatefullindivuals(size,fullgrid): # check the notes for individual nodes for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list: fullgrid[i+1][j+1]=list(dict.fromkeys(fullgrid[i+1][j+1])) fullgrid[i+1][j+1]=sorted(fullgrid[i+1][j+1]) if len(fullgrid[i+1][j+1])==(size-1): eliminationlist=possiblevalueslist[:] for k in range(size-1): eliminationlist.remove(fullgrid[i+1][j+1][k]) fullgrid[i+1][j+1]=eliminationlist[0] cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) facade=("Completion and correction checks") def testcorrectcompletion(size,fullgrid): gridcorrect=True for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list: gridcorrect=False if gridcorrect==True: for i in range(size): bordervalue=int(fullgrid[0][i+1]) if bordervalue!=0: highcount=0 currenthigh=0 testorder=[] for j in range(size): testorder.append(fullgrid[j+1][i+1]) if fullgrid[j+1][i+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[j+1][i+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): bordervalue=int(fullgrid[i+1][size+1]) if bordervalue!=0: highcount=0 currenthigh=0 testorder=[] for j in range(size): testorder.append(fullgrid[i+1][size-j]) if fullgrid[i+1][size-j]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[i+1][size-j] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): bordervalue=int(fullgrid[size+1][i+1]) if bordervalue!=0: highcount=0 currenthigh=0 testorder=[] for j in range(size): testorder.append(fullgrid[size-j][i+1]) if fullgrid[size-j][i+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[size-j][i+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): bordervalue=int(fullgrid[i+1][0]) if bordervalue!=0: highcount=0 currenthigh=0 testorder=[] for j in range(size): testorder.append(fullgrid[i+1][j+1]) if fullgrid[i+1][j+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[i+1][j+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False return gridcorrect def testcompletion(size,fullgrid): gridcomplete=True for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list: gridcomplete=False return gridcomplete def testcorrectbeforecompletion(size,fullgrid): gridcorrect=True fullgrid=cleannotes(size,fullgrid) for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list and len(set(fullgrid[i+1][j+1]))>=size: gridcorrect=False for i in range(size): testorder=[] for j in range(size): if type(fullgrid[j+1][i+1])==int: testorder.append(fullgrid[j+1][i+1]) if len(set(testorder))!=len(testorder): gridcorrect=False bordervalue=int(fullgrid[0][i+1]) if bordervalue!=0: closedcount=0 for j in range(size): if type(fullgrid[j+1][i+1])==int: closedcount=closedcount+1 if closedcount==size: highcount=0 currenthigh=0 for j in range(size): if fullgrid[j+1][i+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[j+1][i+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): testorder=[] for j in range(size): if type(fullgrid[i+1][size-j])==int: testorder.append(fullgrid[i+1][size-j]) if len(set(testorder))!=len(testorder): gridcorrect=False bordervalue=int(fullgrid[i+1][size+1]) if bordervalue!=0: closedcount=0 for j in range(size): if type(fullgrid[i+1][size-j])==int: closedcount=closedcount+1 if closedcount==size: highcount=0 currenthigh=0 for j in range(size): if fullgrid[i+1][size-j]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[i+1][size-j] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): testorder=[] for j in range(size): if type(fullgrid[size-j][i+1])==int: testorder.append(fullgrid[size-j][i+1]) if len(set(testorder))!=len(testorder): gridcorrect=False bordervalue=int(fullgrid[size+1][i+1]) if bordervalue!=0: closedcount=0 for j in range(size): if type(fullgrid[size-j][i+1])==int: closedcount=closedcount+1 if closedcount==size: highcount=0 currenthigh=0 for j in range(size): if fullgrid[size-j][i+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[size-j][i+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False for i in range(size): testorder=[] for j in range(size): if type(fullgrid[i+1][j+1])==int: testorder.append(fullgrid[i+1][j+1]) if len(set(testorder))!=len(testorder): gridcorrect=False bordervalue=int(fullgrid[i+1][0]) if bordervalue!=0: closedcount=0 for j in range(size): if type(fullgrid[i+1][j+1])==int: closedcount=closedcount+1 if closedcount==size: highcount=0 currenthigh=0 for j in range(size): if fullgrid[i+1][j+1]>currenthigh: highcount=highcount+1 currenthigh=fullgrid[i+1][j+1] if highcount!=bordervalue or len(set(testorder))!=size: gridcorrect=False if gridcorrect==True: for i in range(size): if fullgrid[0][i+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[j+1][i+1])==list: opencount=opencount+1 if type(fullgrid[j+1][i+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[0][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if unknownvaluesordered=="impossible": gridcorrect=False for i in range(size): if fullgrid[i+1][size+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if type(fullgrid[i+1][size-j])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[i+1][size+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if unknownvaluesordered=="impossible": gridcorrect=False for i in range(size): if fullgrid[size+1][i+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if type(fullgrid[size-j][i+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[size+1][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if unknownvaluesordered=="impossible": gridcorrect=False for i in range(size): if fullgrid[i+1][0]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if type(fullgrid[i+1][j+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[i+1][0]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if unknownvaluesordered=="impossible": gridcorrect=False return gridcorrect facade=("Stoic functions") def startinggridupdate(size,fullgrid): # fill in maxes next to borders ones for i in range(size): if fullgrid[0][i+1]=="1": fullgrid[1][i+1]=size if fullgrid[size+1][i+1]=="2": fullgrid[size][i+1]=size-1 for i in range(size): if fullgrid[i+1][size+1]=="1": fullgrid[i+1][size]=size if fullgrid[i+1][0]=="2": fullgrid[i+1][1]=size-1 for i in range(size): if fullgrid[size+1][i+1]=="1": fullgrid[size][i+1]=size if fullgrid[0][i+1]=="2": fullgrid[1][i+1]=size-1 for i in range(size): if fullgrid[i+1][0]=="1": fullgrid[i+1][1]=size if fullgrid[i+1][size+1]=="2": fullgrid[i+1][size]=size-1 cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) # write notes for border twos for i in range(size): if fullgrid[0][i+1]=="2": if type(fullgrid[1][i+1])==list: fullgrid[1][i+1].append(size) if type(fullgrid[2][i+1])==list: fullgrid[2][i+1].append(size-1) for i in range(size): if fullgrid[i+1][size+1]=="2": if type(fullgrid[i+1][size])==list: fullgrid[i+1][size].append(size) if type(fullgrid[i+1][size-1])==list: fullgrid[i+1][size-1].append(size-1) for i in range(size): if fullgrid[size+1][i+1]=="2": if type(fullgrid[size][i+1])==list: fullgrid[size][i+1].append(size) if type(fullgrid[size-1][i+1])==list: fullgrid[size-1][i+1].append(size-1) for i in range(size): if fullgrid[i+1][0]=="2": if type(fullgrid[i+1][1])==list: fullgrid[i+1][1].append(size) if type(fullgrid[i+1][2])==list: fullgrid[i+1][2].append(size-1) for i in range(size): if fullgrid[0][i+1]=="2" and fullgrid[size+1][i+1]=="2": for j in range(size-2): if type(fullgrid[j+2][i+1])==list: fullgrid[j+2][i+1].append(size-1) for i in range(size): if fullgrid[i+1][0]=="2" and fullgrid[i+1][size+1]=="2": for j in range(size-2): if type(fullgrid[i+1][j+2])==list: fullgrid[i+1][j+2].append(size-1) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) # border notes for all nums except 1 2 and size for j in range(size-3): # for each border num for i in range(size): # for each of the border nums on the 4 borders if int(fullgrid[0][i+1])==j+3: # sets which border num is in play for k in range(j+2): # affecting to a distance of one less than the border num for l in range((j-k)+2): if type(fullgrid[k+1][i+1])==list: fullgrid[k+1][i+1].append(size-l) for i in range(size): if int(fullgrid[i+1][size+1])==j+3: for k in range(j+2): for l in range((j-k)+2): if type(fullgrid[i+1][size-k])==list: fullgrid[i+1][size-k].append(size-l) for i in range(size): if int(fullgrid[size+1][i+1])==j+3: for k in range(j+2): for l in range((j-k)+2): if type(fullgrid[size-k][i+1])==list: fullgrid[size-k][i+1].append(size-l) for i in range(size): if int(fullgrid[i+1][0])==j+3: for k in range(j+2): for l in range((j-k)+2): if type(fullgrid[i+1][k+1])==list: fullgrid[i+1][k+1].append(size-l) # fill in full lines next to border maxes for i in range(size): if fullgrid[0][i+1]==str(size): for j in range(size): fullgrid[j+1][i+1]=j+1 for i in range(size): if fullgrid[i+1][size+1]==str(size): for j in range(size): fullgrid[i+1][size-j]=j+1 for i in range(size): if fullgrid[size+1][i+1]==str(size): for j in range(size): fullgrid[size-j][i+1]=j+1 for i in range(size): if fullgrid[i+1][0]==str(size): for j in range(size): fullgrid[i+1][j+1]=j+1 cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) return fullgrid def bordernotes(size,fullgrid,possiblevalueslist): # applies to both maxes with obscurred values and # running over low notes when max unknown for j in range(size-3): # for each border num example if size is 9, from 3 to 8 for i in range(size): # for each of the border nums on the 4 borders if int(fullgrid[0][i+1])==j+3: # sets which border num is in play distanceofmax=0 for k in range(size): if fullgrid[k+1][i+1]==size: distanceofmax=k+1 if distanceofmax!=0: impossiblevalueslist=[] impossiblevalueslist.append(size) for k in range(size-distanceofmax): if type(fullgrid[distanceofmax+1+k][i+1])==int: impossiblevalueslist.append(fullgrid[distanceofmax+1+k][i+1]) # might need a gatekeep here possiblevalues=possiblevalueslist[:] for k in range(len(impossiblevalueslist)): possiblevalues.remove(impossiblevalueslist[k]) possiblevalues=sorted(possiblevalues) distanceextension=0 for k in range(j+1): # affecting to a distance of one less than the border num distanceextensioncheck=True while distanceextensioncheck==True: distanceextensioncheck=False if type(fullgrid[k+1+distanceextension][i+1])==int and fullgrid[k+1+distanceextension][i+1]<=k: distanceextension=distanceextension+1 distanceextensioncheck=True if type(fullgrid[k+1+distanceextension][i+1])==list: remainingvalues=possiblevalueslist[:] for l in range(len(fullgrid[k+1+distanceextension][i+1])): remainingvalues.remove(fullgrid[k+1+distanceextension][i+1][l]) if remainingvalues[-1]<=k or (type(fullgrid[1][i+1])==int and remainingvalues[-1]1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=lownotesforatrangemaxes(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[j+1][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][size+1]) opencount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=lownotesforatrangemaxes(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][size-j]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[size+1][i+1]) opencount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=lownotesforatrangemaxes(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[size-j][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][0]) opencount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=lownotesforatrangemaxes(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][j+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) return fullgrid def lownotesforatrangemaxes(size,bordervalue,lineofvalues,possiblevalueslist): # this only checks for max being at range accounting for low notes, but high and pos should be added to take care of all heights adjacentvalue=False if type(lineofvalues[1])==int: adjacentvalue=lineofvalues[1] # distance of max distanceofmax=False for i in range(size): if lineofvalues[1+i]==size: distanceofmax=1+i # only designed to work if distance of max is known if distanceofmax!=False: existinglownotes=[] # not perfect but necessary, possible values now has a different definition/purpose possiblevalues=[] for i in range(distanceofmax-1): if type(lineofvalues[1+i])==list: for j in range(size): if j+1 not in lineofvalues[1+i]: possiblevalues.append(j+1) if type(lineofvalues[1+i])==int: possiblevalues.append(lineofvalues[1+i]) possiblevalues.append(size) possiblevalues=list(set(possiblevalues)) for i in range(distanceofmax-2): if type(lineofvalues[2+i])==int: for j in range(i+1): if lineofvalues[2+i]2: # fills in adjacent low notes if max is known impossiblevalues=[] for j in range(distanceofmax-2): # doesnt account for obscured values impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[1][i+1].append(impossiblevalues[j]) impossiblevalues=[] for j in range(distanceofmax-1): if type(fullgrid[j+1][i+1])==int: impossiblevalues.append(fullgrid[j+1][i+1]) if impossiblevalues!=[]: impossiblevalues=sorted(impossiblevalues) for j in range(impossiblevalues[-1]-1): fullgrid[1][i+1].append(j+1) if distanceofmax==0: # fills in adjacent low notes if max is unknown shortestpossibledistanceofmax=0 for j in range(size): if type(fullgrid[j+1][i+1])!=int and size not in fullgrid[j+1][i+1] and shortestpossibledistanceofmax==0: shortestpossibledistanceofmax=j+1 if shortestpossibledistanceofmax>2: # still doesnt account for obscured values impossiblevalues=[] for j in range(shortestpossibledistanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[1][i+1].append(impossiblevalues[j]) if type(fullgrid[1][i+1])==list and type(fullgrid[2][i+1])==int and fullgrid[2][i+1]!=size: for j in range(fullgrid[2][i+1]-1): fullgrid[1][i+1].append(j+1) # here we go, since distanceofmax or shortestpossibledistanceofmax must now be defined # levees are used to control the flow of water, hence the levee node acts as a cinch between values before and after it cleannotes(size,fullgrid) shortestpossible=0 if distanceofmax!=0: shortestpossible=distanceofmax elif shortestpossibledistanceofmax!=0: shortestpossible=shortestpossibledistanceofmax if shortestpossible!=0: existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[j+2][i+1])==list: if len(fullgrid[j+2][i+1])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[leveeposition][i+1][j]) for j in range(possiblevalues[0]): fullgrid[1][i+1].append(j+1) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) updatefullindivuals(size,fullgrid) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) for i in range(size): if fullgrid[i+1][size+1]=="2" and type(fullgrid[i+1][size])==list: distanceofmax=0 for j in range(size): if fullgrid[i+1][size-j]==size: distanceofmax=j+1 if distanceofmax>2: impossiblevalues=[] for j in range(distanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[i+1][size].append(impossiblevalues[j]) impossiblevalues=[] for j in range(distanceofmax-1): if type(fullgrid[i+1][size-j])==int: impossiblevalues.append(fullgrid[i+1][size-j]) if impossiblevalues!=[]: impossiblevalues=sorted(impossiblevalues) for j in range(impossiblevalues[-1]-1): fullgrid[i+1][size].append(j+1) if distanceofmax==0: shortestpossibledistanceofmax=0 for j in range(size): if type(fullgrid[i+1][size-j])!=int and size not in fullgrid[i+1][size-j] and shortestpossibledistanceofmax==0: shortestpossibledistanceofmax=j+1 if shortestpossibledistanceofmax>2: impossiblevalues=[] for j in range(shortestpossibledistanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[i+1][size].append(impossiblevalues[j]) if type(fullgrid[i+1][size])==list and type(fullgrid[i+1][size-1])==int and fullgrid[i+1][size-1]!=size: for j in range(fullgrid[i+1][size-1]-1): fullgrid[i+1][size].append(j+1) cleannotes(size,fullgrid) shortestpossible=0 if distanceofmax!=0: shortestpossible=distanceofmax elif shortestpossibledistanceofmax!=0: shortestpossible=shortestpossibledistanceofmax if shortestpossible!=0: existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[i+1][(size-1)-j])==list: if len(fullgrid[i+1][(size-1)-j])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[i+1][(size+1)-leveeposition][j]) for j in range(possiblevalues[0]): fullgrid[i+1][size].append(j+1) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) updatefullindivuals(size,fullgrid) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) for i in range(size): if fullgrid[size+1][i+1]=="2" and type(fullgrid[size][i+1])==list: distanceofmax=0 for j in range(size): if fullgrid[size-j][i+1]==size: distanceofmax=j+1 if distanceofmax>2: impossiblevalues=[] for j in range(distanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[size][i+1].append(impossiblevalues[j]) impossiblevalues=[] for j in range(distanceofmax-1): if type(fullgrid[size-j][i+1])==int: impossiblevalues.append(fullgrid[size-j][i+1]) if impossiblevalues!=[]: impossiblevalues=sorted(impossiblevalues) for j in range(impossiblevalues[-1]-1): fullgrid[size][i+1].append(j+1) if distanceofmax==0: shortestpossibledistanceofmax=0 for j in range(size): if type(fullgrid[size-j][i+1])!=int and size not in fullgrid[size-j][i+1] and shortestpossibledistanceofmax==0: shortestpossibledistanceofmax=j+1 if shortestpossibledistanceofmax>2: impossiblevalues=[] for j in range(shortestpossibledistanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[size][i+1].append(impossiblevalues[j]) if type(fullgrid[size][i+1])==list and type(fullgrid[size-1][i+1])==int and fullgrid[size-1][i+1]!=size: for j in range(fullgrid[size-1][i+1]-1): fullgrid[size][i+1].append(j+1) cleannotes(size,fullgrid) shortestpossible=0 if distanceofmax!=0: shortestpossible=distanceofmax elif shortestpossibledistanceofmax!=0: shortestpossible=shortestpossibledistanceofmax if shortestpossible!=0: existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[(size-1)-j][i+1])==list: if len(fullgrid[(size-1)-j][i+1])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[(size+1)-leveeposition][i+1][j]) for j in range(possiblevalues[0]): fullgrid[size][i+1].append(j+1) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) updatefullindivuals(size,fullgrid) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) for i in range(size): if fullgrid[i+1][0]=="2" and type(fullgrid[i+1][1])==list: distanceofmax=0 for j in range(size): if fullgrid[i+1][j+1]==size: distanceofmax=j+1 if distanceofmax>2: impossiblevalues=[] for j in range(distanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[i+1][1].append(impossiblevalues[j]) impossiblevalues=[] for j in range(distanceofmax-1): if type(fullgrid[i+1][j+1])==int: impossiblevalues.append(fullgrid[i+1][j+1]) if impossiblevalues!=[]: impossiblevalues=sorted(impossiblevalues) for j in range(impossiblevalues[-1]-1): fullgrid[i+1][1].append(j+1) if distanceofmax==0: shortestpossibledistanceofmax=0 for j in range(size): if type(fullgrid[i+1][j+1])!=int and size not in fullgrid[i+1][j+1] and shortestpossibledistanceofmax==0: shortestpossibledistanceofmax=j+1 if shortestpossibledistanceofmax>2: impossiblevalues=[] for j in range(shortestpossibledistanceofmax-2): impossiblevalues.append(j+1) for j in range(len(impossiblevalues)): fullgrid[i+1][1].append(impossiblevalues[j]) if type(fullgrid[i+1][1])==list and type(fullgrid[i+1][2])==int and fullgrid[i+1][2]!=size: for j in range(fullgrid[i+1][2]-1): fullgrid[i+1][1].append(j+1) cleannotes(size,fullgrid) shortestpossible=0 if distanceofmax!=0: shortestpossible=distanceofmax elif shortestpossibledistanceofmax!=0: shortestpossible=shortestpossibledistanceofmax if shortestpossible!=0: existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[i+1][j+2])==list: if len(fullgrid[i+1][j+2])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[i+1][leveeposition][j]) for j in range(possiblevalues[0]): fullgrid[i+1][1].append(j+1) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) updatefullindivuals(size,fullgrid) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) return fullgrid def bordertwosdistantmaxesleadingtoprecursor(size,fullgrid,possiblevalueslist): for i in range(size): bordervalue=int(fullgrid[0][i+1]) opencount=0 for j in range(size): if type(fullgrid[j+1][i+1])==list: opencount=opencount+1 if opencount>1 and bordervalue==2: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=bordertwosdistantmaxesleadingto(size,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[j+1][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][size+1]) opencount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if opencount>1 and bordervalue==2: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=bordertwosdistantmaxesleadingto(size,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][size-j]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[size+1][i+1]) opencount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if opencount>1 and bordervalue==2: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=bordertwosdistantmaxesleadingto(size,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[size-j][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][0]) opencount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if opencount>1 and bordervalue==2: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=bordertwosdistantmaxesleadingto(size,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][j+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) return fullgrid def bordertwosdistantmaxesleadingto(size,lineofvalues,possiblevalueslist): # notes leading up to max but not border adjacent bordervalue=lineofvalues[0] distanceofmax=0 for i in range(size): # standard distance of max if lineofvalues[1+i]==size: distanceofmax=i+1 if distanceofmax!=0: # accounts for obscurred values if max is known impossiblevalueslist=[] impossiblevalueslist.append(size) for i in range(size-distanceofmax): # gets all ints after max if type(lineofvalues[distanceofmax+1+i])==int: impossiblevalueslist.append(lineofvalues[distanceofmax+1+i]) possiblevalues=possiblevalueslist[:] for i in range(len(impossiblevalueslist)): # makes an inverse possiblevalues.remove(impossiblevalueslist[i]) possiblevalues=sorted(possiblevalues) highvalue=possiblevalues[-1] # takes the highest value left in play for i in range(distanceofmax-2): # puts it leading up to max if type(lineofvalues[2+i])==list: lineofvalues[2+i].append(highvalue) if distanceofmax==0: # accounts for if max is unknown shortestpossibledistanceofmax=0 for i in range(size): if type(lineofvalues[1+i])!=int and size not in lineofvalues[1+i] and shortestpossibledistanceofmax==0: shortestpossibledistanceofmax=i+1 for i in range(shortestpossibledistanceofmax-2): if type(lineofvalues[3+i])==list: lineofvalues[3+i].append(size-1) if distanceofmax!=0: actingdistanceofmax=distanceofmax else: actingdistanceofmax=shortestpossibledistanceofmax if type(lineofvalues[1])==int: adjacentvalue=lineofvalues[1] else: adjacentvalue=noteinversion(lineofvalues[1],possiblevalueslist)[-1] for i in range(actingdistanceofmax-1): if type(lineofvalues[2+i])==list: for j in range(size-adjacentvalue): lineofvalues[2+i].append(adjacentvalue+j) for i in range(size): if type(lineofvalues[i+1])==list: lineofvalues[i+1]=list(set(lineofvalues[i+1])) return lineofvalues def unknownmaxes(size,fullgrid): # add notes for maxes behind one below max for i in range(size): bordervalue=int(fullgrid[0][i+1]) if bordervalue!=0: distanceofmax=0 for j in range(size): if fullgrid[j+1][i+1]==size: distanceofmax=j+1 secondaryposition=0 for j in range(size): if fullgrid[j+1][i+1]==size-1: secondaryposition=j+1 if bordervalue==2 and type(fullgrid[1][i+1])==list: if distanceofmax==0 and secondaryposition>1: for j in range(size-secondaryposition): if type(fullgrid[secondaryposition+1+j][i+1])==list: fullgrid[secondaryposition+1+j][i+1].append(size) if type(fullgrid[size][i+1])==list and size-1 in fullgrid[1][i+1]: # please generalize fullgrid[size][i+1].append(size) if distanceofmax==0: possiblevalues=possiblevalueslist[:] for j in range(len(fullgrid[1][i+1])): possiblevalues.remove(fullgrid[1][i+1][j]) closedcount=[] for j in range(size): if type(fullgrid[j+1][i+1])==int: closedcount.append(fullgrid[j+1][i+1]) closedcount=sorted(closedcount) if closedcount!=[] and possiblevalues[-1]1: for j in range(size-secondaryposition): if type(fullgrid[i+1][j+1])==list: fullgrid[i+1][j+1].append(size) if type(fullgrid[i+1][1])==list and size-1 in fullgrid[i+1][size]: fullgrid[i+1][1].append(size) if distanceofmax==0: possiblevalues=possiblevalueslist[:] for j in range(len(fullgrid[i+1][size])): possiblevalues.remove(fullgrid[i+1][size][j]) closedcount=[] for j in range(size): if type(fullgrid[i+1][size-j])==int: closedcount.append(fullgrid[i+1][size-j]) closedcount=sorted(closedcount) if closedcount!=[] and possiblevalues[-1]1: for j in range(size-secondaryposition): if type(fullgrid[j+1][i+1])==list: fullgrid[j+1][i+1].append(size) if type(fullgrid[1][i+1])==list and size-1 in fullgrid[size][i+1]: fullgrid[1][i+1].append(size) if distanceofmax==0: possiblevalues=possiblevalueslist[:] for j in range(len(fullgrid[size][i+1])): possiblevalues.remove(fullgrid[size][i+1][j]) closedcount=[] for j in range(size): if type(fullgrid[size-j][i+1])==int: closedcount.append(fullgrid[size-j][i+1]) closedcount=sorted(closedcount) if closedcount!=[] and possiblevalues[-1]1: for j in range(size-secondaryposition): if type(fullgrid[i+1][secondaryposition+1+j])==list: fullgrid[i+1][secondaryposition+1+j].append(size) if type(fullgrid[i+1][size])==list and size-1 in fullgrid[i+1][1]: fullgrid[i+1][size].append(size) if distanceofmax==0: possiblevalues=possiblevalueslist[:] for j in range(len(fullgrid[i+1][1])): possiblevalues.remove(fullgrid[i+1][1][j]) closedcount=[] for j in range(size): if type(fullgrid[i+1][j+1])==int: closedcount.append(fullgrid[i+1][j+1]) closedcount=sorted(closedcount) if closedcount!=[] and possiblevalues[-1]1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=heightssuccessor(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[j+1][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][size+1]) opencount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=heightssuccessor(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][size-j]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[size+1][i+1]) opencount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=heightssuccessor(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[size-j][i+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) if testcorrectbeforecompletion(size,fullgrid)==True: for i in range(size): bordervalue=int(fullgrid[i+1][0]) opencount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if opencount>1 and bordervalue>1: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) lineofvalues.insert(0,bordervalue) oldlineofvalues=lineofvalues[:] newlineofvalues=heightssuccessor(size,bordervalue,lineofvalues,possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][j+1]=newlineofvalues[j+1] cleannotes(size,fullgrid) return fullgrid def heightssuccessor(size,bordervalue,lineofvalues,possiblevalueslist): adjacentvalue=False if type(lineofvalues[1])==int: adjacentvalue=lineofvalues[1] # highests and positions highandpos=[] for i in range(bordervalue): highandpos.append([False,False]) highandpos[-1][1]=1 highandpos[0][0]=size if adjacentvalue!=False: highandpos[-1][0]=adjacentvalue # distance of max for i in range(size): if lineofvalues[1+i]==size: highandpos[0][1]=1+i # if max unknown if highandpos[0][1]==False: farthestpossibledistanceofmax=0 for i in range(size): if type(lineofvalues[1+i])==list and size not in lineofvalues[1+i]: farthestpossibledistanceofmax=i+1 shortestpossibledistanceofmax=0 for i in range(size): if type(lineofvalues[size-i])==list and size not in lineofvalues[size-i]: shortestpossibledistanceofmax=size-i # if distance of max is known if highandpos[0][1]!=False: # gather all the obcured values behind it obscuredvalues=[] for i in range(size-highandpos[0][1]): if type(lineofvalues[highandpos[0][1]+1+i])==int: obscuredvalues.append(lineofvalues[highandpos[0][1]+1+i]) inverseobscuredvalues=noteinversion(obscuredvalues,possiblevalueslist) inverseobscuredvalues.remove(size) # gather all the possible values in front of it possiblevalues=[] for i in range(highandpos[0][1]-1): if type(lineofvalues[1+i])==list: for j in range(size): if j+1 not in lineofvalues[1+i]: possiblevalues.append(j+1) if type(lineofvalues[1+i])==int: possiblevalues.append(lineofvalues[1+i]) possiblevalues=list(set(possiblevalues)) # if distance of max is unknown, gather all the obscured values behind it if highandpos[0][1]==False: # gather all the obcured values behind it obscuredvalues=[] for i in range(size-farthestpossibledistanceofmax): if type(lineofvalues[farthestpossibledistanceofmax+1+i])==int: obscuredvalues.append(lineofvalues[farthestpossibledistanceofmax+1+i]) inverseobscuredvalues=noteinversion(obscuredvalues,possiblevalueslist) inverseobscuredvalues.remove(size) # gather all the possible values in front of it possiblevalues=[] for i in range(farthestpossibledistanceofmax-1): if type(lineofvalues[1+i])==list: for j in range(size): if j+1 not in lineofvalues[1+i]: possiblevalues.append(j+1) if type(lineofvalues[1+i])==int: possiblevalues.append(lineofvalues[1+i]) possiblevalues=list(set(possiblevalues)) # the basics, finds the other integers that are going into high and pos for j in range(bordervalue-1): if highandpos[0+j][1]!=False: for i in range(highandpos[0+j][1]-1): # the sweep for integers, only triggers once if lineofvalues[1+i]==inverseobscuredvalues[-1]: highandpos[1+j][0]=inverseobscuredvalues[-1] highandpos[1+j][1]=1+i # finds more obscured values inverseobscuredvalues.remove(highandpos[1+j][0]) for k in range(highandpos[j][1]-highandpos[1+j][1]-1): if type(lineofvalues[highandpos[1+j][1]+1+k])==int: #integers in the valley between obscuredvalues.append(lineofvalues[highandpos[1+j][1]+1+k]) obscuredvalues=sorted(obscuredvalues) inverseobscuredvalues.remove(lineofvalues[highandpos[1+j][1]+1+k]) # finds the new possible values possiblevalues=[] for k in range(i): if type(lineofvalues[1+k])==list: for l in range(size): if l+1 not in lineofvalues[1+k]: possiblevalues.append(l+1) if type(lineofvalues[1+k])==int: possiblevalues.append(lineofvalues[1+k]) possiblevalues=list(set(possiblevalues)) break elif j==0 and highandpos[0+j][1]==False: for i in range(shortestpossibledistanceofmax-1): # the sweep for integers, only triggers once if lineofvalues[1+i]==inverseobscuredvalues[-1]: highandpos[1+j][0]=inverseobscuredvalues[-1] highandpos[1+j][1]=1+i # finds more obscured values inverseobscuredvalues.remove(highandpos[1+j][0]) for k in range(highandpos[j][1]-highandpos[1+j][1]-1): if type(lineofvalues[highandpos[1+j][1]+1+k])==int: #integers in the valley between obscuredvalues.append(lineofvalues[highandpos[1+j][1]+1+k]) obscuredvalues=sorted(obscuredvalues) inverseobscuredvalues.remove(lineofvalues[highandpos[1+j][1]+1+k]) # finds the new possible values possiblevalues=[] for k in range(i): if type(lineofvalues[1+k])==list: for l in range(size): if l+1 not in lineofvalues[1+k]: possiblevalues.append(l+1) if type(lineofvalues[1+k])==int: possiblevalues.append(lineofvalues[1+k]) possiblevalues=list(set(possiblevalues)) break # i think there's supposed to be a break here ah ha ha else: break # obscured values only counts the values after the lowest known high, and doesn't count the highs. inverse obscured values is the inverse of that, minus the highs already known. possible values is a reading of the notes up to the lowest known high. use these two differently. if adjacentvalue!=False: while True: i=0 if type(lineofvalues[2+i])==int and highandpos[-2-i][1]==False and lineofvalues[2+i]>highandpos[-1-i][0]: highandpos[-2-i][0]=lineofvalues[2+i] highandpos[-2-i][1]=2+i i=i+1 else: break # checks for the high values that are at range for i in range(size-3): if bordervalue==3+i: for j in range(i+1): if type(lineofvalues[2+j])==int and lineofvalues[2+j]==size-i+j-1: highandpos[i-j+1][0]=size-i+j-1 highandpos[i-j+1][1]=2+j # checks for higher integers immediately behind known values. needs more generalizing to run over low values. for i in range(size-3): if bordervalue>2+i and highandpos[1+i][1]==False and highandpos[2+i][0]!=False and type(lineofvalues[highandpos[2+i][1]+1])==int and lineofvalues[highandpos[2+i][1]+1]>highandpos[2+i][0]: highandpos[1+i][0]=lineofvalues[highandpos[2+i][1]+1] highandpos[1+i][1]=highandpos[2+i][1]+1 elif bordervalue>2+i and highandpos[1+i][1]==False and highandpos[2+i][0]!=False and type(lineofvalues[highandpos[2+i][1]+1])==int and lineofvalues[highandpos[2+i][1]+1]highandpos[2+i][0]: highandpos[1+i][0]=lineofvalues[highandpos[2+i][1]+2] highandpos[1+i][1]=highandpos[2+i][1]+2 # for values right in front of at range maxes. please expand to include the nodes right in front of other at range values. if highandpos[0][1]!=False and highandpos[1][0]==False and highandpos[1][1]==False: for i in range(size-3): if bordervalue==3+i and highandpos[0][1]==3+i and type(lineofvalues[2+i])==int: highandpos[1][0]=lineofvalues[2+i] highandpos[1][1]=2+i inverseobscuredvalues.remove(lineofvalues[2+i]) # need to deal with when distance of max is unknown. this is the part of the show where we deal with that. its not a transplant of the old function unknownmaxes. this will be ungeneralized for a bit. if highandpos[0][1]==False: if bordervalue==2: possibledistanceofsecondary=highandpos[1][1] if possibledistanceofsecondary!=False and possibledistanceofsecondary!=1: for i in range(size-possibledistanceofsecondary): if type(lineofvalues[possibledistanceofsecondary+1+i])==list: lineofvalues[possibledistanceofsecondary+1+i].append(size) # past the standard definitions onto the goods # adjacent node low values if adjacentvalue==False: if highandpos[bordervalue-2][1]!=False and highandpos[bordervalue-2][1]>2: for i in range(highandpos[bordervalue-2][1]-2): lineofvalues[1].append(inverseobscuredvalues[i]) # adjacent node high notes if highandpos[0][1]!=False and highandpos[bordervalue-2][1]==False and type(lineofvalues[1])==list: lineofvalues[1].append(inverseobscuredvalues[-1]) # danger, danger # on one hand, this funcetion needs a lot of generalizing. on the other hand, it might actually be obsolete, and just left over from a long time ago. for now, it will be left as is, since it is very self explanatory. if highandpos[0][1]==size: if bordervalue==3 and highandpos[1][1]==size-1: lineofvalues[1]=size-2 if bordervalue==4 and highandpos[1][1]==size-1 and highandpos[2][1]==size-2: lineofvalues[1]=size-3 if bordervalue==5 and highandpos[1][1]==size-1 and highandpos[2][1]==size-2 and highandpos[3][1]==size-3: lineofvalues[1]=size-4 # if adjacent value was out bread, this is our butter. does all the notes leading up to a known value. needs to be generalized to account for obscured values. if highandpos[bordervalue-2][1]!=False and highandpos[bordervalue-2][1]>2 and type(lineofvalues[1])==list: for i in range(highandpos[bordervalue-2][1]-2): if type(lineofvalues[2+i])==list: # lineofvalues[2+i].append(highandpos[bordervalue-2][0]-1) lineofvalues[2+i].append(possiblevalues[-1]) # changed from inverse # just in case some notes in front of definite values got lost. protect what is certain. for k in range(size-3): if bordervalue==3+k and highandpos[1+k][1]!=False and size-highandpos[1+k][0]-1>1: for i in range(highandpos[1+k][1]-1): if type(lineofvalues[1+i])==list: for j in range(size-highandpos[1+k][0]-1): lineofvalues[1+i].append(highandpos[1+k][0]+1+j) # this is for when the actual important values are sort of all smushed to the left and right. needs to be generalized. if bordervalue==3 and highandpos[1][1]==False and highandpos[0][1]!=False and highandpos[0][1]==size-len(obscuredvalues) and adjacentvalue==inverseobscuredvalues[0] and type(lineofvalues[2])==list: lineofvalues[2]=inverseobscuredvalues[-1] highandpos[1][0]=inverseobscuredvalues[-1] highandpos[1][1]=2 inverseobscuredvalues.remove(inverseobscuredvalues[-1]) if bordervalue==3 and highandpos[1][1]==False and highandpos[0][1]!=False and highandpos[0][1]==size-len(obscuredvalues) and adjacentvalue==False and inverseobscuredvalues[-2] in lineofvalues[1] and type(lineofvalues[highandpos[0][1]-1])==list: lineofvalues[highandpos[0][1]-1].append(inverseobscuredvalues[-1]) # sorta of a meet in the middle type query. come upwards from a known value, and downwards along inverse value. still needs work. for i in range(bordervalue-2): if highandpos[0+i][1]!=False and highandpos[2+i][0]!=False and highandpos[0+i][0]-highandpos[2+i][0]==2: for j in range(size-highandpos[0+i][1]): if type(lineofvalues[highandpos[0+i][1]+1+j])==list: lineofvalues[highandpos[0+i][1]+1+j].append(highandpos[0+i][0]-1) # for notes between definite values. protect what is certain, but for between, not in front. for k in range(size-3): for l in range(bordervalue-1): if bordervalue==3+k and highandpos[l][1]!=False and highandpos[l][0]!=False and highandpos[1+l][1]!=False and highandpos[1+l][0]!=False: for i in range(highandpos[l][1]-highandpos[1+l][1]-1): if type(lineofvalues[highandpos[1+l][1]+1+i])==list: for j in range(highandpos[l][0]-highandpos[1+l][0]-1): lineofvalues[highandpos[1+l][1]+1+i].append(highandpos[1+l][0]+1+j) # one might call this butter like. if the adjacent value is low, then it can affect whether there can be high values that are really far back. for j in range(bordervalue-2): if type(lineofvalues[1])==int and bordervalue-(3+j)>=0 and highandpos[bordervalue-(3+j)][1]!=False and highandpos[bordervalue-(2+j)][1]==False and highandpos[bordervalue-(1+j)][1]!=False: for i in range(highandpos[bordervalue-(3+j)][1]-highandpos[bordervalue-(1+j)][0]-2): if type(lineofvalues[highandpos[bordervalue-(3+j)][1]-1-i])==list: lineofvalues[highandpos[bordervalue-(3+j)][1]-1-i].append(inverseobscuredvalues[-1]) # this is butter like, like. if the adjacent value is low, then it can affect whether there can be values just a little higher right next to it. for i in range(size-3): if bordervalue==3+i and highandpos[i][1]!=False and highandpos[1+i][1]==False and type(lineofvalues[1])==int and type(lineofvalues[2])==list and highandpos[i][1]>lineofvalues[1]+2: lineofvalues[2].append(lineofvalues[1]+1) # please make this a for loop. danger will robinson. # a direct copy. should be destroyed. if bordervalue==3 and type(lineofvalues[1])==list and highandpos[0][1]!=False and highandpos[1][1]==False: possiblevalues=sorted(possiblevalues) # this is a better version of inverse values, as it reads the notes as well lineofvalues[1].append(possiblevalues[-1]) # for when we know what a value is, just not where it is supposed to be. this almost edits high and pos, so it should be split and frontloaded. if bordervalue==3 and highandpos[0][1]!=False and highandpos[1][0]==False and highandpos[2][0]!=False and highandpos[2][1]!=False and highandpos[2][0]+1==inverseobscuredvalues[-1]: for i in range(size-highandpos[0][1]): if type(lineofvalues[highandpos[0][1]+1])==list: lineofvalues[highandpos[0][1]+1].append(inverseobscuredvalues[-1]) return lineofvalues def borderthreesagain(size,fullgrid): # on border 3s puts 2 below max in front of 1 below max, just notes, other things involving 2 below max for i in range(size): if fullgrid[0][i+1]=="3": distanceofmax=0 secondaryposition=0 tertiaryposition=0 for j in range(size): if fullgrid[j+1][i+1]==size: distanceofmax=j+1 for j in range(size): if fullgrid[j+1][i+1]==size-1: secondaryposition=j+1 for j in range(size): if fullgrid[j+1][i+1]==size-2: tertiaryposition=j+1 if secondaryposition==0 and distanceofmax!=0: farthestpossibledistanceofsecondary=0 for j in range(size): if type(fullgrid[j+1][i+1])==list and size-1 not in fullgrid[j+1][i+1]: farthestpossibledistanceofsecondary=j+1 if farthestpossibledistanceofsecondarytertiaryposition and tertiaryposition!=1: for j in range((distanceofmax-tertiaryposition)-1): if type(fullgrid[tertiaryposition+j+1][i+1])==list: fullgrid[tertiaryposition+j+1][i+1].append(size-1) # should be adjusted to account for the shortest possible distance of max cleannotes(size,fullgrid) if distanceofmax!=0: shortestpossible=distanceofmax existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[j+2][i+1])==list: if len(fullgrid[j+2][i+1])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[leveeposition][i+1][j]) if possiblevalues==[size-2,size-1]: for j in range((shortestpossible-leveeposition)-1): if type(fullgrid[leveeposition+1+j][i+1])==list: fullgrid[leveeposition+1+j][i+1].append(size-1) for j in range(leveeposition-2): if type(fullgrid[j+2][i+1])==list: fullgrid[j+2][i+1].append(size-2) cleannotes(size,fullgrid) for i in range(size): if fullgrid[i+1][size+1]=="3": distanceofmax=0 secondaryposition=0 tertiaryposition=0 for j in range(size): if fullgrid[i+1][size-j]==size: distanceofmax=j+1 for j in range(size): if fullgrid[i+1][size-j]==size-1: secondaryposition=j+1 for j in range(size): if fullgrid[i+1][size-j]==size-2: tertiaryposition=j+1 if secondaryposition==0 and distanceofmax!=0: farthestpossibledistanceofsecondary=0 for j in range(size): if type(fullgrid[i+1][size-j])==list and size-1 not in fullgrid[i+1][size-j]: farthestpossibledistanceofsecondary=j+1 if farthestpossibledistanceofsecondarytertiaryposition and tertiaryposition!=1: for j in range((distanceofmax-tertiaryposition)-1): if type(fullgrid[i+1][((size-distanceofmax)+2)+j])==list: fullgrid[i+1][((size-distanceofmax)+2)+j].append(size-1) cleannotes(size,fullgrid) if distanceofmax!=0: shortestpossible=distanceofmax existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[i+1][(size-1)-j])==list: if len(fullgrid[i+1][(size-1)-j])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[i+1][(size+1)-leveeposition][j]) if possiblevalues==[size-2,size-1]: for j in range((shortestpossible-leveeposition)-1): if type(fullgrid[i+1][(size-leveeposition)-j])==list: fullgrid[i+1][(size-leveeposition)-j].append(size-1) for j in range(leveeposition-2): if type(fullgrid[i+1][(size-1)-j])==list: fullgrid[i+1][(size-1)-j].append(size-2) cleannotes(size,fullgrid) for i in range(size): if fullgrid[size+1][i+1]=="3": distanceofmax=0 secondaryposition=0 tertiaryposition=0 for j in range(size): if fullgrid[size-j][i+1]==size: distanceofmax=j+1 for j in range(size): if fullgrid[size-j][i+1]==size-1: secondaryposition=j+1 for j in range(size): if fullgrid[size-j][i+1]==size-2: tertiaryposition=j+1 if secondaryposition==0 and distanceofmax!=0: farthestpossibledistanceofsecondary=0 for j in range(size): if type(fullgrid[size-j][i+1])==list and size-1 not in fullgrid[size-j][i+1]: farthestpossibledistanceofsecondary=j+1 if farthestpossibledistanceofsecondarytertiaryposition and tertiaryposition!=1: for j in range((distanceofmax-tertiaryposition)-1): if type(fullgrid[((size-distanceofmax)+2)+j][i+1])==list: fullgrid[((size-distanceofmax)+2)+j][i+1].append(size-1) cleannotes(size,fullgrid) if distanceofmax!=0: shortestpossible=distanceofmax existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[(size-1)-j][i+1])==list: if len(fullgrid[(size-1)-j][i+1])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[(size+1)-leveeposition][i+1][j]) if possiblevalues==[size-2,size-1]: for j in range((shortestpossible-leveeposition)-1): if type(fullgrid[(size-leveeposition)-j][i+1])==list: fullgrid[(size-leveeposition)-j][i+1].append(size-1) for j in range(leveeposition-2): if type(fullgrid[(size-1)-j][i+1])==list: fullgrid[(size-1)-j][i+1].append(size-2) cleannotes(size,fullgrid) for i in range(size): if fullgrid[i+1][0]=="3": distanceofmax=0 secondaryposition=0 tertiaryposition=0 for j in range(size): if fullgrid[i+1][j+1]==size: distanceofmax=j+1 for j in range(size): if fullgrid[i+1][j+1]==size-1: secondaryposition=j+1 for j in range(size): if fullgrid[i+1][j+1]==size-2: tertiaryposition=j+1 if secondaryposition==0 and distanceofmax!=0: farthestpossibledistanceofsecondary=0 for j in range(size): if type(fullgrid[i+1][j+1])==list and size-1 not in fullgrid[i+1][j+1]: farthestpossibledistanceofsecondary=j+1 if farthestpossibledistanceofsecondarytertiaryposition and tertiaryposition!=1: for j in range((distanceofmax-tertiaryposition)-1): if type(fullgrid[i+1][tertiaryposition+j+1])==list: fullgrid[i+1][tertiaryposition+j+1].append(size-1) cleannotes(size,fullgrid) if distanceofmax!=0: shortestpossible=distanceofmax existingnotes=[] leveeposition=0 for j in range(shortestpossible-2): if type(fullgrid[i+1][j+2])==list: if len(fullgrid[i+1][j+2])==size-2: leveeposition=j+2 if leveeposition!=0: possiblevalues=possiblevalueslist[:] for j in range(size-2): possiblevalues.remove(fullgrid[i+1][leveeposition][j]) if possiblevalues==[size-2,size-1]: for j in range((shortestpossible-leveeposition)-1): if type(fullgrid[i+1][leveeposition+1+j])==list: fullgrid[i+1][leveeposition+1+j].append(size-1) for j in range(leveeposition-2): if type(fullgrid[i+1][j+2])==list: fullgrid[i+1][j+2].append(size-2) cleannotes(size,fullgrid) return fullgrid facade=("Guessing functions") def twoorthreeopenrestclosedanywhereprecursor(size,fullgrid,possiblevalueslist): cleannotes(size,fullgrid) for i in range(size): if fullgrid[0][i+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[j+1][i+1])==list: opencount=opencount+1 if type(fullgrid[j+1][i+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[0][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: for j in range(size): if type(fullgrid[j+1][i+1])==list: fullgrid[j+1][i+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) if opencount==3 and closedcount==(size-3): bordervalue=int(fullgrid[0][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) unknownvaluesordered = threeopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: if unknownvaluesordered[0]!="conclusive": for j in range(size): if type(fullgrid[j+1][i+1])==list: if unknownvaluesordered[0]!=[]: fullgrid[j+1][i+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) else: unknownvaluesordered.remove("conclusive") for k in range(len(unknownvaluesordered)): for j in range(size): if type(fullgrid[j+1][i+1])==list: if unknownvaluesordered[k][1]==0: fullgrid[j+1][i+1].append(unknownvaluesordered[k][0]) unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 else: unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 for i in range(size): if fullgrid[i+1][size+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if type(fullgrid[i+1][size-j])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[i+1][size+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: for j in range(size): if type(fullgrid[i+1][size-j])==list: fullgrid[i+1][size-j]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) if opencount==3 and closedcount==(size-3): bordervalue=int(fullgrid[i+1][size+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) unknownvaluesordered = threeopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: if unknownvaluesordered[0]!="conclusive": for j in range(size): if type(fullgrid[i+1][size-j])==list: if unknownvaluesordered[0]!=[]: fullgrid[i+1][size-j]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) else: unknownvaluesordered.remove("conclusive") for k in range(len(unknownvaluesordered)): for j in range(size): if type(fullgrid[i+1][size-j])==list: if unknownvaluesordered[k][1]==0: fullgrid[i+1][size-j].append(unknownvaluesordered[k][0]) unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 else: unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 for i in range(size): if fullgrid[size+1][i+1]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if type(fullgrid[size-j][i+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[size+1][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: for j in range(size): if type(fullgrid[size-j][i+1])==list: fullgrid[size-j][i+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) if opencount==3 and closedcount==(size-3): bordervalue=int(fullgrid[size+1][i+1]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) unknownvaluesordered = threeopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: if unknownvaluesordered[0]!="conclusive": for j in range(size): if type(fullgrid[size-j][i+1])==list: if unknownvaluesordered[0]!=[]: fullgrid[size-j][i+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) else: unknownvaluesordered.remove("conclusive") for k in range(len(unknownvaluesordered)): for j in range(size): if type(fullgrid[size-j][i+1])==list: if unknownvaluesordered[k][1]==0: fullgrid[size-j][i+1].append(unknownvaluesordered[k][0]) unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 else: unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 for i in range(size): if fullgrid[i+1][0]!="0": opencount=0 closedcount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if type(fullgrid[i+1][j+1])==int: closedcount=closedcount+1 if opencount==2 and closedcount==(size-2): bordervalue=int(fullgrid[i+1][0]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) unknownvaluesordered = twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: for j in range(size): if type(fullgrid[i+1][j+1])==list: fullgrid[i+1][j+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) if opencount==3 and closedcount==(size-3): bordervalue=int(fullgrid[i+1][0]) lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) unknownvaluesordered = threeopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist) if type(unknownvaluesordered)==list: if unknownvaluesordered[0]!="conclusive": for j in range(size): if type(fullgrid[i+1][j+1])==list: if unknownvaluesordered[0]!=[]: fullgrid[i+1][j+1]=unknownvaluesordered[0] unknownvaluesordered.remove(unknownvaluesordered[0]) else: unknownvaluesordered.remove("conclusive") for k in range(len(unknownvaluesordered)): for j in range(size): if type(fullgrid[i+1][j+1])==list: if unknownvaluesordered[k][1]==0: fullgrid[i+1][j+1].append(unknownvaluesordered[k][0]) unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 else: unknownvaluesordered[k][1]=unknownvaluesordered[k][1]-1 cleannotes(size,fullgrid) return fullgrid def twoopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist): possiblevalues=[] for i in range(size): if type(lineofvalues[i])==int: possiblevalues.append(lineofvalues[i]) if len(possiblevalues)==len(set(possiblevalues)): remainingvalues=possiblevalueslist[:] for i in range(size): if type(lineofvalues[i])==int: remainingvalues.remove(lineofvalues[i]) testorder1=lineofvalues[:] testremainingvalues1=remainingvalues[:] for i in range(size): if type(testorder1[i])==list: testorder1[i]=testremainingvalues1[0] testremainingvalues1.remove(testremainingvalues1[0]) highcount1=0 currenthigh=0 for i in range(size): if testorder1[i]>currenthigh: highcount1=highcount1+1 currenthigh=testorder1[i] testorder2=lineofvalues[:] testremainingvalues2=remainingvalues[:] for i in range(size): if type(testorder2[i])==list: testorder2[i]=testremainingvalues2[-1] testremainingvalues2.remove(testremainingvalues2[-1]) highcount2=0 currenthigh=0 for i in range(size): if testorder2[i]>currenthigh: highcount2=highcount2+1 currenthigh=testorder2[i] if bordervalue==highcount1 and bordervalue!=highcount2: return remainingvalues if bordervalue!=highcount1 and bordervalue==highcount2: return remainingvalues[::-1] if bordervalue==highcount1 and bordervalue==highcount2: return "inconclusive" if bordervalue!=highcount1 and bordervalue!=highcount2: return "impossible" else: return "impossible" def threeopenrestclosedanywhere(size,bordervalue,lineofvalues,possiblevalueslist): # same as two open rest closed, but for three possiblevalues=[] for i in range(size): if type(lineofvalues[i])==int: possiblevalues.append(lineofvalues[i]) if len(possiblevalues)==len(set(possiblevalues)): remainingvalues=possiblevalueslist[:] for i in range(size): # determines the remaining values to be settled if type(lineofvalues[i])==int: remainingvalues.remove(lineofvalues[i]) testremainingvalues1=[remainingvalues[0],remainingvalues[1],remainingvalues[2]] testremainingvalues2=[remainingvalues[0],remainingvalues[2],remainingvalues[1]] testremainingvalues3=[remainingvalues[1],remainingvalues[0],remainingvalues[2]] testremainingvalues4=[remainingvalues[1],remainingvalues[2],remainingvalues[0]] testremainingvalues5=[remainingvalues[2],remainingvalues[0],remainingvalues[1]] testremainingvalues6=[remainingvalues[2],remainingvalues[1],remainingvalues[0]] remainingvalues1=[remainingvalues[0],remainingvalues[1],remainingvalues[2]] remainingvalues2=[remainingvalues[0],remainingvalues[2],remainingvalues[1]] remainingvalues3=[remainingvalues[1],remainingvalues[0],remainingvalues[2]] remainingvalues4=[remainingvalues[1],remainingvalues[2],remainingvalues[0]] remainingvalues5=[remainingvalues[2],remainingvalues[0],remainingvalues[1]] remainingvalues6=[remainingvalues[2],remainingvalues[1],remainingvalues[0]] testorder1=lineofvalues[:] testorder2=lineofvalues[:] testorder3=lineofvalues[:] testorder4=lineofvalues[:] testorder5=lineofvalues[:] testorder6=lineofvalues[:] for i in range(size): if type(testorder1[i])==list: testorder1[i]=testremainingvalues1[0] testremainingvalues1.remove(testremainingvalues1[0]) highcount=0 currenthigh=0 for i in range(size): if testorder1[i]>currenthigh: highcount=highcount+1 currenthigh=testorder1[i] if highcount==bordervalue: test1=1 else: test1=0 for i in range(size): if type(testorder2[i])==list: testorder2[i]=testremainingvalues2[0] testremainingvalues2.remove(testremainingvalues2[0]) highcount=0 currenthigh=0 for i in range(size): if testorder2[i]>currenthigh: highcount=highcount+1 currenthigh=testorder2[i] if highcount==bordervalue: test2=1 else: test2=0 for i in range(size): if type(testorder3[i])==list: testorder3[i]=testremainingvalues3[0] testremainingvalues3.remove(testremainingvalues3[0]) highcount=0 currenthigh=0 for i in range(size): if testorder3[i]>currenthigh: highcount=highcount+1 currenthigh=testorder3[i] if highcount==bordervalue: test3=1 else: test3=0 for i in range(size): if type(testorder4[i])==list: testorder4[i]=testremainingvalues4[0] testremainingvalues4.remove(testremainingvalues4[0]) highcount=0 currenthigh=0 for i in range(size): if testorder4[i]>currenthigh: highcount=highcount+1 currenthigh=testorder4[i] if highcount==bordervalue: test4=1 else: test4=0 for i in range(size): if type(testorder5[i])==list: testorder5[i]=testremainingvalues5[0] testremainingvalues5.remove(testremainingvalues5[0]) highcount=0 currenthigh=0 for i in range(size): if testorder5[i]>currenthigh: highcount=highcount+1 currenthigh=testorder5[i] if highcount==bordervalue: test5=1 else: test5=0 for i in range(size): if type(testorder6[i])==list: testorder6[i]=testremainingvalues6[0] testremainingvalues6.remove(testremainingvalues6[0]) highcount=0 currenthigh=0 for i in range(size): if testorder6[i]>currenthigh: highcount=highcount+1 currenthigh=testorder6[i] if highcount==bordervalue: test6=1 else: test6=0 newnotes=["conclusive"] if test1+test2+test3+test4+test5+test6==0: return "impossible" elif test1+test2+test3+test4+test5+test6==1: if test1==1: return remainingvalues1 if test2==1: return remainingvalues2 if test3==1: return remainingvalues3 if test4==1: return remainingvalues4 if test5==1: return remainingvalues5 if test6==1: return remainingvalues6 elif test1==1 and test2==1 and test3==0 and test4==0 and test5==0 and test6==0: return [remainingvalues[0],[],[]] elif test1==0 and test2==0 and test3==1 and test4==1 and test5==0 and test6==0: return [remainingvalues[1],[],[]] elif test1==0 and test2==0 and test3==0 and test4==0 and test5==1 and test6==1: return [remainingvalues[2],[],[]] elif test1==0 and test2==0 and test3==1 and test4==0 and test5==1 and test6==0: return [[],remainingvalues[0],[]] elif test1==1 and test2==0 and test3==0 and test4==0 and test5==0 and test6==1: return [[],remainingvalues[1],[]] elif test1==0 and test2==1 and test3==0 and test4==1 and test5==0 and test6==0: return [[],remainingvalues[2],[]] elif test1==0 and test2==0 and test3==0 and test4==1 and test5==0 and test6==1: return [[],[],remainingvalues[0]] elif test1==0 and test2==1 and test3==0 and test4==0 and test5==1 and test6==0: return [[],[],remainingvalues[1]] elif test1==1 and test2==0 and test3==1 and test4==0 and test5==0 and test6==0: return [[],[],remainingvalues[2]] else: if test1==0 and test2==0: newnotes.append([remainingvalues[0],0]) if test3==0 and test4==0: newnotes.append([remainingvalues[1],0]) if test5==0 and test6==0: newnotes.append([remainingvalues[2],0]) if test3==0 and test5==0: newnotes.append([remainingvalues[0],1]) if test1==0 and test6==0: newnotes.append([remainingvalues[1],1]) if test2==0 and test4==0: newnotes.append([remainingvalues[2],1]) if test4==0 and test6==0: newnotes.append([remainingvalues[0],2]) if test2==0 and test5==0: newnotes.append([remainingvalues[1],2]) if test1==0 and test3==0: newnotes.append([remainingvalues[2],2]) if newnotes!=["conclusive"]: return newnotes if newnotes==["conclusive"] and test1+test2+test3+test4+test5+test6>1: return "inconclusive" else: return "impossible" def guessrandomvalue(size,fullgrid,possiblevalueslist,depth): frozengrid=duplicategrid(size,fullgrid) # set what we know to be true while True: testnode=[random.randint(1,size),random.randint(1,size)] if type(fullgrid[testnode[0]][testnode[1]])==list: break eliminationlist=possiblevalueslist[:] for i in range(len(fullgrid[testnode[0]][testnode[1]])): eliminationlist.remove(fullgrid[testnode[0]][testnode[1]][i]) eliminationlist=sorted(eliminationlist) testvalue=eliminationlist[-1] # find our random node and value """ rig=str(input("\nWould you like to rig the test? If so say yes.\n")) if rig=="yes": testnode=list(input("\nTest node\n")) for i in range(len(testnode)): testnode[i]=int(testnode[i]) print(testnode) testvalue=int(input("\nTest value\n")) print(testvalue) """ fullgrid[testnode[0]][testnode[1]]=testvalue # set the test value f.write("Guess of "+str(testvalue)+" made at "+str(testnode)+"\n\n") fullgrid=cycleofsteps(size,fullgrid,depth+1) # here's our issue gridincorrect=not(testcorrectbeforecompletion(size,fullgrid)) if gridincorrect==True: fullgrid=duplicategrid(size,frozengrid) fullgrid[testnode[0]][testnode[1]].append(testvalue) f.write("Guess eliminated\n\n") # see if its over before it even started else: gridcomplete=testcompletion(size,fullgrid) gridcorrect=testcorrectcompletion(size,fullgrid) if gridcomplete==True and gridcorrect==True: return fullgrid if gridcomplete==True and gridcorrect==False: # redundant? print("Testing for redundancy primary") fullgrid=duplicategrid(size,frozengrid) fullgrid[testnode[0]][testnode[1]].append(testvalue) if gridcomplete==False: print("Testing for redundancy secondary") fullgrid=guessrandomvalue(size,fullgrid,possiblevalueslist) return fullgrid def singlelineguessprecursor(size,fullgrid,possiblevalueslist): cleannotes(size,fullgrid) for i in range(size): opencount=0 for j in range(size): if type(fullgrid[j+1][i+1])==list: opencount=opencount+1 if opencount>3: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) oldlineofvalues=lineofvalues[:] newlineofvalues=singlelineguess(size,lineofvalues,int(fullgrid[0][i+1]),int(fullgrid[size+1][i+1]),possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[j+1][i+1]=newlineofvalues[j] if testcorrectbeforecompletion(size,fullgrid)==True: cleannotes(size,fullgrid) for i in range(size): opencount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if opencount>3: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) oldlineofvalues=lineofvalues[:] newlineofvalues=singlelineguess(size,lineofvalues,int(fullgrid[i+1][0]),int(fullgrid[i+1][size+1]),possiblevalueslist) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][j+1]=newlineofvalues[j] cleannotes(size,fullgrid) return fullgrid def singlelineguess(size,lineofvalues,nearbordervalue,farbordervalue,possiblevalueslist): possiblevalues=possiblevalueslist[:] for i in range(size): if type(lineofvalues[i])==int: possiblevalues.remove(lineofvalues[i]) permutationslist=list(itertools.permutations(possiblevalues,len(possiblevalues))) for i in range(len(permutationslist)): permutationslist[i]=list(permutationslist[i]) validlineslist=[] for i in range(len(permutationslist)): invalid=False lineofvaluestemp=lineofvalues[:] for j in range(size): if type(lineofvaluestemp[j])==list and invalid==False: if len(permutationslist[i])!=0 and permutationslist[i][0] in lineofvaluestemp[j]: invalid=True break else: lineofvaluestemp[j]=permutationslist[i][0] permutationslist[i].remove(permutationslist[i][0]) if invalid==False: validlineslist.append(lineofvaluestemp) possiblelineslist=[] for i in range(len(validlineslist)): highcountforward=0 currenthighforward=0 for j in range(size): if validlineslist[i][j]>currenthighforward: highcountforward=highcountforward+1 currenthighforward=validlineslist[i][j] highcountbackward=0 currenthighbackward=0 for j in range(size): if validlineslist[i][(size-1)-j]>currenthighbackward: highcountbackward=highcountbackward+1 currenthighbackward=validlineslist[i][(size-1)-j] if (highcountforward==nearbordervalue or nearbordervalue==0) and (highcountbackward==farbordervalue or farbordervalue==0): possiblelineslist.append(validlineslist[i]) lineofvalues=[] for i in range(size): possiblevalues=[] for j in range(len(possiblelineslist)): possiblevalues.append(possiblelineslist[j][i]) possiblevalues=list(set(possiblevalues)) if len(possiblevalues)==1: lineofvalues.append(possiblevalues[0]) else: lineofvalues.append(noteinversion(possiblevalues,possiblevalueslist)) return lineofvalues facade=("Equivalence checks") def equivalentopennodecheckprecursor(size,fullgrid,possiblevalueslist): for k in range(size-4): cleannotes(size,fullgrid) for i in range(size): opencount=0 for j in range(size): if type(fullgrid[j+1][i+1])==list: opencount=opencount+1 if opencount>4+k: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[j+1][i+1]) oldlineofvalues=lineofvalues[:] newlineofvalues=equivalencecheck(size,lineofvalues,possiblevalueslist,3+k) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[j+1][i+1]=newlineofvalues[j] for i in range(size): opencount=0 for j in range(size): if type(fullgrid[i+1][size-j])==list: opencount=opencount+1 if opencount>4+k: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][size-j]) oldlineofvalues=lineofvalues[:] newlineofvalues=equivalencecheck(size,lineofvalues,possiblevalueslist,3+k) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][size-j]=newlineofvalues[j] for i in range(size): opencount=0 for j in range(size): if type(fullgrid[size-j][i+1])==list: opencount=opencount+1 if opencount>4+k: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[size-j][i+1]) oldlineofvalues=lineofvalues[:] newlineofvalues=equivalencecheck(size,lineofvalues,possiblevalueslist,3+k) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[size-j][i+1]=newlineofvalues[j] for i in range(size): opencount=0 for j in range(size): if type(fullgrid[i+1][j+1])==list: opencount=opencount+1 if opencount>4+k: lineofvalues=[] for j in range(size): lineofvalues.append(fullgrid[i+1][j+1]) oldlineofvalues=lineofvalues[:] newlineofvalues=equivalencecheck(size,lineofvalues,possiblevalueslist,3+k) if oldlineofvalues!=newlineofvalues: for j in range(size): fullgrid[i+1][j+1]=newlineofvalues[j] return fullgrid def equivalencecheck(size,lineofvalues,possiblevalueslist,equivalentopennodes): possiblevalues=possiblevalueslist[:] for i in range(size): if type(lineofvalues[i])==int: possiblevalues.remove(lineofvalues[i]) combinationslength=len(possiblevalues)-equivalentopennodes combinationslist=list(itertools.combinations(possiblevalues,combinationslength)) for i in range(len(combinationslist)): activecount=[] for j in range(size): closedcount=0 if type(lineofvalues[j])==list: for k in range(combinationslength): if combinationslist[i][k] in lineofvalues[j]: closedcount=closedcount+1 if closedcount==combinationslength: activecount.append(j) if len(activecount)==equivalentopennodes: triplet=possiblevalues[:] for j in range(combinationslength): triplet.remove(combinationslist[i][j]) for j in range(size): if type(lineofvalues[j])==list and j not in activecount: for k in range(equivalentopennodes): lineofvalues[j].append(triplet[k]) for j in range(size): if type(lineofvalues[j])==list: lineofvalues[j]=list(set(lineofvalues[j])) break return lineofvalues facade=("Main logic") def cycleofsteps(size,fullgrid,depth): fullgrid=duplicategrid(size,fullgrid) game=True count=0 randomizer=True while game==True: count=count+1 complexitylevel=1 exitgame=False unchangedgrid=duplicategrid(size,fullgrid) print("The count is "+str(count)+", the depth is "+str(depth)) """ if depth==1: printgrid(size,fullgrid) """ if depth==1: f.write("The depth is 1\n") f.write("The count is "+str(count)+"\n") gridtotextfile(size,fullgrid) if complexitylevel==1: cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) updatefullindivuals(size,fullgrid) cleannotes(size,fullgrid) updatenotes(size,fullgrid) cleannotes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=2 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==2: checkrownotes(fullgrid,size) checkcolumnnotes(fullgrid,size) if fullgrid==unchangedgrid: complexitylevel=3 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==3: # border twos with distant maxes fullgrid=bordertwosdistancemaxesadjacentnode(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=4 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==4: # on border twos put one below maxes in front of distant maxes fullgrid=bordertwosdistantmaxesleadingtoprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=5 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==5: # for eliminating maxes on border twos when one below max is known, and more fullgrid=unknownmaxes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=6 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==6: fullgrid=heightsprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=7 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==7: # more tests on border threes fullgrid=borderthreesagain(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=8 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==8: # fill in low notes for at range maxes lownotesforatrangemaxesprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=9 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==9: # find double or triple opens in otherwise completed lines and fill in if randomizer==True: fullgrid=twoorthreeopenrestclosedanywhereprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=10 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==10: # fill in border notes in lines with high values obscured behind maxes fullgrid=bordernotes(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=11 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==11: # row equivalence check for i in range(size): for j in range(size): for k in range(size): if fullgrid[i+1][j+1]==fullgrid[i+1][k+1] and j!=k and type(fullgrid[i+1][j+1])==list and len(fullgrid[i+1][j+1])==size-2: eliminationlist=possiblevalueslist[:] for l in range(size-2): eliminationlist.remove(fullgrid[i+1][j+1][l]) for l in range(size): if l!=j and l!=k and type(fullgrid[i+1][l+1])==list: fullgrid[i+1][l+1].append(eliminationlist[0]) fullgrid[i+1][l+1].append(eliminationlist[1]) cleannotes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=12 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==12: # column equivalence check for i in range(size): for j in range(size): for k in range(size): if fullgrid[j+1][i+1]==fullgrid[k+1][i+1] and j!=k and type(fullgrid[j+1][i+1])==list and len(fullgrid[j+1][i+1])==size-2: eliminationlist=possiblevalueslist[:] for l in range(size-2): eliminationlist.remove(fullgrid[j+1][i+1][l]) for l in range(size): if l!=j and l!=k and type(fullgrid[l+1][i+1])==list: fullgrid[l+1][i+1].append(eliminationlist[0]) fullgrid[l+1][i+1].append(eliminationlist[1]) cleannotes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=13 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==13: equivalentopennodecheckprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=14 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==14: # for example if border is 2 and adjacent is 1 put max next to it fullgrid=lowvaluesatbordersunknownmaxes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=15 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==15: # putting high notes in front of maxes where the border adjacent node is at its max possible value for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[j+1][i+1]==size: distanceofmax=j+1 if distanceofmax!=0 and type(fullgrid[1][i+1])==int: if fullgrid[1][i+1]==(size+1)-int(fullgrid[0][i+1]): # okay actaully though, we have a lot of generalization to do here if int(fullgrid[0][i+1])>3: # makes sure its at least a border 4 for j in range(int(fullgrid[0][i+1])-3): # affecting to a distance bordervalues-3 if type(fullgrid[(distanceofmax-1)-j][i+1])==list: # if node in front of max is a list for k in range(((int(fullgrid[0][i+1])-3)-j)): # as j increases k range decreases fullgrid[(distanceofmax-1)-j][i+1].append(fullgrid[1][i+1]+1+k) cleannotes(size,fullgrid) for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[i+1][size-j]==size: distanceofmax=j+1 if distanceofmax!=0 and type(fullgrid[i+1][size])==int: if fullgrid[i+1][size]==(size+1)-int(fullgrid[i+1][size+1]): inverteddistanceofmax=(size+1)-distanceofmax if int(fullgrid[i+1][size+1])>3: for j in range(int(fullgrid[i+1][size+1])-3): if type(fullgrid[i+1][(inverteddistanceofmax+1)+j])==list: for k in range(((int(fullgrid[i+1][size+1])-3)-j)): fullgrid[i+1][(inverteddistanceofmax+1)+j].append(fullgrid[i+1][size]+1+k) cleannotes(size,fullgrid) for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[size-j][i+1]==size: distanceofmax=j+1 if distanceofmax!=0 and type(fullgrid[size][i+1])==int: if fullgrid[size][i+1]==(size+1)-int(fullgrid[size+1][i+1]): inverteddistanceofmax=(size+1)-distanceofmax if int(fullgrid[size+1][i+1])>3: for j in range(int(fullgrid[size+1][i+1])-3): if type(fullgrid[(inverteddistanceofmax+1)+j][i+1])==list: for k in range(((int(fullgrid[size+1][i+1])-3)-j)): fullgrid[(inverteddistanceofmax+1)+j][i+1].append(fullgrid[size][i+1]+1+k) cleannotes(size,fullgrid) for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[i+1][j+1]==size: distanceofmax=j+1 if distanceofmax!=0 and type(fullgrid[i+1][1])==int: if fullgrid[i+1][1]==(size+1)-int(fullgrid[i+1][0]): if int(fullgrid[i+1][0])>3: for j in range(int(fullgrid[i+1][0])-3): if type(fullgrid[i+1][(distanceofmax-1)-j])==list: for k in range(((int(fullgrid[i+1][0])-3)-j)): fullgrid[i+1][(distanceofmax-1)-j].append(fullgrid[i+1][1]+1+k) cleannotes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=16 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==16: # opposite border values can have size-1 appended in the middle for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[j+1][i+1]==size: distanceofmax=j+1 bordervaluenear=int(fullgrid[0][i+1]) bordervaluefar=int(fullgrid[size+1][i+1]) if distanceofmax==0 and bordervaluenear!=0 and bordervaluefar!=0: nearlineofvalues=[] farlineofvalues=[] for j in range(size): if type(fullgrid[j+1][i+1])==int: nearlineofvalues.append(fullgrid[j+1][i+1]) else: break for j in range(size): if type(fullgrid[size-j][i+1])==int: farlineofvalues.append(fullgrid[size-j][i+1]) else: break for j in range(len(nearlineofvalues)): if nearlineofvalues[j]==j+1: continue else: nearlineofvalues=0 break for j in range(len(farlineofvalues)): if farlineofvalues[j]==j+1: continue else: farlineofvalues=0 break if nearlineofvalues!=0 and farlineofvalues!=0: if len(nearlineofvalues)==bordervaluenear-2 and len(farlineofvalues)==bordervaluefar-2: for j in range(size-((bordervaluenear-1)+(bordervaluefar-1))): if type(fullgrid[bordervaluenear+j][i+1])==list: fullgrid[bordervaluenear+j][i+1].append(size-1) for i in range(size): distanceofmax=0 for j in range(size): if fullgrid[i+1][j+1]==size: distanceofmax=j+1 bordervaluenear=int(fullgrid[i+1][0]) bordervaluefar=int(fullgrid[i+1][size+1]) if distanceofmax==0 and bordervaluenear!=0 and bordervaluefar!=0: nearlineofvalues=[] farlineofvalues=[] for j in range(size): if type(fullgrid[i+1][j+1])==int: nearlineofvalues.append(fullgrid[i+1][j+1]) else: break for j in range(size): if type(fullgrid[i+1][size-j])==int: farlineofvalues.append(fullgrid[i+1][size-j]) else: break for j in range(len(nearlineofvalues)): if nearlineofvalues[j]==j+1: continue else: nearlineofvalues=0 break for j in range(len(farlineofvalues)): if farlineofvalues[j]==j+1: continue else: farlineofvalues=0 break if nearlineofvalues!=0 and farlineofvalues!=0: if len(nearlineofvalues)==bordervaluenear-2 and len(farlineofvalues)==bordervaluefar-2: for j in range(size-((bordervaluenear-1)+(bordervaluefar-1))): if type(fullgrid[i+1][bordervaluenear+j])==list: fullgrid[i+1][bordervaluenear+j].append(size-1) cleannotes(size,fullgrid) if fullgrid==unchangedgrid: complexitylevel=17 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==17: if randomizer==True: fullgrid=singlelineguessprecursor(size,fullgrid,possiblevalueslist) if fullgrid==unchangedgrid: complexitylevel=18 if fullgrid!=unchangedgrid: f.write("Change made at complexity level "+str(complexitylevel)+"\n") complexitylevel=1 if complexitylevel==18: if randomizer==True: fullgrid=guessrandomvalue(size,fullgrid,possiblevalueslist,depth) else: exitgame=True """ printgrid(size,fullgrid) givennode=list(input("Instead of guessing, let's add notes.\n")) fullgrid[int(givennode[0])][int(givennode[1])].append(int(givennode[2])) print("") """ if fullgrid==unchangedgrid: exitgame=True if fullgrid!=unchangedgrid: complexitylevel=1 # test to see if the grid is incorrect even before completion fullgrid=cleannotes(size,fullgrid) gridcorrect=testcorrectbeforecompletion(size,fullgrid) if gridcorrect==False: exitgame=True # test to see if the grid is complete or count is too high game=False for i in range(size): for j in range(size): if type(fullgrid[i+1][j+1])==list: game=True if exitgame==True: game=False if count==200: print("\nEnded because count is too high") game=False return fullgrid # end of function definitions facade=("End of function definitions") # for manual input #""" size=int(input("\nWhat is the size of the puzzle?\n")) border=str(input("\nStarting in the top left corner and going clockwise, enter the border numbers.\n")) # create a list of possible values within each line possiblevalueslist=[] for i in range(size): possiblevalueslist.append(i+1) # create the grid fullgrid=[] for i in range(size+2): fullgrid.append([]) for i in range(size+2): for j in range(size+2): fullgrid[i].append([]) # create the border for i in range(size): fullgrid[0][i+1]=border[i] for i in range(size): fullgrid[i+1][size+1]=border[i+size] for i in range(size): fullgrid[size+1][size-i]=border[i+(size*2)] for i in range(size): fullgrid[size-i][0]=border[i+(size*3)] # runs the one time basic commands related to the border fullgrid=startinggridupdate(size,fullgrid) entergivens=True while entergivens==True: givennode=list(input("\nEnter any givens. Consider the top left corner of the grid to be 1,1. Enter 000 when done.\n")) if givennode==["0","0","0"]: entergivens=False else: fullgrid[int(givennode[0])][int(givennode[1])]=int(givennode[2]) print("") #""" #""" # on a normal day starttime=time.time() fullgrid=cycleofsteps(size,fullgrid,1) endtime=time.time() # test the grid for completion gridcorrect=testcorrectcompletion(size,fullgrid) if gridcorrect==True: print("") printgridfinal(size,fullgrid) print("The grid is correct. Puzzle completed in "+str(endtime-starttime)+" seconds!\n") if gridcorrect==False: print("") printgrid(size,fullgrid) print("The grid is incorrect. Puzzle incomplete!") #""" """ # for testing purposes totaltime=0 attempts=10 frozengrid=duplicategrid(size,fullgrid) for i in range(attempts): starttime=time.time() tempgrid=cycleofsteps(size,frozengrid,1) endtime=time.time() totaltime=totaltime+(endtime-starttime) gridcorrect=testcorrectcompletion(size,tempgrid) if gridcorrect==False: print("The grid is incorrect. Puzzle incomplete!") f.write("The grid is incorrect. Puzzle incomplete!\n") print("\nFinished in an average time of "+str(totaltime/attempts)+" seconds!") """ # for testing a lot of boards at once inputgrids=[[7,"0300420000500303004233022304",2,672,721],[7,"4000502033400024042002320045",4,152,674,721,743],[7,"0020000030200003003345200043",5,152,233,343,511,724],[7,"0502200034043004032100020122",2,143,372],[7,"4040240042320430242200330324",0],[7,"0002000002042303203023000430",4,112,244,271,627],[7,"0014400220002002404010000500",4,372,435,662,731],[9,"002303304003033300000434040000330222",14,122,263,333,367,379,454,537,693,744,761,843,878,891,912]] # inputgrids=[[7,"0000310003303520000000044103",5,124,151,244,341,773],[7,"0000403030040003230004022022",5,353,437,521,673,761],[7,"4032002003023504000003301000",5,143,215,231,454,553],[7,"0024203002330024303420434020",4,272,361,411,424]] # inputgrids=[[7,"0122025300302000530500501000",5,112,224,331,622,634],[7,"2100500030300404040300002320",4,174,471,664,742],[7,"4023002003030010050043000240",3,371,475,633],[7,"5030002030330333300402030306",3,212,324,361],[7,"3343400000440535020020020443",2,452,634],[7,"0040002000431000353400342002",5,153,261,352,532,765],[7,"0012403020403420002000341303",5,112,251,354,431,524],[7,"0301340030360440200010300033",4,132,421,563,571],[7,"0300140000030360004300002120",2,221,632]] # inputgrids=[[7,"0001222005203002031342302042",3,435,673,743],[7,"3030205533000203030520004100",5,162,425,467,641,723],[7,"0430020000302030402340040230",4,364,521,653,672],[7,"0045005052421000000600543400",2,165,663],[7,"0324030032000300210000003043",4,374,514,533,624],[7,"0302000002035030410400000325",5,244,311,363,553,672],[7,"5003005302200300340000020500",3,371,554,563],[7,"3322030032020000033400340003",6,172,232,375,435,552,643],[7,"0302403003022202043043050220",5,172,452,466,653,734],[7,"0020003430030430033600340300",5,341,512,531,632,721],[7,"0300204060300000013000040003",6,413,437,472,643,654,724,751],[7,"0304400000042200204030320230",4,173,261,313,671],[7,"0033004244005000400032030300",3,343,612,741],[7,"0100243000324200024423033400",4,145,242,332,544],[7,"4340020004340400330300402043",4,263,341,422,547],[7,"4330020100030200402000300204",6,145,335,366,441,514,762],[7,"3303300004002204000323051020",4,371,621,643,733],[7,"0034000100045005140003000340",5,214,243,413,572,622],[7,"0002632000414004000000330230",4,372,442,535,721],[7,"3002220010000334100400304030",4,111,432,542,664],[7,"0403122000453041430003004333",3,242,456,564],[7,"4032004000250000224404000440",5,312,562,676,731,755],[7,"2122004000020402004300002420",4,143,272,362,621],[7,"0430023200401404001002002010",5,231,242,532,543,653]] # inputgrids=webscraper(1000) starttime=time.time() #multiple test cycle """ cycles=5 length=len(inputgrids) correctgridscount=0 incorrectgridscount=0 incorrectgrids=[] for l in range(cycles): for k in range(length): size=inputgrids[k][0] border=inputgrids[k][1] # create a list of possible values within each line possiblevalueslist=[] for i in range(size): possiblevalueslist.append(i+1) # create the grid fullgrid=[] for i in range(size+2): fullgrid.append([]) for i in range(size+2): for j in range(size+2): fullgrid[i].append([]) # create the border for i in range(size): fullgrid[0][i+1]=border[i] for i in range(size): fullgrid[i+1][size+1]=border[i+size] for i in range(size): fullgrid[size+1][size-i]=border[i+(size*2)] for i in range(size): fullgrid[size-i][0]=border[i+(size*3)] # runs the one time basic commands related to the border fullgrid=startinggridupdate(size,fullgrid) # the givens givenslength=inputgrids[k][2] for j in range(givenslength): givennode=list(str(inputgrids[k][3+j])) fullgrid[int(givennode[0])][int(givennode[1])]=int(givennode[2]) fullgrid=cycleofsteps(size,fullgrid,1) gridcorrect=testcorrectcompletion(size,fullgrid) if gridcorrect==True: correctgridscount=correctgridscount+1 print("The grid is correct.") f.write("The grid is correct.\n") if gridcorrect==False: incorrectgridscount=incorrectgridscount+1 incorrectgrids.append(k) print("The grid is incorrect. Puzzle incomplete!") f.write("The grid is incorrect.\n") if correctgridscount == length*cycles: print("All grids were correctly completed.") else: print("There were errors at the following indexes.") print(incorrectgrids) """ endtime=time.time() # print(endtime-starttime) var=str(input("\nHit enter to exit.")) # completed # 0300420000500303004233022304 672 721 # 4000502033400024042002320045 152 674 721 743 # 0020000030200003003345200043 152 233 343 511 724 # 0502200034043004032100020122 143 372 # 4040240042320430242200330324 # 0002000002042303203023000430 112 244 271 627 # 0014400220002002404010000500 372 435 662 731 # 002303304003033300000434040000330222 122 263 333 367 379 454 537 693 744 761 843 878 891 912 # works in progress # 0122025300302000530500501000 112 224 331 622 634 # 2100500030300404040300002320 174 471 664 742 # 4023002003030010050043000240 371 475 633 # 5030002030330333300402030306 212 324 361 # 3343400000440535020020020443 452 634 # 0040002000431000353400342002 153 261 352 532 765 # 0012403020403420002000341303 112 251 354 431 524 # 0301340030360440200010300033 132 421 563 571 # 0300140000030360004300002120 221 632 # 240204030022420220000043026343000033 155 236 275 312 427 473 491 566 584 686 733 815 831 852 963 # 0000310003303520000000044103 124 151 244 341 773 *112 113 716 714 726 252 725 413 425 465 421 456 657* # 0000403030040003230004022022 353 437 521 673 761 *722 412 151 152* # 4032002003023504000003301000 143 215 231 454 553 *361* # 0024203002330024303420434020 272 361 411 424 *571 514 515 153 621 622 344 345 655 645* # 0001222005203002031342302042 435 673 743 # 3030205533000203030520004100 162 425 467 641 723 # 0430020000302030402340040230 364 521 653 672 # 0045005052421000000600543400 165 663 # 0324030032000300210000003043 374 514 533 624 # 0302000002035030410400000325 244 311 363 553 672 # 5003005302200300340000020500 371 554 563 # 3322030032020000033400340003 172 232 375 435 552 643 # 0302403003022202043043050220 172 452 466 653 734 # 0020003430030430033600340300 341 512 531 632 721 # 0300204060300000013000040003 413 437 472 643 654 724 751 # 0304400000042200204030320230 173 261 313 671 # 0033004244005000400032030300 343 612 741 # 0100243000324200024423033400 145 242 332 544 # 4340020004340400330300402043 263 341 422 547 # 4330020100030200402000300204 145 335 366 441 514 762 # 3303300004002204000323051020 371 621 643 733 # 0034000100045005140003000340 214 243 413 572 622 # 0002632000414004000000330230 372 442 535 721 # 3002220010000334100400304030 111 432 542 664 # 0403122000453041430003004333 242 456 564 # 4032004000250000224404000440 312 562 676 731 755 # 2122004000020402004300002420 143 272 362 621 # 0430023200401404001002002010 231 242 532 543 653 # border="240204030022420220000043026343000033" # border="002303304003033300000434040000330222" # border="002303304003033300000434040000330222" # fullgrid=[[[], '2', '4', '0', '2', '0', '4', '0', '3', '0', []], ['3', [8, 9], [7, 8, 9], [], [9], 5, [7, 8, 9], [], [8, 9], [], '0'], ['3', [8, 9], [8, 9], 6, [8], [], [8, 9], 5, [8, 9], [9], '2'], ['0', 2, [9], [], [], [], [9], [], [8], [9], '2'], ['0', [], 7, [], [], [], [], 3, [8, 9], 1, '4'], ['0', [9], [], [], [], [], 6, [], 4, [9], '2'], ['0', [8, 9], [], [], [], [], [], [], 6, [], '0'], ['3', [7, 8, 9], [9], 3, [], [9], [], [], [8], [9], '2'], ['4', 5, [8, 9], 1, [9], 2, [], [], [8], [9], '2'], ['3', [5, 6, 7, 8, 9], [9], [], [8, 9], [7, 8, 9], 3, [], [], [], '0'], [[], '6', '2', '0', '3', '4', '0', '0', '0', '0', []]] # fullgrid=[[[], '0', '0', '2', '3', '0', '3', '3', '0', '4', []], ['2', [9], 2, [9], [8, 9], [], [8, 9], [8, 9], [], [7, 8, 9], '0'], ['2', [9], [8], [8], [9], [], 3, [9], [], [8, 9], '0'], ['2', [9], [8], 3, [], [], 7, 9, [9], [8, 9], '3'], ['0', [], [], [], [], 4, [], [], [], [], '0'], ['3', [8, 9], [9], 7, [], [], [], [], [9], [8, 9], '3'], ['3', [8, 9], [9], [], [], [], [], [], [9], 3, '3'], ['0', [], [9], [], 4, [], 1, [], [9], [8, 9], '3'], ['0', [], [8, 9], [], 3, [9], [8, 9], 8, [], 1, '0'], ['0', 2, [7, 8, 9], [], [7, 8, 9], [8, 9], [7, 8, 9], [], [], [], '0'], [[], '0', '4', '0', '4', '3', '4', '0', '0', '0', []]] # fullgrid=[[[], '0', '0', '2', '3', '0', '3', '3', '0', '4', []], ['2', [9], 2, [9], [8, 9], [], [8, 9], [8, 9], [], [7, 8, 9], '0'], ['2', [9], [8], [8], [9], [], 3, [9], [], [8, 9], '0'], ['2', [9], [8], 3, [], [], 7, 9, [9], [8, 9], '3'], ['0', [], [], [], [], 4, [], [], [], [], '0'], ['3', [8, 9], [9], 7, [], [], [], [], [9], [8, 9], '3'], ['3', [8, 9], [9], [], [], [], [], [], [9], 3, '3'], ['0', [], [9], [], 4, [], 1, [], [9], [8, 9], '3'], ['0', [], [8, 9], [], 3, [9], [8, 9], 8, [], 1, '0'], ['0', 2, [7, 8, 9], [], [7, 8, 9], [8, 9], [7, 8, 9], [], [], [], '0'], [[], '0', '4', '0', '4', '3', '4', '0', '0', '0', []]] """ 9/9/2022 Looked at 5030002030330333300402030306. Can do some surface stuff to make it easier. 11/19/2022 Investigated 0033004244005000400032030300, it can be solved in 2 additions. Investigated 0001222005203002031342302042. 11/23/2022 Heights successor has caught up to heights, so I have deleted heights. Went from 5150 lines to 3523 lines. 1/8/2023 Discern which function will best fit the 43140072 secenario. Identified [5,[],2,[],6,[],7,[]] and [6,[],[],[1,2,5,6,7],5,[1,2,5,6,7],[],[]] and [4,[7],4,[7],[],[],6,[7]] as a good line of values to work on. 4/1/2023 Identified [3,[1,4,5,6,7],[5,6,7],6,[6,7],[6,7],7,[2,5,6,7]] as a good line of values to work on. 4/3/2023 New iteration. Cleaning out a lot. Extensive testing says this is a safe point. The goal is to now reduce this to as few lines as possible, mainly by turning 4 into 1. Looking at the border 2s functions. """