Skip to main content
Golfed more. Will not update explanation b/c it is so similar
Source Link
Blue
  • 2k
  • 13
  • 23

#Python 3, 990 943 770770 709 bytes

EDIT 3: Shortened the code for conversion from index in list to coordinates, golfed a few more things.

from math import*
b=abs
c=max
e=range
f=len
A=input()
B=input()
C=ceil(sqrt((lenf(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-lenf(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[1,0,-1,-1,0,1]
K=[0,1,1,0,-1,-1]
G=[set()for rx in e(E-1D)]
I=lambda H:G[r+1]=G[r]+E+sum(E+.5-b(rt-C+1F+.5)
L=0
for rt in e(E):
 M=cint(-r,1-CH+F)))
 for qx in e(D):
 r=sum([[J-F]*(E-b(rJ-C+1)F):H[L]=M+q;I[L]=r-F;L+=1
N=[set()for xJ in e(DE)]
for x in e,[])[x];q=x-I(Dr):
 q,r=H[x],I[x];s=;s=-q-r;a=lambda q,r:N[x]G[x].add(q+G[r+F]int(q+I(r)));m=c(map(b,[q,r,s]))
 if m==F:
  if q in(m,-m):a(-q,-s)
  if r in(m,-m):a(-s,-r)
  if s in(m,-m):a(-r,-q)
 for dK,L in ezip(6[1,0,-1,-1,0,1],[0,1,1,0,-1,-1]):
  OM,P=q+J[d]H=q+K,r+K[d]r+L
  if c(map(b,[O[M,PH,-OM-P]H]))<C:a(OM,PH)
def QN(i,RO,SP):
 T=R*(R[0]==A[i]or'Q=O and O[0]==A[i]or'.'==A[i]);U=0'==A[i];R=0
 if(2>len2>f(RO))*T*Q:U=1R=1
 elif TQ:U=cR=c([(x not in SP)*Q*N(x,R[1O[1:],S+[i]P+[i])for x in N[i]]+[0]G[i]]+[0])
 return UR
print(c([Q[N(x,B,[])for x in e(D)])*(lenf(B)<=D))

So close toSo close to Retina! :( Yay, beat Retina! :(

#Python 3, 990 943 770 bytes

from math import*
b=abs
c=max
e=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[1,0,-1,-1,0,1]
K=[0,1,1,0,-1,-1]
for r in e(E-1):G[r+1]=G[r]+E+.5-b(r-C+1.5)
L=0
for r in e(E):
 M=c(-r,1-C)
 for q in e(E-b(r-C+1)):H[L]=M+q;I[L]=r-F;L+=1
N=[set()for x in e(D)]
for x in e(D):
 q,r=H[x],I[x];s=-q-r;a=lambda q,r:N[x].add(q+G[r+F]);m=c(map(b,[q,r,s]))
 if m==F:
  if q in(m,-m):a(-q,-s)
  if r in(m,-m):a(-s,-r)
  if s in(m,-m):a(-r,-q)
 for d in e(6):
  O,P=q+J[d],r+K[d]
  if c(map(b,[O,P,-O-P]))<C:a(O,P)
def Q(i,R,S):
 T=R*(R[0]==A[i]or'.'==A[i]);U=0
 if(2>len(R))*T:U=1
 elif T:U=c([(x not in S)*Q(x,R[1:],S+[i])for x in N[i]]+[0])
 return U
print(c([Q(x,B,[])for x in e(D)])*(len(B)<=D))

So close to Retina! :(

#Python 3, 990 943 770 709 bytes

EDIT 3: Shortened the code for conversion from index in list to coordinates, golfed a few more things.

from math import*
b=abs
c=max
e=range
f=len
A=input()
B=input()
C=ceil(sqrt((f(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-f(A))
G=[set()for x in e(D)]
I=lambda H:sum(E+.5-b(t-F+.5)for t in e(int(H+F)))
for x in e(D):
 r=sum([[J-F]*(E-b(J-F))for J in e(E)],[])[x];q=x-I(r);s=-q-r;a=lambda q,r:G[x].add(int(q+I(r)));m=c(map(b,[q,r,s]))
 if m==F:
  if q in(m,-m):a(-q,-s)
  if r in(m,-m):a(-s,-r)
  if s in(m,-m):a(-r,-q)
 for K,L in zip([1,0,-1,-1,0,1],[0,1,1,0,-1,-1]):
  M,H=q+K,r+L
  if c(map(b,[M,H,-M-H]))<C:a(M,H)
def N(i,O,P):
 Q=O and O[0]==A[i]or'.'==A[i];R=0
 if(2>f(O))*Q:R=1
 elif Q:R=c([(x not in P)*N(x,O[1:],P+[i])for x in G[i]]+[0])
 return R
print(c([N(x,B,[])for x in e(D)])*(f(B)<=D))

So close to Retina! :( Yay, beat Retina!

improved golf
Source Link
Blue
  • 2k
  • 13
  • 23

#Python 3, 990 943943 770 bytes

EDIT 2: Removed unnecessary fluff, golfed a lot more.

from math import*
Y=rangeb=abs
c=max
e=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[(1,0,-1)J=[1,(0,1,-1),(-1,1,0),(-11]
K=[0,01,1),(0,-1,1),(1,-1,0)]
K=lambda q,r:q+G[r+F]
L=lambda q,r,s:max(map(abs,[q,r,s]))
M=[set()for x in Y(D)]
N=01]
for r in Ye(E-1):G[r+1]=int(G[r]+E+G[r+1]=G[r]+E+.5-absb(r-C+1.5))
L=0
for r in Ye(E):
 O=maxM=c(-r,1-C)
 for q in Ye(E-absb(r-C+1)):H[N]=O+q;I[N]=rH[L]=M+q;I[L]=r-F;N+=1F;L+=1
P=[-H[x]-I[x]forN=[set()for x in Ye(D)]
for x in Ye(D):
 q,r,s=H[x],I[x]r=H[x],P[x];p=F and(I[x];s=-q/F,r/F,s/F);m=L(-r;a=lambda q,r,s);a=M[x]:N[x].add
 if p in J:a(K(s,q)q+G[r+F]);a;m=c(Kmap(b,[q,r,ss]))
 elifif L(q,r,s)==Fm==F:
  if m==rq orin(m,-m==rm):a(K(-sq,-r)s)
  if m==qr orin(m,-m==qm):a(K(-qs,-s)r)
  if m==ss orin(m,-m==sm):a(K(-r,-q))
 for d in Ye(6):
  Q,R,S=q+J[d][0]O,r+J[d][1]P=q+J[d],s+J[d][2]r+K[d]
  if Lc(Qmap(b,R[O,SP,-O-P]))<C:a(K(QO,R)P)
def TQ(i,UR,VS):
 W=U[0]==A[i]or'T=R*(R[0]==A[i]or'.'==A[i];X=0'==A[i]);U=0
 if(2>len(UR))*W*T:X=1U=1
 elif WT:X=maxU=c([T[(x,U[1:],V+[i])if x not in V else 0 S)*Q(x,R[1:],S+[i])for x in M[i]]+[0]N[i]]+[0])
 return XU
print(maxc([T[Q(x,B,[])for x in Ye(D)])and *(len(B)<=D))
from math import*

#Rundown of the formula:
# * Get data about the size of the hexagon
# * Create lookup tables for index <-> coordinate conversion
#   * q=0, r=0 is the center of the hexagon
#   * I chose to measure in a mix of cubic and axial coordinates,
# as that allows
#  as that allows for easy oob checks and easy retrevial  
# * Create the adjacency list using the lookup tables, while
#   checking for wrapping
# * HeuristicallyBrute-force check if a path in the hexagon matches the
#   expression

# shorten functions used a lot
b=abs
c=max
e=range

# Get input 

prog=input()
expr=input()

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1

# dirs contains the q,r and s values needed to move a point
# in the direction refrenced by the index
dirs=[(1,0,-1)
qdir=[1,(0,1,-1),(-1,1,0),(-11]
rdir=[0,01,1),(0,-1,1),(1,-1,0)]1]

# generate nmbf using a summation formula I made

for r in rangee(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-absb(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in rangee(nmrw):
    bgnq=maxbgnq=c(-r,1-sdln)
    for q in rangee(nmrw-absb(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r-usdl
        cntr+=1

# in2s = index to s. Useful for bounds checking
# c2in = coords to index conversion
# mxab = return roughly how far away a point is from the center
# adjn = Adjacency sets

in2s=[-in2q[x]-in2r[x]for x in range(hxln)]
c2in=lambda q,r:q+nmbf[r+usdl]
mxab=lambda q,r,s:max(map(abs,[q,r,s]))
adjn=[set()for x in rangee(hxln)]

# Generate adjacency sets

for x in rangee(hxln):
    #Get the q,r,s coords
    q,r,s=in2q[x]r=in2q[x],in2r[x],in2s[x]
    # Are we at a corner?
    p=usdl and(s=-q/usdl,-r/usdl,s/usdl)
    # ma = distance from center
 function to add m=mxab(q,r,s)
    # if we areto atthe aadjacency corner...list
    if p ina=lambda dirsq,r:adjn[x].add(q+nmbf[r+usdl])
        # addm the= otherabsolute 2value cornersdistance weaway canfrom gothe tocenter
        adjn[x].addm=c(c2inmap(sb,q))
        adjn[x].add(c2in([q,r,ss]))
    # otherwise, if we are on the edge (includes corners)...
    elifif mxab(q,r,s)==usdlm==usdl:
        # add the only other point it wraps to
        if m==rq orin(m,-m==rm):
            adjn[x].add(c2ina(-sq,-r)s)
        if m==qr orin(m,-m==qm):
            adjn[x].add(c2ina(-qs,-s)r)
        if m==ss orin(m,-m==sm):
            adjn[x].add(c2ina(-r,-q))
    # for all the directions...
    for d in rangee(6):
        # tmp{q,r,s} = moving in direction d from q,r,s
        tmpq,tmpr,tmps=q+dirs[d][0],r+dirs[d][1]tmpr=q+qdir[d],s+dirs[d][2]r+rdir[d]
        # if the point we moved to is in bounds...
        if mxabc(tmpqmap(b,[tmpq,tmpr,tmps-tmpq-tmpr]))<sdln:
            # add it
            adjn[x].add(c2ina(tmpq,tmpr))

# Recursive path checking function
def mtch(i,mtst,past):
    # dmch = Does the place we are on in the hexagon match
    #        the place we are in the expression?
    # out = the value to return
    dmch=mtst[0]==prog[i]or'dmch=mtst and mtst[0]==prog[i]or'.'==prog[i]
    out=0
    # if we are at the end, and it matches...
    if(2>len(mtst))*dmch:
        out=1
    # otherwise...
    elif dmch:
        # Recur in all directions that we haven't visited yet
        out=max# replace '*' with 'and' to speed up the recursion
        out=c([mtch[(x not in past)*mtch(x,mtst[1:],past+[i]) if x not in past else 0 for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(maxc([mtch(x,expr,[])for x in rangee(hxln)])and *(len(expr)<=hxln))

If I missed out on anythingSo close to golf more, please let me knowRetina! :(thanks).

#Python, 990 943 bytes

from math import*
Y=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[(1,0,-1),(0,1,-1),(-1,1,0),(-1,0,1),(0,-1,1),(1,-1,0)]
K=lambda q,r:q+G[r+F]
L=lambda q,r,s:max(map(abs,[q,r,s]))
M=[set()for x in Y(D)]
N=0
for r in Y(E-1):G[r+1]=int(G[r]+E+.5-abs(r-C+1.5))
for r in Y(E):
 O=max(-r,1-C)
 for q in Y(E-abs(r-C+1)):H[N]=O+q;I[N]=r-F;N+=1
P=[-H[x]-I[x]for x in Y(D)]
for x in Y(D):
 q,r,s=H[x],I[x],P[x];p=F and(q/F,r/F,s/F);m=L(q,r,s);a=M[x].add
 if p in J:a(K(s,q));a(K(r,s))
 elif L(q,r,s)==F:
  if m==r or-m==r:a(K(-s,-r))
  if m==q or-m==q:a(K(-q,-s))
  if m==s or-m==s:a(K(-r,-q))
 for d in Y(6):
  Q,R,S=q+J[d][0],r+J[d][1],s+J[d][2]
  if L(Q,R,S)<C:a(K(Q,R))
def T(i,U,V):
 W=U[0]==A[i]or'.'==A[i];X=0
 if(2>len(U))*W:X=1
 elif W:X=max([T(x,U[1:],V+[i])if x not in V else 0 for x in M[i]]+[0])
 return X
print(max([T(x,B,[])for x in Y(D)])and len(B)<=D)
from math import*

#Rundown of the formula:
# * Get data about the size of the hexagon
# * Create lookup tables for index <-> coordinate conversion
#   * I chose to measure in cubic coordinates, as that allows
#     for easy oob checks
# * Create the adjacency list using the lookup tables, while
#   checking for wrapping
# * Heuristically check if a path in the hexagon matches the
#   expression

# Get input
prog=input()
expr=input()

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1

# dirs contains the q,r and s values needed to move a point
# in the direction refrenced by the index
dirs=[(1,0,-1),(0,1,-1),(-1,1,0),(-1,0,1),(0,-1,1),(1,-1,0)]

# generate nmbf using a summation formula I made

for r in range(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-abs(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in range(nmrw):
    bgnq=max(-r,1-sdln)
    for q in range(nmrw-abs(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r-usdl
        cntr+=1

# in2s = index to s. Useful for bounds checking
# c2in = coords to index conversion
# mxab = return roughly how far away a point is from the center
# adjn = Adjacency sets

in2s=[-in2q[x]-in2r[x]for x in range(hxln)]
c2in=lambda q,r:q+nmbf[r+usdl]
mxab=lambda q,r,s:max(map(abs,[q,r,s]))
adjn=[set()for x in range(hxln)]

# Generate adjacency sets

for x in range(hxln):
    #Get the q,r,s coords
    q,r,s=in2q[x],in2r[x],in2s[x]
    # Are we at a corner?
    p=usdl and(q/usdl,r/usdl,s/usdl)
    # m = distance from center
    m=mxab(q,r,s)
    # if we are at a corner...
    if p in dirs:
        # add the other 2 corners we can go to
        adjn[x].add(c2in(s,q))
        adjn[x].add(c2in(r,s))
    # otherwise, if we are on the edge...
    elif mxab(q,r,s)==usdl:
        # add the only other point it wraps to
        if m==r or-m==r:
            adjn[x].add(c2in(-s,-r))
        if m==q or-m==q:
            adjn[x].add(c2in(-q,-s))
        if m==s or-m==s:
            adjn[x].add(c2in(-r,-q))
    # for all the directions...
    for d in range(6):
        # tmp{q,r,s} = moving in direction d from q,r,s
        tmpq,tmpr,tmps=q+dirs[d][0],r+dirs[d][1],s+dirs[d][2]
        # if the point we moved to is in bounds...
        if mxab(tmpq,tmpr,tmps)<sdln:
            # add it
            adjn[x].add(c2in(tmpq,tmpr))

# Recursive path checking function
def mtch(i,mtst,past):
    # dmch = Does the place we are on in the hexagon match
    #        the place we are in the expression?
    # out = the value to return
    dmch=mtst[0]==prog[i]or'.'==prog[i]
    out=0
    # if we are at the end, and it matches...
    if(2>len(mtst))*dmch:
        out=1
    # otherwise...
    elif dmch:
        # Recur in all directions that we haven't visited yet
        out=max([mtch(x,mtst[1:],past+[i]) if x not in past else 0 for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(max([mtch(x,expr,[])for x in range(hxln)])and len(expr)<=hxln)

If I missed out on anything to golf more, please let me know (thanks).

#Python 3, 990 943 770 bytes

EDIT 2: Removed unnecessary fluff, golfed a lot more.

from math import*
b=abs
c=max
e=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[1,0,-1,-1,0,1]
K=[0,1,1,0,-1,-1]
for r in e(E-1):G[r+1]=G[r]+E+.5-b(r-C+1.5)
L=0
for r in e(E):
 M=c(-r,1-C)
 for q in e(E-b(r-C+1)):H[L]=M+q;I[L]=r-F;L+=1
N=[set()for x in e(D)]
for x in e(D):
 q,r=H[x],I[x];s=-q-r;a=lambda q,r:N[x].add(q+G[r+F]);m=c(map(b,[q,r,s]))
 if m==F:
  if q in(m,-m):a(-q,-s)
  if r in(m,-m):a(-s,-r)
  if s in(m,-m):a(-r,-q)
 for d in e(6):
  O,P=q+J[d],r+K[d]
  if c(map(b,[O,P,-O-P]))<C:a(O,P)
def Q(i,R,S):
 T=R*(R[0]==A[i]or'.'==A[i]);U=0
 if(2>len(R))*T:U=1
 elif T:U=c([(x not in S)*Q(x,R[1:],S+[i])for x in N[i]]+[0])
 return U
print(c([Q(x,B,[])for x in e(D)])*(len(B)<=D))
from math import*

#Rundown of the formula:
# * Get data about the size of the hexagon
# * Create lookup tables for index <-> coordinate conversion
#   * q=0, r=0 is the center of the hexagon
#   * I chose to measure in a mix of cubic and axial coordinates,
#     as that allows for easy oob checks and easy retrevial  
# * Create the adjacency list using the lookup tables, while
#   checking for wrapping
# * Brute-force check if a path in the hexagon matches the
#   expression

# shorten functions used a lot
b=abs
c=max
e=range

# Get input 

prog=input()
expr=input()

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1

# dirs contains the q,r and s values needed to move a point
# in the direction refrenced by the index

qdir=[1,0,-1,-1,0,1]
rdir=[0,1,1,0,-1,-1]

# generate nmbf using a summation formula I made

for r in e(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-b(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in e(nmrw):
    bgnq=c(-r,1-sdln)
    for q in e(nmrw-b(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r-usdl
        cntr+=1

# adjn = Adjacency sets

adjn=[set()for x in e(hxln)]

# Generate adjacency sets

for x in e(hxln):
    #Get the q,r,s coords
    q,r=in2q[x],in2r[x]
    s=-q-r
    # a = function to add q,r to the adjacency list
    a=lambda q,r:adjn[x].add(q+nmbf[r+usdl])
    # m = absolute value distance away from the center
    m=c(map(b,[q,r,s]))
    # if we are on the edge (includes corners)...
    if m==usdl:
        # add the only other point it wraps to
        if q in(m,-m):
            a(-q,-s)
        if r in(m,-m):
            a(-s,-r)
        if s in(m,-m):
            a(-r,-q)
    # for all the directions...
    for d in e(6):
        # tmp{q,r,s} = moving in direction d from q,r,s
        tmpq,tmpr=q+qdir[d],r+rdir[d]
        # if the point we moved to is in bounds...
        if c(map(b,[tmpq,tmpr,-tmpq-tmpr]))<sdln:
            # add it
            a(tmpq,tmpr)

# Recursive path checking function
def mtch(i,mtst,past):
    # dmch = Does the place we are on in the hexagon match
    #        the place we are in the expression?
    # out = the value to return
    dmch=mtst and mtst[0]==prog[i]or'.'==prog[i]
    out=0
    # if we are at the end, and it matches...
    if(2>len(mtst))*dmch:
        out=1
    # otherwise...
    elif dmch:
        # Recur in all directions that we haven't visited yet
        # replace '*' with 'and' to speed up the recursion
        out=c([(x not in past)*mtch(x,mtst[1:],past+[i])for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(c([mtch(x,expr,[])for x in e(hxln)])*(len(expr)<=hxln))

So close to Retina! :(

edited score
Source Link
Blue
  • 2k
  • 13
  • 23

#Python, 990990 943 bytes

EDIT: Golfed adjacency list making. I now use a slightly different formula

from math import*
Y=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
F=[0]*E
G=[0]*DG=[0]*E
H=[0]*D
I=[0,I=[0]*D
J=[(1,0,-1),(0,1,-1),(-1]
J=[11,1,0),(-1,-0,1),(0,1]
K=[set(-1,1)for x in Y,(D)]
L=[D*[1,-1]for d in Y(61,0)]
M=lambdaK=lambda q,r:q+F[r]
N=C-1q+G[r+F]
O=lambdaL=lambda a,b,q,r,s:max(q+N*map(J[a%6]+J[b%6])abs,r+N*[q,r,s]))
M=[set(I[a%6]+I[b%6])for x in Y(D)]
P=0N=0
for r in Y(E-1):F[r+1]=intG[r+1]=int(F[r]+E+G[r]+E+.5-abs(r-C+1.5))
for r in Y(E):
 Q=maxO=max(-r,1-C)
 for q in Y(E-abs(r-C+1)):G[P]=Q+q;H[P]=r;P+=1H[N]=O+q;I[N]=r-F;N+=1
forP=[-H[x]-I[x]for dx in Y(6D):
 q,r=J[~-d%6]*N,N+I[~-d%6]*N]
 for x in Y(ND):R
 q,S=O(d+2r,d+3s=H[x],qI[x],r);L[d][MP[x];p=F and(q/F,r)]=M(R/F,Ss/F);q+=J[-~d%6];r+=I[-~d%6]
 L[d][M;m=L(q,r,s)]=-2;a=M[x].add
 forif xp in Y(N)J:q+=J[(d+2)%6];r+=I[a(d+2)%6];R,S=OK(d+4,d+3s,q,));a(K(r,s);L[d][M)
 elif L(q,r)]=M(R,Ss)==F:
for x inif Ym==r or-m==r:a(DK(-s,-r):)
  if m==q or-m==q:a(K(-q,r=G[x]-s))
  if m==s or-m==s:a(K(-r,H[x]-q))
 for d in Y(6):
  if-1==L[d][x]:Q,R,S=q+J[d]S=q+J[d][0],r+I[d];K[x].add(M(Rr+J[d][1],S))s+J[d][2]
  elif-2==L[d][x]:pass
 if elseL(Q,R,S)<C:K[x].adda(L[d][x]K(Q,R))
def T(i,U,V):
 W=U[0]==A[i]or'.'==A[i];X=0
 if 1==len(2>len(U)and W)*W:X=1
 elif W:X=max([T(x,U[1:],V+[i])if x not in V else 0 for x in K[i]]+[0]M[i]]+[0])
 return X
print(max([T(x,B,[])for x in Y(D)])and len(B)<=D)
from math import*

#Rundown of the formula:
# * Get inputdata about the size of the hexagon
prog=input('Enter# * Create lookup tables for index <-> coordinate conversion
#   * I chose to measure in cubic coordinates, as that allows
#     for easy oob checks
# * Create the adjacency list using the lookup tables, while
#   checking for wrapping
# * Heuristically check if a path in the hexagon: ')matches the
expr=input('Enter#   expression:

# 'Get input
prog=input()
expr=input()

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1 

# qdirdirs contains the q,r and rdirs representvalues theneeded aboveto directionsmove a point
# in axialthe form
direction refrenced by the index
rdir=[0,dirs=[(1,0,-1),(0,1,-1),(-1]
qdir=[11,1,0),(-1,-0,1),(0,1]-1,1),(1,-1,0)]

# generate nmbf using a summation formula I made

for r in range(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-abs(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in range(nmrw):
    bgnq=max(-r,1-sdln)
    for q in range(nmrw-abs(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r-usdl
        cntr+=1
        
# wrpnin2s = Spaces that wrap, and which ones they goindex to
# mayb = corners, turns out we don't need it

wrpn=[hxln*[-1]for d ins. range(6)]
#mayb=[[0,0]forUseful dfor inbounds range(6)]
checking
# c2in = coords to index conversion
# usdlmxab = one less thanreturn theroughly sidehow length.far Iaway usea itpoint ais lotfrom later

c2in=lambdathe q,r:q+nmbf[r]
usdl=sdln-1
center
# mkptadjn = Mark a pointAdjacency usdlsets

in2s=[-in2q[x]-in2r[x]for unitsx in direction a and b starting fromrange(hxln)]
c2in=lambda q and ,r
 :q+nmbf[r+usdl]
mkpt=lambdamxab=lambda a,b,q,r,s:max(q+usdl*map(qdir[a%6]+qdir[b%6])abs,r+usdl*(rdir[a%6]+rdir[b%6]))

# The below loop generates the wrapping table.

# Basically[q, for each directionr, it goes along 2 edges
# marking the points that will wrap and the point it will wrap to
s]))
adjn=[set()for dx in range(6hxln):]
     
# Go to the 'forward-top'Generate (d+1)adjacency cornersets

    q,r=qdir[~-d%6]*usdl,usdl+rdir[~-d%6]*usdl
    for x in range(usdlhxln):
        # Mark a point 'backwards' (d+3) and 'backwards-down' (d+2) on#Get the otherq,r,s edgecoords
        mkdqq,mkdr=mkpt(d+2r,d+3s=in2q[x],qin2r[x],r)
in2s[x]
        # Add itAre towe theat wrappinga listcorner?
       p=usdl wrpn[d][c2inand(q/usdl,r)]=c2in(mkdq/usdl,mkdrs/usdl)
 
        # Move down the current edge
    m = distance from q+=qdir[-~d%6]center
        r+=rdir[-~d%6]
m=mxab(q,r,s)
    # Nowif we are at thea corner...
    # Theif belowp codein isdirs:
 unnecessary, because
    # corners already# wrapadd tothe other 2 corners

  we can go #mkdq,mkdr=mkpt(d+2,d+3,q,r)to
    #mayb[d][0]=c2in(mkdq,mkdr)
    #mkdq,mkdr=mkptadjn[x].add(d+4,d+3c2in(s,q,r))
    #mayb[d][1]=c2in(mkdq,mkdr)

    wrpn[d][c2inadjn[x].add(q,c2in(r,s)]=-2
)
    # gootherwise, alongif thewe 'bottom'are edge
on the edge...
  for x inelif rangemxab(usdlq,r,s)==usdl:
        # move 'backwards-down'
        q+=qdir[(d+2)%6]
 add the only other point it wraps r+=rdir[(d+2)%6]
to
        # mark a point on the opposite edgeif bym==r goingor-m==r:
        # 'backwards' (d+3) and 'backwards-up' adjn[x].add(d+4)
        mkdq,mkdr=mkptc2in(d+4,d+3,q-s,-r)
 )
        # addif thatm==q pairor-m==q:
 to the wrapping list
        wrpn[d][c2inadjn[x].add(c2in(-q,r-s)]=c2in(mkdq,mkdr)
 
# adjn = Adjacency sets
adjn=[set()for x in range(hxln)]

# Generate theif adjacencym==s sets
or-m==s:
for x in range(hxln):
    # Get the row and columnadjn[x].add(c2in(-r,-q))
 of the current index
# for all the q,r=in2q[x],in2r[x]directions...
    for d in range(6):
        if-1==wrpn[d][x]:
            # on the insidetmp{q, don't use wrapping table
     r,s} = moving in direction d from mkdqq,mkdr=q+qdir[d]r,r+rdir[d]s
            adjn[x].add(c2in(mkdqtmpq,mkdr))
        elif-2==wrpn[d][x]:passtmpr,tmps=q+dirs[d][0],r+dirs[d][1],s+dirs[d][2]
        # is a corner
        #if Alreadythe takenpoint carewe ofmoved byto wrappingis in other directions
        #    adjn[x]bounds.add(mayb[d][0])..
        #   if adjn[x].addmxab(mayb[d][1]tmpq,tmpr,tmps)
        else<sdln:
            # going oob, use the wrappingadd tableit
            adjn[x].add(wrpn[d][x]c2in(tmpq,tmpr))

# Recursive brute-forcepath checking function
 
def mtch(i,mtst,past):
    # dmch = Does the currentplace charwe are on in the hexagon match the
    # current char      the place we are in the regexexpression?
    dmch=mtst[0]==prog[i]or'.'==prog[i]
# out = the out=0
value to return
  if 1==len(mtst)and dmch:dmch=mtst[0]==prog[i]or'.'==prog[i]
    out=0
    # if we are at the last characterend, and it matches,...
 return true  if(2>len(mtst))*dmch:
        out=1
    # otherwise...
    elif dmch:
        # otherwise, recurRecur in all directions that we haven't visited yet
        out=max([mtch(x,mtst[1:],past+[i]) if x not in past else 0 for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(max([mtch(x,expr,[])for x in range(hxln)])and len(expr)<=hxln)

#Python, 990 bytes

from math import*
Y=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
A+='.'*(D-len(A))
F=[0]*E
G=[0]*D
H=[0]*D
I=[0,1,1,0,-1,-1]
J=[1,0,-1,-1,0,1]
K=[set()for x in Y(D)]
L=[D*[-1]for d in Y(6)]
M=lambda q,r:q+F[r]
N=C-1
O=lambda a,b,q,r:(q+N*(J[a%6]+J[b%6]),r+N*(I[a%6]+I[b%6]))
P=0
for r in Y(E-1):F[r+1]=int(F[r]+E+.5-abs(r-C+1.5))
for r in Y(E):
 Q=max(-r,1-C)
 for q in Y(E-abs(r-C+1)):G[P]=Q+q;H[P]=r;P+=1
for d in Y(6):
 q,r=J[~-d%6]*N,N+I[~-d%6]*N
 for x in Y(N):R,S=O(d+2,d+3,q,r);L[d][M(q,r)]=M(R,S);q+=J[-~d%6];r+=I[-~d%6]
 L[d][M(q,r)]=-2
 for x in Y(N):q+=J[(d+2)%6];r+=I[(d+2)%6];R,S=O(d+4,d+3,q,r);L[d][M(q,r)]=M(R,S)
for x in Y(D):
 q,r=G[x],H[x]
 for d in Y(6):
  if-1==L[d][x]:R,S=q+J[d],r+I[d];K[x].add(M(R,S))
  elif-2==L[d][x]:pass
  else:K[x].add(L[d][x])
def T(i,U,V):
 W=U[0]==A[i]or'.'==A[i];X=0
 if 1==len(U)and W:X=1
 elif W:X=max([T(x,U[1:],V+[i])if x not in V else 0 for x in K[i]]+[0])
 return X
print(max([T(x,B,[])for x in Y(D)]))
from math import*

# Get input
prog=input('Enter hexagon: ')
expr=input('Enter expression: ')

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1
# qdir and rdir represent the above directions in axial form

rdir=[0,1,1,0,-1,-1]
qdir=[1,0,-1,-1,0,1]

# generate nmbf using a summation formula I made

for r in range(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-abs(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in range(nmrw):
    bgnq=max(-r,1-sdln)
    for q in range(nmrw-abs(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r
        cntr+=1
        
# wrpn = Spaces that wrap, and which ones they go to
# mayb = corners, turns out we don't need it

wrpn=[hxln*[-1]for d in range(6)]
#mayb=[[0,0]for d in range(6)]

# c2in = coords to index conversion
# usdl = one less than the side length. I use it a lot later

c2in=lambda q,r:q+nmbf[r]
usdl=sdln-1

# mkpt = Mark a point usdl units in direction a and b starting from q and r
 
mkpt=lambda a,b,q,r:(q+usdl*(qdir[a%6]+qdir[b%6]),r+usdl*(rdir[a%6]+rdir[b%6]))

# The below loop generates the wrapping table.

# Basically, for each direction, it goes along 2 edges
# marking the points that will wrap and the point it will wrap to

for d in range(6):
    # Go to the 'forward-top' (d+1) corner

    q,r=qdir[~-d%6]*usdl,usdl+rdir[~-d%6]*usdl
    for x in range(usdl):
        # Mark a point 'backwards' (d+3) and 'backwards-down' (d+2) on the other edge
        mkdq,mkdr=mkpt(d+2,d+3,q,r)

        # Add it to the wrapping list
        wrpn[d][c2in(q,r)]=c2in(mkdq,mkdr)
 
        # Move down the current edge
        q+=qdir[-~d%6]
        r+=rdir[-~d%6]

    # Now we are at the corner
    # The below code is unnecessary, because
    # corners already wrap to other corners

     #mkdq,mkdr=mkpt(d+2,d+3,q,r)
    #mayb[d][0]=c2in(mkdq,mkdr)
    #mkdq,mkdr=mkpt(d+4,d+3,q,r)
    #mayb[d][1]=c2in(mkdq,mkdr)

    wrpn[d][c2in(q,r)]=-2

    # go along the 'bottom' edge
    for x in range(usdl):
        # move 'backwards-down'
        q+=qdir[(d+2)%6]
        r+=rdir[(d+2)%6]

        # mark a point on the opposite edge by going
        # 'backwards' (d+3) and 'backwards-up' (d+4)
        mkdq,mkdr=mkpt(d+4,d+3,q,r)
 
        # add that pair to the wrapping list
        wrpn[d][c2in(q,r)]=c2in(mkdq,mkdr)
 
# adjn = Adjacency sets
adjn=[set()for x in range(hxln)]

# Generate the adjacency sets

for x in range(hxln):
    # Get the row and column of the current index
    q,r=in2q[x],in2r[x]
    for d in range(6):
        if-1==wrpn[d][x]:
            # on the inside, don't use wrapping table
            mkdq,mkdr=q+qdir[d],r+rdir[d]
            adjn[x].add(c2in(mkdq,mkdr))
        elif-2==wrpn[d][x]:pass
        # is a corner
        # Already taken care of by wrapping in other directions
        #    adjn[x].add(mayb[d][0])
        #    adjn[x].add(mayb[d][1])
        else:
            # going oob, use the wrapping table
            adjn[x].add(wrpn[d][x])

# Recursive brute-force function
 
def mtch(i,mtst,past):
    # dmch = Does the current char in the hexagon match the
    # current char in the regex?
    dmch=mtst[0]==prog[i]or'.'==prog[i]
    out=0
    if 1==len(mtst)and dmch:
        # if we are at the last character and it matches, return true
        out=1
    elif dmch:
        # otherwise, recur in all directions that we haven't visited yet
        out=max([mtch(x,mtst[1:],past+[i]) if x not in past else 0 for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon

print(max([mtch(x,expr,[])for x in range(hxln)]))

#Python, 990 943 bytes

EDIT: Golfed adjacency list making. I now use a slightly different formula

from math import*
Y=range
A=input()
B=input()
C=ceil(sqrt((len(A)-.25)/3)+.5)
D=3*C*~-C+1
E=2*C-1
F=C-1
A+='.'*(D-len(A))
G=[0]*E
H=[0]*D
I=[0]*D
J=[(1,0,-1),(0,1,-1),(-1,1,0),(-1,0,1),(0,-1,1),(1,-1,0)]
K=lambda q,r:q+G[r+F]
L=lambda q,r,s:max(map(abs,[q,r,s]))
M=[set()for x in Y(D)]
N=0
for r in Y(E-1):G[r+1]=int(G[r]+E+.5-abs(r-C+1.5))
for r in Y(E):
 O=max(-r,1-C)
 for q in Y(E-abs(r-C+1)):H[N]=O+q;I[N]=r-F;N+=1
P=[-H[x]-I[x]for x in Y(D)]
for x in Y(D):
 q,r,s=H[x],I[x],P[x];p=F and(q/F,r/F,s/F);m=L(q,r,s);a=M[x].add
 if p in J:a(K(s,q));a(K(r,s))
 elif L(q,r,s)==F:
  if m==r or-m==r:a(K(-s,-r))
  if m==q or-m==q:a(K(-q,-s))
  if m==s or-m==s:a(K(-r,-q))
 for d in Y(6):
  Q,R,S=q+J[d][0],r+J[d][1],s+J[d][2]
  if L(Q,R,S)<C:a(K(Q,R))
def T(i,U,V):
 W=U[0]==A[i]or'.'==A[i];X=0
 if(2>len(U))*W:X=1
 elif W:X=max([T(x,U[1:],V+[i])if x not in V else 0 for x in M[i]]+[0])
 return X
print(max([T(x,B,[])for x in Y(D)])and len(B)<=D)
from math import*

#Rundown of the formula:
# * Get data about the size of the hexagon
# * Create lookup tables for index <-> coordinate conversion
#   * I chose to measure in cubic coordinates, as that allows
#     for easy oob checks
# * Create the adjacency list using the lookup tables, while
#   checking for wrapping
# * Heuristically check if a path in the hexagon matches the
#   expression

# Get input
prog=input()
expr=input()

# sdln = Side length
# hxln = Closest hexagonal number
# nmrw = Number of rows in the hexagon
# usdl = one less than the side length. I use it a lot later

sdln=ceil(sqrt((len(prog)-.25)/3)+.5)
hxln=3*sdln*~-sdln+1
nmrw=2*sdln-1
usdl=sdln-1

# Pad prog with dots

prog+='.'*(hxln-len(prog))

# nmbf = Number of elements before in each row
# in2q = index to collum
# in2r = index to row

nmbf=[0]*nmrw
in2q=[0]*hxln
in2r=[0]*hxln

#  4    5
#   \  /
# 3 -- -- 0
#   /  \ 
#  2    1 

# dirs contains the q,r and s values needed to move a point
# in the direction refrenced by the index
dirs=[(1,0,-1),(0,1,-1),(-1,1,0),(-1,0,1),(0,-1,1),(1,-1,0)]

# generate nmbf using a summation formula I made

for r in range(nmrw-1):
    nmbf[r+1]=int(nmbf[r]+nmrw+.5-abs(r-sdln+1.5))

# generate in2q and in2r using more formulas
# cntr = running counter

cntr=0
for r in range(nmrw):
    bgnq=max(-r,1-sdln)
    for q in range(nmrw-abs(r-sdln+1)):
        in2q[cntr]=bgnq+q
        in2r[cntr]=r-usdl
        cntr+=1

# in2s = index to s. Useful for bounds checking
# c2in = coords to index conversion
# mxab = return roughly how far away a point is from the center
# adjn = Adjacency sets

in2s=[-in2q[x]-in2r[x]for x in range(hxln)]
c2in=lambda q,r:q+nmbf[r+usdl]
mxab=lambda q,r,s:max(map(abs,[q,r,s]))
adjn=[set()for x in range(hxln)]
 
# Generate adjacency sets

for x in range(hxln):
    #Get the q,r,s coords
    q,r,s=in2q[x],in2r[x],in2s[x]
    # Are we at a corner?
    p=usdl and(q/usdl,r/usdl,s/usdl)
    # m = distance from center
    m=mxab(q,r,s)
    # if we are at a corner...
    if p in dirs:
        # add the other 2 corners we can go to
        adjn[x].add(c2in(s,q))
        adjn[x].add(c2in(r,s))
    # otherwise, if we are on the edge...
    elif mxab(q,r,s)==usdl:
        # add the only other point it wraps to
        if m==r or-m==r:
            adjn[x].add(c2in(-s,-r))
        if m==q or-m==q:
            adjn[x].add(c2in(-q,-s))
        if m==s or-m==s:
            adjn[x].add(c2in(-r,-q))
    # for all the directions...
    for d in range(6):
        # tmp{q,r,s} = moving in direction d from q,r,s
        tmpq,tmpr,tmps=q+dirs[d][0],r+dirs[d][1],s+dirs[d][2]
        # if the point we moved to is in bounds...
        if mxab(tmpq,tmpr,tmps)<sdln:
            # add it
            adjn[x].add(c2in(tmpq,tmpr))

# Recursive path checking function
def mtch(i,mtst,past):
    # dmch = Does the place we are on in the hexagon match
    #        the place we are in the expression?
    # out = the value to return
    dmch=mtst[0]==prog[i]or'.'==prog[i]
    out=0
    # if we are at the end, and it matches...
    if(2>len(mtst))*dmch:
        out=1
    # otherwise...
    elif dmch:
        # Recur in all directions that we haven't visited yet
        out=max([mtch(x,mtst[1:],past+[i]) if x not in past else 0 for x in adjn[i]]+[0])
    return out

# Start function at all the locations in the hexagon
# Automatically return false if the expression is longer
# than the entire hexagon
print(max([mtch(x,expr,[])for x in range(hxln)])and len(expr)<=hxln)
updated explanation
Source Link
Blue
  • 2k
  • 13
  • 23
Loading
Source Link
Blue
  • 2k
  • 13
  • 23
Loading