Skip to content

Commit 07227d6

Browse files
authored
Add Zeckendorf in Euphoria (#5340)
1 parent a548f31 commit 07227d6

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

archive/e/euphoria/zeckendorf.eu

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
include std/io.e
2+
include std/types.e
3+
include std/text.e
4+
include std/get.e as stdget
5+
include std/sequence.e
6+
7+
-- Indices for value() return value
8+
enum VALUE_ERROR_CODE, VALUE_VALUE, VALUE_NUM_CHARS_READ
9+
10+
-- Indices for parse_int() return value
11+
enum PARSE_INT_VALID, PARSE_INT_VALUE
12+
13+
function parse_int(sequence s)
14+
-- Trim off whitespace and parse string
15+
s = trim(s)
16+
sequence result = stdget:value(s,, GET_LONG_ANSWER)
17+
18+
-- Error if any errors, value is not an integer, or any leftover characters
19+
boolean valid = (
20+
result[VALUE_ERROR_CODE] = GET_SUCCESS
21+
and integer(result[VALUE_VALUE])
22+
and result[VALUE_NUM_CHARS_READ] = length(s)
23+
)
24+
25+
-- Get value if invalid
26+
integer value = 0
27+
if valid
28+
then
29+
value = result[VALUE_VALUE]
30+
end if
31+
32+
return {valid, value}
33+
end function
34+
35+
procedure usage()
36+
puts(STDOUT, "Usage: please input a non-negative integer\n")
37+
abort(0)
38+
end procedure
39+
40+
procedure show_list_values(sequence values)
41+
if length(values) > 0
42+
then
43+
sequence format = repeat_pattern("%d, ", length(values))
44+
sequence s = sprintf(format[1..$-2], values)
45+
printf(STDOUT, "%s\n", {s})
46+
end if
47+
end procedure
48+
49+
function get_fibonacci_values(integer value)
50+
-- Initialize Fibonacci state:
51+
-- fib(2) = 1
52+
-- fib(3) = 2
53+
sequence fibs = {}
54+
integer a = 1
55+
integer b = 2
56+
integer t
57+
58+
-- Update Fibonacci state and store values
59+
while a <= value
60+
do
61+
-- fib(n) = fib(n - 1) + fib(n - 2)
62+
fibs &= a
63+
t = a + b
64+
a = b
65+
b = t
66+
end while
67+
68+
return fibs
69+
end function
70+
71+
function get_zeckendorf_values(integer value)
72+
sequence zecks = {}
73+
74+
-- Go through Fibonacci numbers in reverse order, stopping when
75+
-- remaining value is zero
76+
sequence fibs = get_fibonacci_values(value)
77+
integer n = length(fibs)
78+
while n > 0 and value > 0
79+
do
80+
-- If candidate Fibonacci number is greater than or equal to remaining value,
81+
integer f = fibs[n]
82+
if value >= f
83+
then
84+
-- Append Fibonacci number to result
85+
zecks &= f
86+
87+
-- Reduce remaining value
88+
value -= f
89+
90+
-- Skip previous value
91+
n -= 2
92+
-- Else, go to previous value
93+
else
94+
n -= 1
95+
end if
96+
end while
97+
98+
return zecks
99+
end function
100+
101+
-- Check 1st command-line argument
102+
sequence argv = command_line()
103+
if length(argv) < 4 or length(argv[4]) = 0
104+
then
105+
usage()
106+
end if
107+
108+
-- Parse 1st command-line argument
109+
sequence result = parse_int(argv[4])
110+
integer value = result[PARSE_INT_VALUE]
111+
if not result[PARSE_INT_VALID] or value < 0
112+
then
113+
usage()
114+
end if
115+
116+
--Get Zeckendorf values
117+
sequence values = get_zeckendorf_values(value)
118+
show_list_values(values)

0 commit comments

Comments
 (0)