--!name Bridges
--!icon puzzle
--!category Puzzles
local aY="!$%&()+,-0123456789:;<=>?ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnpqrstuvwxyz|~"local function aU(g)return aY:sub(g+1,g+1)end local a0=4 local aq={7,10,12}local R={"Easy","Medium","Hard"}local ay={"EJ-AEA-s-dL9 FEB-LA-dDA-a9 5RdSDJk-d9UX9 LGA-3K-K-aOLI -4W9-HM9-0-0I Db1CAR--3A-LX9 1NA-HP9-F9-gOI SA-B--6CA-CCI 3MI-3NA-s-CL9 FMA3J-f9-dI-9 -CN9-GA-JRdL9 4IBV9J--yCI 5CT--LEB0-jL9 4ZB-MGB-1-C9Lj CS-ESc-v9La -3DI-APA-aUFI BMA1-6J-A49-gU9 DbVA-2-TI-CC9 GNAk-Y9-dILO9 Gb-QS-L99-FR -GAA-adT-FCI DGB-2jJ-FI9 -3VB-G9S-3ILLI GMB-s-LD9-9L9 HDI-k-gBIpFI CDK-8Ieb-0U99 t7C9-QUA-3aUR -GSAAjTFE9-LFI MIBLJ--3ER-LF9 AKbS-LCB-Fa 3b-DNAJ-v9Ra JS--QHAlj93FI 4DK-bT-OB-CCI DEBkk-9-adO9 Ec1CBW9T-0mX9 5ES-1WA-ISCILj 1-wUAMI-FC9-9 7NA-LAT--IU9I 7lAj-7OA-9FI 7OJCJ-B4S-sLj -ENB-GA-sICI 5NK-s-2kRUj 1bPIJ-4T-LILO9 cA4B-c-C9Lj GRfJl--0-FF9 EMAJ-S-O9-Ua 7lDJbj-59I-CR 1bV9mAE9-da -DNA-1kC9XFC9 t49A-MVA-3IIO9 kJc-GRfI-C9 k-17bc-9CLI -5A-wSUB-00CI 8BH9-IJGR-La SbJl-59E9-gL9 GGK--Y9J-9I9 7YACB-WIK-3U9 1b-DDJJ-0mR9 -4c-MTB-3IOa ES-UKLJ-d9m9 6bY9-OCK-UI 1-4S--BCJO9Xa -4DI-9-DI-XC9 7RhR-MA-sOCI -4k-LK-FaUC9 -5QAKK-U9XRgI -3HD9-49--dU9 UBEA-sia-CI 6SB-79-b-vX9 2-3CBHR-Mb-9a -7k-LJ-CL9UF9 M9JLJ-3CEA--CO9 7HIqA1-R-LCR 7QJ---3MI-FC9 tDA--JB-9gL9 -PBA-KG9-39-9 cQJJ-gA-UI0 GMBk-u-X99FR 1LK-3DT-LI--0 CAJ--YJ79-C93O9 5LK-5GT---6CR u5SVA--aIOLI -5bMK-g9XR9 7cNA-a-mIgR XJ-3UANKB-aFFR -Db-GTUA-0LL9 6Q9J-vEA-sOCI -7GK-ALA-CCI 7bPII--4S-IF9 5ES-WJ-IA9RXR","-htXE9-CBYM9--ECImbR-FC9I 8wA-VawcyAII-5kz9-g93II GJ-VTtBjtCB-XA-SLMI-mCCF9 7vB-Z-2LNJA---RnsUsCCCa CNCA-nPTT--9S-A-XEIU9-UCI 4yALER-nPcT-0eBDI-FFF9C-9 HFRguDteSw99a-5LLB-dgI 4POJA-BgJ-oEbkAb-9UF9gjCj 7PkBtz9-wDDK-RR-uUC9ICv9 7m9-eHu-oSSNB--R-m99CLR -YHYK-oI-DHJlJj-4ITdF9CFs DPS-2--KMA-q9I9XCM9D9A-aXXR MGMABA-9Jn9-c-uq9-CICIpdI 7GI-CbQQJ--59-jaDS-UFLI-3I GuA-XX9P-1kmJ-YT-1svF9C9 5DlfJj-d9VMbmJUC9gs-ys GdBB-VuAGCA-tCVB-ma-y-0 5MkeE9K-jtu---HEO99UO9FFa 5mA-mCc-i-1Mb+BA-9Rd9UFa GqB2ES-1k-g9J-xb--3O9I3Ca 5Ol-Wt-vX9M-A-ZfA-a6LF9 1HGEJ-AYA--2a--13FVAk-sFUCI GaB-vFJ-TPj-bDtgA-U9LXR HNSAdBhEA--9R-6IWu-mjLCOI 7Rvn9-ZLAnIc2-WUCB0-mCR9 8-0-pDk-YMQJJA-tE9-d9I6Oa 7-9gJXE9--4NK-lA-m9dCX90 CdK5fJ-SDBJ-l2k-sI-m9LXR 6Gc--GAs-An9R-8UE9-pg99 -3A1McpKA-AGNRA-9DLk-gdI3s 7CCC9L-1-Z-AHlo9b-pRX-06CO9 7eJNAJ--0-EJ-1-AIPBLS-RUgI 5-1LMJA--K-+VAJ-0Jm9LOa0 DUCA-idK-h-1-iNS-yFI9Cs FUS4EZ9--DHJ--YB8A--0-CI6CCR GtZSz9T-1pIKMc-bdIgjOLFI 5RvDUB-WMkdA--MJI-RI-3a -KEGGK--MJ-1a-FIL9XOS--3a -VNETK--1MB--c-RL9XCj3p9 CHYA2c--7N9-CJYEJS-99L9XLU9 4US-eI-Ck-mDbC9-CC9dm9 GC9JYRbNJ--6E9-F9VM9--CCROj 7ZLADAEK--0-7KbK-9I--FCOILLa 4bEAM9--VPGA-BU9-u-9LCOILCj 8-1Va-bVb-TUC9gjD-9-UFj 8mALPIA-VUF9Xt-Z-BFA-v96Oa 4-2QM9--DDJS-xBJla-RI9LUC9 8MlKJbt--UCA49-CDk59FS-R6La 7BDS--NBB-laBoJA--F9saCFa 5dBhRJB-qNBA-WC9S-diB0-Up9 CFCS6DFT--7PBA-AU9--5CRgCaC-9 De9-DA2-q9-amMJCIoq9-C96FU9 49Db-dA-RmMkkt-2-pC9LFs 89COA-h-2-qRa-DDu-RLjLX9 C-14-1-SDs-pdJ4-1UH9UIjLCR 3h9B-ZQESwA-a-XA-jXIjpI FqA1S--EYI--7GCI1gJR-0XR 5-BCQCA-eDHTJ-RX9LNc3I-mICLR PEIS--b-BI-DMH9T-wI9-FFCF9 GiJ-1WJ--1d9hjdDbD9-CCRO9j oFBBJE9s-DF9-oNN9k-AsUC9a GQSA-X9+YTyAA-9DVMB-RsULa 4QaKT-Z9QH9--YK-2lIIa-CUa 1JLA-bPS--U9PNa-nDj0-R9 4-BDOR-noB0MIk-USJ-R-03CL9 1EdAfT--YAA-t-b-j3FF9va DuB-ZCSA1-eDIB-lOI-jOa6FLI 4MaS-nT79--YMGSbo9LIma6LR DFYB1-ZloAb-A--9T9-CLU9 UBJES-gAjpfJ-BWI-CC9Xs GMGBB-hBb-m9k-ADhA-mRICmI -VDNRvABLF9-nCl-mGc-gLFI -f-2NHCAxAtB-9JXD9-aLLO9 GLC9hk2WJ-AS-v9yVB-djO-9 NQS-yD9-CI-V9-DVS0D9KR-ULF9 7-1Maql-kkJ-gaXuCU9dCa -ZVPB-ZEDABuB-9-F9A7FFS-R3UF9 -VgRGMT-yC9-CJLjN-1-aCU9 5GPK-SIkGhAka----0mCIC-9 3vBDDbAT--AT-b--0LF9FOj DWK-AA1----OIc-WhAB-9CL9C9 8VI-CKOCRGMlBu-nDavCB9-FOX9 Mt2MC9a-4Ol-e-22Z9-smICLR 4xA-hqB-tk-SPS9-RICC9FI -VUD9-eoJ-hF9--CiK-U9FCI DLJ-bNJkJ--1jyDOB---3IO9 -1Z9AT-1-zWE9b-kUI--FFI9 4-BHFD9-kHPSSSa-CCF9-m-9 CnA-VU9JDS--C9xb--CUF939 4-1VOB-S-vFJUT--FCG9-mFLI","8HGDK-tL9N9MjCBXOC9M-J--4VIJ-vXa-vma 8FnK-KMMEA-vA-twK-S--bM9-9pFCL9C-C9 HLRTHMDR-kCAe9--IeB2-qSj-vF9vyC9 FXcDUaA-nGmBoEI-J-pA-EBB-RjIdFXL9 -3S4MNSShBt--rA--JiB--IIpDOA09-mLI9 DM9kvT9-V9vA-nVtH9--8AiJ-0-S-vLF9I 4L-2-n-39-x-SDMWBbD9-9jLFCMJ3s--UULI DoS2--4BVB-l-HAYA--CAS-vES-vCXICCv9 1LAHAB-oDIkB-0deSHJ-m9yCuD-9w9a-mRj 7UDCK-3KHmI--7-KXfA--4sJYZJ-tOU99C-C9 -nD-AiCRR-PVt-2n9---3P9-UCS3CCCIUCUR 4MnAhGA--kKS--KRg9XGB-qWEA--LIRUjI9 7MqAnB--1-C9-uCCCcGnKWD9j-69qLS9-pFg9 4CUL9FMk-zYVB-xJKb-qB-1abZEH9-UL9CFCOR -rfbVBSc-tEIj-VAWJT-JI9C9dDk9-pO9C9 mPBCPR-Kl-RCMGMJ--RA--THC9JB-RFCImdL9 7-TBl-4IDK-vDR--NMe9x9g9UC9MFCl-vmR GLdAXQRMRLK-kPPT--L9--neR-QJFI-3mFI 4SPK--RL9A4-I-wDgTfa-CCAwEAA1--IR90FFLI 7CGsoQAEI-sk-nI-YDII-5DKJ-2-0a0UU9UdR 4-CAMnAn9c1-JmRJ8G-1--CCCIA4-I-y-C9 7P-1cLJ--XDTMH9-xKI-2m99IDnMBT--C9OLIa 7EUG9--1CeJ1CO9nzBA-mar-69-vUu-y-I 4DMl--0Ix-39-vDCtkupDJ-1-m9CCLCR 2-1pCKAPb--EAEDF9-sIMgIl---4CR--9Fs 5C-BGPGCA--JNI-NJ--4AU9K--HET-Jd9IRCUXI HWMB-u-nXIyPSLRCAOMM9--JLCInt--3Ca9 HmKdDIJEINB--GS--9Bj-4qKeKA-A-jC9LCCCR 5-F9GDHc-A-B--la-XLJJ--FcmAAa-ULL99 5OWAf9TJVJ-2kv99zU9--UvB-nUCR-v-R CLLT8D-0yYA0OPA-kMGS---89J--1gImCd93-I 3NYDA-vHJqBvA-DAd9k--ak-0ILdJ-vga DLHPAXB-CADK-tDJD9---39J--VVAa-LLC9U-I 4gL9UFPS-oyJMJFK--EML9--LCCTI-X-IyX9 CbGK7DAc-RlVK---39-Dc-DA-x9X99LLs3vI 5nbGR-yJ--4hTBGALA--1S--KSIj9CUIU-I DLDI-OSDeT--FXRMwJ--FSDA-xj-sULCCI AEPM9--9U9Yec-wC9-nIV9--GRu-m9Rg9 FgSGdR-t4YMA---09NVjzkCJ--bL9-3dII 5LDFJ-k8DQb--C9-7hbV9--4JV9b-jdCF9LC-9 3Wg9-kFHtvK-t3DDb-4IJ--0-9--UU96C9 L-B8WbXAGI--w9--MKES--G9CC9gFtC-9F-R G9Dk2-nVEDA-SLIaNa-5oJZSj-Km9bLgIOXLI 6Pt-kWU9---RDA-SE-1I-UDQb-vC9LI6mI EVFB-CBAM9-B-yPKAQ9--IfVR--XDbLI-6OCa -rPoABMD9--mCIZD-2pOABQMI--dCC99LjUvI EVBCA1--aSX9-3-497UE9---kFdKID9---3UL9 HJ-nV9L9-ECE9S-zYVA-S-KeIaJPHMAI-I6I9L9 CCWCA-oNEETtt---NAkKk-9mB0yI-3aFXL9 eb--ODKhI-2hA--1kKc-Is9mMVS-yFC9C9 7faWAPT-EB---0-DCI--fIjgJyIUUjLCLa 2FWC9-CT6qTW9--C9GCVb-zGMb-j-jC9-U9a 5xS--wAA----RWwJJM9J-jLOLCA3LsXOj 5DeGA-SeJK-2---SSfA-jSsRJOVI-OI0CdI DmC9LMb--7Vbc-Se9p9-EGLK-8Jg9-CaId-0 1-neNAMIKS-KVXAxE9-BC9sCSA--3CaAF-9CFFs 4vTMMPAb-1-Sf9--Ja--aVnJ-pCFFC9vj 1DX9v-14EtwI-OS--fHNBlsRtwILCIjFLCR CFnA5d9r9-11-o-4Ak-3ItLLC9M-SC-2--6-C9 nkDAPK--CAIa-59-UK4B--MSI-LLDFCA-yUj D-4BZMB--ktAs-4DLADB-jN9m9-5b-pRFa 4NtJ--3CBKFFReCn9LY9-VGJ5Il--JvA0j-6LLI 7ZLI-6bFLjH-4J-Tc--yLeA--3P9--I3XU9 3ACJK-JWDbSujs--1-vCYE9-XADb--aLFCI 4nbMKGIb-B-8JSS-vA-F9--vFBU9vCUa 4Dd9zECK-nCCHc-whK--Y9F9--0OMc-vLCCI 1ELUBVMS-j2LKBA-wDS--9-NI-TB-vUF9CLR 3HM9HA--7MRATMBS-s-LMA-j-9-CeOJ--UC99 7vIOD-1-nLQI--Gfc-3AYEB-SDIJa-0OCa3Od9 -mP-1--Uc--5Gt-BbcL9J-ldDA9FCIUFv9 4LuVe9w9CAt-E9O9oDLA--JYB--RRKCCLRULj HCCUA1DiJ--CFO9V-AeYA--VIB-jm9LBLp993-I 5D-A-uNDI-LSLFCJ--D-3A--4CtA-RCp9L-I AXEJiKb-C9m9OA-vEUT--CU9i-B-pCjI DmK--4-A-kWEG9utRVJMJ--39AO9-paLga 5F-AE-A-spB--MxAAJJ-kIOCImEa--LCmI LFkDNL9b--DGJJ--CF9YDtmFKmRm-0O-I DyJVjJ-nE-1fk--Va-4acMc9RvILROOs 4-69OeMA4F9-HRAvR-OO9Y-K--DeA--0-9CLdI 5H-2--2DGJJ1--3H9J-8BqBt-km9m9-FXaFmCI DDDk1wJtk-E9---CA1-69zDT-DBI--9II3LUI 5mbFVPB-wSJn9-1-1v9tFUA--2FNR--0OCdI gANAE9-WUA--WHAuu-I-6GSInA-jJj-6LLF9 2MACKSlT-Jx9---u1I-VMO9--9hT-mLC9C9 5DBCD9-YBPFIJ-RQDm9---eGyB-ju--93Ca 3DWPB-2dA---L9L9MnS--4Il-kHdR9djC-0 4CWDJDRbBDZBJ-j9m9--7db-w-AB-ms9C-R CUb-xFVTP9k--DS-DBCI--1ALRSLl9Cd9U-9 DV9KAl+A-BAZDAIli9R--ZLG9nI-0ODI--ORa 4-GBHt--Ujd-0M-S-wVMA--3FC9S6-39L-39"}local aX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-"local aA={}for g=1,64 do aA[aX:byte(g)]=g-1 end local az={}for d=1,3 do az[d]=select(2,ay[d]:gsub(" ",""))+1 end local function a4(d)return az[d]end local function bb(j)local d=os.date("*t",j)return os.time({year=d.year,month=d.month,day=d.day,hour=12})//86400 end local function ac()local j=os.time()if not j or j<1700000000 then return nil end return bb(j)end local a2={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}local a1={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}local aZ={3,1,1,2,2,2,3}local function aF(W)return os.date("*t",W*86400+43200)end local function aG(W)local d=aF(W)return a2[d.wday].." "..a1[d.month].." "..d.day end local function aE(W)return aZ[aF(W).wday]end local f=7 local F,q,z,U={},{},{},{}local v,V,Q,E,p,L,M={},{},{},{},{},{},{}local a local J={}local e={}for g=1,13 do e[g]=0 end local Z={1,1,1}local K={}local u,H,X=1,false,false local m,s,aC="menu",1,"menu"local x,af,ai=nil,nil,nil local function S(h)h=math.floor(h or 0)if h>=3600 then return string.format("%d:%02d:%02d",h//3600,h//60%60,h%60)end return string.format("%d:%02d",h//60,h%60)end local function ah(G)if G.kind=="d"then return"Daily, "..aG(G.num)end return R[G.diff].." #"..G.num end local function bk(ag,r,B)local k=a4(r)if ag=="d"then return(B*37+11)%k,B%8 end return(B-1)%k,(B*5+(B-1)//k)%8 end local function bq(y,o,j)local ab,aa=y,o if j&4~=0 then ab,aa=aa,ab end if j&1~=0 then ab=f-1-ab end if j&2~=0 then aa=f-1-aa end return ab*f+aa end local function aj(ag,r,B)local a5,j=bk(ag,r,B)local h,ak=ay[r],1 for a3=1,a5 do ak=h:find(" ",ak,true)+1 end local bm=(h:find(" ",ak,true)or#h+1)-1 f=aq[r]local ae,_={},-1 for t=ak,bm do local P=aA[h:byte(t)]or 0 if P==63 then _=_+7 else _=_+P//9+1 ae[_]=P%9 end end local at={}F,q,z,U={},{},{},{}v,V,Q,E,p,L,M={},{},{},{},{},{},{}for y=0,f-1 do for o=0,f-1 do local T=bq(y,o,j)if ae[T]then local g=y*f+o+1 at[T]=g q[#q+1]=g F[g]=#q z[#q]=0 end end end local aS={}for T,P in pairs(ae)do local y,o=T//f,T%f for d=0,1 do local n=d==0 and P//3 or P%3 if n>0 then local C,A=y,o repeat if d==0 then A=A+1 else C=C+1 end until C>=f or A>=f or ae[C*f+A]if C<f and A<f then local l,ao=at[T],at[C*f+A]aS[math.min(l,ao)*256+math.max(l,ao)]=n z[F[l]]=z[F[l]]+n z[F[ao]]=z[F[ao]]+n end end end end for c,g in ipairs(q)do local y,o=(g-1)//f,(g-1)%f for d=0,1 do local t,C,A=g,y,o repeat if d==0 then A,t=A+1,t+1 else C,t=C+1,t+f end until A>=f or C>=f or F[t]if A<f and C<f then local b=#v+1 v[b],V[b],Q[b],E[b],p[b]=c,F[t],d==0,aS[g*256+t]or 0,0 U[c*4+3-d*2]=b U[F[t]*4+2-d*2]=b local D=d==0 and 1 or f for l=g+D,t-D,D do if d==0 then L[l]=b else M[l]=b end end end end end u,H=1,false a={kind=ag,diff=r,num=B,el=0,hints=0,done=false}K,X,x={},false,nil end local function bp()return table.concat({a.kind,a.diff,a.num,a.el,a.hints,a.done and 1 or 0,u,table.concat(p)},",")end local function aQ(h)local i={}for l in(h..","):gmatch("([^,]*),")do i[#i+1]=l end local r,B=tonumber(i[2]),tonumber(i[3])if(i[1]~="d"and i[1]~="b")or not r or r<1 or r>3 or not B then return end aj(i[1],r,B)a.el,a.hints,a.done=tonumber(i[4])or 0,tonumber(i[5])or 0,i[6]=="1"local o=tonumber(i[7])or 0 if o>=1 and o<=#q then u=o end local P=i[8]or""for b=1,#v do local l=(P:byte(b)or 48)-48 if l>=0 and l<=2 then p[b]=l end end return true end local function I()if a then J[a.kind]=bp()end snail.save(table.concat({"BR1",table.concat(e,","),table.concat(Z,","),a and a.kind or"",J.d or"",J.b or""},";"))end local function bg()local h=snail.load()if type(h)~="string"or h:sub(1,4)~="BR1;"then return end local i={}for l in(h..";"):gmatch("([^;]*);")do i[#i+1]=l end local c=0 for l in(i[2]or""):gmatch("[^,]+")do c=c+1 if c<=13 then e[c]=tonumber(l)or 0 end end c=0 for l in(i[3]or""):gmatch("[^,]+")do c=c+1 if c<=3 then Z[c]=math.max(1,tonumber(l)or 1)end end if i[5]and i[5]~=""then J.d=i[5]end if i[6]and i[6]~=""then J.b=i[6]end local ar=i[4]if ar and J[ar]then local av,aw=pcall(aQ,J[ar])if not(av and aw)then a=nil end end end local function aK(c)local k=0 for d=0,3 do local b=U[c*4+d]if b then k=k+p[b]end end return k end local function ba(b)local D=Q[b]and 1 or f for l=q[v[b]]+D,q[V[b]]-D,D do local i=Q[b]and M[l]or L[l]if i and p[i]>0 then return true end end return false end local function aW(b)return p[b]>E[b]end local function bi()local k=0 for b=1,#v do if aW(b)then k=k+1 end end return k end local function aP(b)K[#K+1]=b*4+p[b]if#K>150 then table.remove(K,1)end end local function aI()for b=1,#v do if p[b]~=E[b]then return end end a.done,X,H=true,false,false local n=(a.diff-1)*3 e[n+1]=e[n+1]+1 if e[n+2]==0 or a.el<e[n+2]then e[n+2]=math.max(1,a.el)end e[n+3]=e[n+3]+a.el if a.kind=="d"and e[13]~=a.num then e[10]=e[10]+1 e[11]=e[13]==a.num-1 and e[11]+1 or 1 if e[11]>e[12]then e[12]=e[11]end e[13]=a.num end end local function be()local ap=#v local aJ=1 for b=1,ap do if v[b]==u or V[b]==u then aJ=b break end end for c=0,ap-1 do local b=(aJ-1+c)%ap+1 if p[b]~=E[b]then local D,G=Q[b]and 1 or f,b for l=q[v[G]]+D,q[V[G]]-D,D do local i=Q[G]and M[l]or L[l]if i and p[i]>0 and E[G]>0 then b=i end end aP(b)p[b]=E[b]u=v[b]a.hints=a.hints+1 x=E[b]==0 and"Hint: no bridge there"or("Hint: "..E[b]..(E[b]==1 and" bridge "or" bridges ")..(Q[b]and"across"or"down"))aI()return end end end local function am()local d=ac()if d and e[13]<d-1 then return 0 end return e[11]end local function O()m,ai,s="play",os.time(),1 end local function aT(r)if a then I()end local k=Z[r]Z[r]=k+1 aj("b",r,k)O()I()end local function br(d)if a then I()end a=nil if J.d then local av,aw=pcall(aQ,J.d)if not(av and aw)or a.num~=d then a=nil end end if not a then aj("d",aE(d),d)end O()I()end local function a9()local aM=os.time()if a and m=="play"and ai and not a.done then local aH=aM-ai if aH>0 then a.el=a.el+math.min(aH,600)end end ai=aM end local function aL()local j={}if a and not a.done then j[#j+1]={"Continue: "..ah(a).." ("..S(a.el)..")","cont"}end local d=ac()if d then local h="Daily puzzle: "..aG(d)..", "..R[aE(d)]if e[13]==d then h=h.." (solved)"end j[#j+1]={h,"daily"}else j[#j+1]={"Daily puzzle: needs the clock","noclock"}end for c=1,3 do j[#j+1]={"New "..R[c].." "..aq[c].."x"..aq[c].." puzzle (#"..Z[c]..")",c}end j[#j+1]={"Statistics","stats"}j[#j+1]={"How to play","help"}return j end local function aN()return{{"Back to the puzzle","cont"},{#K>0 and("Undo ("..#K..(#K==1 and" move)"or" moves)"))or"Undo (nothing to undo)","undo"},{"Check for mistakes","check"},{"Hint: fix a bridge","hint"},{"Restart this puzzle","restart"},{"Main menu","menu"},{"How to play","help"},}end local function a8(w)if w=="cont"then O()elseif w=="undo"then local an=table.remove(K)if an then p[an//4]=an%4 u=v[an//4]O()I()else x="Nothing to undo"end elseif w=="check"then O()local k=bi()X=k>0 x=k==0 and"No mistakes so far"or(k==1 and"1 wrong bridge, marked"or k.." wrong bridges, marked")elseif w=="hint"then O()if not a.done then be();I()end elseif w=="restart"then aj(a.kind,a.diff,a.num)O()I()elseif w=="menu"then m,s="menu",1 elseif w=="daily"then br(ac())elseif type(w)=="number"then if a and a.kind=="b"and not a.done and af~=w then af,x=w,"Press OK again to leave "..ah(a)else af=nil aT(w)end else aC,m=m,w end end local aB={up=0,down=1,left=2,right=3}local function bj(d)if d>=2 then u=(u+(d==3 and 0 or#q-2))%#q+1 return end local g=q[u]local y,o=(g-1)//f,(g-1)%f local as,aD=nil,1e9 for c,t in ipairs(q)do local ad,bo=(t-1)//f-y,math.abs((t-1)%f-o)if d==0 then ad=-ad end local aR=ad*4+bo*9 if ad>0 and aR<aD then as,aD=c,aR end end if as then u=as end end local function a7(d)local b=U[u*4+d]if not b then x="No island that way"return end if p[b]==0 and ba(b)then x="Bridges can't cross"return end aP(b)p[b]=(p[b]+1)%3 aI()I()end local function bl(c)if a.done then if c=="top"then m,s="menu",1 elseif c=="ok"then if a.kind=="b"then aT(a.diff)else m,s="menu",1 end end return end if c=="top"then if H then H=false else m,s="opts",1 I()end elseif c=="ok"then H=not H elseif H then a7(aB[c])else bj(aB[c])end end function key(c)a9()x,X=nil,false if m=="play"and a then bl(c)return end if m=="menu"or m=="opts"then local N=m=="menu"and aL()or aN()if c~="ok"then af=nil end if c=="up"then s=(s-2)%#N+1 elseif c=="down"then s=s%#N+1 elseif c=="ok"then a8(N[math.min(s,#N)][2])elseif c=="top"and m=="opts"then m,s="menu",1 end return end if c=="top"or c=="ok"then m=aC end end local function a6()local bn=a.done local ax={}for y=0,f-1 do local j={}for o=1,f do local g=y*f+o local c,b=F[g],L[g]or M[g]if c then local Y=aK(c)local bh=(Y==z[c]and 3 or Y>z[c]and 6 or 0)+((c==u and not bn)and(H and 2 or 1)or 0)j[o]=aU(a0+z[c]-1+8*bh)else local au,aV=L[g]and p[L[g]]or 0,M[g]and p[M[g]]or 0 b=au>0 and L[g]or aV>0 and M[g]or nil if not b then j[o]=" "elseif X and aW(b)then j[o]="@"else j[o]=aU(au>0 and au-1 or aV+1)end end end ax[#ax+1]=table.concat(j)end return table.concat(ax,"/")end local function bc()snail.title("Bridges - "..ah(a))local h if a.done then local n=(a.diff-1)*3 h="Solved! Best "..R[a.diff].." time "..S(e[n+2])if a.hints>0 then h=h..", "..a.hints..(a.hints==1 and" hint"or" hints")end elseif x then h=x else local al,aO=0,false for c=1,#q do local Y=aK(c)if Y~=z[c]then al=al+1 end if Y>z[c]then aO=true end end h=S(a.el).."  "..(aO and"An island has too many bridges"or(al==1 and"1 island to go"or al.." islands to go"))end snail.status(h:sub(1,47))snail.board(a6(),nil,a.done and("Solved in "..S(a.el))or nil)if a.done then local n=(a.diff-1)*3 snail.text(R[a.diff].." puzzles solved: "..e[n+1])if a.kind=="d"then snail.text("Daily streak: "..am()..(am()==1 and" day"or" days"))end snail.hint(a.kind=="b"and"BACK puzzles OK next puzzle"or"BACK puzzles OK puzzles")elseif H then snail.hint("BACK done OK done L/R bridge UP/DN bridge")else snail.hint("BACK options OK pick L/R move UP/DN move")end end local function bd()snail.title("Bridges statistics")for c=1,3 do local n=(c-1)*3 local k=e[n+1]if k>0 then snail.text(R[c]..": "..k.." solved, best "..S(e[n+2])..", average "..S(e[n+3]/k))else snail.text(R[c]..": none solved yet")end end snail.gap()snail.text("Daily puzzles solved: "..e[10])snail.text("Daily streak "..am()..", best "..e[12])snail.hint("BACK back OK back")end local a_={"Join the islands with bridges. The number on an island is how many bridges it has.","Bridges run straight across or down, one or two between a pair, and never cross.","In the end every island must be joined into one group.","Left and right step through the islands row by row; up and down jump to the nearest one.","OK picks an island; then each arrow cycles the bridges that way: one, two, none.","OK or BACK puts it down. An island turns black once it has all its bridges.","BACK opens options: undo, check for mistakes, a hint.",}function draw()if m=="play"and a then bc()return end if m=="stats"then bd()return end if m=="help"then snail.title("How to play")for a3,h in ipairs(a_)do snail.text(h)end snail.hint("BACK back OK back")return end if m=="noclock"then snail.title("Daily puzzle")snail.text("The daily puzzle needs the date. Connect to Wi-Fi once so the clock gets set, then come back.")snail.text("The Easy, Medium and Hard puzzles work any time.")snail.hint("BACK back OK back")return end local N=m=="menu"and aL()or aN()if s>#N then s=#N end snail.title(m=="menu"and"Bridges"or("Bridges - "..ah(a)))if x then snail.status(x)end for g,bf in ipairs(N)do snail.row(bf[1],g==s)end snail.gap()if m=="menu"then local k=e[1]+e[4]+e[7]snail.small("Daily streak "..am()..", "..k..(k==1 and" puzzle"or" puzzles").." solved.")snail.hint("BACK leave OK choose UP/DN move")else snail.small("Time "..S(a.el)..(a.hints>0 and(", hints "..a.hints)or""))snail.hint("BACK puzzles OK choose UP/DN move")end end function start()snail.ink("fast")bg()if a and not a.done and not(a.kind=="d"and ac()and a.num~=ac())then O()else m,s="menu",1 end end
