Created
February 23, 2021 23:22
-
-
Save mgritter/549f38b9cc7fdd25c1b7e34ce8fb80df to your computer and use it in GitHub Desktop.
King placement problem, brute force version
This file contains hidden or 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 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