Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

benchmarks_game/fannkuch.fz


# https://benchmarksgame-team.pages.debian.net/benchmarksgame/description/fannkuchredux.html#fannkuchredux
# based on ocaml version by Ethan Burns
fannkuch is

  flip (n i32, a marray i32) =>
    for i := 0, i+1
    while i <= n / 2
      t := a[i]
      k := n - i
      a[i] := a[k]
      a[k] := t

  count(c i32, a marray i32) i32 is
    z := a[0]
    if z != 0
      flip z a
      count (c + 1) a
    else
      c

  rotate (n i32, a marray i32) =>
    t := a[0]
    m := n - 1
    for i in 1..m do
      a[i - 1] := a[i]
    a[m] := t

  copy_marray(x marray i32) =>
    marray x.length x.asArray.internalArray

  to_marray(x array i32) =>
    res := (marrays i32).new x.length 0
    for i in 0..x.length-1 do
      res[i] := x[i]
    res

  print(x marray i32) =>
    yak "arr: "
    for e in x do
      yak "$e "
    say

  iter_perms (n i32, f (i32, marray i32) -> unit) =>
    num := mut 0
    do_iter (mperm marray i32, f (i32, marray i32) -> unit, ht i32) =>
      copy := copy_marray(mperm)
      if ht = 1 then
        f num.get copy
        num <- num.get + 1
      else
        for i in 1..ht do
          do_iter mperm f (ht - 1)
          rotate ht mperm
      unit
    perm := array i32 n i->i
    do_iter to_marray(perm) f n

  n := 7
  csum := mut 0
  m := mut 0
  f(num i32, a marray i32) =>
    c := count 0 a
    csum <- csum.get + c * (1 - ((num & 1) << 1))
    if c > m.get then
      m <- c

  iter_perms n (fun f)

  say "$csum"
  say "Pfannkuchen($n) = ($m)"