authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-03 00:30:41-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-03 00:30:41-07:00
logb453345554cf7a48061e0cb43a6e8b45641cb4c3
treee5a835a32d371db45be4092c741cd044770e2ae9
parent1abb4e59be4ceed603ec377d89b4b8ce831dbebe

add rand example that doesn't yet work


3 files changed, 110 insertions(+), 8 deletions(-)

example/guess_number/main.zig+7-7
...@@ -18,19 +18,19 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {...@@ -18,19 +18,19 @@ pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
18 return 1;18 return 1;
19 }19 }
2020
21 print_str("Seed: ");
22 print_u64(seed);
23 print_str("\n");
24
25 /*
26 var rand_state = rand_init(seed);21 var rand_state = rand_init(seed);
2722
28 const answer = rand_int(&rand_state, 0, 100) + 1;23 const answer = rand_u64(&rand_state, 0, 100) + 1;
2924
25 print_str("Answer: ");
26 print_u64(answer);
27 print_str("\n");
28
29 /*
30 while (true) {30 while (true) {
31 const line = readline("\nGuess a number between 1 and 100: ");31 const line = readline("\nGuess a number between 1 and 100: ");
3232
33 if (const guess ?= parse_number(line)) {33 if (const guess ?= parse_u64(line)) {
34 if (guess > answer) {34 if (guess > answer) {
35 print_str("Guess lower.\n");35 print_str("Guess lower.\n");
36 } else if (guess < answer) {36 } else if (guess < answer) {
example/rand/main.zig created+103
...@@ -0,0 +1,103 @@
1// Mersenne Twister
2const ARRAY_SIZE : u16 = 624;
3
4/// Use `rand_init` to initialize this state.
5pub struct Rand {
6 array: [u32; ARRAY_SIZE],
7 index: #typeof(ARRAY_SIZE),
8
9 /// Get 32 bits of randomness.
10 pub fn get_u32(r: &Rand) -> u32 {
11 if (r.index == 0) {
12 r.generate_numbers();
13 }
14
15 // temper the number
16 var y : u32 = r.array[r.index];
17 y ^= y >> 11;
18 y ^= (y >> 7) & 0x9d2c5680;
19 y ^= (y >> 15) & 0xefc60000;
20 y ^= y >> 18;
21
22 r.index = (r.index + 1) % ARRAY_SIZE;
23 return y;
24 }
25
26 /// Write `count` bytes of randomness into `buf`.
27 pub fn get_bytes(r: &Rand, buf: &u8, count: usize) {
28 var bytes_left = r.get_bytes_aligned(buf, buf, count);
29 if (bytes_left > 0) {
30 var rand_val_array : [u8; #sizeof(u32)];
31 *(rand_val_array.ptr as &u32) = r.get();
32 while (bytes_left > 0) {
33 buf[count - bytes_left] = rand_val_array[#sizeof(u32) - bytes_left];
34 bytes_left -= 1;
35 }
36 }
37 }
38
39 /// Get a random unsigned integer with even distribution between `start`
40 /// inclusive and `end` exclusive.
41 pub fn range_u64(r: &Rand, start: u64, end: u64) -> u64 {
42 const range = end - start;
43 const leftover = #max_int(u64) % range;
44 const upper_bound = #max_int(u64) - leftover;
45 var rand_val_array : [u8; #sizeof(u64)];
46
47 while (true) {
48 r.get_bytes_aligned(r, rand_val_array.ptr, rand_val_array.len);
49 const rand_val = *(rand_val_array.ptr as &u64);
50 if (rand_val < upper_bound) {
51 return start + (rand_val % range);
52 }
53 }
54 }
55
56 fn generate_numbers(r: &Rand) {
57 var i : #typeof(ARRAY_SIZE) = 0;
58 while (i < ARRAY_SIZE) {
59 const y : u32 = (r.array[i] & 0x80000000) + (r.array[(i + 1) % ARRAY_SIZE] & 0x7fffffff);
60 const untempered : u32 = r.array[(i + 397) % ARRAY_SIZE] ^ (y >> 1);
61 r.array[i] = if ((y % 2) == 0) {
62 untempered
63 } else {
64 // y is odd
65 untempered ^ 0x9908b0df
66 };
67 i += 1;
68 }
69 }
70
71 // does not populate the remaining (count % 4) bytes
72 fn get_bytes_aligned(r: &Rand, buf: &u8, count: usize) -> usize {
73 var bytes_left = count;
74 var buf_ptr = buf;
75 while (bytes_left > 4) {
76 *(buf_ptr as &u32) = r.get();
77 bytes_left -= #sizeof(u32);
78 buf_ptr += #sizeof(u32);
79 }
80 return bytes_left;
81 }
82}
83
84/// Initialize random state with the given seed.
85pub fn rand_init(seed: u32) -> (out: Rand) {
86 out.index = 0;
87 out.array[0] = seed;
88 var i : #typeof(ARRAY_SIZE) = 1;
89 while (i < ARRAY_SIZE) {
90 const prev_value : u64 = out.array[i - 1];
91 out.array[i] = ((previous_value ^ (previous_value << 30)) * 0x6c078965 + i) as u32;
92 i += 1;
93 }
94}
95
96pub fn main(argc: isize, argv: &&u8, env: &&u8) -> i32 {
97 var rand = rand_init(13);
98 const answer = rand.range_u64(0, 100) + 1;
99 print_str("random number: ");
100 print_u64(answer);
101 print_str("\n");
102 return 0;
103}
std/std.zig-1
...@@ -90,4 +90,3 @@ fn buf_print_u64(out_buf: &u8, x: u64) -> usize {...@@ -90,4 +90,3 @@ fn buf_print_u64(out_buf: &u8, x: u64) -> usize {
9090
91 return len;91 return len;
92}92}
93