use scala 3:   /**
    * A simple ripple carry adder with modulo semantics.
    * Returns a bus that evaluates to the sum of values of the argument buses
    * (modulo 2^bus1.length).
    * The argument buses must be of the same length.
    * The resulting bus is of the same length, as well.
    */
    def buildAdder(bus1: Bus, bus2: Bus) =
      require(bus1.length == bus2.length, "Can only add buses of same length")
      var carry_in: Gate = Gate.False // no initial carry
      val ss = new Array[Gate](bus1.length)
      for i <- 0 until bus1.length do
        val (carry_out, sum) = buildFullAdder(bus1(i), bus2(i), carry_in)
        carry_in = carry_out // carry from bit i propagates to bit i+1
        ss(i) = sum
      new Bus(ss.toIndexedSeq)
    end buildAdder

    /**
    * A simple ripple carry adder with no overflow.
    * Returns a bus that evaluates to the sum of values of the argument buses.
    * The resulting bus is of the length (bus1.length max bus2.length)+1.
    *
    * For instance, assume that aa and bb are buses with 3 bits.
    * When aa evaluates to 011 (3 in decimal) and bb to 110 (6 in decimal),
    * then the bus buildAdderNoOverflow(aa, bb) should evaluate to 1001 
    * (9 in decimal).
    *
    */
    def buildAdderNoOverflow(bus1: Bus, bus2: Bus) =
      require(bus1.length > 0, "Can not build an adder on an empty bus")
      require(bus2.length > 0, "Can not build an adder on empty bus")
      val newBusLength = (bus1.length max bus2.length) + 1
      var carry_in: Gate = Gate.False // no initial carry
      val ss = new Array[Gate](newBusLength)
      for i <- 0 until newBusLength - 1 do
        val g1 = if i < bus1.length then bus1(i) else Gate.False
        val g2 = if i < bus2.length then bus2(i) else Gate.False
        val (carry_out, sum) = buildFullAdder(g1, g2, carry_in)
        carry_in = carry_out // carry from bit i propagates to bit i+1
        ss(i) = sum
      ss(newBusLength - 1) = carry_in
      new Bus(ss.toIndexedSeq)
    end buildAdderNoOverflow

    /** A helper for computing base 2 logarithms */
    protected def log2ceil(i: Int) =
      var v = 0
      var t = i
      while t != 0 do
        v += 1
        t = t >> 1
      v
    end log2ceil

    /**
    * Count number of true bits in a bus.
    * Returns a bus that evaluates (in binary) to the sum of true values in 
    * the argument bus.
    * The resulting bus is of the length ceil(log2(bus.length)) 
    * [you can use the log2ceil function defined above].
    *
    * For instance, assume that aa is a bus with 3 bits. Now the bus 
    * buildCountTrueBits(aa) is a bus with 2 bits.
    * When aa evaluates to 101, then the bus buildCountTrueBits(aa) 
    * should evaluate to 10 (2 in decimal).
    *
    * As another example, assume that aa is a bus with 4 bits. 
    * Now the bus buildCountTrueBits(aa) is a bus with 3 bits.
    * When aa evaluates to 1111, then the bus buildCountTrueBits(aa) 
    * should evaluate to 100 (4 in decimal).
    *
    * Hint:
    * Perhaps you can use some of the builder functions above?
    *
    */
    def buildCountTrueBits(bus: Bus): Bus =
      require(bus.length > 0, "Can not build a true bit counter on an empty bus")
      ???
    end buildCountTrueBits