import scala.collection.mutable.ListBuffer

object ZeckendorfArithmetic extends App {


  val elapsed: (=> Unit) => Long = f => {
    val s = System.currentTimeMillis

    f

    (System.currentTimeMillis - s) / 1000
  }
  val add: (Z, Z) => Z = (z1, z2) => z1 + z2
  val subtract: (Z, Z) => Z = (z1, z2) => z1 - z2
  val multiply: (Z, Z) => Z = (z1, z2) => z1 * z2
  val divide: (Z, Z) => Option[Z] = (z1, z2) => z1 / z2
  val modulo: (Z, Z) => Option[Z] = (z1, z2) => z1 % z2
  val ops = Map(("+", add), ("-", subtract), ("*", multiply), ("/", divide), ("%", modulo))
  val calcs = List(
    (Z("101"), "+", Z("10100"))
    , (Z("101"), "-", Z("10100"))
    , (Z("101"), "*", Z("10100"))
    , (Z("101"), "/", Z("10100"))
    , (Z("-1010101"), "+", Z("10100"))
    , (Z("-1010101"), "-", Z("10100"))
    , (Z("-1010101"), "*", Z("10100"))
    , (Z("-1010101"), "/", Z("10100"))
    , (Z("1000101010"), "+", Z("10101010"))
    , (Z("1000101010"), "-", Z("10101010"))
    , (Z("1000101010"), "*", Z("10101010"))
    , (Z("1000101010"), "/", Z("10101010"))
    , (Z("10100"), "+", Z("1010"))
    , (Z("100101"), "-", Z("100"))
    , (Z("1010101010101010101"), "+", Z("-1010101010101"))
    , (Z("1010101010101010101"), "-", Z("-1010101010101"))
    , (Z("1010101010101010101"), "*", Z("-1010101010101"))
    , (Z("1010101010101010101"), "/", Z("-1010101010101"))
    , (Z("1010101010101010101"), "%", Z("-1010101010101"))
    , (Z("1010101010101010101"), "+", Z("101010101010101"))
    , (Z("1010101010101010101"), "-", Z("101010101010101"))
    , (Z("1010101010101010101"), "*", Z("101010101010101"))
    , (Z("1010101010101010101"), "/", Z("101010101010101"))
    , (Z("1010101010101010101"), "%", Z("101010101010101"))
    , (Z("10101010101010101010"), "+", Z("1010101010101010"))
    , (Z("10101010101010101010"), "-", Z("1010101010101010"))
    , (Z("10101010101010101010"), "*", Z("1010101010101010"))
    , (Z("10101010101010101010"), "/", Z("1010101010101010"))
    , (Z("10101010101010101010"), "%", Z("1010101010101010"))
    , (Z("1010"), "%", Z("10"))
    , (Z("1010"), "%", Z("-10"))
    , (Z("-1010"), "%", Z("10"))
    , (Z("-1010"), "%", Z("-10"))
    , (Z("100"), "/", Z("0"))
    , (Z("100"), "%", Z("0"))
  )
  val iadd: (BigInt, BigInt) => BigInt = (a, b) => a + b
  val isub: (BigInt, BigInt) => BigInt = (a, b) => a - b