#!/usr/bin/env python """ From technology review puzzle corner, Nov/Dec 2006 issue, N/D 3. Place 13 three digit squares in this pattern: * * * * * * * * * * * * * * * * * * * * * * * * * thirty:Desktop$ time ./squares_crossword.py There are 22 three-digit perfect squares: [100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 474, 529, 576, 625, 676, 729, 784, 841, 900, 961 ] Brute force search space = 22 **13 = 282810057883082752 . Looking for solutions... done. Looked at 27447 nodes in search tree. Number of solutions = 14436 . Here's the first: 1 225 121 1 225 729 900 1 676 676 0 Number of unique solutions = 1 . 8 169 225 1 484 625 729 1 441 676 6 real 0m3.766s user 0m3.536s sys 0m0.099s thirty:Desktop$ """ # First I want a list of the three digit squares. # 9**2 = 81 which has two digits. # 32**2 = 1024 which has four digits. # So the three digit squares are i**2 where 912 " return False # Save some typing. def c(position,digit): return str(crossword[position][digit]) def num(position): return c(position,0)+c(position,1)+c(position,2) # printable version of a crossword. def crossword2string(): return " "*3+c(0,0)+" "+num(3)+" "+num(8)+" "+c(12,0)+"\n"+\ " "*3+num(1)+" "+num(6)+" "+num(11)+"\n"+\ " "*3+c(0,2)+" "+num(4)+" "+num(9)+" "+c(12,2) # Here's where answers to the crossword will be stored, as displayable strings. answers = [] answer_strings = [] unique = [] def save_answer(): list = [] for tuple in crossword: list.append( 100*tuple[0]+10*tuple[1]+tuple[2] ) answers.append(list) answer_strings.append(crossword2string()) # Finally, I define a recursive routine to solve the puzzle, # that first, tries to find a valid number for postion p, # and for each that works, looks for a valid number at position p+1. n_nodes = [0] def solve(p): if p >= 13: save_answer() else: n_nodes[0] += 1 for square in squares_digits: if is_valid(p, square): crossword[p] = square solve(p+1) n_squares = len(squares_list) print "Brute force search space = ",n_squares,"**13 = ", n_squares**13, "." print "Looking for solutions..." solve(0) print "done." print "Looked at", n_nodes[0]," nodes in search tree." def is_unique(answer): for i in range(len(answer)): for j in range(i+1, len(answer)): if answer[i] == answer[j]: return False return True def count_unique(): n = 0; i = 0 for i in range(len(answers)): answer=answers[i] if is_unique(answer): n += 1 unique.append(i) return n print "Number of solutions =",len(answers),"." print "Here's the first:" print answer_strings[0] print "Number of unique solutions = ", count_unique(), "." for i in unique: print answer_strings[i] """ thirty:Desktop$ ./squares_crossword.py There are 22 three-digit perfect squares: [100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961] Brute force search space = 22 **13 = 282810057883082752 . Looking for solutions... done. Looked at 27447 nodes in search tree. Number of solutions = 14436 . Here's the first: 1 225 121 1 225 729 900 1 676 676 0 Number of unique solutions = 1 . 8 169 225 1 484 625 729 1 441 676 6 """