# More games at ti84calcwiz.com
AC='SUDOKU'
AB='EXPERT'
AA='MEDIUM'
r='sol'
q=Exception
p=list
i=len
b='hints'
a='hint'
Z='given'
Y=int
X=set
S='notesmode'
O='conf'
N=None
M=str
L=False
J='cur'
I=divmod
H='notes'
G=True
D='grid'
A=range
import random as s
try:import ti_draw as C,ti_system as j,time as k;t=G
except ImportError:t=L
def AD(i):
	C,D=I(i,9);F,G=C//3*3,D//3*3;B=[]
	for E in A(9):B.append(C*9+E);B.append(E*9+D)
	for H in A(3):
		for J in A(3):B.append((F+H)*9+(G+J))
	return[A for A in X(B)if A!=i]
c=[AD(A)for A in A(81)]
def Q(lst,ri):
	B=lst
	for C in A(i(B)-1,0,-1):D=ri(0,C);B[C],B[D]=B[D],B[C]
def AE():
	C=[0]*81
	for B in A(9):
		for D in A(9):C[B*9+D]=(3*(B%3)+B//3+D)%9+1
	return C
def AF(ri):
	B=ri;J=p(A(1,10));Q(J,B);N=[J[A-1]for A in AE()];C=[N[A*9:A*9+9]for A in A(9)]
	for D in A(3):
		E=[0,1,2];Q(E,B);I=[C[D*3+E[A]]for A in A(3)]
		for F in A(3):C[D*3+F]=I[F]
	G=[0,1,2];Q(G,B);C=[C[G[B]*3+D]for B in A(3)for D in A(3)];H=[[C[A][B]for A in A(9)]for B in A(9)]
	for D in A(3):
		E=[0,1,2];Q(E,B);I=[H[D*3+E[A]]for A in A(3)]
		for F in A(3):H[D*3+F]=I[F]
	G=[0,1,2];Q(G,B);H=[H[G[B]*3+C]for B in A(3)for C in A(3)];K=[0]*81
	for L in A(9):
		for M in A(9):K[M*9+L]=H[L][M]
	return K
def AG(board,limit=2,node_cap=2600):
	G=board[:];H=[0]*9;J=[0]*9;K=[0]*9
	for R in A(81):
		F=G[R]
		if F:C,D=I(R,9);B=1<<F;H[C]|=B;J[D]|=B;K[C//3*3+D//3]|=B
	def S():
		D=-1;E=N;F=10
		for B in A(81):
			if G[B]==0:
				L,M=I(B,9);P=H[L]|J[M]|K[L//3*3+M//3];O=[A for A in A(1,10)if not P>>A&1];C=i(O)
				if C<F:
					D=B;E=O;F=C
					if C<=1:break
		return D,E
	E,L=S()
	if E==-1:return 1
	M=[[E,L,0]];O=0;T=0
	while M:
		T+=1
		if T>node_cap:return-1
		P=M[-1];E=P[0];L=P[1];Q=P[2]
		if Q>=i(L):
			F=G[E]
			if F:C,D=I(E,9);B=1<<F;H[C]&=~B;J[D]&=~B;K[C//3*3+D//3]&=~B;G[E]=0
			M.pop();continue
		F=L[Q];P[2]=Q+1;C,D=I(E,9);U=C//3*3+D//3;V=G[E]
		if V:B=1<<V;H[C]&=~B;J[D]&=~B;K[U]&=~B
		B=1<<F;G[E]=F;H[C]|=B;J[D]|=B;K[U]|=B;W,X=S()
		if W==-1:
			O+=1
			if O>=limit:return O
		elif X:M.append([W,X,0])
	return O
d=[]
for AH in A(9):d.append([AH*9+A for A in A(9)])
for AI in A(9):d.append([A*9+AI for A in A(9)])
for AJ in A(3):
	for AK in A(3):d.append([(AJ*3+B)*9+(AK*3+C)for B in A(3)for C in A(3)])
u=0
for AL in A(1,10):u|=1<<AL
def AM(x):
	A=0
	while x:x&=x-1;A+=1
	return A
def AN(c):
	A=1
	while c>2:c>>=1;A+=1
	return A
def AO(grid):
	C=grid[:]
	while G:
		E=[0]*81
		for B in A(81):
			if C[B]==0:
				H=0
				for N in c[B]:
					I=C[N]
					if I:H|=1<<I
				J=u&~H
				if J==0:return L
				E[B]=J
		D=L
		for B in A(81):
			if C[B]==0 and AM(E[B])==1:C[B]=AN(E[B]);D=G
		if D:continue
		for O in d:
			for K in A(1,10):
				P=1<<K;F=0;M=-1
				for B in O:
					if C[B]==0 and E[B]&P:
						F+=1;M=B
						if F>1:break
				if F==1:C[M]=K;D=G
			if D:break
		if D:continue
		break
	return all(C)
v={'EASY':(46,G),AA:(38,G),'HARD':(31,N),AB:(26,N)}
Ao={A:B[0]for(A,B)in v.items()}
def l(ri,target):
	F=AF(ri);B=F[:];E=81;G=p(A(41));Q(G,ri)
	for C in G:
		if E<=target:break
		D=80-C
		if B[C]==0:continue
		I,J=B[C],B[D];B[C]=0;H=1
		if D!=C and B[D]!=0:B[D]=0;H=2
		if AG(B,2)==1:E-=H
		else:B[C]=I;B[D]=J
	return B,F,E
def AP(ri,diff,tries=10):
	B=diff
	if isinstance(B,Y):return l(ri,B)
	D,E=v[B]
	if E is N:return l(ri,D)
	F=N
	for I in A(tries):
		C,G,H=l(ri,D)
		if AO(C)==E:return C,G,H
		F=C,G,H
	return F
def T(grid):
	C=[L]*81
	for B in A(81):
		D=grid[B]
		if D:
			for E in c[B]:
				if grid[E]==D:C[B]=G;break
	return C
def AQ(grid):
	if any(A==0 for A in grid):return L
	return not any(T(grid))
if t:
	U,V,K=6,8,20;w,x=1,18;P=194;E=P+(319-P)//2;y=118,122,130;AR=250,250,250;AS=219,224,232;AT=255,232,130;AU=120,178,252;AV=24,24,30;AW=36,82,214;AX=20,150,92;AY=214,44,44;AZ=108,114,128;z=30,32,38
	def F(c):C.set_color(c[0],c[1],c[2])
	def W(x,y,t,c):F(c);C.draw_text(x,y,t)
	def B(cx,y,t,c):F(c);C.draw_text(cx-(i(t)*10-2)//2,y,t)
	def Aa(k):
		try:return Y(k)
		except(ValueError,TypeError):return 0
	A0={92:1,93:2,94:3,82:4,83:5,84:6,72:7,73:8,74:9};m=0
	def Ab(refresh=N):
		B=refresh;global m
		while G:
			A=Aa(j.get_key(0))
			if A!=m:
				m=A
				if A!=0:return A
			if B:B()
	def n():return Ab(N)
	def Ac(diff,ri):A,B,C=AP(ri,diff);return{'diff':diff,D:A[:],Z:[A!=0 for A in A],r:B,a:[L]*81,H:[0]*81,O:T(A),J:40,S:L,b:0}
	def Ad(st,i):
		if i==st[J]:return AT
		A=st[D][st[J]]
		if A and st[D][i]==A:return AU
		B,C=I(i,9);return AS if(B//3+C//3)%2 else AR
	def e(st,i):
		B=st;Q,R=I(i,9);G,J=U+R*K+w,V+Q*K+w;F(Ad(B,i));C.fill_rect(G,J,x,x);N=B[D][i]
		if N:
			if B[Z][i]:E=AV
			elif B[O][i]:E=AY
			elif B[a][i]:E=AX
			else:E=AW
			W(G+4,J+21,M(N),E)
		else:
			P=B[H][i]
			if P:
				F(AZ)
				for L in A(1,10):
					if P>>L&1:S,T=(L-1)//3,(L-1)%3;C.fill_rect(G+T*6+1,J+S*6+1,4,4)
	def Ae(st):
		F(y);C.fill_rect(U,V,9*K,9*K)
		for D in A(81):e(st,D)
		F((70,74,82))
		for B in(3,6):C.fill_rect(U+B*K-1,V,2,9*K);C.fill_rect(U,V+B*K-1,9*K,2)
		F((40,42,50));C.draw_rect(U,V,9*K,9*K)
	def f(st,idxs):
		for A in idxs:e(st,A)
	def A1(sec):A=sec;B=A//60;return(M(B)if B>9 else'0'+M(B))+':'+(M(A%60)if A%60>9 else'0'+M(A%60))
	g=319-P
	def A2(y):F(z);C.fill_rect(P,y-18,g,24)
	def Af(st):F(z);C.fill_rect(P,0,g,209);B(E,24,AC,(250,205,70));B(E,48,st['diff'],(150,210,250));B(E,146,'1-9 place',(150,154,164));B(E,164,'0/DEL erase',(150,154,164));B(E,182,'2nd notes',(150,154,164));B(E,200,'ENTER hint',(150,154,164))
	def A3(st):
		A2(84)
		if st[S]:B(E,84,'NOTES',(250,180,70))
		else:B(E,84,'PEN',(150,250,160))
	def A4(st):A2(110);B(E,110,'hints '+M(st[b]),(180,184,194))
	def Ag(st):C.clear();Ae(st);Af(st);A3(st);A4(st)
	def R(st,val):return[A for A in A(81)if val and st[D][A]==val]
	def h(st,nc):
		A=st;C=A[J];E=A[D][C];F=A[D][nc];A[J]=nc;B=X([C,nc])
		if E!=F:B.update(R(A,E));B.update(R(A,F))
		f(A,B)
	def Ah(st,v):
		B=st;C=B[J]
		if B[Z][C]:return
		if B[S]:
			if B[D][C]==0:B[H][C]^=1<<v;e(B,C)
			return
		if B[D][C]==v:return A5(B)
		K=B[D][C];B[D][C]=v;B[H][C]=0;B[a][C]=L;E=X([C]);E.update(R(B,K));E.update(R(B,v))
		for F in c[C]:
			if B[H][F]&1<<v:B[H][F]&=~(1<<v);E.add(F)
		I=T(B[D])
		for G in A(81):
			if I[G]!=B[O][G]:E.add(G)
		B[O]=I;f(B,E)
	def A5(st):
		B=st;C=B[J]
		if B[Z][C]:return
		if B[S]and B[D][C]==0:
			if B[H][C]:B[H][C]=0;e(B,C)
			return
		G=B[D][C]
		if G==0 and B[H][C]==0:return
		B[D][C]=0;B[H][C]=0;B[a][C]=L;E=X([C]);E.update(R(B,G));I=T(B[D])
		for F in A(81):
			if I[F]!=B[O][F]:E.add(F)
		B[O]=I;f(B,E)
	def Ai(st):
		B=st;C=B[J]
		if B[Z][C]or B[D][C]==B[r][C]:return
		E=B[r][C];B[D][C]=E;B[H][C]=0;B[a][C]=G;B[b]+=1;F=X([C]);F.update(R(B,E))
		for I in c[C]:
			if B[H][I]&1<<E:B[H][I]&=~(1<<E);F.add(I)
		L=T(B[D])
		for K in A(81):
			if L[K]!=B[O][K]:F.add(K)
		B[O]=L;f(B,F);A4(B)
	A6='SUDBT';A7='SUDWN';o=['EASY',AA,'HARD',AB]
	def A8(name):
		try:A=[Y(A)for A in p(j.recall_list(name))];return(A+[0,0,0,0])[:4]
		except q:return[0,0,0,0]
	def A9(name,v):
		try:j.store_list(name,[float(A)for A in v])
		except q:pass
	def Aj(sel,best,wins):
		D=sel;F((18,19,24));C.fill_rect(0,0,319,209);J,K,E=22,20,18;F(y);C.fill_rect(J,K,3*E,3*E);O={0:'5',2:'3',4:'7',6:'1',8:'9'}
		for H in A(9):
			L,N=I(H,3);F((244,244,248)if(L+N)%2==0 else(210,214,224));C.fill_rect(J+N*E+1,K+L*E+1,E-2,E-2)
			if H in O:W(J+N*E+4,K+L*E+20,O[H],(36,82,214))
		W(96,40,AC,(250,205,70));W(96,64,'a new puzzle',(150,160,176));W(96,82,'every time',(150,160,176));B(160,108,'1-9 place   0/DEL erase',(170,174,184));B(160,126,'2nd notes   ENTER hint',(170,174,184))
		while G:
			F((18,19,24));C.fill_rect(0,138,319,71);Q=o[D];B(160,158,'< '+Q+' >',(250,210,90));P=best[D];R=wins[D];S='best '+(A1(P)if P else'--')+'   won '+M(R);B(160,180,S,(150,200,250));B(160,202,'ENTER play    CLEAR quit',(120,126,138));H=n()
			if H==45:return
			elif H==24:D=(D-1)%4
			elif H==26:D=(D+1)%4
			elif H==105:return D
	def Ak(diff):F((18,19,24));C.fill_rect(0,0,319,209);B(160,96,'Generating '+diff,(240,220,120));B(160,120,'please wait...',(150,156,168))
	def Al(diff,best,wins):
		K=diff;F=best;Ak(K);N=s.randint
		try:s.seed(Y(k.monotonic()*1000)&2147483647)
		except q:pass
		A=Ac(K,N);O=k.monotonic();Ag(A)
		while G:
			B=n()
			if B==45:return'quit'
			elif B==24:C,E=I(A[J],9);h(A,C*9+(E-1)%9)
			elif B==26:C,E=I(A[J],9);h(A,C*9+(E+1)%9)
			elif B==25:C,E=I(A[J],9);h(A,(C-1)%9*9+E)
			elif B==34:C,E=I(A[J],9);h(A,(C+1)%9*9+E)
			elif B==21:A[S]=not A[S];A3(A)
			elif B in(102,23):A5(A)
			elif B==105:Ai(A)
			elif B in A0:Ah(A,A0[B])
			else:continue
			if AQ(A[D]):
				L=Y(k.monotonic()-O);H=o.index(K);wins[H]+=1;A9(A7,wins);M=F[H]==0 or L<F[H]
				if M:F[H]=L;A9(A6,F)
				Am(A,L,M);return'won'
	def Am(st,sec,newbest):
		F((16,40,24));C.fill_rect(P,0,g,209);F((30,90,50));C.draw_rect(P,0,g-1,208);B(E,40,'SOLVED!',(120,250,150));B(E,72,A1(sec),(240,244,250))
		if newbest:B(E,98,'NEW BEST',(250,210,90))
		elif st[b]:B(E,98,M(st[b])+' hints',(170,176,186))
		B(E,150,'ENTER new',(200,206,216));B(E,172,'<> menu',(200,206,216));B(E,194,'CLEAR quit',(140,146,158))
	def An():
		B=A8(A6);D=A8(A7);A=1
		while G:
			E=Aj(A,B,D)
			if E is N:break
			A=E;H=o[A]
			while G:
				I=Al(H,B,D)
				if I=='quit':break
				F=n()
				if F==45:break
				if F in(24,26,25,34):break
		C.clear()
	An()