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

are_we_fast_yet/towers.fz


# ported from https://github.com/smarr/are-we-fast-yet/blob/master/benchmarks/Java/src/Towers.java
towers is
  Towersdisk(size i32, next Towersdisk|nil) ref is

  piles := (marrays (choice Towersdisk nil)).new 3 nil
  moves_done := mut 0

  push_disk(disk Towersdisk, pile i32)
    pre
      match piles[pile]
        nil => true
        top Towersdisk =>
          top.size > disk.size
    =>
    piles[pile] := Towersdisk disk.size piles[pile]

  build_tower_at(pile i32, disks i32) =>
    for i in -disks..0 do
      push_disk (Towersdisk -i nil) pile

  pop_disk_from(pile i32) Towersdisk is
    match piles[pile]
      nil => fuzion.std.panic "attempting to pop from empty pile"
      top Towersdisk =>
        piles[pile] := top.next
        top

  move_top_disk(from i32, to i32) =>
    push_disk (pop_disk_from from) to
    moves_done <- moves_done.get + 1

  move_disks(disks i32, from i32, to i32) unit is
    if disks == 1
      move_top_disk from to
    else
      other := 3 - from - to
      move_disks (disks - 1) from other
      move_top_disk from to
      move_disks (disks - 1) other to

  benchmark =>
    build_tower_at 0 13
    move_disks 13 0 1

  benchmark

  say moves_done