Skip to content

Commit 07fb00f

Browse files
chore: auto-sync new Rosetta Code examples
1 parent fb25f12 commit 07fb00f

21 files changed

Lines changed: 1183 additions & 5 deletions

examples/rosetta/100_prisoners.zc

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import "std/random.zc"
2+
import "locale.h"
3+
4+
let rng: Random;
5+
6+
fn shuffle(a: int*, len: usize) {
7+
for let i: usize = len - 1; i >= 1; --i {
8+
let j = rng.next_int_range(0, (int)i);
9+
if j != i {
10+
let t = a[i];
11+
a[i] = a[j];
12+
a[j] = t;
13+
}
14+
}
15+
}
16+
17+
fn do_trials(trials: int, np: int, strategy: string) {
18+
let pardoned = 0;
19+
for t in 0..trials {
20+
let drawers: [int; 100];
21+
for i in 0..100 { drawers[i] = i; }
22+
shuffle((int*)drawers, 100);
23+
let next_trial = false;
24+
for p in 0..np {
25+
let next_prisoner = false;
26+
if strcmp(strategy, "optimal") == 0 {
27+
let prev = p;
28+
for d in 0..50 {
29+
let curr = drawers[prev];
30+
if curr == p {
31+
next_prisoner = true;
32+
break;
33+
}
34+
prev = curr;
35+
}
36+
} else {
37+
let opened: [bool; 100];
38+
for d in 0..50 {
39+
let n: int;
40+
loop {
41+
n = rng.next_int_range(0, 99);
42+
if !opened[n] {
43+
opened[n] = true;
44+
break;
45+
}
46+
}
47+
if drawers[n] == p {
48+
next_prisoner = true;
49+
break;
50+
}
51+
}
52+
}
53+
if !next_prisoner {
54+
next_trial = true;
55+
break;
56+
}
57+
}
58+
if !next_trial { pardoned++; }
59+
}
60+
let rf = (f64)pardoned / (f64)trials * 100.0;
61+
println " strategy = {strategy:-7s} pardoned = {pardoned:'6d} relative frequency = {rf:5.2f}%\n";
62+
}
63+
64+
fn main() {
65+
rng = Random::new();
66+
setlocale(LC_NUMERIC, "");
67+
let trials = 100_000;
68+
let nps = [10, 100];
69+
let strategies = ["random", "optimal"];
70+
for np in nps {
71+
println "Results from {trials:'d} trials with {np} prisoners:\n";
72+
for i in 0..strategies.len { do_trials(trials, np, strategies[i]); }
73+
}
74+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
fn accumulator<T>(acc: T) -> fn(T) -> T {
2+
return fn(f: T) -> T {
3+
acc += f;
4+
return acc;
5+
}
6+
}
7+
8+
fn main() {
9+
// Example with f64s.
10+
let x = accumulator(1.0);
11+
x(5.0);
12+
accumulator(3.0);
13+
println "{x(2.3):g}";
14+
15+
// Example with ints.
16+
let y = accumulator(1);
17+
y(5);
18+
accumulator(3);
19+
println "{y(2)}";
20+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import "std/complex.zc"
2+
import "std/string.zc"
3+
4+
fn negate(c: Complex) -> Complex {
5+
return Complex{real: -c.real, imag: -c.imag};
6+
}
7+
8+
fn inverse(c: Complex) -> Complex {
9+
return Complex::new(1, 0) / c;
10+
}
11+
12+
fn conjugate(c: Complex) -> Complex {
13+
return Complex{real: c.real, imag: -c.imag};
14+
}
15+
16+
fn cstr(c: Complex) -> String {
17+
let rsign = c.real < 0 ? "-" : " ";
18+
let isign = c.imag < 0 ? "-" : "+";
19+
let s = "{rsign}{fabs(c.real):g} {isign} {fabs(c.imag):g}i";
20+
return String::from(s);
21+
}
22+
23+
fn main() {
24+
let x = Complex::new(1.0, 3.0);
25+
let y = Complex::new(5.0, 2.0);
26+
println "x = {cstr(x)}";
27+
println "y = {cstr(y)}";
28+
println "x + y = {cstr(x + y)}";
29+
println "x - y = {cstr(x - y)}";
30+
println "x * y = {cstr(x * y)}";
31+
println "x / y = {cstr(x / y)}";
32+
println "-x = {cstr(negate(x))}";
33+
println "1 / x = {cstr(inverse(x))}";
34+
println "x* = {cstr(conjugate(x))}";
35+
}
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
/* rat.zc */
2+
3+
import "std/string.zc"
4+
5+
fn gcd(x: i64, y: i64) -> i64 {
6+
while y {
7+
let t = y;
8+
y = x % y;
9+
x = t;
10+
}
11+
return labs(x);
12+
}
13+
14+
@derive(Copy)
15+
struct Rat {
16+
num: i64;
17+
den: i64;
18+
}
19+
20+
impl Rat {
21+
// Creates a new Rat struct in canonical form
22+
// i.e. n and d have no common factors and d > 0.
23+
// The Rat struct should not be created directly
24+
// unless you're certain it's already in such a form.
25+
fn new(n: i64, d: i64 = 1) -> Self {
26+
assert(d != 0, "Denominator must be non-zero.");
27+
if n == 0 {
28+
d = 1;
29+
} else if d < 0 {
30+
n = -n;
31+
d = -d;
32+
}
33+
if labs(n) != 1 && d > 1 {
34+
let g = gcd(n, d);
35+
if g > 1 {
36+
n /= g;
37+
d /= g;
38+
}
39+
}
40+
return Rat{num: n, den: d};
41+
}
42+
43+
fn neg(self) -> Rat {
44+
return Rat{num: -self.num, den: self.den};
45+
}
46+
47+
fn add(self, other: Rat) -> Rat {
48+
return Rat::new(
49+
self.num * other.den + self.den * other.num,
50+
self.den * other.den
51+
);
52+
}
53+
54+
fn sub(self, other: Rat) -> Rat {
55+
return *self + (-other);
56+
}
57+
58+
fn mul(self, other: Rat) -> Rat {
59+
return Rat::new(
60+
self.num * other.num,
61+
self.den * other.den
62+
);
63+
}
64+
65+
fn div(self, other: Rat) -> Rat {
66+
return Rat::new(
67+
self.num * other.den,
68+
self.den * other.num
69+
);
70+
}
71+
72+
fn trunc(self) -> Rat {
73+
return Rat{num: self.num / self.den, den: 1};
74+
}
75+
76+
fn ceil(self) -> Rat {
77+
if self.den == 1 return self.clone();
78+
return self.num >= 0 ? self.trunc().inc() : self.trunc();
79+
}
80+
81+
fn floor(self) -> Rat {
82+
if self.den == 1 return self.clone();
83+
return self.num >= 0 ? self.trunc() : self.trunc().dec();
84+
}
85+
86+
fn round(self) -> Rat {
87+
if self.num >= 0 { return (*self + Rat{num: 1, den: 2}).trunc(); }
88+
return (*self - Rat{num: 1, den: 2}).trunc();
89+
}
90+
91+
fn frac(self) -> Rat {
92+
return *self - self.trunc();
93+
}
94+
95+
fn idiv(self, other: Rat) -> Rat {
96+
return (*self / other).trunc();
97+
}
98+
99+
fn rem(self, other: Rat) -> Rat {
100+
return *self - self.idiv(other) * other;
101+
}
102+
103+
fn pow(self, exp: int) -> Rat {
104+
let r = Rat{num: self.num ** abs(exp), den: self.den ** abs(exp)};
105+
return exp >= 0 ? r : r.inv();
106+
}
107+
108+
fn inv(self) -> Rat {
109+
return Rat::new(self.den, self.num);
110+
}
111+
112+
fn abs(self) -> Rat {
113+
return Rat{num: labs(self.num), den: self.den};
114+
}
115+
116+
fn inc(self) -> Rat {
117+
return Rat{num: self.num + self.den, den: self.den};
118+
}
119+
120+
fn dec(self) -> Rat {
121+
return Rat{num: self.num - self.den, den: self.den};
122+
}
123+
124+
fn sign(self) -> int {
125+
return self.num > 0 ? 1 : self.num < 0 ? -1 : 0;
126+
}
127+
128+
fn eq(self, other: Rat) -> bool {
129+
return self.num == other.num && self.den == other.den;
130+
}
131+
132+
fn neq(self, other: Rat) -> bool {
133+
return !self.eq(other);
134+
}
135+
136+
fn lt(self, other: Rat) -> bool {
137+
return (*self - other).num < 0;
138+
}
139+
140+
fn gt(self, other: Rat) -> bool {
141+
return (*self - other).num > 0;
142+
}
143+
144+
fn le(self, other: Rat) -> bool {
145+
return (*self - other).num <= 0;
146+
}
147+
148+
fn ge(self, other: Rat) -> bool {
149+
return (*self - other).num >= 0;
150+
}
151+
152+
fn to_f64(self) -> f64 {
153+
return (f64)self.num / (f64)self.den;
154+
}
155+
156+
fn to_i64(self) -> i64 {
157+
return self.trunc().num;
158+
}
159+
160+
fn to_string(self) -> String {
161+
let s = .den > 1 ? "{self.num:ld} / {self.den:ld}" : "{self.num:ld}";
162+
return String::from(s);
163+
}
164+
165+
fn max(r1: Rat, r2: Rat) -> Rat {
166+
return r1 < r2 ? r2 : r1;
167+
}
168+
169+
fn min(r1: Rat, r2: Rat) -> Rat {
170+
return r1 < r2 ? r1 : r2;
171+
}
172+
}
173+
174+
impl Clone for Rat {
175+
fn clone(self) -> Rat {
176+
return Rat{num: self.num, den: self.den};
177+
}
178+
}
179+
180+
import "std/vec.zc"
181+
import "rat.zc"
182+
183+
fn divisors(n: int) -> Vec<int> {
184+
let divs = Vec<int>::new();
185+
if n < 1 { return divs; }
186+
let divs2 = Vec<int>::new();
187+
let i = 1;
188+
let k = (n % 2 == 0) ? 1 : 2;
189+
while i * i <= n {
190+
if n % i == 0 {
191+
divs << i;
192+
let j = n / i;
193+
if j != i { divs2 << j; }
194+
}
195+
i += k;
196+
}
197+
if divs2.length() {
198+
divs2.reverse();
199+
for l in 0..divs2.length() { divs << divs2[l]; }
200+
}
201+
return divs;
202+
}
203+
204+
fn main() {
205+
println "The following numbers (less than 2^19) are perfect:";
206+
let one: const Rat = Rat::new(1);
207+
for i in 2..(1 << 19) {
208+
let sum = Rat::new(1, i);
209+
let pd = divisors(i);
210+
for j in 1..(pd.length() - 1) { sum += Rat::new(1, pd[j]); }
211+
if sum == one { println " {i}"; }
212+
}
213+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import "std/map.zc"
2+
3+
fn print_map(m: Map<string>*) {
4+
for entry in *m {
5+
print "{{{entry.key}: {entry.val}}}, ";
6+
}
7+
println "\b\b ";
8+
}
9+
10+
fn main() {
11+
let fruit = Map<string>::new(); // creates an empty map
12+
fruit.put("1", "orange"); // associates a key of "1" with "orange"
13+
fruit.put("2", "apple"); // associates a key of "2" with "apple"
14+
let f = fruit["1"].unwrap(); // retrieves the value with a key of "1"
15+
println "{f}"; // and prints it out
16+
fruit.remove("1"); // removes the entry with a key of "1" from the map
17+
print_map(&fruit); // prints the rest of the map
18+
println "";
19+
20+
let capitals = Map<string>::new(); // creates a new map with four entries
21+
capitals.put("France","Paris");
22+
capitals.put("Germany", "Berlin");
23+
capitals.put("Spain", "Madrid");
24+
capitals.put("Russia", "Moscow");
25+
let c = capitals["France"].unwrap(); // retrieves the "France" entry
26+
println "{c}"; // and prints out its capital
27+
capitals.remove("France") // removes the "France" entry
28+
print_map(&capitals); // prints all remaining entries
29+
println "{capitals.length()}" // prints the number of remaining entries
30+
c = capitals["Sweden"].unwrap_or("none");
31+
println "{c}" // prints the entry for Sweden (none as there isn't one)
32+
}

0 commit comments

Comments
 (0)