Skip to content

Instantly share code, notes, and snippets.

@mgritter
Created February 23, 2021 23:22
Show Gist options
  • Select an option

  • Save mgritter/549f38b9cc7fdd25c1b7e34ce8fb80df to your computer and use it in GitHub Desktop.

Select an option

Save mgritter/549f38b9cc7fdd25c1b7e34ce8fb80df to your computer and use it in GitHub Desktop.
King placement problem, brute force version
import itertools
# How many kings can be placed on an NxN board such that there are
# 2 kings in each row
# 2 kings in each column?
# No pair of attacking kings?
def kingPositionsInRow( availableColumns ):
for k1, k2 in itertools.combinations( availableColumns, 2 ):
if k2 == k1 + 1:
continue
if k2 == k1 - 1:
continue
yield (k1, k2)
def discardAttackedColumns( available, k1 ):
available.discard( k1 - 1 )
available.discard( k1 )
available.discard( k1 + 1 )
def updateCounts( prevCounts, k1, k2 ):
counts = list( prevCounts )
counts[k1] += 1
counts[k2] += 1
return counts
def placeKings( width, remainingRows, prevPlaced, prevCounts,
fullColumns, availableColumns ):
if remainingRows == 1:
for (k1,k2) in kingPositionsInRow( availableColumns ):
colCounts = updateCounts( prevCounts, k1, k2 )
if colCounts == [2] * width:
yield prevPlaced + [(k1,k2)]
else:
for (k1,k2) in kingPositionsInRow( availableColumns ):
#print( "Attempting", (k1,k2), "for row", remainingRows )
newCount = updateCounts( prevCounts, k1, k2 )
if newCount[k1] == 2 or newCount[k2] == 2:
newFull = set( fullColumns )
if newCount[k1] == 2:
newFull.add( k1 )
if newCount[k2] == 2:
newFull.add( k2 )
else:
newFull = fullColumns
nextAvail = set( range( width ) ) - fullColumns
discardAttackedColumns( nextAvail, k1 )
discardAttackedColumns( nextAvail, k2 )
for placement in placeKings( width,
remainingRows - 1,
prevPlaced + [(k1,k2)],
newCount,
newFull,
nextAvail ):
yield placement
def showPlacements( width ):
count = 0
for p in placeKings( width, width, [], [0] * width,
set(), set( range( width ) ) ):
count += 1
print( p )
print( "total", count )
def countPlacements( width ):
count = 0
example = None
for p in placeKings( width, width, [], [0] * width,
set(), set( range( width ) ) ):
example = p
count += 1
print( "total", count )
print( "example", example )
def showExample( kings ):
width = max( max(k1,k2) for (k1,k2) in kings ) + 1
for k1,k2 in kings:
output = ["."] * width
output[k1] = "K"
output[k2] = "K"
print( "".join( output ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment