Same Five Digits

April 19, 2011

I chose to use Python to solve this problem.

The brute force solution is to enumerate all the perfect squares with five digits. Then try them in all combinations taken three at a time.

from itertools import count, takewhile

squares = filter(lambda s: len(s) == 5,
                 takewhile(lambda s: len(s) <= 5,
                           (str(s**2) for s in count())))

for a, b, c in combinations(squares, 3):
    # ...

Each trio of numbers has to meet three criteria.

  • C1. five different digits occur in the trio.
  • C2. each digit occurs a different number of times (has a different count).
  • C3. the five counts are the same as the five digits.

A digit count histogram would help with all of those. Let’s define a function to build it.

from collections import defaultdict

def histogram(s):
    d = defaultdict(int)
    for c in s:
        d[c] += 1
    return d

That returns a dictionary mapping each digit to the number of times it occurs. For example, hist('31415') would return {1: 2, 3: 1, 4: 1, 5: 1}, meaning 1 occurs twice and 3, 4 and 5 each occur once.

Now we can test for the three criteria like this.

hist = histogram(a + b + c)
digits = set(hist.keys())
counts = set(hist.values())
if   (len(digits) == 5 and                     # five different digits
      digits == counts and                     # digits == counts
      not any(hist[k] == k for k in hist)):    # k does not occur k times.
    # then a, b, c meet the criteria.

We need to find all trios that meet the criteria, then find the one whose singleton digit is unique. So we’ll build a map from singleton digit to the set of trios with that singleton.

matches = defaultdict(list)
for a, b, c in combinations(squares, 3):
    # ...
    if «criteria met»:
        inverse_hist = dict((hist[k], k) for k in hist)
        singleton = inverse_hist[1]
        matches[singleton].append((a, b, c))

Now we need to find the entry in matches that has length one. We’ll do that by creating yet another map, this time from number of matches to the list of matches. Then we can extract the answer directly.

match_counts = dict((len(ls), ls) for ls in matches.values())
print(*match_counts[1][0])

On my computer, this solution runs for about 30 seconds. It is a brute force solution, and was coded with the barest minimum amount of analysis of the problem. So 30 seconds is not unreasonable. But we can do much better.

We can determine what digits the solution will use. Since the three numbers have 15 digits total, the five counts must sum to 15. Since the digits match the counts, the digits must sum to 15 as well. The only possible set of five unique digits is {1, 2, 3, 4, 5}. So let’s discard all the candidate squares that have digits outside that set. We can refine the way we collect the list of squares like this.

squares = filter(lambda s: len(s) == 5 and all(c in '12345' for c in s),
                 takewhile(lambda s: len(s) <= 5,
                           (str(s**2) for s in count())))

That small change reduces the number of candidate squares from 217 to 9, and the number of combinations from 1,679,580 to 84. The program now runs in under 20 milliseconds, which is more than 10,000 times faster.

To run either program, save the program text into a file enigma_1638.py and say:

$ python enigma_1638.py
12321 33124 34225

You can run the program at http://programmingpraxis.codepad.org/l2hDGwBm, where a definition of the combinations function is provided for backward compatibility to versions of Python prior to 2.6.

Pages: 1 2

11 Responses to “Same Five Digits”

  1. […] today’s Programming Praxis exercise, our goal is to solve a numeric riddle. Let’s get started, shall […]

  2. My Haskell solution (see http://bonsaicode.wordpress.com/2011/04/19/programming-praxis-same-five-digits/ for a version with comments):

    import Data.List
    import qualified Data.List.Key as K
    
    squares :: [Integer]
    squares = filter (all (`elem` "12345") . show) .
              takeWhile (< 100000) $ map (^2) [100..]
    
    sameFive :: Maybe (Integer, Integer, Integer)
    sameFive = fmap (fst . head) . find (null . tail) . K.group snd $ K.sort snd
               [ ((a,b,c), findIndex (== 1) dc)
               | a <- squares, b <- squares, a < b, c <- squares, b < c
               , let dc = map length . group . sort $ show =<< [a,b,c]
               , sort dc == [1..5], and $ zipWith (/=) dc [1..5]
               ]
    
    main :: IO ()
    main = print $ sameFive == Just (12321,33124,34225)
    
  3. programmingpraxis said

    Here is my solution:

    (list-of (list a b c s)
      (x is (list-of x2
              (x range 100 236) (x2 is (* x x))
              (not (= (apply min (digits x2)) 0))
              (< (apply max (digits x2)) 6)))
      (a in x) (b in x) (c in x) (< a b) (< b c)
      (d is (sort < (mappend digits (list a b c))))
      (s is (uniq-c = d))
      (= (length (unique = (sort < (map cdr s)))) 5)
      (equal? (unique = d) (unique = (sort < (map cdr s))))
      (ok? s))

    Let’s look at that slowly. X is a list of all five-digit squares that contain only the digits 1 through 5. The inner x ranges from 100 (because 1002 is the smallest 5-digit number) to 236 (because 2362 is the smallest square greater than 55555). Then the predicate (< 0 (apply max (digits x2)) 6) passes only those numbers with the digits 1 through 5. There are 9 such numbers, the squares of 111, 112, 115, 182, 185, 188, 211, 229, and 235.

    On the next line, the three "in" clauses form the cross product of the nine squares, a total of 93=729 triplets. The remaining two clauses on that line eliminate duplicates, reducing the number of triplets from 729 to 84, which by the binomial theorem is the number of ways 3 items can be chosen from a list of 9:

    (define (choose n k)
      (if (zero? k) 1
        (* n (/ k) (choose (- n 1) (- k 1)))))

    > (choose 9 3)
    84

    Next we want to calculate the “signature” of the digit counts in the solution. We calculate the fifteen digits in d, and the signature of the counts in s.

    Now we return to the puzzle. Each of the five digits is used a different number of times, which is tested by the predicate (= (length (unique = (sort < (map cdr s)))) 5). The counts have to be the same as the digits, which is tested by the predicate (equal? (unique = d) (unique = (sort < (map cdr s)))); the solution works if you omit that predicate, but I couldn't articulate a clear reason why, so I included it. Finally, no digit may be used its own number of times, which is tested by the ok? function:

    (define (ok? s)
      (cond ((null? s) #t)
            ((= (caar s) (cdar s)) #f)
            (else (ok? (cdr s)))))

    At this point the list comprehension gives us seven remaining triplets:

    ((12321 12544 55225 ((1 . 3) (2 . 5) (3 . 1) (4 . 2) (5 . 4)))
    (12321 33124 34225 ((1 . 3) (2 . 5) (3 . 4) (4 . 2) (5 . 1)))
    (12321 44521 55225 ((1 . 3) (2 . 5) (3 . 1) (4 . 2) (5 . 4)))
    (12321 52441 55225 ((1 . 3) (2 . 5) (3 . 1) (4 . 2) (5 . 4)))
    (12544 34225 44521 ((1 . 2) (2 . 4) (3 . 1) (4 . 5) (5 . 3)))
    (12544 34225 52441 ((1 . 2) (2 . 4) (3 . 1) (4 . 5) (5 . 3)))
    (34225 44521 52441 ((1 . 2) (2 . 4) (3 . 1) (4 . 5) (5 . 3))))

    I was going to invert the s matrix to determine the correct answer, but it is obvious by inspection that there is only one triplet where the digit used once is unique, and I am lazy. The solution to the puzzle is the triplet 1112 = 12321, 1822 = 33124, and 1852 = 34225.

    I used list comprehensions, digits, unique, uniq-c, and mappend from the Standard Prelude. You can run the program at http://programmingpraxis.codepad.org/ujS7gS9I.

  4. slabounty said

    Here’s a ruby version with some of the ideas from above incorporated. In a couple of places I use inject() to figure out if something is true for all elements of a hash. In this case inject() will return an array of two values (a pair) with the key the first element and the value as the second element. In both cases we initialize with “true” and then “and” with our test.

    # squares is a hash with the square and another hash that is the digits and their count. For
    # example { 12321 => {"1"=>2, "2"=>2, "3"=>1}, 33124 => { "3"=>2, "1"=>1, "2"=>1, "4"=>1}... }
    squares = {}
    
    # We're going from 100 (squared to 10000) to 236 (squared to 55696, first number greater than all
    # fives. See https://programmingpraxis.com/2011/04/19/same-five-digits/ for the explanation of
    # why this is true and why we're only searching for numbers containing the digits 0-5.
    100.upto(236) do |n|
        h = Hash.new(0)
        square = (n**2)
        square.to_s.each_char { |d| h[d] += 1 }
        squares[square] = h if h.inject(true) { |r, pair| r && ("012345".index(pair[0]) != nil) }
    end
    
    # solution_hash will look be an array of the three squares and a hash of digit counts of the three numbers.
    # For example { [12321, 12544, 55225] => {"1"=>"3", "2"=>"5", "3"=>"1", "5"=>"4", "4"=>"2"}, 
    #               [12321, 33124, 34225] => {"1"=>"3", "2"=>"5", "3"=>"4", "4"=>"2", "5"=>"1"} ... }
    solution_hash = {}
    
    # We need to go through the squares hash and generate a new hash, h2 which contains a merge of
    # three hashes derived by adding the values together in the three. After we have this
    # new hash, we convert the values strings for final processing. Our final processing is a series
    # of checks. First make sure that the number of keys is five and that the number of values is five.
    # Then make sure that the keys and values contain the same digits, and finally make sure that none
    # of the values is equal to its key. If all of these are true then add this solution to the solution
    # hash if it's not already there.
    squares.each_pair do |k1, v1|
        squares.each_pair do |k2, v2|
            squares.each_pair do |k3, v3|
                next if (k1 == k2) || (k2 == k3) || (k1 == k3)
                h2 = v1.merge(v2){|k4, oldval1, newval1| newval1+oldval1}.merge(v3){|k5, oldval2, newval2| newval2+oldval2}
                h2.each_pair {|k6, v6| h2[k6] = v6.to_s }
                if h2.length == 5 && h2.values.uniq.length == 5 && 
                   h2.keys.sort.eql?(h2.values.sort) && h2.inject(true) {|r, pair| r && (pair[0] != pair[1]) }
                    solution_hash[[k1, k2, k3].sort] = h2 if !solution_hash.has_key?([k1, k2, k3].sort)
                end
            end
        end
    end
    
    # Display all the solutions.
    solution_hash.each_pair do |k, v|
        puts "Solution: #{k} #{v}"
    end
    

    Here’s the results …

    Solution: [12321, 12544, 55225] {“1″=>”3”, “2”=>”5″, “3”=>”1″, “5”=>”4″, “4”=>”2″}
    Solution: [12321, 33124, 34225] {“1″=>”3”, “2”=>”5″, “3”=>”4″, “4”=>”2″, “5”=>”1″}
    Solution: [12321, 44521, 55225] {“1″=>”3”, “2”=>”5″, “3”=>”1″, “4”=>”2″, “5”=>”4″}
    Solution: [12321, 52441, 55225] {“1″=>”3”, “2”=>”5″, “3”=>”1″, “5”=>”4″, “4”=>”2″}
    Solution: [12544, 34225, 44521] {“1″=>”2”, “2”=>”4″, “5”=>”3″, “4”=>”5″, “3”=>”1″}
    Solution: [12544, 34225, 52441] {“1″=>”2”, “2”=>”4″, “5”=>”3″, “4”=>”5″, “3”=>”1″}
    Solution: [34225, 44521, 52441] {“3″=>”1”, “4”=>”5″, “2”=>”4″, “5”=>”3″, “1”=>”2″}

  5. Jussi Piitulainen said

    Let’s see what Prolog looks like when formatted as lang=”css”.
    It’s been many years since I used Prolog, but I installed
    SWI-Prolog for this now and found its help system helpful.

    I didn’t bother to find the least upper bound for the square
    roots. It is easy to see that 300 is a safe choice. (I even
    started at 99 instead of 100 to make the columns align.)

    candidate(Fifteen) :-
            between(99, 300, Q), digits(Q, Fifteen-Ten), Q1 is Q + 1,
            between(Q1, 300, R), digits(R, Ten-Five),    R1 is R + 1,
            between(R1, 300, S), digits(S, Five-[]),
            counts(Fifteen, Counts),
            setof(C, D^( member(D-C, Counts) ), [1,2,3,4,5]),
            \+ member(N-N, Counts).
    
    digits(M, [D1,D2,D3,D4,D5|More]-More) :-
            M5 is M * M,       digit(M5, M4, D5), digit(M4, M3, D4),
            digit(M3, M2, D3), digit(M2, M1, D2), digit(M1, 0,  D1).
    
    digit(M, M1, D) :- M1 is M // 10, D is M mod 10, between(1, 5, D).
    
    counts(Candidate, Counts) :-
            setof(D-C, ( between(1,5,D), count(D,Candidate,C) ), Counts).
    
    count(Digit, Candidate, Count) :-
            bagof(Digit, member(Digit, Candidate), Occurrences),
            length(Occurrences, Count),
            between(1, 5, Count).
    

    I got one constraint wrong at first – the one that each of the
    five counts be used – and thought the unique single digit was 4.
    After correcting that, the following interaction prints the
    possible pairs of the single digit and the sequence of the
    fifteen digits, from which the three numbers can be read.

    ?- candidate(X), counts(X,Cs), member(D-1,Cs), write(D-X), nl, fail.                                                       
    3-[1, 2, 3, 2, 1, 1, 2, 5, 4, 4, 5, 5, 2, 2, 5]                                                                            
    5-[1, 2, 3, 2, 1, 3, 3, 1, 2, 4, 3, 4, 2, 2, 5]                                                                            
    3-[1, 2, 3, 2, 1, 4, 4, 5, 2, 1, 5, 5, 2, 2, 5]                                                                            
    3-[1, 2, 3, 2, 1, 5, 2, 4, 4, 1, 5, 5, 2, 2, 5]                                                                            
    3-[1, 2, 5, 4, 4, 3, 4, 2, 2, 5, 4, 4, 5, 2, 1]                                                                            
    3-[1, 2, 5, 4, 4, 3, 4, 2, 2, 5, 5, 2, 4, 4, 1]                                                                            
    3-[3, 4, 2, 2, 5, 4, 4, 5, 2, 1, 5, 2, 4, 4, 1]                                                                            
    false.                                                                                                                     
    
  6. slabounty said

    @Jussi, Nice! I was thinking this would be a good Prolog problem as I was working on my version.

  7. Dan Harasty said

    I love using Python’s built-in set() object to “uniquify” and also to compare if two sequences have the same stuff irrespective of order. And, as much fun as it to write an combination-generator, here I rely on the combinations() function from Python’s itertools library.

    
    from itertools import combinations
    
    # 100*100 is the smallest 5-digit perfect square (10000)
    # 316*316 is the largest 5-digit perfect square (99856)
    # we'll be doing alot of string processing on them, 
    # so convert the square to a string
    five_dig_squares = [str(x*x) for x in range(100, 317)]
    
    print("found %d 5-digit perfect squares" % len(five_dig_squares))
    
    candidates_found = 0
    
    # use combinations() from Python's itertools library to cycle
    # through the squares in unique three-up sets
    for set_of_three in combinations(five_dig_squares, 3):
    
    	# string-concatenate the three squares
    	fifteen_digits  = "".join(set_of_three)
    	
    	# pass the string to set()
    	# since fifteen_digits is a string, and string
    	# is a sequence, the set() constructor naturally
    	# breaks the sequence up, and keeps only unique occurances
    	unique_digits = set(fifteen_digits)
    
    	# if the size of the unique_digits set is not exactly 5,
    	# then consider the next set_of_three
    	if len(unique_digits) != 5:
    		continue
    	
    	# create a dictionary where the key is the character, and the value is the count
    	count_digits = dict((c, str(fifteen_digits.count(c))) for c in unique_digits)
    
    	# if any of the keys (a given digit) match the values (that digit's number
    	# of occurrences), then this is not a viable candidate
    	if sum([1 for k, v in count_digits.items() if k == v]) > 0: continue
    		
    	# create a set of the count values (the numbers of occurrences)
    	count_digits_values = set(count_digits.values())
    	
    	# and if the set digits we found match the set of occurrences, then
    	# we have a candidate... print out the info
    	if unique_digits == count_digits_values:
    		print(set_of_three)
    		print(unique_digits)
    		print(count_digits)
    		print()
    		candidates_found += 1
    
    print("candidates found: %d" % candidates_found)
    
    

    Yields the seven candidates from 217 possibilities:

    found 217 5-digit perfect squares
    ('12321', '12544', '55225')
    {'1', '3', '2', '5', '4'}
    {'1': '3', '3': '1', '2': '5', '5': '4', '4': '2'}
    
    ('12321', '33124', '34225')
    {'1', '3', '2', '5', '4'}
    {'1': '3', '3': '4', '2': '5', '5': '1', '4': '2'}
    
    ('12321', '44521', '55225')
    {'1', '3', '2', '5', '4'}
    {'1': '3', '3': '1', '2': '5', '5': '4', '4': '2'}
    
    ('12321', '52441', '55225')
    {'1', '3', '2', '5', '4'}
    {'1': '3', '3': '1', '2': '5', '5': '4', '4': '2'}
    
    ('12544', '34225', '44521')
    {'1', '3', '2', '5', '4'}
    {'1': '2', '3': '1', '2': '4', '5': '3', '4': '5'}
    
    ('12544', '34225', '52441')
    {'1', '3', '2', '5', '4'}
    {'1': '2', '3': '1', '2': '4', '5': '3', '4': '5'}
    
    ('34225', '44521', '52441')
    {'1', '3', '2', '5', '4'}
    {'1': '2', '3': '1', '2': '4', '5': '3', '4': '5'}
    
    candidates found: 7
    

    Visual inspection shows 6 of these 7 candidates have the digit 3 occurring only once… so the last clue implies that the answer must be the set where that is not 1 of those 6:

    (‘12321’, ‘33124’, ‘34225’)

    Fun!

  8. Graham said

    An uncommented Python version; I’ll put up a github gist later if people are interested.

    #!/usr/bin/env python
    from collections import Counter
    from itertools import combinations
    
    def histogram(triple):
        return Counter(int(d) for d in ''.join(str(x) for x in triple))
    
    def meets_criteria(triple):
        hist = histogram(triple)
        digits, counts = set(hist.keys()), set(hist.values())
        return digits == counts and not any(hist[k] == k for k in hist)
    
    def unique_single(triples):
        digits = {i: [] for i in xrange(1, 6)}
        for t in triples:
            hist = histogram(triple)
            digits[min(hist.iterkeys(), key=lambda k: hist[k])].append(t)
        return filter(lambda v: len(v) == 1, digits.itervalues())[0][0]
    
    def main():
        nums = (n**2 for n in xrange(100, 236) if set(str(n**2)).issubset('12345'))
        return unique_single(t for t in combinations(nums, 3) if meets_criteria(t))
    
    if __name__ == "__main__":
        print main()
    
  9. arturasl said

    My solution in vimscript:

    let aInitial = []
    for i in range(100, 236)
    	let aTimes = split(i * i, '\zs')
    	if max(aTimes) <= 5 && count(aTimes, '0') == 0
    		call add(aInitial, aTimes)
    	endif
    endfor
    
    let aMatrix = []
    for i in range(0, len(aInitial) - 1)
    	for j in range(i + 1, len(aInitial) - 1)
    		for k in range(j + 1, len(aInitial) - 1)
    			call add(aMatrix, [aInitial[i], aInitial[j], aInitial[k]])
    		endfor
    	endfor
    endfor
    
    let aNewMatrix = []
    for aLine in aMatrix
    	let aNewLine = copy(aLine)
    	let aCounts = []
    
    	for i in range(1, 5)
    		call add(aCounts, count(extend(extend(copy(aLine[0]), aLine[1]), aLine[2]), string(i)))
    		call extend(aNewLine, [[i, aCounts[i - 1]]])
    	endfor
    
    	let bAdd = 1
    
    	for i in range(1, 5)
    		if aCounts[i - 1] == i || count(aCounts, i) != 1
    			let bAdd = 0
    		endif
    	endfor
    
    	if bAdd
    		call add(aNewMatrix, aNewLine)
    	endif
    endfor
    
    let aUniqueOnes = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
    for i in range(0, len(aNewMatrix) - 1)
    	for j in range(3, 7)
    		if aNewMatrix[i][j][1] == 1
    			let aUniqueOnes[j - 3][0] += 1
    			let aUniqueOnes[j - 3][1] = i
    			break
    		endif
    	endfor
    endfor
    
    for a in aUniqueOnes
    	if a[0] == 1
    		echo 'Output: ' . string(aNewMatrix[a[1]])
    	endif
    endfor
    
    Output: [['1', '2', '3', '2', '1'], ['3', '3', '1', '2', '4'], ['3', '4', '2', '2', '5'], [1, 3], [2, 5], [3, 4], [4, 2], [5, 1]]
    
  10. Sefer said

    I too found seven such numbers (and not one as specified).
    Another optimization may be that none of the numbers can contain the zero digit (since no appearing number can appear zero times). That should cut down overall runtime a bit further.

    12321 12544 55225
    3 = 1
    2 = 5
    4 = 2
    1 = 3
    5 = 4
    12321 33124 34225
    3 = 4
    2 = 5
    4 = 2
    1 = 3
    5 = 1
    12321 44521 55225
    3 = 1
    2 = 5
    4 = 2
    1 = 3
    5 = 4
    12321 52441 55225
    3 = 1
    2 = 5
    4 = 2
    1 = 3
    5 = 4
    12544 34225 44521
    3 = 1
    2 = 4
    1 = 2
    4 = 5
    5 = 3
    12544 34225 52441
    3 = 1
    2 = 4
    1 = 2
    4 = 5
    5 = 3
    34225 44521 52441
    3 = 1
    2 = 4
    1 = 2
    4 = 5
    5 = 3

  11. This Forth program is not very elegant, but it finds the single solution in about 0.7 seconds.

    
    0 VALUE n          PRIVATE
    0 VALUE used-once  PRIVATE
    CREATE pfs PRIVATE    #220 CELLS ALLOT
    CREATE xi  PRIVATE     #10 CELLS ALLOT
    CREATE sol PRIVATE #10 4 * CELLS ALLOT ( count a b c | used-once rows )
    
    :NONAME  CLEAR n  #236 #105 DO  I I *  pfs n CELL[] !  1 +TO n  LOOP ; EXECUTE
     
    : DISSECT ( n -- ) 5 0 DO  #10 /MOD 1 ROT xi []CELL +!  LOOP DROP ; PRIVATE 
    
    : NOT-EXACT? ( n -- bool ) 
    	LOCAL n
    	xi n CELL[] @
    	n 0=  n 5 > OR IF  0<> EXIT  ENDIF \ number of 0,6,7,8,9's should be 0
    	0= ; PRIVATE 
    
    : HAVE-54321? ( -- bool )
    	TRUE 6 1 DO  FALSE  
    		     6 1 DO  xi I CELL[] @ J = 
    		     	     I J <> ( no digit is used its own number of times )
    		     	     AND IF  J 1 = IF  I TO used-once  ENDIF 
    			     	     DROP TRUE LEAVE  
    			      ENDIF  
    		       LOOP  
    		     AND  
    	       LOOP ; PRIVATE
    
    : 5DIGITS-TESTS? ( -- bool ) 
    	#10 0 DO  I NOT-EXACT? IF  FALSE UNLOOP EXIT  ENDIF  LOOP 
    	HAVE-54321? ; PRIVATE
    
    : UNEQUAL? ( i j k -- a b c TRUE | FALSE )
    	pfs []CELL @ LOCAL a
    	pfs []CELL @ LOCAL b
    	pfs []CELL @ LOCAL c
    	a b =  a c = OR  b c = OR  
    	0= IF  a b c TRUE 
    	 ELSE  FALSE 
    	ENDIF ; PRIVATE
    
    : SORTED! ( a b c -- )
    	used-once 4 * sol []CELL LOCALS| addr c b a |
    	a b < IF  a  b TO a  TO b  ENDIF
    	a c < IF  a  c TO a  TO c  ENDIF
    	b c < IF  b  c TO b  TO c  ENDIF
    	addr 1 CELL[] @ a <>
    	addr 2 CELL[] @ b <> AND
    	addr 3 CELL[] @ c <> AND
    	   IF   1 addr +!
    	 	a addr 1 CELL[] !  
    		b addr 2 CELL[] ! 
    		c addr 3 CELL[] ! 
    	ENDIF ; PRIVATE
    
    : DISCARD ( -- u )
    	sol #10 4 * CELLS ERASE
    	n 0 ?DO  
    	n 0 ?DO  
    	n 0 ?DO  xi #10 CELLS ERASE
    		 pfs I CELL[] @ DISSECT
    		 pfs J CELL[] @ DISSECT
    		 pfs K CELL[] @ DISSECT
    		 5DIGITS-TESTS? IF  I J K UNEQUAL? IF  SORTED!  ENDIF  ENDIF  
    	   LOOP 
    	   LOOP 
    	   LOOP ; PRIVATE
    
    : .SOLUTION ( -- )
    	0 LOCAL addr
    	TIMER-RESET
    	DISCARD
    	6 1 DO  sol I 4 * CELL[] TO addr
    		addr @ 1 = IF  CR ." Solution = " 
    				  addr 1 CELL[] @ .  
    				  addr 2 CELL[] @ . 
    				  addr 3 CELL[] @ .
    		        ENDIF
    	  LOOP 
    	'(' EMIT .ELAPSED ')' EMIT ; 
    
    :ABOUT	CR ." Same Five Digits"
         	CR ." Try .SOLUTION " ;
    
    
    		.ABOUT -samefivedigits CR
    
    

Leave a comment