diff options
-rw-r--r-- | src/gleam/float.gleam | 84 | ||||
-rw-r--r-- | test/gleam/float_test.gleam | 30 | ||||
-rw-r--r-- | test/gleam/int_test.gleam | 10 |
3 files changed, 56 insertions, 68 deletions
diff --git a/src/gleam/float.gleam b/src/gleam/float.gleam index 87d232c..c9d367d 100644 --- a/src/gleam/float.gleam +++ b/src/gleam/float.gleam @@ -228,6 +228,13 @@ pub fn absolute_value(float: Float) -> Float { } } +/// Returns the absolute distance of the inputs as a positive Float +/// +pub fn distance(a: Float, b: Float) -> Float { + absolute_value(a) -. absolute_value(b) + |> absolute_value() +} + /// Returns the results of the base being raised to the power of the /// exponent, as a `Float`. /// @@ -344,62 +351,37 @@ if javascript { import gleam/io +/// Based on: +/// ```javascript +/// return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is exclusive +/// ``` +/// See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values> +/// pub fn random_between(boundary_a: Float, boundary_b: Float) -> Float { - // ```javascript - // return Math.random() * (max - min) + min; // The minimum is inclusive and the maximum is exclusive - // ``` - // See: <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values> - // - case boundary_a, boundary_b { - a, b if a <. 0.0 && b == 0.0 -> - //io.debug("-a, b=0") - random_uniform() *. a - a, b if a == 0.0 && b <. 0.0 -> - //io.debug("a=0, -b") - random_uniform() *. b - a, b if a <. 0.0 && b <. 0.0 && a <. b -> { - //io.debug("-a, -b, a < b") - let a1 = absolute_value(a) - let b1 = absolute_value(b) - random_uniform() *. { b1 -. a1 } +. b1 - |> negate() + let #(min, max) = case boundary_a, boundary_b { + a, b if a <=. b -> #(a, b) + a, b if a >. b -> #(b, a) + } + case min, max { + min, max if min >=. 0.0 && max >. 0.0 -> { + // io.debug("min >=. 0.0 && max >. 0.0 ") + let range = distance(min, max) + random_uniform() *. range +. min } - a, b if a <. 0.0 && b <. 0.0 && a >. b -> { - //io.debug("-a, -b, a > b") - let a1 = absolute_value(a) - let b1 = absolute_value(b) - random_uniform() *. { a1 -. b1 } +. a1 - |> negate() + min, max if min <. 0.0 && max <=. 0.0 -> { + // io.debug("min <. 0.0 && max <=. 0.0") + let range = distance(min, max) + random_uniform() *. range +. min } - a, b if a >=. 0.0 && a <. b -> - //io.debug("+a < +b") - random_uniform() *. { b -. a } +. a - a, b if a >=. 0.0 && a >. b -> - //io.debug("+a > +b") - random_uniform() *. { a -. b } +. b - a, b if a <. 0.0 && b >. 0.0 -> { - //io.debug("a < 0.0, b > 0.0") - let range = - absolute_value(a) -. absolute_value(b) - |> absolute_value() - let offset = - absolute_value(a) - |> negate() - random_uniform() *. range +. offset + min, max if min <. 0.0 && max >. 0.0 -> { + // io.debug("min <. 0.0 && max >. 0.0") + let range = distance(min, max) + random_uniform() *. range +. min } - a, b if a >. 0.0 && b <. 0.0 -> { - //io.debug("a > 0.0, b < 0.0") - let range = - absolute_value(a) -. absolute_value(b) - |> absolute_value() - let offset = - absolute_value(b) - |> negate() - random_uniform() *. range +. offset + min, _max if min == max -> { + io.debug("min == max") + min } - a, b if a == b -> - //io.debug("a == b noop") - a } } diff --git a/test/gleam/float_test.gleam b/test/gleam/float_test.gleam index 65878bf..e13112f 100644 --- a/test/gleam/float_test.gleam +++ b/test/gleam/float_test.gleam @@ -335,7 +335,12 @@ pub fn random_between_test() { |> fn(x) { x >=. 0.0 && x <. 1.0 } |> should.be_true + float.random_between(1.0, 0.0) + |> fn(x) { x >=. 0.0 && x <. 1.0 } + |> should.be_true + float.random_between(0.0, -1.0) + |> function.tap(io.debug) |> fn(x) { x >=. -1.0 && x <. 0.0 } |> should.be_true @@ -343,12 +348,20 @@ pub fn random_between_test() { |> fn(x) { x >=. -1.0 && x <. 0.0 } |> should.be_true - float.random_between(0.0, -2.0) - |> fn(x) { x >=. -2.0 && x <. 0.0 } + float.random_between(0.0, -10.0) + |> fn(x) { x >=. -10.0 && x <. 0.0 } + |> should.be_true + + float.random_between(-10.0, 0.0) + |> fn(x) { x >=. -10.0 && x <. 0.0 } |> should.be_true - float.random_between(-2.0, 0.0) - |> fn(x) { x >=. -2.0 && x <. 0.0 } + float.random_between(-10.0, 10.0) + |> fn(x) { x >=. -10.0 && x <. 10.0 } + |> should.be_true + + float.random_between(-10.0, 10.0) + |> fn(x) { x >=. -10.0 && x <. 10.0 } |> should.be_true } @@ -370,11 +383,14 @@ pub fn random_to_test() { |> fn(x) { x >=. 0.0 && x <. 1.0 } |> should.be_true - float.random_to(2.0) - |> fn(x) { x >=. 0.0 && x <. 2.0 } + float.random_to(10.0) + |> fn(x) { x >=. 0.0 && x <. 10.0 } |> should.be_true - } + float.random_to(-10.0) + |> fn(x) { x >=. -10.0 && x <. 0.0 } + |> should.be_true + } list.range(0, 100) |> iterator.from_list |> iterator.fold(Nil, one_random_to_test_set) diff --git a/test/gleam/int_test.gleam b/test/gleam/int_test.gleam index aeec7e7..017596a 100644 --- a/test/gleam/int_test.gleam +++ b/test/gleam/int_test.gleam @@ -323,20 +323,16 @@ pub fn random_between_test() { let one_random_between_test_set = fn(_acc, _e) { int.random_between(0, 0) |> should.equal(0) - int.random_between(-1, 0) |> list.contains([-1, 0], _) |> should.be_true - int.random_between(-1, 1) |> list.contains([-1, 0], _) |> should.be_true - int.random_between(-1, 2) |> list.contains([-1, 0, 1], _) |> should.be_true } - list.range(0, 100) |> iterator.from_list |> iterator.fold(Nil, one_random_between_test_set) @@ -346,28 +342,22 @@ pub fn random_to_test() { let one_random_to_test_set = fn(_acc, _e) { int.random_to(0) |> should.equal(0) - int.random_to(-1) |> list.contains([-1], _) |> should.be_true - int.random_to(1) |> list.contains([0], _) |> should.be_true - int.random_to(2) |> list.contains([0, 1], _) |> should.be_true - int.random_to(3) |> list.contains([0, 1, 2], _) |> should.be_true - int.random_to(4) |> list.contains([0, 1, 2, 3], _) |> should.be_true } - list.range(0, 100) |> iterator.from_list |> iterator.fold(Nil, one_random_to_test_set) |