Skip to content

Instantly share code, notes, and snippets.

@lspector
Last active October 1, 2017 21:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lspector/09b1472ecc7036d52b89c29ef0d716a4 to your computer and use it in GitHub Desktop.
Save lspector/09b1472ecc7036d52b89c29ef0d716a4 to your computer and use it in GitHub Desktop.
Lecture notes on AI search algorithms, with Clojure code; view at http://viewer.gorilla-repl.org/view.html?source=gist&id=09b1472ecc7036d52b89c29ef0d716a4
;; gorilla-repl.fileformat = 1
;; **
;;; # Search
;;;
;;; Lecture notes on AI search algorithms, with Clojure code.
;;;
;;; Lee Spector, lspector@hampshire.edu, 20141015-20170930
;;;
;;; Some of the code here was adapted from the [search.lisp](https://norvig.com/paip/search.lisp) Common Lisp code in Peter Norvig's Paradigms of AI Programming (1991), but with substantial modifications.
;; **
;; @@
(ns search.core)
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-nil'>nil</span>","value":"nil"}
;; <=
;; **
;;; In AI, the concept of "search" is applied broadly.
;;;
;;; Every problem-solving process can be considered to be a search through an abstract "space" of potential answers.
;;;
;;; For example, we can think of the process of solving a Rubik's cube as navigating an abstract space in which each location is associated with one configuration of the cube, and each neighboring location is associated with a configuration that's one twist of the cube away. The problem-solver aims to find a path through this space that reaches a location associated with a configuration in which each face is uniformly colored.
;;;
;;; The process of proving a theorem in symbolic logic can be thought of as searching through a space in which each location is associated with a set of logical statements, and in which one is a neighbor of another if its statements can be produced by applying a rule of inference to the statements of the other.
;;;
;;; The process of planning a day's activites can be thought of as searching through the space of all possible arrangements of tasks, trying to find one that meets all requirements and also accomplishes as many optional goals as possible.
;;;
;;; And so on.
;;;
;;; In some cases the "search space" may be complex, with many branches and alternative paths from one place to another.
;;;
;;; In some, it can be "deceptive," in the sense that you can only reach a good place by going through worse places.
;;;
;;; In some, different agents control moves between different locations. For example, the search space for chess can be thought of as having a location for every possible configuration of pieces, with locations being linked if one can be reached from the other by one legal move. A player's goal is to find a path through the space that leads to a configuration in which it wins, but the player only gets to make half of the moves through the space. So it should make a move from which _all_ of the counter-moves that its opponent _could_ make lead to places that will allow it to reach a winning configuration.
;;;
;;; Once we're thinkling of all problem-solving processes as kinds of search, we can consider different kinds of search algorithms, and which may be appropriate for which kinds of problems. Some can be solved efficiently with deterministic, exhaustive search algorithms, while others involve uncertainty or require guesses.
;;;
;;; Most interesting applications of AI search will involve huge spaces that we don't actually have in our programs explicitly. For example, a chess program won't have all possible configurations of pieces in memory at the same time. Rather, it'll have one or a small subset of them in memory, and generate others as it considers moves.
;;;
;;; Nonetheless, we can begin to explore search algorithms by considering how we could search for something in a small, finite space, even one as simple as a flat list.
;; **
;; @@
(def space [2 4 2 39 1 2 3 5 7 298 1 2 39 5 4 3])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/space</span>","value":"#'search.core/space"}
;; <=
;; **
;;; How would we sarch for something in this list that satisfies a particular goal? Let's start with an arbitrary goal like "is equal to 5".
;; **
;; @@
(defn satisfies-goal?
[n]
(= n 5))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/satisfies-goal?</span>","value":"#'search.core/satisfies-goal?"}
;; <=
;; **
;;; Now one way to do the search is just to use Clojure's built-in `filter` function.
;; **
;; @@
(filter satisfies-goal? space)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-lazy-seq'>(</span>","close":"<span class='clj-lazy-seq'>)</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"(5 5)"}
;; <=
;; **
;;; If we only need to find one thing that satisfies the goal, we can wrap that in `first`.
;; **
;; @@
(first (filter satisfies-goal? space))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}
;; <=
;; **
;;; By the way, `filter` returns a lazy sequence, computing only as much as it needs. So if we only ask for the `first` element of its result, then it won't necessarily process the whole sequence. It'll just go as far as it needs to go to get the first item that satisfies the goal.
;;;
;;; To make it even neater, we can package `filter` and `first` into a single `search` function.
;; **
;; @@
(defn search
[goal-function flat-sequence]
(first (filter goal-function flat-sequence)))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; @@
(search satisfies-goal? space)
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}
;; <=
;; **
;;; We can pass in other goals, and other spaces.
;; **
;; @@
(search odd? [2 4 6 8 10 11 29 38 1 7])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>11</span>","value":"11"}
;; <=
;; **
;;; For the goals we can use anonymous functions if that's more convenient.
;; **
;; @@
(search (fn [n] (> n 20))
[2 4 6 8 10 11 29 38 1 7])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>29</span>","value":"29"}
;; <=
;; **
;;; The abbreviated anonymous function syntax can be used too.
;; **
;; @@
(search #(> % 20)
[2 4 6 8 10 11 29 38 1 7])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>29</span>","value":"29"}
;; <=
;; **
;;; The `filter` function is great, because it's built in and does the searching for you. But we're going to want to search spaces that aren't just linear sequences, and we're going to want to explore different ways of exploring the space. So we're going to have to build our own search functions.
;;;
;;; Let's start with a function that still just searches a linear sequence, but uses an explicit `loop` rather than `filter` to look for something that satisfies the goal. We'll write it to check for success with `satisfies-goal?`, which we defined above to return true only for an input of 5.
;; **
;; @@
(defn search
[sequence]
(loop [remaining sequence]
(if (empty? remaining)
false
(if (satisfies-goal? (first remaining))
(first remaining)
(recur (rest remaining))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; @@
(search [1 2 3 4 5 6 7 8 9 10])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}
;; <=
;; @@
(search [1 2 3])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-unkown'>false</span>","value":"false"}
;; <=
;; **
;;; Now let's re-write it to take the goal function as another parameter.
;; **
;; @@
(defn search
[goal sequence] ;;***
(loop [remaining sequence]
(if (empty? remaining)
false
(if (goal (first remaining)) ;;***
(first remaining)
(recur (rest remaining))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; @@
(search even? [1 2 3 4 5 6 7 8 9 10])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}
;; <=
;; **
;;; Now let's begin to generalize it and make it smarter.
;;;
;;; In a search space that's a linear sequence, there's just one "next" item to look at after each item that you examine. There's never a choice about which thing to look at next.
;;;
;;; In contrast, in most interesting search spaces that we'll want to explore, there will be several possible next items. We think of the overall search space in such cases as a "tree" composed of branches that lead to "leaves" (the actual items) and to subtrees, which may themselves be composed of branches to leaves or smaller subtrees, etc.
;;;
;;; For historical reasons, computer scientists generally draw trees upside down, with branches going down. And when we move from the main tree into a subtree, and then into a subtree of the subtree, etc., we say that we are going "deeper" into the tree. And we call the starting point of the search the "root." And we call each item in the tree a "node," or sometimes a "state." Weird, but that's the standard terminology.
;;;
;;; In Clojure, if we want to explicitly represent an entire search tree then we can do so in a nested vector like `[1 [3 5 7 8] [[[4 5] 6] 7]]`. There are three main branches here, one of which goes directly to a leaf (`1`), one of which goes to a subtree with 4 leaves, and one of which goes to a subtree composed of smaller subtrees.
;;;
;;; When you have a tree-structured search space, you have choices about what order in which to search it. The two most basic search strategies are "depth-first" and "breadth first" search.
;;;
;;; In depth-first search, we follow the first branch, and then the first branch of the first branch, and so on, deeper and deeper until we hit a leaf. Then we check to see if the leaf satisfies the goal. If it does, then we're done. If it doesn't, then we back up to our last place where there were multiple options, and explore the next option, again going all the way to a leaf before checking anything. Until we find a solution or exhaust the entire tree, we keep following this strategy, of going deep first, and when the test for whether a leaf satisfies the goal fails, backing up to the last choice point that hasn't yet been fully explored.
;;;
;;; In breadth-first search, by contrast, we first check all of the leaves that are one step away from the root. If none of them satisfy the goal, then we check all of the leaves that are two steps away from the goal, and so on.
;;;
;;; Here is a version of the `search` function with the explicit loop, above, that has been changed to search a tree rather than a linear sequence. The lines that have been changed are marked with `;;***`.
;; **
;; @@
(defn depth-search ;;***
[goal tree] ;;***
(loop [remaining tree]
(if (empty? remaining)
false
(if (sequential? (first remaining)) ;;***
(recur (concat (first remaining) (rest remaining))) ;;***
(if (goal (first remaining))
(first remaining)
(recur (rest remaining)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/depth-search</span>","value":"#'search.core/depth-search"}
;; <=
;; @@
(depth-search even? [1 [3 5 7 8] [[[4 5] 6] 7]])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; **
;;; We can use `let` to make `f` and `r` shorthand for `(first remaining)` and `(rest remaining)`, which will make some of our subsequent steps neater.
;; **
;; @@
(defn depth-search
[goal tree]
(loop [remaining tree]
(if (empty? remaining)
false
(let [f (first remaining) ;;***
r (rest remaining)] ;;***
(if (sequential? f)
(recur (concat f r))
(if (goal f)
f
(recur r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/depth-search</span>","value":"#'search.core/depth-search"}
;; <=
;; @@
(depth-search even? [1 [3 5 7 8] [[[4 5] 6] 7]])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; **
;;; It can be instructive to print each item as you check it.
;; **
;; @@
(defn depth-search
[goal tree]
(loop [remaining tree]
(if (empty? remaining)
false
(let [f (first remaining)
r (rest remaining)]
(println "checking:" f) ;; ***
(if (sequential? f)
(recur (concat f r))
(if (goal f)
f
(recur r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/depth-search</span>","value":"#'search.core/depth-search"}
;; <=
;; @@
(depth-search even? [1 [3 5 7 8] [[[4 5] 6] 7]])
;; @@
;; ->
;;; checking: 1
;;; checking: [3 5 7 8]
;;; checking: 3
;;; checking: 5
;;; checking: 7
;;; checking: 8
;;;
;; <-
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; **
;;; Now let's define `breadth-search` similarly, but with `f` and `r` combined in the opposite way in `remaining` (which is the remaining space to search) when we return to the top of the loop.
;; **
;; @@
(defn breadth-search ;;***
[goal tree]
(loop [remaining tree]
(if (empty? remaining)
false
(let [f (first remaining)
r (rest remaining)]
(println "checking:" f)
(if (sequential? f)
(recur (concat r f)) ;;***
(if (goal f)
f
(recur r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/breadth-search</span>","value":"#'search.core/breadth-search"}
;; <=
;; @@
(breadth-search even? [1 [3 5 7 8] [[[4 5] 6] 7]])
;; @@
;; ->
;;; checking: 1
;;; checking: [3 5 7 8]
;;; checking: [[[4 5] 6] 7]
;;; checking: 3
;;; checking: 5
;;; checking: 7
;;; checking: 8
;;;
;; <-
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; @@
(breadth-search even? [1 [3 5 7 8] [[[4 5] 6] 7] 10])
;; @@
;; ->
;;; checking: 1
;;; checking: [3 5 7 8]
;;; checking: [[[4 5] 6] 7]
;;; checking: 10
;;;
;; <-
;; =>
;;; {"type":"html","content":"<span class='clj-long'>10</span>","value":"10"}
;; <=
;; **
;;; We can write a more general `search` function that takes an argument that indicates whether to perform depth-first or breadth-first search. In fact, since these differ just in the way toat `f` and `r` are combined, we can write `search` to take a `combiner` function, so that we can call it with one function to perform depth-first search, another to perform breadth-first search, and yet others to perform other kinds of search.
;; **
;; @@
(defn search
[goal tree combiner] ;;***
(loop [remaining tree]
(if (empty? remaining)
false
(let [f (first remaining)
r (rest remaining)]
(println "checking:" f)
(if (sequential? f)
(recur (combiner f r)) ;;***
(if (goal f)
f
(recur r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; **
;;; We can now define `depth-search` as a call to `search` with a combiner of `concat`.
;; **
;; @@
(defn depth-search
[goal tree]
(search goal tree concat))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/depth-search</span>","value":"#'search.core/depth-search"}
;; <=
;; @@
(depth-search even? [1 [3 5 7 8] [[[4 5] 6] 7] 10])
;; @@
;; ->
;;; checking: 1
;;; checking: [3 5 7 8]
;;; checking: 3
;;; checking: 5
;;; checking: 7
;;; checking: 8
;;;
;; <-
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; **
;;; We can define `breadth-search` in a similar way, but providing a function that `concat`s its arguments in backwards order as the `combiner`.
;; **
;; @@
(defn breadth-search
[goal tree]
(search goal tree #(concat %2 %1)))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/breadth-search</span>","value":"#'search.core/breadth-search"}
;; <=
;; @@
(breadth-search even? [1 [3 5 7 8] [[[4 5] 6] 7] 10])
;; @@
;; ->
;;; checking: 1
;;; checking: [3 5 7 8]
;;; checking: [[[4 5] 6] 7]
;;; checking: 10
;;;
;; <-
;; =>
;;; {"type":"html","content":"<span class='clj-long'>10</span>","value":"10"}
;; <=
;; **
;;; For some search problems, we'll want to keep track of how we got to each branch of the tree.
;;;
;;; We can do this by replacing each item in the tree, as we explore it, with a map with values for the keys `:contents` and `:history`. The value for `:contents` will be the actual item at that point in the search space, while the value for `:history` will be the sequence of items that were explored on the way to this point.
;;;
;;; We can replace the items in the tree with these maps one level at a time, as we search the tree.
;; **
;; @@
(defn search
[goal tree combiner]
(loop [remaining (map #(hash-map :contents % :history []) tree)] ;;***
(if (empty? remaining)
false
(let [f (first remaining)
r (rest remaining)]
(if (sequential? (:contents f))
(recur
(combiner
(map #(hash-map :contents %
:history (conj (:history f) (:contents f))) ;;***
(:contents f))
r))
(if (goal (:contents f))
f
(recur r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; @@
(defn depth-search
[goal tree]
(search goal tree concat))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/depth-search</span>","value":"#'search.core/depth-search"}
;; <=
;; @@
(depth-search even? [1 [3 5 7 8] [[[4 5] 6] 7] 10])
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[3 5 7 8]"}],"value":"[[3 5 7 8]]"}],"value":"[:history [[3 5 7 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[:contents 8]"}],"value":"{:history [[3 5 7 8]], :contents 8}"}
;; <=
;; @@
(depth-search even? [1 [3 5 7] [[[4 5] 6] 7] 10])
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[4 5]"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[[4 5] 6]"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[[[4 5] 6] 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[4 5]"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[[4 5] 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[4 5]"}],"value":"[[[[4 5] 6] 7] [[4 5] 6] [4 5]]"}],"value":"[:history [[[[4 5] 6] 7] [[4 5] 6] [4 5]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"}],"value":"[:contents 4]"}],"value":"{:history [[[[4 5] 6] 7] [[4 5] 6] [4 5]], :contents 4}"}
;; <=
;; @@
(defn breadth-search
[goal tree]
(search goal tree #(concat %2 %1)))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/breadth-search</span>","value":"#'search.core/breadth-search"}
;; <=
;; @@
(breadth-search even? [1 [3 5 7 8] [[[4 5] 6] 7] 10])
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[],"value":"[]"}],"value":"[:history []]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>10</span>","value":"10"}],"value":"[:contents 10]"}],"value":"{:history [], :contents 10}"}
;; <=
;; @@
(breadth-search even? [1 [3 5 7] [[[4 5] 6] 7]])
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[4 5]"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[[4 5] 6]"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[[[4 5] 6] 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[4 5]"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[[4 5] 6]"}],"value":"[[[[4 5] 6] 7] [[4 5] 6]]"}],"value":"[:history [[[[4 5] 6] 7] [[4 5] 6]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[:contents 6]"}],"value":"{:history [[[[4 5] 6] 7] [[4 5] 6]], :contents 6}"}
;; <=
;; **
;;; Now we'll take a big step, of switching from searching an explicitly specified space to searching a space that we create as we explore it. This is what we'll usually want to do in real applications of AI, because the search spaces are usually much too big to generate completely.
;;;
;;; We'll usually start at one place in the space (like an initial configuration of a Rubik's cube) and, if the solution isn't at that location, generate the "successors" at the neighboring locations in the space.
;;;
;;; We can generalize our `search` function to work in this context by writing it to take another argument, a function that takes a node of the tree and returns all of its successors. We'll also print the "frontier" of the search tree -- all of the states that have been generated but not yet explored -- as we proceed.
;; **
;; @@
(defn search
[goal start combiner successors] ;;***
(loop [frontier [(hash-map :contents start :history [])]]
(if (empty? frontier)
false
(let [f (first frontier)
r (rest frontier)]
(println "Frontier:" (map :contents frontier) "Checking:" (:contents f))
(if (goal (:contents f))
f
(recur
(combiner
(map #(hash-map :contents %
:history (conj (:history f) (:contents f)))
(successors (:contents f)))
r)))))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; **
;;; For most real problems there will be a natural successor function, for example when solving a Rubik's cube the successors will be all of the configurations reachable by one twist from the current configuration.
;;;
;;; But to demonstrate this function first with searches through numbers, let's use the concept of a binary tree to generate a tree-structured space of the natural numbers.
;;;
;;; The binary tree we'll use looks like this:
;;;
;;; ```
;;; 1
;;; 2 3
;;; 4 5 6 7
;;; ```
;;; and so on. It starts at 1, which has two successors, 2 and 3. 2 has two successors, 4 and 5. And so on.
;;;
;;; This means that the successors of any number are that number doubled, and that number doubled plus one.
;;;
;; **
;; @@
(defn binary-tree [x]
[(* 2 x) (inc (* 2 x))])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/binary-tree</span>","value":"#'search.core/binary-tree"}
;; <=
;; @@
(binary-tree 23)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>46</span>","value":"46"},{"type":"html","content":"<span class='clj-long'>47</span>","value":"47"}],"value":"[46 47]"}
;; <=
;; **
;;; Now we can use this function to perform a depth-first search of a binary tree, looking for a number greater than 20.
;; **
;; @@
(search #(> % 20) 1 concat binary-tree)
;; @@
;; ->
;;; Frontier: (1) Checking: 1
;;; Frontier: (2 3) Checking: 2
;;; Frontier: (4 5 3) Checking: 4
;;; Frontier: (8 9 5 3) Checking: 8
;;; Frontier: (16 17 9 5 3) Checking: 16
;;; Frontier: (32 33 17 9 5 3) Checking: 32
;;;
;; <-
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>16</span>","value":"16"}],"value":"[1 2 4 8 16]"}],"value":"[:history [1 2 4 8 16]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>32</span>","value":"32"}],"value":"[:contents 32]"}],"value":"{:history [1 2 4 8 16], :contents 32}"}
;; <=
;; **
;;; And we can also do this with breadth-first search.
;; **
;; @@
(search #(> % 20) 1 #(concat %2 %1) binary-tree)
;; @@
;; ->
;;; Frontier: (1) Checking: 1
;;; Frontier: (2 3) Checking: 2
;;; Frontier: (3 4 5) Checking: 3
;;; Frontier: (4 5 6 7) Checking: 4
;;; Frontier: (5 6 7 8 9) Checking: 5
;;; Frontier: (6 7 8 9 10 11) Checking: 6
;;; Frontier: (7 8 9 10 11 12 13) Checking: 7
;;; Frontier: (8 9 10 11 12 13 14 15) Checking: 8
;;; Frontier: (9 10 11 12 13 14 15 16 17) Checking: 9
;;; Frontier: (10 11 12 13 14 15 16 17 18 19) Checking: 10
;;; Frontier: (11 12 13 14 15 16 17 18 19 20 21) Checking: 11
;;; Frontier: (12 13 14 15 16 17 18 19 20 21 22 23) Checking: 12
;;; Frontier: (13 14 15 16 17 18 19 20 21 22 23 24 25) Checking: 13
;;; Frontier: (14 15 16 17 18 19 20 21 22 23 24 25 26 27) Checking: 14
;;; Frontier: (15 16 17 18 19 20 21 22 23 24 25 26 27 28 29) Checking: 15
;;; Frontier: (16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31) Checking: 16
;;; Frontier: (17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33) Checking: 17
;;; Frontier: (18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35) Checking: 18
;;; Frontier: (19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37) Checking: 19
;;; Frontier: (20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39) Checking: 20
;;; Frontier: (21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41) Checking: 21
;;;
;; <-
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>10</span>","value":"10"}],"value":"[1 2 5 10]"}],"value":"[:history [1 2 5 10]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"html","content":"<span class='clj-long'>21</span>","value":"21"}],"value":"[:contents 21]"}],"value":"{:history [1 2 5 10], :contents 21}"}
;; <=
;; **
;;; Searching for numbers in a binary tree is an artificial and pretty useless thing to do, but the `search` function we've developed here can be used for _any_ problem for which we can specify a `goal` function, a `start` state, and a `successors` function. And by providing different `combiner` functions, we can get it to search the space in different orders.
;;;
;;; Let's illustrate this by considering the sliding tile puzzle called the "8 puzzle" (which is a smaller version of the [15 puzzle](https://en.wikipedia.org/wiki/15_puzzle)).
;;;
;;; We'll represent a state in the search space as a vector of the numbers from 0 to 8, where the 0 is the empty space into which adjacent tiles can be slid.
;;;
;;; As an example, the vector [8 2 3 1 0 4 5 6 7] corresponds to this puzzle board:
;;;
;;; ```
;;; 8 2 3
;;; 1 4
;;; 5 6 7
;;; ```
;;; The empty space is in the middle. From this position, sliding one tile, you could get:
;;; ```
;;; 8 3
;;; 1 2 4
;;; 5 6 7
;;; ```
;;; or
;;; ```
;;; 8 2 3
;;; 1 4
;;; 5 6 7
;;; ```
;;; or
;;; ```
;;; 8 2 3
;;; 1 4
;;; 5 6 7
;;; ```
;;; or
;;; ```
;;; 8 2 3
;;; 1 6 4
;;; 5 7
;;; ```
;;; The goal of the puzzle is to start at some other state and to reach [1 2 3 4 5 6 7 8 0], which looks like this:
;;; ```
;;; 1 2 3
;;; 4 5 6
;;; 7 8
;;; ```
;;;
;;; We'll write a function that takes a puzzle board and two positions, and returns the boards with the contents of the positions swapped. We'll use this later to swap the 0 with the value in an adjacent position.
;; **
;; @@
(defn slide
[from-index to-index board]
(-> board
(assoc from-index (get board to-index))
(assoc to-index (get board from-index))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/slide</span>","value":"#'search.core/slide"}
;; <=
;; **
;;; Now we can write a function that returns the successors of any board -- that is, the boards reachable by sliding one tile.
;; **
;; @@
(defn eight-puzzle-moves
"Returns a vector of all of the eight-puzzle boards reachable by sliding a
tile into the empty (zero) space in board b. Note that the indices of positions
in boards are as follows:
[0 1 2
3 4 5
6 7 8]"
[b]
(case (count (take-while pos? b)) ;; this gives us the index of the 0
0 [(slide 1 0 b) (slide 3 0 b)]
1 [(slide 0 1 b) (slide 2 1 b) (slide 4 1 b)]
2 [(slide 1 2 b) (slide 5 2 b)]
3 [(slide 0 3 b) (slide 4 3 b) (slide 6 3 b)]
4 [(slide 1 4 b) (slide 3 4 b) (slide 5 4 b) (slide 7 4 b)]
5 [(slide 2 5 b) (slide 4 5 b) (slide 8 5 b)]
6 [(slide 3 6 b) (slide 7 6 b)]
7 [(slide 4 7 b) (slide 6 7 b) (slide 8 7 b)]
8 [(slide 5 8 b) (slide 7 8 b)]))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/eight-puzzle-moves</span>","value":"#'search.core/eight-puzzle-moves"}
;; <=
;; **
;;; Let's also define a function that takes a board and tells us whether it's a solution.
;; **
;; @@
(defn eight-puzzle-solution
[board]
(= board [1 2 3 4 5 6 7 8 0]))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/eight-puzzle-solution</span>","value":"#'search.core/eight-puzzle-solution"}
;; <=
;; **
;;; Now we're ready to solve the puzzle with tree search!
;;;
;;; Here's how we solve it from this initial state:
;;; ```
;;; 1 2 3
;;; 4 5 6
;;; 7 8
;;; ```
;;; This is obviously quite easy, since we just have to slide the 7 to the left, and then the 8. We'll do it here with breadth-first search.
;; **
;; @@
(search eight-puzzle-solution
[1 2 3 4 5 6 0 7 8]
#(concat %2 %1)
eight-puzzle-moves)
;; @@
;; ->
;;; Frontier: ([1 2 3 4 5 6 0 7 8]) Checking: [1 2 3 4 5 6 0 7 8]
;;; Frontier: ([1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 7 0 8]) Checking: [1 2 3 0 5 6 4 7 8]
;;; Frontier: ([1 2 3 4 5 6 7 0 8] [0 2 3 1 5 6 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 4 5 6 0 7 8]) Checking: [1 2 3 4 5 6 7 0 8]
;;; Frontier: ([0 2 3 1 5 6 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 8 0]) Checking: [0 2 3 1 5 6 4 7 8]
;;; Frontier: ([1 2 3 5 0 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 8 0] [2 0 3 1 5 6 4 7 8] [1 2 3 0 5 6 4 7 8]) Checking: [1 2 3 5 0 6 4 7 8]
;;; Frontier: ([1 2 3 4 5 6 0 7 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 8 0] [2 0 3 1 5 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 0 3 5 2 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 5 6 0 4 7 8] [1 2 3 5 7 6 4 0 8]) Checking: [1 2 3 4 5 6 0 7 8]
;;; Frontier: ([1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 8 0] [2 0 3 1 5 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 0 3 5 2 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 5 6 0 4 7 8] [1 2 3 5 7 6 4 0 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 7 0 8]) Checking: [1 2 3 4 0 6 7 5 8]
;;; Frontier: ([1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 8 0] [2 0 3 1 5 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 0 3 5 2 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 5 6 0 4 7 8] [1 2 3 5 7 6 4 0 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 7 0 8] [1 0 3 4 2 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 6 0 7 5 8] [1 2 3 4 5 6 7 0 8]) Checking: [1 2 3 4 5 6 0 7 8]
;;; Frontier: ([1 2 3 4 5 6 7 8 0] [2 0 3 1 5 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 0 3 5 2 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 5 6 0 4 7 8] [1 2 3 5 7 6 4 0 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 7 0 8] [1 0 3 4 2 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 6 0 7 5 8] [1 2 3 4 5 6 7 0 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 7 0 8]) Checking: [1 2 3 4 5 6 7 8 0]
;;;
;; <-
;; =>
;;; {"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"}
;; <=
;; **
;;; Many other starting points take too long. We'll make several improvements before trying them.
;;;
;;; First, it's important to realize that the tree we'll be producing here will include many duplicate states. Every time we slide a tile, one of the successors of the resulting state will be the original state before the slide, since a legal next move will be to just slide the tile back. There are other ways to get back to the same states as well, and the number of duplicates will quickly get out of hand.
;;;
;;; Here we'll re-define `search` to keep track of all of the states that have been seen, in a set, and remove any already-seen states from successors before we explore them. We'll also stop printing the frontier, since it'll be annoyingly verbose for any non-trivial search.
;; **
;; @@
(defn search
[goal start combiner successors]
(loop [frontier [(hash-map :contents start :history [])]
seen #{start} ;;***
steps 0] ;;***
(if (empty? frontier)
false
(let [f (first frontier)
r (rest frontier)]
(if (goal (:contents f))
[f {:seen (count seen) :steps steps}]
(let [unseen-successors (clojure.set/difference ;;***
(set (successors (:contents f)))
seen)]
(recur
(combiner
(map #(hash-map :contents %
:history (conj (:history f) (:contents f)))
unseen-successors) ;;***
r)
(clojure.set/union seen unseen-successors) ;;***
(inc steps)))))))) ;;***
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/search</span>","value":"#'search.core/search"}
;; <=
;; @@
(search eight-puzzle-solution
[1 2 3 4 5 6 7 0 8]
#(concat %2 %1)
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>7</span>","value":"7"}],"value":"[:seen 7]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[:steps 2]"}],"value":"{:seen 7, :steps 2}"}],"value":"[{:history [[1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 7, :steps 2}]"}
;; <=
;; @@
(search eight-puzzle-solution
[1 2 3 4 0 5 6 7 8]
#(concat %2 %1)
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 0 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 8 6 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 6 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 0 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 0 5 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 0 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 6 8 4 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 5 6 8 4 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 6 0 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 0 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 0 5 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>7926</span>","value":"7926"}],"value":"[:seen 7926]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>5093</span>","value":"5093"}],"value":"[:steps 5093]"}],"value":"{:seen 7926, :steps 5093}"}],"value":"[{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 7926, :steps 5093}]"}
;; <=
;; **
;;; Many, however, are still too hard to be solved with breadth-first search.
;;;
;;; When neither depth-first nor breadth-first search will suffice, we can use a "heuristic" (guess!) combiner function to try to put the most promising states earlier in the list of states to explore.
;;;
;;; A heuristic function that works pretty well for the 8 puzzle is based on the distance of each tile from where it's supposed to be, moving only left, right, up and down (not diagonally). We add up all of the distances for all of the tiles, and consider boards with the lowest total distances first. This is called the "Manhattan distance" heuristic, because it's reminiscent of the ways to calculate travel distance in a city with a rectangular grid of streets.
;;;
;;; First we define a few utilites that will help.
;; **
;; @@
(defn xcoord
"The x coordinate of an index into
[0 1 2
3 4 5
6 7 8]"
[index]
(case index
(0 3 6) 0
(1 4 7) 1
(2 5 8) 2))
(defn ycoord
"The y coordinate of an index into
[0 1 2
3 4 5
6 7 8]"
[index]
(case index
(0 1 2) 0
(3 4 5) 1
(6 7 8) 2))
(defn index-distance
"The distance between positions with the two given indices"
[index1 index2]
(+ (Math/abs (- (xcoord index1) (xcoord index2)))
(Math/abs (- (ycoord index1) (ycoord index2)))))
(defn index-in-board
"The index of the given tile in the given board"
[tile board]
(count (take-while #(not (= % tile)) board)))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/index-in-board</span>","value":"#'search.core/index-in-board"}
;; <=
;; **
;;; Let's try that out.
;; **
;; @@
(index-in-board 3 [8 7 6 5 4 3 2 1 0])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-unkown'>5</span>","value":"5"}
;; <=
;; **
;;; That says that the 3 tile is in position 5, which is correct (remember that the indices start at 0).
;;;
;;; Now the Manhattan distance between two boards is just the sum of the distances of each tile from one board to the other.
;;;
;; **
;; @@
(defn manhattan-distance
[board1 board2]
(reduce + (for [tile (range 9)]
(index-distance (index-in-board tile board1)
(index-in-board tile board2)))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/manhattan-distance</span>","value":"#'search.core/manhattan-distance"}
;; <=
;; @@
(manhattan-distance [0 1 2 3 4 5 6 7 8]
[8 1 2 3 4 5 6 7 0])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}
;; <=
;; @@
(manhattan-distance [0 1 2 3 4 5 6 7 8]
[1 2 3 4 5 6 7 8 0])
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-long'>16</span>","value":"16"}
;; <=
;; **
;;; This makes it easy to define a function saying how far any board is from a solution.
;; **
;; @@
(defn solution-distance
[board]
(manhattan-distance board
[1 2 3 4 5 6 7 8 0]))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/solution-distance</span>","value":"#'search.core/solution-distance"}
;; <=
;; **
;;; Now let's define a combiner function that uses solution distance.
;;;
;;; Actually, we'll use the length of a state's history (that is, how many moves it took to get to the state from the initial board) **plus** it's solution distance, which is an estimate of the total number of moves that it will take to get from the initial board to a solution. Using this as a heuristic is the core idea of the "A-star" (A\*) search algorithm.
;;;
;;; We'll also limit the "width" of the frontier to 10, keeping only the 10 best-looking states at each step of the search. This kind of limitation is sometimes said to define a "beam" search.
;; **
;; @@
(defn best-10-combiner
[new-nodes old-nodes]
(take 10 (sort #(< (+ (count (:history %1))
(solution-distance (:contents %1)))
(+ (count (:history %2))
(solution-distance (:contents %2))))
(concat new-nodes old-nodes))))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/best-10-combiner</span>","value":"#'search.core/best-10-combiner"}
;; <=
;; **
;;; Now we can use heuristic search for the same problem that we solved above with breadth-first search.
;; **
;; @@
(search eight-puzzle-solution
[1 2 3 4 0 5 6 7 8]
best-10-combiner
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 0 3 4 2 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 1 3 4 2 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 1 3 0 2 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 1 3 6 2 5 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 1 3 6 2 5 7 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 1 3 6 0 5 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 1 3 0 6 5 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 1 3 4 6 5 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 0 3 4 6 5 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 3 0 4 6 5 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 3 5 4 6 0 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 3 5 4 0 6 7 2 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 3 5 4 2 6 7 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 3 5 4 2 6 7 8 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 3 5 4 2 0 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 3 0 4 2 5 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 0 3 4 2 5 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 4 0 5 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 4 5 0 7 8 6]"}],"value":"[[1 2 3 4 0 5 6 7 8] [1 0 3 4 2 5 6 7 8] [0 1 3 4 2 5 6 7 8] [4 1 3 0 2 5 6 7 8] [4 1 3 6 2 5 0 7 8] [4 1 3 6 2 5 7 0 8] [4 1 3 6 0 5 7 2 8] [4 1 3 0 6 5 7 2 8] [0 1 3 4 6 5 7 2 8] [1 0 3 4 6 5 7 2 8] [1 3 0 4 6 5 7 2 8] [1 3 5 4 6 0 7 2 8] [1 3 5 4 0 6 7 2 8] [1 3 5 4 2 6 7 0 8] [1 3 5 4 2 6 7 8 0] [1 3 5 4 2 0 7 8 6] [1 3 0 4 2 5 7 8 6] [1 0 3 4 2 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]]"}],"value":"[:history [[1 2 3 4 0 5 6 7 8] [1 0 3 4 2 5 6 7 8] [0 1 3 4 2 5 6 7 8] [4 1 3 0 2 5 6 7 8] [4 1 3 6 2 5 0 7 8] [4 1 3 6 2 5 7 0 8] [4 1 3 6 0 5 7 2 8] [4 1 3 0 6 5 7 2 8] [0 1 3 4 6 5 7 2 8] [1 0 3 4 6 5 7 2 8] [1 3 0 4 6 5 7 2 8] [1 3 5 4 6 0 7 2 8] [1 3 5 4 0 6 7 2 8] [1 3 5 4 2 6 7 0 8] [1 3 5 4 2 6 7 8 0] [1 3 5 4 2 0 7 8 6] [1 3 0 4 2 5 7 8 6] [1 0 3 4 2 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 0 5 6 7 8] [1 0 3 4 2 5 6 7 8] [0 1 3 4 2 5 6 7 8] [4 1 3 0 2 5 6 7 8] [4 1 3 6 2 5 0 7 8] [4 1 3 6 2 5 7 0 8] [4 1 3 6 0 5 7 2 8] [4 1 3 0 6 5 7 2 8] [0 1 3 4 6 5 7 2 8] [1 0 3 4 6 5 7 2 8] [1 3 0 4 6 5 7 2 8] [1 3 5 4 6 0 7 2 8] [1 3 5 4 0 6 7 2 8] [1 3 5 4 2 6 7 0 8] [1 3 5 4 2 6 7 8 0] [1 3 5 4 2 0 7 8 6] [1 3 0 4 2 5 7 8 6] [1 0 3 4 2 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>210</span>","value":"210"}],"value":"[:seen 210]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>124</span>","value":"124"}],"value":"[:steps 124]"}],"value":"{:seen 210, :steps 124}"}],"value":"[{:history [[1 2 3 4 0 5 6 7 8] [1 0 3 4 2 5 6 7 8] [0 1 3 4 2 5 6 7 8] [4 1 3 0 2 5 6 7 8] [4 1 3 6 2 5 0 7 8] [4 1 3 6 2 5 7 0 8] [4 1 3 6 0 5 7 2 8] [4 1 3 0 6 5 7 2 8] [0 1 3 4 6 5 7 2 8] [1 0 3 4 6 5 7 2 8] [1 3 0 4 6 5 7 2 8] [1 3 5 4 6 0 7 2 8] [1 3 5 4 0 6 7 2 8] [1 3 5 4 2 6 7 0 8] [1 3 5 4 2 6 7 8 0] [1 3 5 4 2 0 7 8 6] [1 3 0 4 2 5 7 8 6] [1 0 3 4 2 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 210, :steps 124}]"}
;; <=
;; **
;;; We can see that this finds a solution more efficiently, although in this case it finds a longer solution.
;;;
;;; This can succeed in cases that would fail with breadth-first search.
;; **
;; @@
(search eight-puzzle-solution
[0 1 2 3 4 5 6 7 8]
best-10-combiner
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 1 2 3 4 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[3 1 2 0 4 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[3 1 2 4 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[3 0 2 4 1 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 3 2 4 1 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 3 2 0 1 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 3 2 1 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 3 2 1 5 0 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 3 0 1 5 2 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 0 3 1 5 2 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 5 3 1 0 2 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 5 3 1 7 2 6 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 5 3 1 7 2 0 6 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[4 5 3 0 7 2 1 6 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 5 3 4 7 2 1 6 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 0 3 4 7 2 1 6 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 7 3 4 0 2 1 6 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 7 3 4 6 2 1 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[5 7 3 4 6 2 1 8 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[5 7 3 4 6 0 1 8 2]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[5 7 3 4 0 6 1 8 2]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[5 0 3 4 7 6 1 8 2]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[5 3 0 4 7 6 1 8 2]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"}],"value":"[5 3 6 4 7 0 1 8 2]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[5 3 6 4 7 2 1 8 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 3 6 4 7 2 1 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 3 6 4 0 2 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 3 6 4 2 0 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 3 0 4 2 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 0 3 4 2 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 2 3 4 0 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[5 2 3 0 4 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 2 3 5 4 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 0 3 5 4 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 4 3 5 0 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 4 3 0 5 6 1 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 4 3 1 5 6 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 4 3 1 5 6 7 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 4 3 1 0 6 7 5 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[2 0 3 1 4 6 7 5 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 2 3 1 4 6 7 5 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 0 4 6 7 5 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 0 6 7 5 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[0 1 2 3 4 5 6 7 8] [3 1 2 0 4 5 6 7 8] [3 1 2 4 0 5 6 7 8] [3 0 2 4 1 5 6 7 8] [0 3 2 4 1 5 6 7 8] [4 3 2 0 1 5 6 7 8] [4 3 2 1 0 5 6 7 8] [4 3 2 1 5 0 6 7 8] [4 3 0 1 5 2 6 7 8] [4 0 3 1 5 2 6 7 8] [4 5 3 1 0 2 6 7 8] [4 5 3 1 7 2 6 0 8] [4 5 3 1 7 2 0 6 8] [4 5 3 0 7 2 1 6 8] [0 5 3 4 7 2 1 6 8] [5 0 3 4 7 2 1 6 8] [5 7 3 4 0 2 1 6 8] [5 7 3 4 6 2 1 0 8] [5 7 3 4 6 2 1 8 0] [5 7 3 4 6 0 1 8 2] [5 7 3 4 0 6 1 8 2] [5 0 3 4 7 6 1 8 2] [5 3 0 4 7 6 1 8 2] [5 3 6 4 7 0 1 8 2] [5 3 6 4 7 2 1 8 0] [5 3 6 4 7 2 1 0 8] [5 3 6 4 0 2 1 7 8] [5 3 6 4 2 0 1 7 8] [5 3 0 4 2 6 1 7 8] [5 0 3 4 2 6 1 7 8] [5 2 3 4 0 6 1 7 8] [5 2 3 0 4 6 1 7 8] [0 2 3 5 4 6 1 7 8] [2 0 3 5 4 6 1 7 8] [2 4 3 5 0 6 1 7 8] [2 4 3 0 5 6 1 7 8] [2 4 3 1 5 6 0 7 8] [2 4 3 1 5 6 7 0 8] [2 4 3 1 0 6 7 5 8] [2 0 3 1 4 6 7 5 8] [0 2 3 1 4 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[0 1 2 3 4 5 6 7 8] [3 1 2 0 4 5 6 7 8] [3 1 2 4 0 5 6 7 8] [3 0 2 4 1 5 6 7 8] [0 3 2 4 1 5 6 7 8] [4 3 2 0 1 5 6 7 8] [4 3 2 1 0 5 6 7 8] [4 3 2 1 5 0 6 7 8] [4 3 0 1 5 2 6 7 8] [4 0 3 1 5 2 6 7 8] [4 5 3 1 0 2 6 7 8] [4 5 3 1 7 2 6 0 8] [4 5 3 1 7 2 0 6 8] [4 5 3 0 7 2 1 6 8] [0 5 3 4 7 2 1 6 8] [5 0 3 4 7 2 1 6 8] [5 7 3 4 0 2 1 6 8] [5 7 3 4 6 2 1 0 8] [5 7 3 4 6 2 1 8 0] [5 7 3 4 6 0 1 8 2] [5 7 3 4 0 6 1 8 2] [5 0 3 4 7 6 1 8 2] [5 3 0 4 7 6 1 8 2] [5 3 6 4 7 0 1 8 2] [5 3 6 4 7 2 1 8 0] [5 3 6 4 7 2 1 0 8] [5 3 6 4 0 2 1 7 8] [5 3 6 4 2 0 1 7 8] [5 3 0 4 2 6 1 7 8] [5 0 3 4 2 6 1 7 8] [5 2 3 4 0 6 1 7 8] [5 2 3 0 4 6 1 7 8] [0 2 3 5 4 6 1 7 8] [2 0 3 5 4 6 1 7 8] [2 4 3 5 0 6 1 7 8] [2 4 3 0 5 6 1 7 8] [2 4 3 1 5 6 0 7 8] [2 4 3 1 5 6 7 0 8] [2 4 3 1 0 6 7 5 8] [2 0 3 1 4 6 7 5 8] [0 2 3 1 4 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[0 1 2 3 4 5 6 7 8] [3 1 2 0 4 5 6 7 8] [3 1 2 4 0 5 6 7 8] [3 0 2 4 1 5 6 7 8] [0 3 2 4 1 5 6 7 8] [4 3 2 0 1 5 6 7 8] [4 3 2 1 0 5 6 7 8] [4 3 2 1 5 0 6 7 8] [4 3 0 1 5 2 6 7 8] [4 0 3 1 5 2 6 7 8] [4 5 3 1 0 2 6 7 8] [4 5 3 1 7 2 6 0 8] [4 5 3 1 7 2 0 6 8] [4 5 3 0 7 2 1 6 8] [0 5 3 4 7 2 1 6 8] [5 0 3 4 7 2 1 6 8] [5 7 3 4 0 2 1 6 8] [5 7 3 4 6 2 1 0 8] [5 7 3 4 6 2 1 8 0] [5 7 3 4 6 0 1 8 2] [5 7 3 4 0 6 1 8 2] [5 0 3 4 7 6 1 8 2] [5 3 0 4 7 6 1 8 2] [5 3 6 4 7 0 1 8 2] [5 3 6 4 7 2 1 8 0] [5 3 6 4 7 2 1 0 8] [5 3 6 4 0 2 1 7 8] [5 3 6 4 2 0 1 7 8] [5 3 0 4 2 6 1 7 8] [5 0 3 4 2 6 1 7 8] [5 2 3 4 0 6 1 7 8] [5 2 3 0 4 6 1 7 8] [0 2 3 5 4 6 1 7 8] [2 0 3 5 4 6 1 7 8] [2 4 3 5 0 6 1 7 8] [2 4 3 0 5 6 1 7 8] [2 4 3 1 5 6 0 7 8] [2 4 3 1 5 6 7 0 8] [2 4 3 1 0 6 7 5 8] [2 0 3 1 4 6 7 5 8] [0 2 3 1 4 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>738</span>","value":"738"}],"value":"[:seen 738]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>440</span>","value":"440"}],"value":"[:steps 440]"}],"value":"{:seen 738, :steps 440}"}],"value":"[{:history [[0 1 2 3 4 5 6 7 8] [3 1 2 0 4 5 6 7 8] [3 1 2 4 0 5 6 7 8] [3 0 2 4 1 5 6 7 8] [0 3 2 4 1 5 6 7 8] [4 3 2 0 1 5 6 7 8] [4 3 2 1 0 5 6 7 8] [4 3 2 1 5 0 6 7 8] [4 3 0 1 5 2 6 7 8] [4 0 3 1 5 2 6 7 8] [4 5 3 1 0 2 6 7 8] [4 5 3 1 7 2 6 0 8] [4 5 3 1 7 2 0 6 8] [4 5 3 0 7 2 1 6 8] [0 5 3 4 7 2 1 6 8] [5 0 3 4 7 2 1 6 8] [5 7 3 4 0 2 1 6 8] [5 7 3 4 6 2 1 0 8] [5 7 3 4 6 2 1 8 0] [5 7 3 4 6 0 1 8 2] [5 7 3 4 0 6 1 8 2] [5 0 3 4 7 6 1 8 2] [5 3 0 4 7 6 1 8 2] [5 3 6 4 7 0 1 8 2] [5 3 6 4 7 2 1 8 0] [5 3 6 4 7 2 1 0 8] [5 3 6 4 0 2 1 7 8] [5 3 6 4 2 0 1 7 8] [5 3 0 4 2 6 1 7 8] [5 0 3 4 2 6 1 7 8] [5 2 3 4 0 6 1 7 8] [5 2 3 0 4 6 1 7 8] [0 2 3 5 4 6 1 7 8] [2 0 3 5 4 6 1 7 8] [2 4 3 5 0 6 1 7 8] [2 4 3 0 5 6 1 7 8] [2 4 3 1 5 6 0 7 8] [2 4 3 1 5 6 7 0 8] [2 4 3 1 0 6 7 5 8] [2 0 3 1 4 6 7 5 8] [0 2 3 1 4 6 7 5 8] [1 2 3 0 4 6 7 5 8] [1 2 3 4 0 6 7 5 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 738, :steps 440}]"}
;; <=
;; **
;;; If we want to ensure that we find an optimal solution (shortest number of moves), then we can do so by eliminating the beam width of 10, and if we always use a heuristic function that is "admissible," which means it that will never overestimate the true distance. The Manhattan distance heuristic can be proven to be admissible.
;; **
;; @@
(defn best-combiner
[new-nodes old-nodes]
(sort #(< (+ (count (:history %1))
(solution-distance (:contents %1)))
(+ (count (:history %2))
(solution-distance (:contents %2))))
(concat new-nodes old-nodes)))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/best-combiner</span>","value":"#'search.core/best-combiner"}
;; <=
;; @@
(search eight-puzzle-solution
[1 2 3 4 0 5 6 7 8]
best-combiner
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 0 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 8 6 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 6 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 0 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 0 5 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 0 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 6 8 4 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 5 6 8 4 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 6 0 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 0 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 0 5 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>196</span>","value":"196"}],"value":"[:seen 196]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>116</span>","value":"116"}],"value":"[:steps 116]"}],"value":"{:seen 196, :steps 116}"}],"value":"[{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 196, :steps 116}]"}
;; <=
;; **
;;; An additional efficiency enhancement is to keep track of computed solution distances, so that they never have to be recomputed after they are computed the first time. This is easy to accomplish in Clojure using "memoization."
;; **
;; @@
(def solution-distance (memoize solution-distance))
;; @@
;; =>
;;; {"type":"html","content":"<span class='clj-var'>#&#x27;search.core/solution-distance</span>","value":"#'search.core/solution-distance"}
;; <=
;; @@
(search eight-puzzle-solution
[1 2 3 4 0 5 6 7 8]
best-combiner
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 0 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 8 6 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 6 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 4 5 8 0 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 0 5 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 0 8 4 6 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"}],"value":"[1 2 3 5 6 8 4 0 7]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 5 6 8 4 7 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 6 0 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 5 0 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 0 5 6 4 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 2 3 4 5 6 7 0 8]"}],"value":"[[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]"}],"value":"[:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>196</span>","value":"196"}],"value":"[:seen 196]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>116</span>","value":"116"}],"value":"[:steps 116]"}],"value":"{:seen 196, :steps 116}"}],"value":"[{:history [[1 2 3 4 0 5 6 7 8] [1 2 3 4 5 0 6 7 8] [1 2 3 4 5 8 6 7 0] [1 2 3 4 5 8 6 0 7] [1 2 3 4 5 8 0 6 7] [1 2 3 0 5 8 4 6 7] [1 2 3 5 0 8 4 6 7] [1 2 3 5 6 8 4 0 7] [1 2 3 5 6 8 4 7 0] [1 2 3 5 6 0 4 7 8] [1 2 3 5 0 6 4 7 8] [1 2 3 0 5 6 4 7 8] [1 2 3 4 5 6 0 7 8] [1 2 3 4 5 6 7 0 8]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 196, :steps 116}]"}
;; <=
;; **
;;; Now we can solve much harder boards.
;; **
;; @@
(search eight-puzzle-solution
[0 1 2 3 4 5 6 7 8]
best-combiner
eight-puzzle-moves)
;; @@
;; =>
;;; {"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:history</span>","value":":history"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[0 1 2 3 4 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 0 2 3 4 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 4 2 3 0 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 4 2 0 3 5 6 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 4 2 6 3 5 0 7 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"}],"value":"[1 4 2 6 3 5 7 0 8]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 4 2 6 3 5 7 8 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 6 3 0 7 8 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 6 0 3 7 8 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 0 6 3 7 8 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 7 6 3 0 8 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 7 6 3 8 0 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 4 2 7 0 3 8 6 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 0 2 7 4 3 8 6 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 2 0 7 4 3 8 6 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"}],"value":"[1 2 3 7 4 0 8 6 5]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 7 4 5 8 6 0]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 7 4 5 8 0 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 7 4 5 0 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 0 4 5 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 4 0 5 7 8 6]"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"}],"value":"[1 2 3 4 5 0 7 8 6]"}],"value":"[[0 1 2 3 4 5 6 7 8] [1 0 2 3 4 5 6 7 8] [1 4 2 3 0 5 6 7 8] [1 4 2 0 3 5 6 7 8] [1 4 2 6 3 5 0 7 8] [1 4 2 6 3 5 7 0 8] [1 4 2 6 3 5 7 8 0] [1 4 2 6 3 0 7 8 5] [1 4 2 6 0 3 7 8 5] [1 4 2 0 6 3 7 8 5] [1 4 2 7 6 3 0 8 5] [1 4 2 7 6 3 8 0 5] [1 4 2 7 0 3 8 6 5] [1 0 2 7 4 3 8 6 5] [1 2 0 7 4 3 8 6 5] [1 2 3 7 4 0 8 6 5] [1 2 3 7 4 5 8 6 0] [1 2 3 7 4 5 8 0 6] [1 2 3 7 4 5 0 8 6] [1 2 3 0 4 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]]"}],"value":"[:history [[0 1 2 3 4 5 6 7 8] [1 0 2 3 4 5 6 7 8] [1 4 2 3 0 5 6 7 8] [1 4 2 0 3 5 6 7 8] [1 4 2 6 3 5 0 7 8] [1 4 2 6 3 5 7 0 8] [1 4 2 6 3 5 7 8 0] [1 4 2 6 3 0 7 8 5] [1 4 2 6 0 3 7 8 5] [1 4 2 0 6 3 7 8 5] [1 4 2 7 6 3 0 8 5] [1 4 2 7 6 3 8 0 5] [1 4 2 7 0 3 8 6 5] [1 0 2 7 4 3 8 6 5] [1 2 0 7 4 3 8 6 5] [1 2 3 7 4 0 8 6 5] [1 2 3 7 4 5 8 6 0] [1 2 3 7 4 5 8 0 6] [1 2 3 7 4 5 0 8 6] [1 2 3 0 4 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]]]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:contents</span>","value":":contents"},{"type":"list-like","open":"<span class='clj-vector'>[</span>","close":"<span class='clj-vector'>]</span>","separator":" ","items":[{"type":"html","content":"<span class='clj-long'>1</span>","value":"1"},{"type":"html","content":"<span class='clj-long'>2</span>","value":"2"},{"type":"html","content":"<span class='clj-long'>3</span>","value":"3"},{"type":"html","content":"<span class='clj-long'>4</span>","value":"4"},{"type":"html","content":"<span class='clj-long'>5</span>","value":"5"},{"type":"html","content":"<span class='clj-long'>6</span>","value":"6"},{"type":"html","content":"<span class='clj-long'>7</span>","value":"7"},{"type":"html","content":"<span class='clj-long'>8</span>","value":"8"},{"type":"html","content":"<span class='clj-long'>0</span>","value":"0"}],"value":"[1 2 3 4 5 6 7 8 0]"}],"value":"[:contents [1 2 3 4 5 6 7 8 0]]"}],"value":"{:history [[0 1 2 3 4 5 6 7 8] [1 0 2 3 4 5 6 7 8] [1 4 2 3 0 5 6 7 8] [1 4 2 0 3 5 6 7 8] [1 4 2 6 3 5 0 7 8] [1 4 2 6 3 5 7 0 8] [1 4 2 6 3 5 7 8 0] [1 4 2 6 3 0 7 8 5] [1 4 2 6 0 3 7 8 5] [1 4 2 0 6 3 7 8 5] [1 4 2 7 6 3 0 8 5] [1 4 2 7 6 3 8 0 5] [1 4 2 7 0 3 8 6 5] [1 0 2 7 4 3 8 6 5] [1 2 0 7 4 3 8 6 5] [1 2 3 7 4 0 8 6 5] [1 2 3 7 4 5 8 6 0] [1 2 3 7 4 5 8 0 6] [1 2 3 7 4 5 0 8 6] [1 2 3 0 4 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]], :contents [1 2 3 4 5 6 7 8 0]}"},{"type":"list-like","open":"<span class='clj-map'>{</span>","close":"<span class='clj-map'>}</span>","separator":", ","items":[{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:seen</span>","value":":seen"},{"type":"html","content":"<span class='clj-unkown'>1494</span>","value":"1494"}],"value":"[:seen 1494]"},{"type":"list-like","open":"","close":"","separator":" ","items":[{"type":"html","content":"<span class='clj-keyword'>:steps</span>","value":":steps"},{"type":"html","content":"<span class='clj-long'>925</span>","value":"925"}],"value":"[:steps 925]"}],"value":"{:seen 1494, :steps 925}"}],"value":"[{:history [[0 1 2 3 4 5 6 7 8] [1 0 2 3 4 5 6 7 8] [1 4 2 3 0 5 6 7 8] [1 4 2 0 3 5 6 7 8] [1 4 2 6 3 5 0 7 8] [1 4 2 6 3 5 7 0 8] [1 4 2 6 3 5 7 8 0] [1 4 2 6 3 0 7 8 5] [1 4 2 6 0 3 7 8 5] [1 4 2 0 6 3 7 8 5] [1 4 2 7 6 3 0 8 5] [1 4 2 7 6 3 8 0 5] [1 4 2 7 0 3 8 6 5] [1 0 2 7 4 3 8 6 5] [1 2 0 7 4 3 8 6 5] [1 2 3 7 4 0 8 6 5] [1 2 3 7 4 5 8 6 0] [1 2 3 7 4 5 8 0 6] [1 2 3 7 4 5 0 8 6] [1 2 3 0 4 5 7 8 6] [1 2 3 4 0 5 7 8 6] [1 2 3 4 5 0 7 8 6]], :contents [1 2 3 4 5 6 7 8 0]} {:seen 1494, :steps 925}]"}
;; <=
;; **
;;; One other source of inefficiency here is that we sort the whole frontier at each step, when all we really need to do is to move the single best state to the front of the sequence. This would run a little faster if we didn't do the unnecessary sortng, but the gains from that kind of optimization probably won't be as significant as the gains that we get from improving the search strategy.
;;;
;;; If you want to experiment with this search code in Gorilla REPL, then you may run into one of its weaknesses as a development environment: There's no good way to interrupt a long-running process. If you want to kill a long-running process, you pretty much have to kill and restart your gorilla process, and then reload and re-evaluate your worksheet.
;;;
;;; So if you're working in Gorilla REPL but find yourself wanting to start/interrupt long searches, then you may want to run your code from the command line. One way to do this is to create a project with `lein new app mysearch`. Then put your code beneath the namespace declaration in `mysearch/src/mysearch/core.clj`, and your top-level call, which performs your search, in the definition of `-main`. Once you've done this, you can still type `lein gorilla` at the command line and use Gorilla REPL to edit your code. But at any point you can also run it, not in the browser, but from a second command line. At the second command line, just navigate into the `mysearch` directory and type `lein run`. You can interrupt a search with `control-c`, but the Gorilla REPL process will not be disturbed.
;; **
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment