1#!/usr/bin/env perl
2use strict;
3use warnings;
4
5use Test::More;
6use Math::Prime::Util qw/partitions forpart forcomp is_prime/;
7my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
8
9my @parts = qw/
101
111
122
133
145
157
1611
1715
1822
1930
2042
2156
2277
23101
24135
25176
26231
27297
28385
29490
30627
31792
321002
331255
341575
351958
362436
373010
383718
394565
405604
416842
428349
4310143
4412310
4514883
4617977
4721637
4826015
4931185
5037338
5144583
5253174
5363261
5475175
5589134
56105558
57124754
58147273
59173525
60204226
61/;
62
63my %bparts = (
64    101 => "214481126",
65    256 => "365749566870782",
66    501 => "2431070104309287327876",
67   1001 => "25032297938763929621013218349796",
68   2347 => "56751384003004060684283391440819878903446789803099",
69   4128 => "13036233928924552978434294180871407270098426394166677221003078079504",
70   #9988 => "31043825285346179203111322344702502691204288916782299617140664920755263693739998376431336412511604846065386",
71  #13337 => "4841449229081281114351180373774137636239639013054790559544724995314398354517477085116206336008004971541987422037760634642695",
72  #37373 => "885240148270777711759915557428752066370785294706979437063536090533501018735098279767013023483349639513395622225840616033227700794918506274833787569446519667398089943122156454986205555766363295867812094833219935",
73);
74if (!$extra) {
75  my @ns = grep { $_ > 300 } keys %bparts;
76  foreach my $n (@ns) { delete $bparts{$n} }
77}
78
79plan tests => scalar(@parts) + scalar(keys(%bparts)) + 20 + 6;
80
81
82foreach my $n (0..$#parts) {
83  is( partitions($n), $parts[$n], "partitions($n)" );
84}
85
86while (my($n, $epart) = each (%bparts)) {
87  is( partitions($n), $epart, "partitions($n)" );
88}
89
90################### forpart
91
92{ my @p=(); forpart { push @p, [@_] } 0;
93  is_deeply( [@p], [[]], "forpart 0" ); }
94
95{ my @p=(); forpart { push @p, [@_] } 1;
96  is_deeply( [@p], [[1]], "forpart 1" ); }
97
98{ my @p=(); forpart { push @p, [@_] } 2;
99  is_deeply( [@p], [[1,1],[2]], "forpart 2" ); }
100
101{ my @p=(); forpart { push @p, [@_] } 3;
102  is_deeply( [@p], [[1,1,1],[1,2],[3]], "forpart 3" ); }
103
104{ my @p=(); forpart { push @p, [@_] } 4;
105  is_deeply( [@p], [[1,1,1,1],[1,1,2],[1,3],[2,2],[4]], "forpart 4" ); }
106
107{ my @p=(); forpart { push @p, [@_] } 6;
108  is_deeply( [@p], [[1,1,1,1,1,1],[1,1,1,1,2],[1,1,1,3],[1,1,2,2],[1,1,4],[1,2,3],[1,5],[2,2,2],[2,4],[3,3],[6]], "forpart 6" ); }
109
110{ my @p=(); forpart { push @p, [@_] } 17,{n=>2};
111  is_deeply( [@p], [[1,16],[2,15],[3,14],[4,13],[5,12],[6,11],[7,10],[8,9]], "forpart 17 restricted n=[2,2]" ); }
112
113{ my @p1 = (); my @p2 = ();
114  forpart { push @p1, [@_] if @_ <= 5 } 27;
115  forpart { push @p2, [@_] } 27, {nmax=>5};
116  is_deeply( [@p1], [@p2], "forpart 27 restricted nmax 5" ); }
117
118{ my @p1 = (); my @p2 = ();
119  forpart { push @p1, [@_] if @_ >= 20 } 27;
120  forpart { push @p2, [@_] } 27, {nmin=>20};
121  is_deeply( [@p1], [@p2], "forpart 27 restricted nmin 20" ); }
122
123{ my @p1 = (); my @p2 = ();
124  forpart { push @p1, [@_] if @_ >= 10 && @_ <= 13 } 19;
125  forpart { push @p2, [@_] } 19, {nmin=>10,nmax=>13};
126  is_deeply( [@p1], [@p2], "forpart 19 restricted n=[10..13]" ); }
127
128{ my @p1 = (); my @p2 = ();
129  forpart { push @p1, [@_] unless scalar grep { $_ > 4 } @_ } 20;
130  forpart { push @p2, [@_] } 20, {amax=>4};
131  is_deeply( [@p1], [@p2], "forpart 20 restricted amax 4" ); }
132
133{ my @p1 = (); my @p2 = ();
134  forpart { push @p1, [@_] unless scalar grep { $_ < 4 } @_ } 15;
135  forpart { push @p2, [@_] } 15, {amin=>4};
136  is_deeply( [@p1], [@p2], "forpart 15 restricted amin 4" ); }
137
138{ my @p1 = (); my @p2 = ();
139  forpart { push @p1, [@_] unless scalar grep { $_ < 3 || $_ > 6 } @_ } 21;
140  forpart { push @p2, [@_] } 21, {amin=>3,amax=>6};
141  is_deeply( [@p1], [@p2], "forpart 21 restricted a=[3..6]" ); }
142
143#{ my @p1 = (); my @p2 = ();
144#  forpart { push @p1, [@_] unless @_ != 4 || scalar grep { $_ < 2 || $_ > 8 } @_ } 22;
145#  forpart { push @p2, [@_] } 22, {amin=>2,amax=>8,n=>4};
146#  is_deeply( [@p1], [@p2], "forpart 22 restricted n=4 and a=[3..6]" ); }
147{ my @p=(); forpart { push @p, [@_] } 22, {amin=>2,amax=>8,n=>4};
148  is_deeply( [@p], [[2,4,8,8],[2,5,7,8],[2,6,6,8],[2,6,7,7],[3,3,8,8],[3,4,7,8],[3,5,6,8],[3,5,7,7],[3,6,6,7],[4,4,6,8],[4,4,7,7],[4,5,5,8],[4,5,6,7],[4,6,6,6],[5,5,5,7],[5,5,6,6]], "forpart 22 restricted n=4 and a=[3..6]" ); }
149
150{ my @p = ();
151  forpart { push @p, [@_] unless scalar grep {!is_prime($_)} @_ } 20,{amin=>3};
152  is_deeply( [@p], [[3,3,3,3,3,5],[3,3,3,11],[3,3,7,7],[3,5,5,7],[3,17],[5,5,5,5],[7,13]], "forpart 20 restricted to odd primes" );
153}
154
155{ my @p=(); forpart { push @p, [@_] } 21, {amax=>0};
156  is_deeply( [@p], [], "forpart 21 restricted amax 0" );
157}
158
159{ my $c = 0;
160  forpart { $c++ } 2*89+1,{n=>3,amin=>3,prime=>1};
161  is($c, 86, "A007963(89) = number of odd-prime 3-tuples summing to 2*89+1 = 86");
162}
163{ my $c = 0;
164  forpart { $c++ } 23,{n=>4,amin=>2};
165  is($c, 54, "23 partitioned into 4 with mininum 2 => 54");
166}
167{ my $c = 0;
168  forpart { $c++ } 23,{n=>4,amin=>2,prime=>1};
169  is($c, 5, "23 partitioned into 4 with mininum 2 and prime => 5");
170}
171{ my $c = 0;
172  forpart { $c++ } 23,{n=>4,amin=>2,prime=>0};
173  is($c, 1, "23 partitioned into 4 with mininum 2 and composite => 1");
174}
175
176
177################### forcomp
178
179{ my @p=(); forcomp { push @p, [@_] } 0;
180  is_deeply( [@p], [[]], "forcomp 0" ); }
181
182{ my @p=(); forcomp { push @p, [@_] } 1;
183  is_deeply( [@p], [[1]], "forcomp 1" ); }
184
185{ my @p=(); forcomp { push @p, [@_] } 2;
186  is_deeply( [@p], [[1,1],[2]], "forcomp 2" ); }
187
188{ my @p=(); forcomp { push @p, [@_] } 3;
189  is_deeply( [@p], [[1,1,1],[1,2],[2,1],[3]], "forcomp 3" ); }
190
191{ my @p=(); forcomp { push @p, [@_] } 5,{n=>3};
192  is_deeply( [@p], [[1,1,3],[1,2,2],[1,3,1],[2,1,2],[2,2,1],[3,1,1]], "forcomp 5 restricted n=3" ); }
193
194{ my @p=(); forcomp { push @p, [@_] } 12,{n=>3,amin=>3,amax=>5};
195  is_deeply( [@p], [[3,4,5],[3,5,4],[4,3,5],[4,4,4],[4,5,3],[5,3,4],[5,4,3]], "forcomp 12 restricted n=3,a=[3..5]" ); }
196