24 game: Difference between revisions
Content deleted Content added
Correction: the input is not an equation, but an arithmetic expression. An equation requires two sides joined by the = operator, which is explicitly disallowed. |
|||
Line 1,039: | Line 1,039: | ||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
<lang Clojure> |
<lang Clojure> |
||
(ns rosettacode.24game |
(ns rosettacode.24game |
||
; For printing lists, something that printf/format can't do AFAIK. |
|||
(:use [clojure.pprint :only (cl-format)])) |
|||
(defn gen-new-game-nums [amount] (repeatedly amount #(inc ( rand-int 9)))) |
|||
(defn orderless-seq-eq? [seq1 seq2] (apply = (map frequencies (list seq1 seq2)))) |
|||
(defn valid-input? |
(defn valid-input? |
||
"A rudimentary check for prefix-notation form." |
|||
"checks whether the expression is somewhat valid prefix notation |
|||
[in] |
|||
(+ 1 2 3 4) (+ 3 (+ 4 5) 6) |
|||
(->> in flatten pr-str (re-find #"^\(([0-9-+*/] )+[0-9]?\)$"))) |
|||
this is done by making sure the only contents of the list are numbers operators and brackets |
|||
flatten gets rid of the brackets, so we just need to test for operators and integers after that" |
|||
(defn game-nums-&-input= |
|||
"Tests equality of the numbers entered with those generated by the game." |
|||
(if (re-find #"^\(([\d-+/*] )+\d?\)$" (pr-str (flatten user-input))) |
|||
⚫ | |||
true |
|||
(->> in flatten (filter integer?) set (= (set game-nums)))) |
|||
false)) |
|||
⚫ | |||
(defn game-numbers-and-user-input-same? |
|||
"input form: (+ 1 2 (+ 3 4)) |
|||
tests to see if the numbers the user entered are the same as the ones given to them by the game" |
|||
⚫ | |||
(orderless-seq-eq? game-nums (filter integer? (flatten user-input)))) |
|||
(def *start-prompt* |
|||
⚫ | |||
"Your numbers are ~A. Your goal is ~D. |
|||
⚫ | |||
Use the numbers provided and the ops +,-,*,/ to reach ~:*~D. |
|||
(defn game-start [goal game-numbers] (do |
|||
Your input should be prefix notation: (- (+ 9 8 8) 1) or (* 3 (/ 2 3) 6). |
|||
(println "Your numbers are " game-numbers) |
|||
'q[enter]' to quit.") |
|||
(println "Your goal is " goal) |
|||
; ~A is for forms, ~D is for decimal integers, and ~:* jumps 1 back in the arguments |
|||
(println "Use the numbers and +*-/ to reach your goal\n") |
|||
(println "'q' to Quit\n"))) |
|||
(defn play-game |
(defn play-game |
||
⚫ | |||
"typing in 'q' quits. |
|||
([goal] (play-game goal (repeatedly 4 #(inc (rand-int 9))))) |
|||
⚫ | |||
⚫ | |||
(cl-format true *start-prompt* goal gns) |
|||
([goal] (play-game goal (gen-new-game-nums 4))) |
|||
(let [input (read-line) |
|||
⚫ | |||
read (read-string input)] |
|||
(game-start goal game-numbers) |
|||
(if (and (valid-input? read) |
|||
(game-nums-&-input= gns read) |
|||
( |
(try (= goal (eval input-read)) ; yes, eval is our friend |
||
⚫ | |||
(game-numbers-and-user-input-same? game-numbers input-as-code) |
|||
⚫ | |||
⚫ | |||
( |
(when (not= input "q") |
||
(println *luser*) |
|||
(recur goal gns)))))) |
|||
</lang> |
</lang> |
||