Created
November 5, 2022 06:05
-
-
Save mgritter/c9ca3e554c4b40d2835f0e755bdb4ccc to your computer and use it in GitHub Desktop.
Counting pairs of nonintersecting or semi-intersection lattice paths
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cairo | |
import math | |
import itertools | |
def base_position( i, j ): | |
return (i * 60 + 10, j * 50 + 10) | |
def drawGrid( ctx, i, j ): | |
ctx.set_line_width( 1 ) | |
ctx.set_source_rgba( 0.0, 0.0, 0.0, 1.0 ) | |
x0, y0 = base_position( i, j ) | |
for y in range( 0, 4 ): | |
for x in range( 0, 5 ): | |
ctx.arc( x0 + x * 10, y0 + y * 10, 1, 0, 2 * math.pi ) | |
ctx.fill() | |
def drawGrayPath( ctx, i, j, path ): | |
ctx.set_line_width( 3 ) | |
ctx.set_source_rgba( 0.0, 0.0, 0.0, 0.5 ) | |
drawPath( ctx, i, j, path ) | |
def drawRedPath( ctx, i, j, path ): | |
ctx.set_line_width( 3 ) | |
ctx.set_source_rgba( 1.0, 0.0, 0.0, 0.85 ) | |
drawPath( ctx, i, j, path ) | |
def drawBluePath( ctx, i, j, path ): | |
ctx.set_line_width( 3 ) | |
ctx.set_source_rgba( 0.0, 0.0, 1.0, 0.85 ) | |
drawPath( ctx, i, j, path ) | |
def drawPath( ctx, i, j, path ): | |
x, y = base_position( i, j ) | |
ctx.move_to( x, y ) | |
for n in range( 7 ): | |
if n in path: | |
y += 10 | |
else: | |
x += 10 | |
ctx.line_to( x, y ) | |
ctx.stroke() | |
# pointwise intersection | |
def intersects( path1, path2 ): | |
x1, y1 = 0, 0 | |
x2, y2 = 0, 0 | |
for n in range( 6 ): # Skip last segment | |
if n in path1: | |
y1 += 1 | |
else: | |
x1 += 1 | |
if n in path2: | |
y2 += 1 | |
else: | |
x2 += 1 | |
if x1 == x2 and y1 == y2: | |
return True | |
return False | |
# traverses the same interior edge | |
def intersects_middle_edge( path1, path2 ): | |
x1, y1 = 0, 0 | |
x2, y2 = 0, 0 | |
edges1 = set() | |
edges2 = set() | |
for n in range( 6 ): # Skip last segment | |
if n in path1: | |
edges1.add( ((x1,y1), (x1,y1+1)) ) | |
y1 += 1 | |
else: | |
edges1.add( ((x1,y1), (x1+1,y1) ) ) | |
x1 += 1 | |
if n in path2: | |
edges2.add( ((x2,y2), (x2,y2+1)) ) | |
y2 += 1 | |
else: | |
edges2.add( ((x2,y2), (x2+1,y2) ) ) | |
x2 += 1 | |
bad_edges = set([ | |
((1,1), (2,1)), | |
((2,1), (3,1)), | |
((1,2), (2,2)), | |
((2,2), (3,2)), | |
((1,1), (1,2)), | |
((2,1), (2,2)), | |
((3,1), (3,2)), | |
]) | |
#print( "edges for", path1, "=", sorted( edges1 ) ) | |
#print( "edges for", path2, "=", sorted( edges2) ) | |
return len( edges1.intersection( edges2 ).intersection( bad_edges ) ) > 0 | |
# traverses any common edge | |
def intersects_edge( path1, path2 ): | |
x1, y1 = 0, 0 | |
x2, y2 = 0, 0 | |
edges1 = set() | |
edges2 = set() | |
for n in range( 7 ): | |
if n in path1: | |
edges1.add( ((x1,y1), (x1,y1+1)) ) | |
y1 += 1 | |
else: | |
edges1.add( ((x1,y1), (x1+1,y1) ) ) | |
x1 += 1 | |
if n in path2: | |
edges2.add( ((x2,y2), (x2,y2+1)) ) | |
y2 += 1 | |
else: | |
edges2.add( ((x2,y2), (x2+1,y2) ) ) | |
x2 += 1 | |
#print( "edges for", path1, "=", sorted( edges1 ) ) | |
#print( "edges for", path2, "=", sorted( edges2) ) | |
return len( edges1.intersection( edges2 ) ) > 0 | |
w, h = base_position( 36, 36 ) | |
paths = list( itertools.combinations( range( 7 ), 3 ) ) | |
with cairo.SVGSurface( "lattice-paths.svg", w, h ) as surface: | |
surface.set_document_unit( cairo.SVG_UNIT_PX ) | |
ctx = cairo.Context(surface) | |
ctx.rectangle( 0, 0, w, h ) | |
ctx.set_source_rgba( 1.0, 1.0, 1.0, 1.0 ) | |
ctx.fill() | |
for i in range( 35 ): | |
drawGrid( ctx, i+1, 0 ) | |
drawGrayPath( ctx, i+1, 0, paths[i] ) | |
for j in range( 35 ): | |
drawGrid( ctx, 0, j+1 ) | |
drawGrayPath( ctx, 0, j+1, paths[j] ) | |
count = 0 | |
for i in range( 35 ): | |
for j in range( 35 ): | |
if not intersects_edge( paths[i], paths[j] ): | |
drawRedPath( ctx, i+1, j+1, paths[i] ) | |
drawBluePath( ctx, i+1, j+1, paths[j] ) | |
count += 1 | |
print( count, "pairs of paths") | |
surface.finish() | |
surface.flush() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment