Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions archive/e/euphoria/zeckendorf.eu
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
include std/io.e
include std/types.e
include std/text.e
include std/get.e as stdget
include std/sequence.e

-- Indices for value() return value
enum VALUE_ERROR_CODE, VALUE_VALUE, VALUE_NUM_CHARS_READ

-- Indices for parse_int() return value
enum PARSE_INT_VALID, PARSE_INT_VALUE

function parse_int(sequence s)
-- Trim off whitespace and parse string
s = trim(s)
sequence result = stdget:value(s,, GET_LONG_ANSWER)

-- Error if any errors, value is not an integer, or any leftover characters
boolean valid = (
result[VALUE_ERROR_CODE] = GET_SUCCESS
and integer(result[VALUE_VALUE])
and result[VALUE_NUM_CHARS_READ] = length(s)
)

-- Get value if invalid
integer value = 0
if valid
then
value = result[VALUE_VALUE]
end if

return {valid, value}
end function

procedure usage()
puts(STDOUT, "Usage: please input a non-negative integer\n")
abort(0)
end procedure

procedure show_list_values(sequence values)
if length(values) > 0
then
sequence format = repeat_pattern("%d, ", length(values))
sequence s = sprintf(format[1..$-2], values)
printf(STDOUT, "%s\n", {s})
end if
end procedure

function get_fibonacci_values(integer value)
-- Initialize Fibonacci state:
-- fib(2) = 1
-- fib(3) = 2
sequence fibs = {}
integer a = 1
integer b = 2
integer t

-- Update Fibonacci state and store values
while a <= value
do
-- fib(n) = fib(n - 1) + fib(n - 2)
fibs &= a
t = a + b
a = b
b = t
end while

return fibs
end function

function get_zeckendorf_values(integer value)
sequence zecks = {}

-- Go through Fibonacci numbers in reverse order, stopping when
-- remaining value is zero
sequence fibs = get_fibonacci_values(value)
integer n = length(fibs)
while n > 0 and value > 0
do
-- If candidate Fibonacci number is greater than or equal to remaining value,
integer f = fibs[n]
if value >= f
then
-- Append Fibonacci number to result
zecks &= f

-- Reduce remaining value
value -= f

-- Skip previous value
n -= 2
-- Else, go to previous value
else
n -= 1
end if
end while

return zecks
end function

-- Check 1st command-line argument
sequence argv = command_line()
if length(argv) < 4 or length(argv[4]) = 0
then
usage()
end if

-- Parse 1st command-line argument
sequence result = parse_int(argv[4])
integer value = result[PARSE_INT_VALUE]
if not result[PARSE_INT_VALID] or value < 0
then
usage()
end if

--Get Zeckendorf values
sequence values = get_zeckendorf_values(value)
show_list_values(values)