Skip to content

Instantly share code, notes, and snippets.

@ekoontz
Last active March 5, 2021 20:53
Show Gist options
  • Select an option

  • Save ekoontz/6bf9b05d33601e67fceb94dc17d12ef6 to your computer and use it in GitHub Desktop.

Select an option

Save ekoontz/6bf9b05d33601e67fceb94dc17d12ef6 to your computer and use it in GitHub Desktop.
;; 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