Skip to content
This repository has been archived by the owner on Aug 14, 2022. It is now read-only.

Commit

Permalink
0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Delta456 authored Jun 25, 2020
1 parent affff27 commit a7e2eb3
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 99 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Build example
run: |
cd ./vlib/random/
v test random_test.v
v test tests/rand_test.v
macos:
runs-on: macos-latest
Expand All @@ -41,7 +41,7 @@ jobs:
- name: Build example
run: |
cd ./vlib/random/
v test random_test.v
v test tests/rand_test.v
windows-msvc:
runs-on: windows-latest
Expand All @@ -57,7 +57,7 @@ jobs:
with:
path: vlib/random
- name: Build V
run: .\make.bat -msvc
run: .\make.bat -msvc -skip-path
# Don't move applying V directory to PATH, to other steps
- name: Build example
run: .\v.exe test .\vlib\random\random_test.v
run: .\v.exe test .\vlib\random\tests\rand_test.v
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ fn bool() bool
// shuffle returns the new shuffled array
fn shuffle<T>(arr []T) []T
// sample returns the new k-sized array
// no_repetitions must be true when no repetitions are needed
// else it must be false
fn sample<T>(arr []T, k int) []T
// choose returns a random element from the array
fn choose<T>(arr []T) T
Expand Down
2 changes: 1 addition & 1 deletion examples/rand.v
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn main() {
println(random.bool())
println(random.choose<int>([2, 4, 6, 8, 9, 7]))
println(random.shuffle<int>([2, 4, 6, 8, 9, 7]))
println(random.sample<int>([2, 4, 6, 7, 12, 8], 4))
println(random.sample<int>([2, 4, 6, 7, 12, 8, 4 , 7, 5], 6, false))
println(random.numeric(5))
println(random.int_range(start: 5, stop: 15, step: 2))
println(random.float_range(start: 5.3, stop: 15.4, step: 2.0))
Expand Down
210 changes: 117 additions & 93 deletions rand.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,129 +5,153 @@ import math

// struct for `int_range()`
pub struct IntRange {
start int
stop int
step int = 1
start int
stop int
step int = 1
}

// struct for `float_range()`
pub struct FloatRange {
start f32
stop f32
step f32 = 1.0
start f32
stop f32
step f32 = 1.0
}

// uniform returns a random number between the range [a, b) or [a, b] depending on rounding
pub fn uniform(a, b f32) f32 {
return a + (b - a) * rand.f32()
return a + (b - a) * rand.f32()
}

// int_range returns a random int between the specified range
pub fn int_range(range IntRange) int {
if range.stop == 0 {
if range.start > 1 {
return rand.intn(range.start)
}
eprintln('random: empty range for int_range()')
exit(1)
}
width := range.stop - range.start
mut n := 0
if range.step == 1 {
if width > 0 {
return range.start + rand.intn(width)
}
eprintln('random: empty range for int_range($range.start, $range.stop, $width)')
exit(1)
}
if range.step > 0 {
n = (width + range.step - 1) / range.step
} else if range.step < 0 {
n = (width + range.step + 1) / range.step
} else {
eprintln('random: empty range provided')
exit(1)
}
return range.start + range.step * rand.intn(n)
if range.stop == 0 {
if range.start > 1 {
return rand.intn(range.start)
}
eprintln('random: empty range for int_range()')
exit(1)
}
width := range.stop - range.start
mut n := 0
if range.step == 1 {
if width > 0 {
return range.start + rand.intn(width)
}
eprintln('random: empty range for int_range($range.start, $range.stop, $width)')
exit(1)
}
if range.step > 0 {
n = (width + range.step - 1) / range.step
} else if range.step < 0 {
n = (width + range.step + 1) / range.step
} else {
eprintln('random.int_range: empty range provided')
exit(1)
}
return range.start + range.step * rand.intn(n)
}

// float_range returns a random float upon the given range
pub fn float_range(range FloatRange) f32 {
if range.stop == 0 {
if range.start >= 1 {
return rand.f32n(range.start)
}
eprintln('random: empty range for float_range()')
exit(1)
}
width := range.stop - range.start
mut n := f32(0)
if range.step == 1 {
if width > 0 {
return range.start + rand.f32n(width)
}
eprintln('random: empty range for float_range($range.start, $range.stop, $width)')
exit(1)
}
if range.step > 0 {
n = (width + range.step - 1) / range.step
} else if range.step < 0 {
n = (width + range.step + 1) / range.step
} else {
eprintln('random: empty range provided')
exit(1)
}
return range.start + range.step * rand.f32n(n)
if range.stop == 0 {
if range.start >= 1 {
return rand.f32n(range.start)
}
eprintln('random: empty range for float_range()')
exit(1)
}
width := range.stop - range.start
mut n := f32(0)
if range.step == 1 {
if width > 0 {
return range.start + rand.f32n(width)
}
eprintln('random: empty range for float_range($range.start, $range.stop, $width)')
exit(1)
}
if range.step > 0 {
n = (width + range.step - 1) / range.step
} else if range.step < 0 {
n = (width + range.step + 1) / range.step
} else {
eprintln('random.float_range: empty range provided')
exit(1)
}
mut result := range.start + range.step * rand.f32n(n)
// this happens in worst cases
if result > range.stop && range.step > 0 {
for result > range.stop {
result = range.start + range.step * rand.f32n(n)
}
}
return result
}

// numeric returns a number with n digits long
pub fn numeric(n int) int {
if n <= 0 {
eprintln('numeric: number must be greater than one')
exit(1)
}
return rand.int() % int(math.pow(10, n))
if n <= 0 {
eprintln('random.numeric: number must be greater than one')
exit(1)
}
return rand.int() % int(math.pow(10, n))
}

// bool returns a random bool
pub fn bool() bool {
b := [true, false]
return b[rand.intn(b.len)]
b := [true, false]
return b[rand.intn(b.len)]
}

// shuffle returns the new shuffled array. If more_randomize is true
// then more random array will be produced which slowers the function.
pub fn shuffle<T>(arr []T, more_randomize bool) []T {
mut clone := arr.clone()
for i in range(0, arr.len).reverse() {
j := rand.intn(i + 1)
temp := clone[j]
clone[j] = clone[i]
clone[i] = temp
if more_randomize {
rand.seed([u32(j), 0])
}
}
return clone
// shuffle returns the new shuffled array.
pub fn shuffle<T>(arr []T) []T {
mut clone := arr.clone()
for i in range(0, arr.len).reverse() {
j := rand.intn(i + 1)
temp := clone[j]
clone[j] = clone[i]
clone[i] = temp
}
return clone
}

pub fn sample<T>(arr []T, k int, more_randomize bool) []T {
mut a := []T{}
if k <= 0 {
eprintln('random.sample: number should be greater than 0')
exit(1)
}
for i in range(0, k) {
j := rand.intn(arr.len)
a << arr[j]
if more_randomize {
rand.seed([u32(arr.len), 0])
}
}
return a
// sample returns the new k-sized array
// no_repetitions must be true when no repetitions are needed
// else it must be false
pub fn sample<T>(arr []T, k int, no_repetitions bool) []T {
mut sub_array := []T{}
if k <= 0 {
eprintln('random.sample: number should be greater than 0')
exit(1)
}
if k == arr.len {
eprintln('random.sample: k and length of array must not be equal')
exit(1)
}
for _ in range(0, k) {
j := rand.intn(arr.len)
if no_repetitions {
if arr[j] !in sub_array {
sub_array << arr[j]
}
} else {
sub_array << arr[j]
}
}
// this can happen in the worst cases
if sub_array.len != k {
for sub_array.len != k {
len := rand.intn(arr.len)
if no_repetitions {
if arr[len] !in sub_array {
sub_array << arr[len]
}
}
}
}
return sub_array
}

// choose returns a random element from the array
pub fn choose<T>(arr []T) T {
return arr[rand.intn(arr.len)]
return arr[rand.intn(arr.len)]
}
81 changes: 81 additions & 0 deletions tests/rand_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import random
import time
import rand

fn init() {
rand.seed([u32(time.now().unix), 0])
}

fn test_bool() {
for i := 0; i < 10; i++ {
b := random.bool()
assert b == true || b == false
}
}

fn test_numeric() {
for i := 0; i < 10; i++ {
b := random.numeric(5)
//println(b.str().len)
assert b.str().len == 5 || b.str().len == 6 || b.str().len == 4
}
}

fn test_int_range() {
for i := 0; i < 10; i++ {
b := random.int_range(start: 5, stop: 15, step: 2)
assert b >= 5
assert b < 15
}

for i := 0; i < 10; i++ {
b := random.int_range(start: 15, stop: 1, step:-1)
assert b <= 15
assert b > 1
}
}

fn test_float_range() {
for i := 0; i < 10; i++ {
b := random.float_range(start: 5.3, stop: 15.4, step: 2.0)
assert b >= f32(5.3)
assert b < f32(15.4)
}

for i := 0; i < 10; i++ {
b := random.float_range(start: 15.0, stop: 5.3, step: -1)
assert b <= f32(15.0)
assert b > f32(5.3)
}
}

fn test_choose() {
for i := 0; i < 10; i++ {
arr_int := [2, 5, 7, 8, 9, 10, 13]
arr_u64 := [u64(2), 37, 56, 79, 10]

assert random.choose<int>(arr_int) in arr_int
assert random.choose<u64>(arr_u64) in arr_u64
}
}

fn test_shuffle() {
for i := 0; i < 10; i++ {
arr_int := [2, 5, 7, 8, 9, 10, 13]
arr_u64 := [u64(2), 37, 56, 79, 10]

assert random.shuffle<int>(arr_int).len == arr_int.len
assert random.shuffle<u64>(arr_u64).len == arr_u64.len
}
}
/*
fn test_sample() {
for i := 0; i < 10; i++ {
arr_int := [2, 5, 7, 8, 9, 10, 13]
arr_u64 := [u64(2), 37, 56, 79, 10]
assert random.sample<int>(arr_int, 5, false).len == 5
assert random.sample<u64>(arr_u64, 6, true).len == 6
}
}
*/
2 changes: 1 addition & 1 deletion v.mod
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Module {
name: 'range'
author: 'Swastik Baranwal'
version: '0.0.1'
version: '0.0.2'
repo_url: 'https://github.com/Delta456/random'
vcs: 'git'
tags: ['random', 'python', 'vlang', 'variate']
Expand Down

0 comments on commit a7e2eb3

Please sign in to comment.