def multi_acc[T](n: PolyNum[T], a: PolyNum[T]): PolyNum[T]
trait PolyNum[T] {
def +(x:PolyNum[T]) : PolyNum[T]
def half : PolyNum[T]
def odd : Boolean
def one : PolyNum[T]
def value: T
}
case class X(v:BigInt) extends PolyNum[BigInt] {
override def +(x:PolyNum[BigInt]) : PolyNum[BigInt] = X(v + x.value)
override def odd : Boolean = v % 2 == 1
override def half : PolyNum[BigInt] = X(v / 2)
override def one : PolyNum[BigInt] = X(BigInt(1))
override def value: BigInt = v
}
case class Y(v:Int) extends PolyNum[Int] {
override def +(x:PolyNum[Int]) : PolyNum[Int] = Y(v + x.value)
override def odd : Boolean = v % 2 == 1
override def half : PolyNum[Int] = Y(v / 2)
override def one : PolyNum[Int] = Y(1)
override def value: Int = v
}
def multi_acc[T](n: PolyNum[T], a: PolyNum[T], r: PolyNum[T]): PolyNum[T] = {
val odin = n.one
(n.odd, n) match {
case (true, odin) => (r + a)
case (true, _) => multi_acc(n.half, a + a, r + a)
case (_, _) => multi_acc(n.half, a + a, r)
}
}
object Main {
def main(args: Array[String]): Unit = {
println("привет")
println(multi_acc(X(BigInt(1)),X(BigInt(3)),X(BigInt(4))).value)
println(multi_acc(Y(1),Y(3),Y(4)).value)
}
}
class Main {
def half(a:Int) : Int = a / 2
def half(a:BigInt) : BigInt = a / 2
def odd(a:Int) : Boolean = a % 2 == 1
def odd(a:BigInt) : Boolean = a % 2 == 1
def odd[T](a: T): Boolean =
a match {
case x: BigInt => odd(x)
case x: Int => odd(x)
}
def half[T](a: T): T =
a match {
case x: Int => half(x).asInstanceOf[T]
case x: BigInt => half(x).asInstanceOf[T]
}
def one[T](n:T): T =
n match {
case x: Int => 1.asInstanceOf[T]
case x: BigInt => BigInt(1).asInstanceOf[T]
}
def sum[T](a: T, b:T): T =
(a, b) match {
case (x: Int, y: Int) => (x + y).asInstanceOf[T]
case (x: BigInt, y: BigInt) => (x + y).asInstanceOf[T]
}
def mult_acc[T](n: T, a: T, r: T): T = {
val odin = one(n)
(odd(n), n) match {
case (true, odin) => sum(r, a)
case (true, _) => mult_acc(half(n), sum(a, a), sum(r, a))
case (_, _) => mult_acc(half(n), sum(a, a), r)
}
}
}
object Main {
def main(args: Array[String]): Unit = {
println("привет")
val test = new Main
println(test.mult_acc(BigInt(1),BigInt(3),BigInt(4)))
println(test.mult_acc(1,3,4))
}
}