Last active
March 5, 2021 20:53
-
-
Save ekoontz/6bf9b05d33601e67fceb94dc17d12ef6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ;; Problem | |
| ;; | |
| ;; Given 4 numbers: [1 3 4 6] and 4 operators [+ - * /], | |
| ;; Find an expression: n1 o1 n2 o2 n3 o3 n4 where: | |
| ;; - n1,n2,n3,n4 is a permutation of those 4 numbers | |
| ;; - o2,o3,o4 each are a member of the operators. | |
| ;; - the result of that expression is 24. | |
| ;; | |
| ;; For example, in: | |
| ;; in the expression: 6 + 4 - 3 + 1 | |
| ;; n1 = 6, n2 = 4, n3 = 3 and n1 = 1 | |
| ;; o1 = +, o2 = -, o3 = +. | |
| ;; The result for this expression 8, so that's not the | |
| ;; correct solution. | |
| ;; | |
| ;; Solution | |
| (def numbers [1 3 4 6]) | |
| (def operators [+ - * /]) | |
| (defn permute | |
| "Return every sequence of the input numbers where | |
| - each number in the set appears exactly once | |
| - the length of each member is the same as the cardinality | |
| of the input numbers. | |
| So if you are given 4 numbers, there are 4 returned numbers for each | |
| returned sequence. | |
| e.g. given [1 2 3], return: | |
| [[1 2 3] | |
| [1 3 2] | |
| [2 1 3] | |
| [2 3 1] | |
| [3 1 2] | |
| [3 2 1]]" | |
| [numbers] | |
| (cond | |
| (= 1 (count numbers)) | |
| numbers | |
| (= 2 (count numbers)) | |
| [numbers (reverse numbers)] | |
| :else | |
| (mapcat (fn [x] | |
| (map (fn [permutation] | |
| (cons x permutation)) | |
| (permute | |
| (vec (remove #(= x %) | |
| (set numbers)))))) | |
| numbers))) | |
| (defn combo | |
| "Return every sequence of length _n_ where each member is in the set of the input _ops_. | |
| e.g. given: ({+,-},2), return: | |
| [[+ +] | |
| [+ -] | |
| [- +] | |
| [- -]]" | |
| [ops n] | |
| (cond | |
| (= n 1) | |
| (map (fn [op] | |
| [op]) | |
| ops) | |
| :else | |
| (mapcat (fn [op] | |
| (map (fn [op2] | |
| (cons op op2)) | |
| (combo ops (- n 1)))) | |
| ops))) | |
| (defn operate | |
| "apply 3 operations to 4 numbers in order they are given" | |
| [[n1 n2 n3 n4] [o1 o2 o3]] | |
| (try | |
| (o1 n1 | |
| (o2 n2 | |
| (o3 n3 | |
| n4))) | |
| (catch Exception e :failed))) | |
| (def num-sequences (permute numbers)) | |
| (def op-sequences (combo operators 3)) | |
| ;; find the permutations P of numbers and combinations of operations O | |
| ;; where (operate P O) = 24: | |
| (def the-answer-is | |
| (->> (mapcat (fn [n] | |
| (map (fn [o] | |
| {:operators o | |
| :numbers n | |
| :result (operate n o)}) | |
| op-sequences)) | |
| num-sequences) | |
| (filter #(= 24 (:result %))))) | |
| ;; the-answer-is: | |
| ;; a sequence with only one member: | |
| ;;{:operators | |
| ;; (#function[clojure.core//] | |
| ;; #function[clojure.core/-] | |
| ;; #function[clojure.core//]), | |
| ;; :numbers (6 1 3 4), | |
| ;; :result 24N} | |
| ;; | |
| ;; | |
| ;; that is: (/ 6 (- 1 (/ 3 4))) = 24 | |
| ;; | |
| ;; or in infix notation: | |
| ;; | |
| ;; 6 / (1 - (3/4)) = 24 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment