-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollatz.echo
More file actions
92 lines (85 loc) · 1.72 KB
/
Copy pathcollatz.echo
File metadata and controls
92 lines (85 loc) · 1.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
; Collatz (3n+1) — steps to reach 1, and hailstone iterate.
; Run: xo run examples/algos/collatz.echo
/ std/io
/ std/str
/ std/test
; One Collatz step: n → n/2 if even, else 3n+1.
$ collatz_step = (n) {
? n % 2 == 0 {
^ n / 2
}
^ 3 * n + 1
}
; Number of steps from n down to 1. Reject non-positive.
$ collatz_steps = (n) {
? n <= 0 {
! "collatz needs positive n"
}
~ x = n
~ steps = 0
* x != 1 {
~ x = collatz_step(x)
~ steps = steps + 1
}
^ steps
}
; Write the hailstone sequence into pre-sized buf; return length used.
$ collatz_seq = (n, buf, cap) {
? n <= 0 {
! "collatz needs positive n"
}
~ x = n
~ len = 0
* len < cap {
~ buf[len] = x
~ len = len + 1
? x == 1 {
^ len
}
~ x = collatz_step(x)
}
^ len
}
| collatz_steps(1) {
$ s {
io.print(str.from_int(s))
}
! err {
io.print(str.from_int(err))
}
}
| collatz_steps(6) {
$ s {
io.print(str.from_int(s))
}
! err {
io.print(str.from_int(err))
}
}
| collatz_steps(15) {
$ s {
io.print(str.from_int(s))
}
! err {
io.print(str.from_int(err))
}
}
~ buf = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
| collatz_seq(6, buf, 16) {
$ len {
~ i = 0
* i < len {
io.print(str.from_int(buf[i]))
~ i = i + 1
}
io.print(str.from_int(len))
}
! err {
io.print(str.from_int(err))
}
}
; Full collatz_steps can be heavy under auto-N; one step is a stable micro canary.
test.bench("collatz_step", () {
$ x = collatz_step(27)
})
\ collatz_step, collatz_steps, collatz_seq