# More games at calcplex.com
k='quit'
j='best  '
i=Exception
V=int
U=tuple
Q=None
P=max
O=all
I=str
G=False
F=len
E=True
B=range
try:import ti_draw as C,ti_system as J,time;K=E
except ImportError:K=G
W=('EASY',5,24,55),('NORMAL',7,18,54),('HARD',9,14,52)
def X(line):
	B=[];A=0
	for C in line:
		if C==1:A+=1
		elif A:B.append(A);A=0
	if A:B.append(A)
	return B
def l(total,parts):
	D=[];A=[([],total,parts)]
	while A:
		E,C,F=A.pop()
		if F==1:D.append(U(E+[C]))
		else:
			for G in B(C+1):A.append((E+[G],C-G,F-1))
	return D
def m(clue,L):
	D=clue;A=F(D)
	if A==0:return[U([0]*L)]
	J=sum(D);H=L-J-(A-1)
	if H<0:return[]
	I=[]
	for E in l(H,A+1):
		C=[0]*E[0]
		for G in B(A):
			C+=[1]*D[G]
			if G<A-1:C+=[0]*(1+E[G+1])
		C+=[0]*E[A];I.append(U(C))
	return I
def Y(clue,known):
	A=known;C=F(A);D=[D for D in m(clue,C)if O(A[B]==-1 or A[B]==D[B]for B in B(C))]
	if not D:return
	G=list(A)
	for E in B(C):
		H=D[0][E]
		if O(A[E]==H for A in D):G[E]=H
	return G
def n(row_clues,col_clues,size):
	C=size;A=[[-1]*C for A in B(C)];H=E
	while H:
		H=G
		for D in B(C):
			F=Y(row_clues[D],A[D])
			if F is Q:return A,G
			if F!=A[D]:A[D]=F;H=E
		for I in B(C):
			J=[A[B][I]for B in B(C)];F=Y(col_clues[I],J)
			if F is Q:return A,G
			if F!=J:
				for D in B(C):A[D][I]=F[D]
				H=E
	K=O(A[D][E]!=-1 for D in B(C)for E in B(C));return A,K
def Z(sol,size):A=size;C=[X(sol[A])for A in B(A)];D=[X([sol[A][C]for A in B(A)])for C in B(A)];return C,D
def o(size,density,rnd,maxclue=3,attempts=1500):
	G=maxclue;A=size
	for I in B(attempts):
		C=[[1 if rnd.randint(0,99)<density else 0 for A in B(A)]for C in B(A)]
		if O(B==0 for A in C for B in A):continue
		D,E=Z(C,A)
		if P(F(A)for A in D)>G or P(F(A)for A in E)>G:continue
		J,H=n(D,E,A)
		if H:return C,D,E
def p(marks,sol,size):
	for A in B(size):
		for C in B(size):
			if(marks[A][C]==1)!=(sol[A][C]==1):return G
	return E
H=18,20,30
a=70,78,100
b=235,238,248
d=40,44,60
q=150,90,90
s=250,210,60
c=170,200,240
e=110,130,165
f=13
def R(k):
	try:return V(k)
	except(ValueError,TypeError):return 0
def A(col):A=col;C.set_color(A[0],A[1],A[2])
def D(y,txt):C.draw_text((319-(F(txt)*10-2))//2,y,txt)
def S(y,txt,col):A(H);C.fill_rect(0,y-18,319,22);A(col);D(y,txt)
def M():
	while R(J.get_key(0))!=0:pass
	while E:
		A=R(J.get_key(0))
		if A!=0:
			while R(J.get_key(0))!=0:pass
			return A
def r(size,cell,rc,cc):
	A=cell;C=P((F(A)for A in rc),default=1)or 1;D=P((F(A)for A in cc),default=1)or 1;E=C*20+8;B=24+(D-1)*f
	while B+size*A>182 and A>8:A-=1
	return A,E,B
def L(marks,r,c,cell,gx,gy,cursor):
	B=cell;D,E=gx+c*B,gy+r*B;A(a);C.fill_rect(D,E,B,B);F=marks[r][c]
	if F==1:A(b);C.fill_rect(D+1,E+1,B-2,B-2)
	else:
		A(d);C.fill_rect(D+1,E+1,B-2,B-2)
		if F==2:A(q);C.fill_rect(D+B//2-2,E+B//2-2,4,4)
	if cursor==(r,c):A(s);C.fill_rect(D,E,B,2);C.fill_rect(D,E+B-2,B,2);C.fill_rect(D,E,2,B);C.fill_rect(D+B-2,E,2,B)
def t(rc,cc,size,cell,gx,gy):
	D=cell
	for E in B(size):H=' '.join(I(A)for A in rc[E])if rc[E]else'0';A(c if rc[E]else e);C.draw_text(gx-F(H)*10-4,gy+E*D+D//2+12,H)
	for G in B(size):
		J=cc[G]if cc[G]else[0];A(c if cc[G]else e);K=F(J)
		for L in B(K):M=J[L];N=gx+G*D+(D-9)//2;O=gy-(K-1-L)*f;C.draw_text(N,O,I(M))
def u(marks,rc,cc,size,cell,gx,gy,cursor):
	D=size;C.clear();A(H);C.fill_rect(0,0,319,209);t(rc,cc,D,cell,gx,gy)
	for E in B(D):
		for F in B(D):L(marks,E,F,cell,gx,gy,cursor)
def v(name,elapsed,best):A(H);C.fill_rect(0,188,319,21);A((210,220,240));C.draw_text(6,204,name);A((150,235,170));B='best '+(N(best)if best else'--');C.draw_text(210,204,B)
def N(sec):B=sec//60;A=sec%60;return I(B)+':'+('0'+I(A)if A<10 else I(A))
g='PICR5','PICR8','PICRA'
def T(mi):
	if not K:return 0
	try:return V(list(J.recall_list(g[mi]))[0])
	except i:return 0
def w(mi,v):
	if K:
		try:J.store_list(g[mi],[float(v)])
		except i:pass
def x():
	A(H);C.fill_rect(0,0,319,209);A((230,235,248));D(20,'HOW TO PLAY');A((205,214,235));E=['Numbers on each row/column are','the lengths of filled RUNS, in','order, with a gap between runs.',"e.g. '3 1' = three filled, a",'gap, then one filled.','Move, ENTER fills a cell,','2nd marks an X (a known blank).','Use the clues to deduce the','picture -- every puzzle is','solvable by logic, no guessing.'];B=44
	for F in E:C.draw_text(6,B,F);B+=16
	A((120,130,160));D(206,'any key = back');M()
def y(mi):
	F=mi
	def K():
		A(H);C.fill_rect(0,0,319,209);K=[[0,1,0,1,0],[0,1,0,1,0],[0,0,0,0,0],[1,0,0,0,1],[0,1,1,1,0]];E=16;L=(319-5*E)//2
		for F in B(5):
			for G in B(5):I,J=L+G*E,30+F*E;A(a);C.fill_rect(I,J,E,E);A(b if K[F][G]else d);C.fill_rect(I+1,J+1,E-2,E-2)
		A((230,235,248));D(140,'P I C R O S S');A((150,165,200));D(162,'<- -> mode    up/dn help')
	def J(m):
		C,A,D,D=W[m];B=T(m);S(186,'< '+C+'  '+I(A)+'x'+I(A)+' >',(215,235,245))
		if B:S(206,j+N(B),(150,235,170))
		else:S(206,'ENTER play   CLEAR quit',(120,130,160))
	K();J(F)
	while E:
		G=M()
		if G==45:return
		if G==24:F=(F-1)%3;J(F)
		elif G==26:F=(F+1)%3;J(F)
		elif G in(25,34):x();K();J(F)
		elif G==105:return F
def h():return time.monotonic()if K else 0
def z():A(H);C.fill_rect(0,0,319,209);A((200,210,235));D(104,'Generating puzzle...')
def A0(mi):
	import random as Y;a,C,F,b=W[mi];z();U=o(C,b,Y)
	if U is Q:P=[[1 if(A+B)%2==0 else 0 for B in B(C)]for A in B(C)];R,S=Z(P,C)
	else:P,R,S=U
	F,J,K=r(C,F,R,S);D=[[0]*C for A in B(C)];A=0,0;c=h();d=T(mi);u(D,R,S,C,F,J,K,A);v(a,0,d)
	while E:
		G=M()
		if G==45:return k,0
		N,O=A
		if G==25:N=(A[0]-1)%C
		elif G==34:N=(A[0]+1)%C
		elif G==24:O=(A[1]-1)%C
		elif G==26:O=(A[1]+1)%C
		elif G==105:
			H,I=A;D[H][I]=0 if D[H][I]==1 else 1;L(D,H,I,F,J,K,A)
			if p(D,P,C):e=V(h()-c);return'win',e
			continue
		elif G==21:H,I=A;D[H][I]=0 if D[H][I]==2 else 2;L(D,H,I,F,J,K,A);continue
		else:continue
		if(N,O)!=A:X=A;A=N,O;L(D,X[0],X[1],F,J,K,A);L(D,A[0],A[1],F,J,K,A)
def A1():
	B=1
	while E:
		K=y(B)
		if K is Q:break
		B=K;F=E
		while F:
			O,I=A0(B)
			if O==k:F=G;continue
			J=T(B)
			if J==0 or I<J:w(B,I);J=I
			A(H);C.fill_rect(0,0,319,209);A((150,235,170));D(70,'SOLVED!');A((235,240,250));D(100,'time  '+N(I));A((150,235,170));D(124,j+N(J));A((150,165,200));D(158,'ENTER new puzzle');D(182,'<- -> menu   CLEAR quit');L=M()
			if L==45:F=G
			elif L in(24,26):F=G
	C.clear()
if K:A1()