Skip to content

Instantly share code, notes, and snippets.

@thesephist
Last active November 21, 2024 07:04
Show Gist options
  • Save thesephist/cd4a0c8defbb8f29f8716e3567a586d3 to your computer and use it in GitHub Desktop.
Save thesephist/cd4a0c8defbb8f29f8716e3567a586d3 to your computer and use it in GitHub Desktop.
Ackermann function calculator
#!/usr/bin/env oak
std := import('std')
str := import('str')
fmt := import('fmt')
math := import('math')
cli := import('cli')
// ackermann computes the Ackermann function of m, n
fn ackermann(m, n) if {
m = 0 -> n + 1
n = 0 -> ackermann(m - 1, 1)
_ -> ackermann(m - 1, ackermann(m, n - 1))
}
Cli := cli.parse()
Time? := Cli.opts.t != ? | Cli.opts.time != ?
std.println('Ackermann function calculator.')
with std.loop() fn {
print('.> ')
// input is of the form "M N, M N, M N"
// assume input never fails b/c it's just a toy calculator
args := input().data |> str.split(',') |> std.map(fn(pair) {
pair |>
str.split(' ') |>
std.map(int) |>
std.compact() |>
std.take(2)
})
args |> with std.each() fn(pair) {
[m, n] := pair
prefix := if len(args) {
1 -> ''
_ -> 'ack({{0}}, {{1}}) = ' |> fmt.format(m, n)
}
if m != ? & n != ? {
true -> {
start := nanotime()
a := ackermann(m, n)
elapsed := nanotime() - start
(prefix + if {
Time? -> '{{0}} ({{1}}ms)'
_ -> '{{0}}'
}) |> fmt.printf(a, math.round(elapsed / 1000000, 3))
}
_ -> std.println('Invalid input. Try again.')
}
}
}
Ackermann function calculator.
.> 1 1
3 (0.008ms)
.> 2 2
7 (0.068ms)
.> 3 4
125 (17.101ms)
.> 3 5, 3 6, 3 7
ack(3, 5) = 253 (54.885ms)
ack(3, 6) = 509 (220.24ms)
ack(3, 7) = 1021 (973.239ms)
.> 3 10
8189 (157760.616ms)
.>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment