### ----------------------------------------------------
### -- Math::Sequences
### -- Licenses: Artistic-2.0
### -- Authors: Aaron Sherman, JJ Merelo, Anton Antonov
### -- File: lib/Math/Sequences/Integer.rakumod
### ----------------------------------------------------
### -- Chunk 2 of 3
 @A000796 is export = lazy Pi-digits;
# A000798 / quasi-orders or topologies
our @A000798 is export = 1, &NOSEQ ... *;
# A000959 / Lucky
# Some sort of bug: https://github.com/ajs/perl6-Math-Sequences/pull/47
# # kickstart the sequence manually to make sure we don't rotorize with 0 elems
# my $lucky-iterator = ((1…∞).rotor(1 => 1).flat.rotor(2 => 1).flat).skip(2).iterator;
# our @A000959 is export = 1, 3,
# {
#     my $val = $lucky-iterator.pull-one;
#     $lucky-iterator = Seq.new($lucky-iterator) # rewrap
#                       .rotor(  $val - 1 - 2 - ++$ => 1, # some elems are already behind
#                               ($val - 1           => 1) xx ∞)
#                       .flat.iterator;
#     $val
# } ... *;
our @A000959 is export = 1, &NOSEQ ... *;
# A000961 / prime powers
our @A000961 is export  = (1..*).grep: { factors($_).unique == 1 };
# A000984 / binomial(2n,n)
our @A000984 is export = 𝕀.map: -> $n {2*$n choose $n};
# A001003 / Schroeder's second problem
our @A001003 is export = 1, 1, -> $n2, $n1 { state $n = 1; $n++; ((6 * $n - 3) * $n1 - ($n - 2) * $n2) / ($n + 1); } ... *;
# A001006 / Motzkin
our @A001006 is export = 1, 1, -> $Mn2, $Mn1 {
    state $n = 1;
    $n++;
    $Mn1 * (2 * $n + 1) / ($n + 2) + $Mn2 * (3 * $n - 3) / ($n + 2)
} ... *;
# A001034 / simple groups
our @A001034 is export = 1, &NOSEQ ... *;
# A001037 / irreducible polynomials
our @A001037 is export = 𝕀.map: anon sub ($n) {
    return 1 if $n == 0;
    $n R/ sum divisors($n).map: -> $d { moebius($d) * 2**($n / $d) }
}
# A001045 / Jacobsthal
our @A001045 is export = 0, 1, -> $a, $b { 2 * $a + $b } ... *;
# A001055 / multiplicative partition function
our @A001055 is export = 1, &NOSEQ ... *;
# A001065 / sum of divisors
our @A001065 is export = ℕ.map: -> $n {
    [+] (1..^$n).grep: -> $i {$n %% $i};
}
# A001057 / all integers
our @A001057 is export = flat lazy gather for 𝕀 -> $n { take $n ?? ($n, -$n) !! 0 };
# A001097 / twin primes
our @A001097 is export = 𝕀.map({$_*2+1}).grep: { .is-prime and ($_+2 | $_-2).is-prime };
# A001113 / e - first 500 digits
our @A001113 is export = Eulers-number.comb( /\d/ );
# A001147 / double factorials
our @A001147 is export = 1, 1, -> $a, $b { ($b/$a + 2) * $b } ... *;
# A001157 / sum of squares of divisors
our @A001157 is export = ℕ.map: -> $n {
    divisors($n).map(* ** 2).sum
}
# A001190 / Wedderburn-Etherington
our @A001190 is export = 0, 1, {
    (state $z = 2)++;
    my \n = $z div 2;
    $z %% 2
    ?? sum((1..n-1).map: -> $i { @A001190[$i] * @A001190[2*n-$i-1] })
    !! sum((1..n-1).map: -> $i { @A001190[$i] * @A001190[2*n-$i  ] })
       + @A001190[n] * (@A001190[n] + 1) / 2;
} ... *;
# A001221 / omega
our @A001221 is export = ℕ.map: -> $n {
    $n >= 2 ?? factors($n).Set.keys.elems !! 0;
}
# A001222 / Omega
our @A001222 is export = ℕ.map: -> $n {
    $n >= 2 ?? factors($n, :map(1=>0)).elems !! 0;
}
# A001227 / odd divisors
our @A001227 is export = ℕ.map: -> $n {
    divisors($n).grep({$_ mod 2 == 1}).elems
}
# A001285 / Thue-Morse (first 32767 terms)
our @A001285 is export = (1, { '1' ~ @_.join.trans( "12" => "21", :g) } ... *)[15].comb;
# A001333 / sqrt(2)
our @A001333 is export = 1, {state $n++; round((1/2)*(1+sqrt(2))**$n) } ... *;
# A001349 / connected graphs
our @A001349 is export = 1, &NOSEQ ... *;
# A001358 / semiprimes
our @A001358 is export = 𝕀.grep: -> $n {factors($n).elems == 2};
# A001405 / binomial(n,n/2)
our @A001405 is export = 𝕀.map: -> $n { $n choose ($n div 2) };
# A001462 / Golomb
our @A001462 is export = ℕ.map: -> $i {
    state @a;
    @a.push: |($i xx (@a ?? @a[0] !! $i));
    @a.shift;
}
# A001477 / integers
our @A001477 is export = 𝕀;
# A001478 / negatives
our @A001478 is export = ℕ.map: -> $n { -$n };
# A001481 / sums of 2 squares
our @A001481 is export = 𝕀.grep: {
    # Based on the comment by Jean-Christophe Hervé, 2013
    # (Fermat's two-squares theorem)
    .&factors.grep(* % 4 == 3)\ # interesting prime factors
        .Bag.values.all %% 2    # have even exponents
}
# A001489 / negatives
our @A001489 is export = 𝕀.map: -> $n {-$n};
# A001511 / ruler function
our @A001511 is export = ℕ.map: -> $n { 1 + $n.base(2).flip.index('1') };
# A001615 / sublattices
our @A001615 is export = 1, &NOSEQ ... *;
# A001699 / binary trees
our @A001699 is export = flat 1, 1, -> $a, $b { $b * ($a + $b + $b / $a) }...*;
# A001700 / binomial(2n+1, n+1)
our @A001700 is export = 𝕀.map: -> $n { (2 * $n + 1) choose ($n + 1) };
# A001519 / Fib. bisection
our @A001519 is export = 1, 1, -> $n2, $n1 { 3 * $n1 - $n2 } ... *;
# A001764 / binomial(3n,n)/(2n+1)
our @A001764 is export = 𝕀.map: -> $n { (3*$n choose $n)/(2*$n+1) };
# A001906 / Fib. bisection
our @A001906 is export = 0, 1, -> $a, $b { 3*$b - $a } ... *;
# A001969 / evil
our @A001969 is export = 𝕀.grep: -> $n { $n.base(2).comb('1') %% 2 };
# A002033 / perfect partitions
our @A002033 is export = 1, &NOSEQ ... *;
# A002083 / Narayana-Zidek-Capell
our @A002083 is export = 1, 1, 1, -> $a1 {
    (state $n = 3)++;
    $n %% 2
    ?? 2 * $a1
    !! 2 * $a1 - @A002083[($n - 1) / 2 - 1]
} ... *;
# A002106 / transitive perm. groups
our @A002106 is export = 1, 1, 2, 5, 5, 16, 7, 50, 34, 45, 8, 301, 9, 63, 104,
                         1954, 10, 983, 8, 1117, 164, 59, 7, 25000, 211, 96,
                         2392, 1854, 8, 5712, 12, 2801324, 162, 115, 407,
                         121279, 11, 76, 306, 315842, 10, 9491, 10, 2113, 10923,
                         56, 6, &NOSEQ ... *;
# A002110 / primorials
our @A002110 is export = lazy flat 1, [\*] @A000040;
# A002113 / palindromes
our @A002113 is export = 𝕀.grep: { $_ == .flip };
# A002275 / repunits
our @A002275 is export = 𝕀.map: -> $n { (10**$n - 1) div 9 };
# A002322 / psi
our @A002322 is export = 1, &NOSEQ ... *;
# A002378 / pronic
our @A002378 is export = 𝕀.map: -> $n { $n*($n+1) };
# A002426 / central trinomial coefficients
our @A002426 is export = 1, 1, -> $a, $b {
    (state $n = 1)++;
    ((3*($n-1))*$a+(2*$n-1)*$b) div $n;
} ... *;
# A002487 / Stern
our @A002487 is export = 𝕀.map: -> $n {
    my &a = &?BLOCK;
    my $h = $n div 2;
    $n < 2 ?? $n !! a($h) + ($n%%2 ?? 0 !! a($h+1));
}
# A002530 / sqrt(3)
our @A002530 is export = 0, |𝕀.map: -> $n {
    [+] (0..($n div 2)).map: -> $k {
        (($n-$k) choose $k) * 2**(($n - 2*$k) div 2);
    }
}
# A002531 / sqrt(3)
our @A002531 is export = @A080040 Z/ 𝕀.map: -> $n { (2*2**($n div 2)) }
# A002572 / binary rooted trees
sub binary-rooted-tree (Int \c, Int \d) is export {
    return 0 if c < 0 or d <= 0;
    return 1 if c == d;
    state %seen;
    sum (1 .. 2*c).map: -> \j { %seen{"{j}|{d - c}"} //= binary-rooted-tree(j, d - c) }
}
our @A002572 is export = lazy flat 1, (1..*).map: { binary-rooted-tree(1, $_) };
# A002620 / quarter-squares
our @A002620 is export = 𝕀.map: -> $n { ($n**2 / 4).floor };
# A002654 / re: sums of squares
our @A002654 is export = ℕ.map: -> $n {
    sum divisors($n).map(* % 4).map: {
        when 1  { +1 }
        when 3  { -1 }
        default {  0 }
    }
}
# A002658 / 3-trees
our @A002658 is export = lazy 1, 1, { @_[0 .. *-2].sum * @_.tail +  @_.tail * (@_.tail + 1) / 2 } ... *;
# A002808 / composites
our @A002808 is export = 𝕀.grep: -> $n {
    not $n.is-prime and factors($n).elems > 1;
}
# A003094 / connected planar graphs
our @A003094 is export = 1, 1, 1, 2, 6, 20, 99, 646, 5974, 71885, 1052805,
                         17449299, 313372298, &NOSEQ ... *;
# A003136 / Loeschian
our @A003136 is export = lazy flat 0, 1, 3, (4..*).map: -> $n {
    next if $n % 3 == 2;
    my $m = (2*sqrt($n/3)).round;
    my $val;
    LOOP: for 0..$m -> $y {
        for 0..$y -> $x {
            if $n == $x * $x + $x*$y + $y * $y {
                $val = $n;
                last LOOP
            }
        }
    }
    next unless $val;
    $val
}
# A003418 / LCM
our @A003418 is export = 𝕀.map: -> $n { [lcm] 1..$n };
# A003484 / Hurwitz-Radon
our @A003484 is export = 1, &NOSEQ ... *;
# A004011 / D_4
our @A004011 is export = 1, |(1..Inf).map( -> $n { 24 * sum(divisors($n).map( -> $d { $d % 2 * $d } )) } );
# A004018 / square lattice
our @A004018 is export = 1, &NOSEQ ... *;
# A004526 / ints repeated
our @A004526 is export = 𝕀.map: -> $n {$n div 2};
# A005036 / dissections
our @A005036 is export = 1, &NOSEQ ... *;
# A005100 / deficient
our @A005100 is export = ℕ.grep: -> $n { sigma($n) < 2 * $n };
# A005101 / abundant
our @A005101 is export = ℕ.grep: -> $n { sigma($n) > 2 * $n };
# A005117 / squarefree
our @A005117 is export  = ℕ.grep: { my @v = .&factors.Bag.values; @v.sum/@v <= 1 };
# A005130 / Robbins
our @A005130 is export = lazy 1, 1, -> $a {state $n++; $a * factorial($n) * factorial(3*$n+1) / factorial(2*$n) / factorial(2*$n+1) } ... *;
# A005230 / Stern
our @A005230 is export = 1, {
    (state $n)++;
    my $m = ceiling (sqrt(8 * $n + 1) - 1) / 2;
    sum @A005230[$n - $m .. $n - 1]
} ... *;

# A005408 / odd
our @A005408 is export = 𝕀.map: -> $n {$n*2+1};
# A005470 / planar graphs
our @A005470 is export = 1, 1, 2, 4, 11, 33, 142, 822, 6966, 79853, 1140916,
                         18681008, 333312451, &NOSEQ ... *;
# A005588 / binary rooted trees
our @A005588 is export = 1, &NOSEQ ... *;
# A005811 / runs in n
our @A005811 is export = lazy flat 0, 1, 2, 1, {
    state @row = 2, 1;
    @row = flat @row[^(@row.elems div 2)], @row[^(@row.elems div 2)].reverse.map(*+1), @row;
}...*;
# A005843 / even
our @A005843 is export = 𝕀.map: -> $n {$n*2};
# A006318 / royal paths or Schroeder numbers
our @A006318 is export = lazy gather {
    my @Schröder = lazy [1], [1, 2], -> @b {
        my @c = 1;
        @c.push: (@b[$_] // 0) + @b[$_ - 1] + @c[$_ - 1] for 1..@b;
        @c
    } ... *;
    @Schröder.map: { take .tail };
};
# A006530 / largest prime factor
our @A006530 is export = ℕ.map: -> $n {factors($n).max};
# A006882 / n!!
our @A006882 is export = 1, 1, -> $a, $b { (state $n = 2)++ * $a } ... *;
# A006894 / 3-trees
our @A006894 is export = 1, 2, -> $n { $n * ($n + 1) / 2 + 1 } ... *;
# A006966 / lattices
our @A006966 is export = 1, 1, 1, 1, 2, 5, 15, 53, 222, 1078, 5994, 37622,
                         262776, 2018305, 16873364, 152233518, 1471613387,
                         15150569446, 165269824761, 1901910625578,
                         23003059864006, &NOSEQ ... *;
# A007318 / Pascal's triangle
our @A007318 is export = 𝕀.triangle.map: -> ($n,$k) { $n choose $k };
# A008275 / Stirling 1
our @A008275 is export = flat (1..*).map: -> $s { (1..$s).map: { Sterling1($s, $_) } };
# A008277 / Stirling 2
our @A008277 is export = flat (1..*).map: -> $s { (1..$s).map: { Sterling2($s, $_) } };
# A008279 / permutations k at a time
our @A008279 is export = 𝕀.triangle.map: -> ($n,$k) {
    factorial($n)/factorial($n-$k);
}
# A008292 / Eulerian
our @A008292 is export = |ℕ.triangle.map: -> ($n,$k) {
    [+] (0..$k).map: -> $j {
        (-1)**$j * ($k-$j)**$n * (($n+1) choose $j);
    }
}
# A008683 / Moebius
our @A008683 is export = ℕ.map: &moebius;
# A010060 / Thue-Morse (first 32767 terms)
our @A010060 is export = (0, { '0' ~ @_.join.trans( "01" => "10", :g) } ... *)[15].comb;
# A018252 / nonprimes
our @A018252 is export = ℕ.grep: {not .is-prime};
# A020639 / smallest prime factor
our @A020639 is export = ℕ.map: -> $n {factors($n).min};
# A020652 / fractal
our @A020652 is export = lazy gather for 2..* -> $de {
    for 1..^$de -> $nu {
        take $nu if ($nu/$de).numerator == $nu;
    }
}
# A020653 / fractal
our @A020653 is export = 1, 2, 1, 3, 1, 4, 3, 2, 1, 5, 1, 6, &NOSEQ ... *;
# A025487 / products of primorials
our @A025487 is export = ℕ.map: -> $n {
    (1 ... ∞).first: {
        state %cache{Bag};
        %cache{ .&prime-signature }++;
        %cache == $n
    }
}
# A027641 / Bernoulli numerators
our @A027641 is export = lazy gather {
                             my @a;
                             for 𝕀 -> $m {
                                 @a = FatRat.new(1, $m + 1),
                                     -> $prev {
                                         my $j = @a.elems;
                                         $j * (@a.shift - $prev);
                                 } ... { not @a.elems }
                                 take @a.tail.numerator * (@a.elems %% 2 ?? -1 !! 1);
                             }
                         };
# A027642 / Bernoulli denominators
our @A027642 is export = lazy gather {
                             my @a;
                             for 𝕀 -> $m {
                                 @a = FatRat.new(1, $m + 1),
                                     -> $prev {
                                         my $j = @a.elems;
                                         $j * (@a.shift - $prev);
                                 } ... { not @a.elems }
                                 take @a.tail.denominator;
                             }
                         };
# A035099 / j_2
our @A035099 is export = 1, 40, 276, -2048, 11202, -49152, 184024, &NOSEQ ... *;
# A038566 / fractal
our @A038566 is export = lazy flat 1, (2..*).map: { (^$_).grep: * gcd $_ == 1 };
# A038567 / fractal
our @A038567 is export = lazy flat 1, (2..*).map: -> $d {
    (1 ..^ $d).map( { $_ / $d } ).grep( { .denominator == $d } ).map: { .denominator }
};
# A038568 / fractal
our @A038568 is export  = lazy flat 1, (2..*).map: -> $d {
    (1 ..^ $d).map( { $_ / $d } ).grep( { .denominator == $d } )\
    .map( { $_, .denominator / .numerator } ).flat.map: { .numerator }
};
# A038569 / fractal
our @A038569 is export = lazy flat 1, (2..*).map: -> $d {
    (1 ..^ $d).map( { $_ / $d } ).grep( { .denominator == $d } )\
    .map( { $_, .denominator / .numerator } ).flat.map: { .denominator }
};
# A049310 / Chebyshev
our @A049310 is export = 𝕀.triangle.map: -> ($n, $k) {
    if $n < $k or ($n+$k) !%% 2 { 0 }
    else { ((-1)**(($n+$k)/2+$k)) * ((($n+$k)/2) choose $k) }
}
#T(n, k) := 0 if n<k or n+k odd, else ((-1)^((n+k)/2+k))*binomial((n+k)/2, k)
# A055512 / lattices
our @A055512 is export = 1, 1, 2, 6, 36, 380, 6390, 157962, 5396888, 243179064,
                         13938711210, 987858368750, 84613071940452,
                         8597251494954564, 1020353444641839854,
                         139627532137612581090, 21788453795572514675760,
                         3840596246648027262079472, 758435490711709577216754642,
                         &NOSEQ ... *;
# A070939 / binary length
our @A070939 is export = 𝕀.map: { .base(2).chars };
# A074206 / ordered factorizations
our @A074206 is export = 0, 1, {
    (state $n = 1)++;
    sum (@A074206[$_] for divisors($n)[0..*-2])
} ... *;
# A104725 / complementing systems
our @A104725 is export = 0, 1, 1, 1, 2, 1, 3, 1, 5, 2, 3, 1, &NOSEQ ... *;
# A226898 / Hooley's Delta
#our @A226898 is export = 1, &NOSEQ ... *;
our @A226898 is export = ℕ.map: -> $n {
    my @div = divisors($n);
    max(gather for 1..$n -> $u {
        take +@div.grep: -> $f { $f >= $u and $f <= $u*e };
    });
};
# A246655 / prime powers
our @A246655 is export = lazy gather for @A000040 -> $p {
    state @p;
    # Keep a list of each prime's infinite list of powers
    # [$p^1, $p^2, ...] and the current index
    @p.push: [(ℕ.map: {$p**$^power}),0];
    # Step through the prime powers until we hit $p
    loop {
        my $next = min(@p, :by({$^entry[0][$^entry[1]]}));
        my $value = $next[0][$next[1]];
        take $value;
        # Bumpt to next index
        $next[1]++;
        last if $value == $p;
    }
}

#Horadam sequences. Just the first 10
our @A085939 is export = Horadam( 0, 1, 6, 4);
our @A085449 is export = Horadam( 0, 1, 4, 2);
our @A085504 is export = Horadam( 0, 1, 9, 3);
our @A001076 is export = Horadam( 0, 1, 1, 4);

#Hofstadter sequences
our @A005206 is export = 0, {++$ - @A005206[@A005206[$++]]} … ∞;
our @A005374 is export = 0, {++$ - @A005374[@A005374[@A005374[$++]]]} … ∞;

## Aliases
our %oeis-core is export = (
    "groups" => @A000001,
    "kolakoski" => @A000002,
    "zeroes" => @A000004,
    "divisors" => @A000005,
    "zeros-powers" => @A000007,
    "distinct-partitions" => @A000009,
    "totient" => @A000010,
    "ones" => @A000012,
    "series-reduced-trees" => @A000014,
    "primitive-permutation-groups" => @A000019,
    "natural-numbers" => @A000027,
    "bracelets" => @A000029,
    "necklaces-two-color" => @A000031,
    "lucas" => @A000032,
    "fours-powers" => @A000302,
    "zero-one" => @A000035,
    "primes" => @A000040,
    "partitions" => @A000041,
    "mersennes" => @A000043,
    "fibonacci" => @A000045,
    "necklaces-two-color-interchangable" => @A000048,
    "trees" => @A000055,
    "sylvester" => @A000058,
    "odious" => @A000069,
    "twos-powers" => @A000079,
    "rooted-trees" => @A000081,
    "self-inverse-permutations" => @A000085,
    "graphs" => @A000088,
    "polyominoes" => @A000105,
    "catalan" => @A000108,
    "polyhedra" => @A000109,
    "bell" => @A000110,
    "euler" => @A000111,
    "posets" => @A000112,
    "ones-count" => @A000120,
    "binary-partitions" => @A000123,
    "lazy-caterer" => @A000124,
    "pell" => @