#!/usr/bin/ruby

# Tests for squarefree related functions.

assert_eq(
    squarefree(2**64 - 100, 2**64 - 1),
    range(2**64 - 100, 2**64 - 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(2**64 - 50, 2**64 + 1),
    range(2**64 - 50, 2**64 + 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(2**65 - 100, 2**65 - 1),
    range(2**65 - 100, 2**65 - 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(2**63 - 100, 2**63 - 1),
    range(2**63 - 100, 2**63 - 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(2**32 - 100, 2**32 - 1),
    range(2**32 - 100, 2**32 - 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(2**31 - 100, 2**31 - 1),
    range(2**31 - 100, 2**31 - 1).grep{.is_squarefree}
)

assert_eq(
    squarefree(100),
    1..100 -> grep{.is_squarefree}
)

assert_eq(
    gather {
        each_squarefree(2**64 - 100, 2**64 - 1, {|k|
            take(k)
        }),
    },
    squarefree(2**64 - 100, 2**64 - 1),
)

assert_eq(
    gather {
        each_squarefree(2**64 - 100, 2**64 - 50, {|k|
            take(k)
        }),
    },
    range(2**64 - 100, 2**64 - 50).grep{.is_squarefree}
)

assert_eq(
    gather {
        each_squarefree(2**64 - 100, 2**64 - 49, {|k|
            take(k)
        }),
    },
    range(2**64 - 100, 2**64 - 49).grep{.is_squarefree}
)

assert_eq(
    gather {
        each_squarefree(2**64 - 100, 2**64 - 50, {|k|
            take(k)
        })
    },
    squarefree(2**64 - 100, 2**64 - 50),
)

assert_eq(
    gather {
        each_squarefree(2**64 - 50, 2**64 + 1, {|k|
            take(k)
        }),
    },
    range(2**64 - 50, 2**64 + 1).grep{.is_squarefree}
)

assert_eq(
    gather {
        for (var k = next_squarefree(0); k <= 100; k.next_squarefree!) {
            take(k)
        }
    },
    squarefree(1..100)
)

assert_eq(
    gather {
        for (var k = next_squarefree(2**64 - 11); k <= (2**64 + 100); k.next_squarefree!) {
            take(k)
        }
    },
    squarefree(2**64 - 10 .. (2**64 + 100))
)

assert_eq(
    10.of { .next_squarefree },
    %n[1, 2, 3, 5, 5, 6, 7, 10, 10, 10]
)

assert_eq(next_squarefree(0), 1)
assert(next_squarefree(-50).is_nan)

assert_eq(next_squarefree(2**64), 2**64 + 1)
assert_eq(next_squarefree(2**32), 2**32 + 1)
assert_eq(next_squarefree(2**16), 2**16 + 1)

assert_eq(next_squarefree(2**16 - 1), 2**16 + 1)
assert_eq(next_squarefree(2**32 - 1), 2**32 + 1)
assert_eq(next_squarefree(2**64 - 1), 2**64 + 1)

assert_eq(next_squarefree(2**16 - 2), 2**16 - 1)
assert_eq(next_squarefree(2**32 - 2), 2**32 - 1)
assert_eq(next_squarefree(2**64 - 2), 2**64 - 1)
assert_eq(next_squarefree(2**128 - 2), 2**128 - 1)

assert_eq(next_squarefree(2**64 + 3), 2**64 + 5)

say "** Test passed!"
