Just for fun, I am trying to implement an A* search for a puzzle solver. I want to keep all states visited so far in an hash. The state is basically a vector of the integers from 0 to 15. (I won't give more information at the moment to not spoil the puzzle.)
(defstruct posn
"A posn is a pair struct containing two integer for the row/col indices."
(row 0 :type fixnum)
(col 0 :type fixnum))
(defstruct state
"A state contains a vector and a posn describing the position of the empty slot."
(matrix '#(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0) :type simple-vector)
(empty-slot (make-posn :row 3 :col 3) :type posn))
Because it seems that I have to check some 100.000s of states I thought It would be more efficient to generate some number as a hash key instead of using the state directly and need to check using equal each time.
I started with
(defun gen-hash-key (state)
"Returns a unique(?) but simple hash key for STATE which is used for tracking
if the STATE was already visited."
(loop
with matrix = (state-matrix state)
for i from 1
for e across matrix
summing (* i e)))
but had to learn that this does not lead to really unique hash keys. E.g. the vectors '#(14 1 4 6 15 11 7 12 9 10 3 0 13 8 5 2)) and '#(15 14 1 6 9 0 4 12 10 11 7 3 13 8 5 2)) will both lead to 940 causing the A* search to miss states and therefore spoiling my whole idea.
Before I continue in my amateurish way to tweak the calculation, I wanted to ask if someone could point me to a way to generate real unique keys in an efficient way? I lack the formal CS education to know if there is a standard way to generate such keys.