Reputation: 21
I managed to create a pair of numbers with code
(defn dart-throwing []
[(- (* 2 (rand-int 2)) 1) (- (* 2 (rand-int 2)) 1)])
(def onetrial (dart-throwing))
But I do not know how to create my win condition which would be x^2 + y^2 < 1
I tried writing
(defn won? [x y]
(< (+ (* x x) (* y y)) 1))
(won? onetrial)
I expected it to check the pair []
from dart-throwing and check if it was less than 1 giving a true or false
I would appreciate it if I had some help, thank you
Upvotes: 0
Views: 106
Reputation: 17859
as far as i can see, you've got an incorrect throwing implementation, returning components -1 | 1
instead of -1 | 0 | 1
.
what i would propose, is something like this:
(defn rand-axis [] (dec (rand-int 3)))
user> (repeatedly 10 rand-axis)
;;=> (-1 -1 0 -1 0 -1 -1 0 1 -1)
then you just use it in an attempt function:
(defn attempt [] [(rand-axis) (rand-axis)])
and the won?
seems to be like the following:
(defn won? [[x y]] (zero? (+ (* x x) (* y y))))
check it:
user> (doseq [att (repeatedly 10 attempt)]
(println (str "throw:\t" att "\twon?:\t" (won? att))))
;; throw: [1 -1] won?: false
;; throw: [-1 1] won?: false
;; throw: [1 -1] won?: false
;; throw: [0 1] won?: false
;; throw: [1 1] won?: false
;; throw: [-1 -1] won?: false
;; throw: [0 1] won?: false
;; throw: [-1 1] won?: false
;; throw: [0 0] won?: true
;; throw: [-1 0] won?: false
moreover, since the only winning situation is [0 0]
, won?
counld be like this:
(defn won? [pair] (= [0 0] pair))
or like this:
(defn won? [[a b]] (= 0 a b))
or even like this:
(def won? (comp boolean #{[0 0]}))
Upvotes: 0
Reputation: 9950
Your code does the same like:
(defn dart-throwing []
[(rand-nth [-1 1])
(rand-nth [-1 1])
(def onetrial (dart-throwing))
rand-nth
chooses deliberately from the given collection - in this case -1
and 1
.
And here is the problem: -1 squared is 1 - so (+ (* x x) (* y y))
will never be <
than 1.
So: What is the point of the won?
function?
Or shouldn't dart-throwing return some float between -1 and 1? a selection from the range? In this case rand-int
is wrong. It must be then rand
.
so, instead of (- (* 2 (rand-int 2)) 1)
it should be then (- (* 2 (rand)) 1)
. However, rand
excludes the upper limit - in this case 1
. One could send the upper limit to 1 + Float/MIN_VALUE
to include 1. Or one keeps it but randomly choose between -1 and 1 and multiply them with the result - then one would get 1 included ... - but it wouldn't be a even distribution ...
Upvotes: 0
Reputation: 1306
Your won?
function expects two arguments, an x
and a y
. Your onetrial
is a vector of two elements, but it is a single argument here.
You have a couple of options:
You can use apply to 'spread' the vector into the argument list.
(apply won? onetrial)
OR
You can rewrite won?
slightly using destructuring
(defn won? [[x y]]
(< (+ (* x x) (* y y)) 1))
Upvotes: 2