### ----------------------------------------------------
### -- Math::NumberTheory
### -- Licenses: Artistic-2.0
### -- Authors: Anton Antonov
### -- File: t/04-prime.rakutest
### ----------------------------------------------------
use v6.d;
use Test;

#use lib <. lib>;
use Math::NumberTheory;

plan *;

## 1
is-deeply (100 .. 103)».&prime.Array, [541, 547, 557, 563];

## 2
my @x2 = -277, -201, -84, 26, 34, 102;
is-deeply @x2».&next-prime.Array, [-271, -199, -83, 29, 37, 103];

## 3
subtest {
    is next-prime(-3), -2;
    is next-prime(-2), 2;
    is next-prime(-1), 2;
    is next-prime(0), 2;
    is next-prime(1), 2;
    is next-prime(32), 37;
    is next-prime(32, 2), 41;
    is next-prime(32, k => 2), 41;
    is next-prime(31, 0), 31;
    is next-prime(-31, 1), -29;
    is next-prime(-31, 12), 3;
    is next-prime(9_532_323), 9_532_331;
    is next-prime(-89_342), -89_329;
    is-deeply next-prime([4, 8, 12, 67]), (5, 11, 13, 71);
    is-deeply next-prime([33, 67], 5), (53, 89);
    is-deeply next-prime(33, [3, 4, 9]), (43, 47, 71);
    is-deeply next-prime([33, 67], [3, 4, 9]), ((43, 47, 71), (79, 83, 107));
}, "next-prime";

## 4
subtest {
    isa-ok random-prime(5), Int:D, 'integer result with no second argument';

    isa-ok random-prime(15, Whatever), Int:D, 'integer result for second argument Whatever';

    my $p = random-prime(5);
    is $p.is-prime, True, '5, gives is a prime';

    my $p2 = random-prime(5 .. 50);
    is $p2.is-prime, True, '5..50 gives a prime';

    my $p3 = random-prime(5 .. 50, 3);
    isa-ok $p3, List:D, "5 .. 50, 3 gives a list";
    is ([&&] $p3».is-prime), True, '5..50, 3 gives all primes';

    my @ps = random-prime(5 .. 50, 40);
    is @ps.elems, 40, "expected number of primes";

}, 'random primes, expected to pass';

## 5
subtest {
    dies-ok { random-prime(-5) };
    dies-ok { random-prime(15 .. 3) };
    dies-ok { random-prime(4, -4) };
    dies-ok { random-prime(4 .. 23, -4) };
    dies-ok { random-prime(4 .. 23, Inf) };
    nok random-prime(14 .. 16);
}, 'random primes, expected to fail';

## 6
subtest {
    is prime-pi(15), 6;
    is prime-pi(15.4), 6;
    is prime-pi(7/2), 2;
    is prime-pi(7/2, method => 'legendre'), 2;
    is prime-pi(10 ** 5, method => 'legendre'), 9592;
}, "prime-pi";

## 7
#subtest {
    is is-prime-gaussian(5), False;
    is is-prime-gaussian(7), True;
    is is-prime-gaussian(35), False;
    is is-prime-gaussian(1 + 2*i), True;
    is is-prime-gaussian(1 + i), True;
    is-deeply is-prime-gaussian([1 + i, 5 ,7]), (True, False, True);
#}, "Gaussian primes";

## 8
subtest {
    is is-prime(5, :gaussian), False;
    is is-prime(7, :gaussian), True;
    is is-prime(1 + 2*i), True;
    is is-prime(1 + i), True;
    is-deeply is-prime([1 + i, 5 ,7], :gaussian), (True, False, True);
    is-deeply is-prime([1 + i, 5 ,7]), (True, True, True);
}, "Gaussian primes via is-prime";

subtest {
    is prime-omega(7 ** 5), 5;
    is prime-omega(30), 3;
    is prime-omega(10 ** 5), 10;
    is prime-omega([4, 12, 24]), (2, 3, 4);
    is prime-omega(24 * 40), prime-omega(24) + prime-omega(40);
    is prime-omega(1), 0;
}, "prime-omega";

subtest {
    is prime-nu(7 ** 5), 1;
    is prime-nu(50), 2;
    is prime-nu(10 ** 5), 2;
    is prime-nu([4, 12, 24]), (1, 2, 2);
    is prime-nu(9 * 40), prime-nu(9) + prime-nu(40);
    is prime-nu(1), 0;

    is ([&&] (1...100).map({ prime-nu($_) ≤ prime-omega($_) })), True;
}, "prime-nu";

done-testing;


