#!/usr/bin/ruby

#
## Test Array#sum and Array#prod
#

var a = [1,2,3,4,5]

assert_eq(a.prod, 120)
assert_eq(a.sum,  15)

assert_eq(a.sum  { _*_ }, 55)
assert_eq(a.prod { _*_ }, 14400)

assert_eq(a.sum(:sqrt), a.sum { .sqrt })
assert_eq(a.prod(:sqrt), a.prod { .sqrt })

# This may change in the future (changed)
# assert_eq(a.sum(42),  57)
# assert_eq(a.prod(2), 240)

# Empty array
assert_eq([].sum,  0)
assert_eq([].prod, 1)

#
## Test RangeNumber#sum and RangeNumber#prod
#

var r = 1..5

assert_eq(r.prod, 120)
assert_eq(r.sum,  15)

assert_eq(r.sum  { _*_ }, 55)
assert_eq(r.prod { _*_ }, 14400)

assert_eq(r.sum(:sqrt), r.sum { .sqrt })
assert_eq(r.prod(:sqrt), r.prod { .sqrt })

# This may change in the future (changed)
# assert_eq(r.sum(42),  57)
# assert_eq(r.prod(2), 240)

# Empty range
assert_eq((5..4).sum,  0)
assert_eq((5..4).prod, 1)

# Auto-conversions
do {
    var arr = ["12", "42"]

    assert_eq(arr.prod, 12*42)
    assert_eq(arr.sum, 12+42)

    assert_eq(arr, ["12", "42"])
}

# Array gcd/lcm
do {
    var arr = ["48", "120", "42"]

    assert_eq(arr.lcm, lcm(42, 48, 120))
    assert_eq(arr.gcd, gcd(42, 48, 120))

    assert_eq(arr.lcm { _ }, lcm(42, 48, 120))
    assert_eq(arr.lcm { .to_i**2 }, lcm(42**2, 48**2, 120**2))

    assert_eq(arr.gcd { _ }, gcd(42, 48, 120))
    assert_eq(arr.gcd { .to_i**2 }, gcd(42**2, 48**2, 120**2))

    assert_eq(arr, ["48", "120", "42"])
}

# Range gcd/lcm
do {

    assert_eq(lcm(1..10), lcm(@|1..10))
    assert_eq(lcm(200..250), lcm(@|200..250))

    assert_eq(lcm(20..10), 1)
    assert_eq(gcd(20..10), 0)

    assert_eq(lcm(1..-10), 1)
    assert_eq(gcd(1..-10), 0)

    assert_eq(20..10 -> lcm { _ }, 1)
    assert_eq(20..10 -> gcd { _ }, 0)

    assert_eq(1..10    -> lcm { _ },   lcm(1..10))
    assert_eq(200..250 -> lcm { _+1 }, lcm(201..251))

    assert_eq(gcd(42..60 `by` 2), 2)
    assert_eq(gcd(42..60 `by` 3), 3)

    assert_eq(4..10 -> gcd { _! }, 24)
    assert_eq(4..10 -> flip.gcd { _! }, 24)
}

say "** Test passed!"