Skip to content

Instantly share code, notes, and snippets.

@aprell
Created February 3, 2013 19:35
Show Gist options
  • Save aprell/4703308 to your computer and use it in GitHub Desktop.
Save aprell/4703308 to your computer and use it in GitHub Desktop.
Fun with Io: Egyptian fractions
#!/usr/bin/env io
# Egyptian fractions
# Load code from utest.io
doFile("utest.io")
# egypt(f) = 1 / ceil(y/x) + egypt((-y mod x) / (y * ceil(y/x)))
egypt := method(x, y, l,
r := (y / x) ceil
l append("1/#{r}" interpolate)
num := - y % x
denom := y * r
if(num == 0,
return l
,
return egypt(num + x, denom, l) # Mathematical definition of remainder!
)
)
checkEqual(egypt(4, 5, List clone), list("1/2", "1/4", "1/20"))
checkEqual(egypt(9, 31, List clone), list("1/4", "1/25", "1/3100"))
checkEqual(egypt(21, 50, List clone), list("1/3", "1/12", "1/300"))
checkEqual(egypt(1023, 1024, List clone), list("1/2", "1/3", "1/7", "1/44", "1/9462", "1/373029888"))
# egypt(f) = 1 / ceil(y/x) + egypt((x * ceil(y/x) - y) / (y * ceil(y/x)))
egypt2 := method(x, y, l,
r := (y / x) ceil
l append("1/#{r}" interpolate)
num := x * r - y
denom := y * r
if(num == 0,
return l
,
return egypt(num, denom, l)
)
)
checkEqual(egypt2(4, 5, List clone), egypt(4, 5, List clone))
checkEqual(egypt2(9, 31, List clone), egypt(9, 31, List clone))
checkEqual(egypt2(21, 50, List clone), egypt(21, 50, List clone))
checkEqual(egypt2(1023, 1024, List clone), egypt(1023, 1024, List clone))
if(System args contains("-test"),
utest
System args remove("-test")
)
if(System args size == 1,
writeln("Usage: ", System args first, " fraction [fraction...]")
return
)
# Drop name of script from list of arguments
System args = System args rest
System args foreach(a,
first := a split("/") first asNumber
second := a split("/") second
if(second == nil,
writeln("\"", a, "\"", " is not a fraction")
continue
,
second = second asNumber
)
ef := egypt(first, second, List clone)
writeln(a, " = ", ef join(" + "))
)
#!/usr/bin/env io
Object failedTests := List clone
Object allTests := 0
Object checkEqual := method(a, b,
if(a != b, failedTests append("#{a} != #{b}" interpolate))
allTests = allTests + 1
return allTests
)
Object utest := method(
if(allTests == 0, return true)
failedTests foreach(println)
write(allTests - failedTests size, " of ", allTests, " tests passed -> ")
if(failedTests isEmpty,
writeln("SUCCESS")
return true
,
writeln("FAILURE")
return false
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment