Skip to content

Commit b0a383b

Browse files

File tree

3 files changed

+147
-3
lines changed

3 files changed

+147
-3
lines changed

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.Map;
88
import java.util.Set;
99
import org.matheclipse.core.basic.Config;
10-
import org.matheclipse.core.basic.OperationSystem;
1110
import org.matheclipse.core.combinatoric.KPartitionsIterable;
1211
import org.matheclipse.core.combinatoric.KPartitionsList;
1312
import org.matheclipse.core.combinatoric.KSubsetsIterable;
@@ -821,7 +820,39 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
821820
max = range.maximum();
822821
}
823822
if (ast.isAST3()) {
824-
return frobeniusPartition(ast, engine);
823+
IExpr kspec = ast.arg2();
824+
if (ast.arg3().equals(S.All)) {
825+
// IntegerPartitions(n_Integer, kspec_, All) := IntegerPartitions(n, kspec)
826+
return F.IntegerPartitions(F.ZZ(n), kspec);
827+
}
828+
if (ast.arg3().isList()) {
829+
IAST s = (IAST) ast.arg3();
830+
if (kspec.isList1() && kspec.first().isInteger()) {
831+
IInteger k = (IInteger) kspec.first();
832+
// "IntegerPartitions(n_Integer, {k_Integer}, s_List) :=
833+
// ReverseSort@Select(Union(ReverseSort /@ Tuples(s, k)), Total(#) == n &),
834+
return F.ReverseSort(F.Select(F.Union(F.Map(S.ReverseSort, F.Tuples(s, k))),
835+
F.Function(F.Equal(F.Total(F.Slot1), n))));
836+
}
837+
if (!s.forAll(x -> x.isInteger() && x.isPositive())) {
838+
return F.NIL;
839+
}
840+
}
841+
IExpr frobeniusPartition = frobeniusPartition(ast, engine);
842+
if (frobeniusPartition.isList()) {
843+
IASTMutable mutableList = ((IAST) frobeniusPartition).copy();
844+
EvalAttributes.sort(mutableList,
845+
Comparators.reversedComparator(Comparators.LEXICAL_COMPARATOR));
846+
return mutableList;
847+
}
848+
return F.NIL;
849+
} else if (ast.argSize() == 4) {
850+
IExpr kspec = ast.arg2();
851+
IExpr sspec = ast.arg3();
852+
IExpr m = ast.arg4();
853+
// "IntegerPartitions(n_Integer, kspec_, sspec_, m_) := Take(IntegerPartitions(n, k,
854+
// sspec), m)",
855+
return F.Take(F.IntegerPartitions(F.ZZ(n), kspec, sspec), m);
825856
}
826857

827858
if (n == 0) {
@@ -979,10 +1010,11 @@ private static boolean createFrobeniusSolution(IInteger[] frobeniusSolution,
9791010

9801011
@Override
9811012
public int[] expectedArgSize(IAST ast) {
982-
return ARGS_1_3;
1013+
return ARGS_1_4;
9831014
}
9841015
}
9851016

1017+
9861018
/**
9871019
*
9881020
*
@@ -1055,6 +1087,7 @@ public int[] expectedArgSize(IAST ast) {
10551087
public void setUp(final ISymbol newSymbol) {}
10561088
}
10571089

1090+
10581091
private static final class KOrderlessPartitions extends AbstractFunctionEvaluator {
10591092

10601093
/** {@inheritDoc} */
@@ -1157,6 +1190,7 @@ private IAST createSinglePartition(final IAST listArg0, final ISymbol symbol,
11571190
}
11581191
}
11591192

1193+
11601194
/**
11611195
* Generate a list of all all k-partitions for a given list with N elements. <br>
11621196
* See <a href="http://en.wikipedia.org/wiki/Partition_of_a_set">Wikipedia - Partition of a
@@ -1189,6 +1223,7 @@ public int[] expectedArgSize(IAST ast) {
11891223
}
11901224
}
11911225

1226+
11921227
/**
11931228
*
11941229
*
@@ -1256,6 +1291,7 @@ public int[] expectedArgSize(IAST ast) {
12561291
public void setUp(final ISymbol newSymbol) {}
12571292
}
12581293

1294+
12591295
/**
12601296
*
12611297
*
@@ -1352,6 +1388,7 @@ public int[] expectedArgSize(IAST ast) {
13521388
}
13531389
}
13541390

1391+
13551392
/**
13561393
*
13571394
*
@@ -1474,6 +1511,7 @@ public int[] expectedArgSize(IAST ast) {
14741511
}
14751512
}
14761513

1514+
14771515
/**
14781516
*
14791517
*
@@ -1540,6 +1578,7 @@ public int[] expectedArgSize(IAST ast) {
15401578
}
15411579
}
15421580

1581+
15431582
/**
15441583
*
15451584
*
@@ -1595,6 +1634,7 @@ public int[] expectedArgSize(IAST ast) {
15951634
}
15961635
}
15971636

1637+
15981638
/**
15991639
*
16001640
*
@@ -1699,6 +1739,7 @@ public int[] expectedArgSize(IAST ast) {
16991739
}
17001740
}
17011741

1742+
17021743
/**
17031744
*
17041745
*
@@ -1754,6 +1795,7 @@ public int[] expectedArgSize(IAST ast) {
17541795
}
17551796
}
17561797

1798+
17571799
/**
17581800
*
17591801
*
@@ -1852,6 +1894,7 @@ public int[] expectedArgSize(IAST ast) {
18521894
}
18531895
}
18541896

1897+
18551898
/**
18561899
*
18571900
*
@@ -2068,6 +2111,7 @@ private IAST createPermutationsWithNParts(final IAST list, int parts,
20682111
}
20692112
}
20702113

2114+
20712115
private static final class PolygonalNumber extends AbstractFunctionEvaluator {
20722116

20732117
@Override
@@ -2093,6 +2137,7 @@ public void setUp(final ISymbol newSymbol) {
20932137
}
20942138
}
20952139

2140+
20962141
/**
20972142
*
20982143
*
@@ -2174,6 +2219,7 @@ public int[] expectedArgSize(IAST ast) {
21742219
public void setUp(final ISymbol newSymbol) {}
21752220
}
21762221

2222+
21772223
/**
21782224
*
21792225
*
@@ -2250,6 +2296,7 @@ public int[] expectedArgSize(IAST ast) {
22502296
public void setUp(final ISymbol newSymbol) {}
22512297
}
22522298

2299+
22532300
/**
22542301
*
22552302
*
@@ -2316,6 +2363,7 @@ public int[] expectedArgSize(IAST ast) {
23162363
}
23172364
}
23182365

2366+
23192367
/**
23202368
*
23212369
*
@@ -2397,6 +2445,7 @@ public void setUp(final ISymbol newSymbol) {
23972445
}
23982446
}
23992447

2448+
24002449
/**
24012450
*
24022451
*
@@ -2585,6 +2634,7 @@ public static KSubsetsList createKSubsets(final IAST list, final int k, IAST res
25852634
}
25862635
}
25872636

2637+
25882638
/**
25892639
*
25902640
*
@@ -2734,6 +2784,7 @@ private void tuplesOfListsRecursive(final IAST originalList, final int k, IASTAp
27342784
}
27352785
}
27362786

2787+
27372788
/**
27382789
*
27392790
*
@@ -2815,6 +2866,7 @@ public int[] expectedArgSize(IAST ast) {
28152866
public void setUp(final ISymbol newSymbol) {}
28162867
}
28172868

2869+
28182870
/**
28192871
* Generate an <code>java.lang.Iterable</code> for (multiset) permutations
28202872
*
@@ -2965,6 +3017,7 @@ public KPermutationsIterable(final int[] data, final int len, final int parts) {
29653017
public Iterator<int[]> iterator() {
29663018
return new KPermutationsIterator();
29673019
}
3020+
29683021
}
29693022

29703023
/**

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5318,6 +5318,10 @@ public static IAST IntegerPart(final IExpr a0) {
53185318
return new AST1(IntegerPart, a0);
53195319
}
53205320

5321+
public static IAST IntegerPartitions(final IExpr n, final IExpr k) {
5322+
return new AST2(IntegerPartitions, n, k);
5323+
}
5324+
53215325
public static IAST IntegerPartitions(final IExpr n, final IExpr k, final IExpr p) {
53225326
return new AST3(IntegerPartitions, n, k, p);
53235327
}
@@ -9017,6 +9021,10 @@ public static IAST Reverse(final IExpr a) {
90179021
return new AST1(Reverse, a);
90189022
}
90199023

9024+
public static IAST ReverseSort(final IExpr a) {
9025+
return new AST1(ReverseSort, a);
9026+
}
9027+
90209028
public static IAST RomanNumeral(final IExpr a) {
90219029
return new AST1(RomanNumeral, a);
90229030
}
@@ -9808,6 +9816,11 @@ public static IExpr subst(IExpr expr, IExpr subExpr, IExpr replacementExpr) {
98089816
.orElse(expr);
98099817
}
98109818

9819+
public static IAST SubsetQ(IExpr x, IExpr y) {
9820+
return new AST2(S.SubsetQ, x, y);
9821+
}
9822+
9823+
98119824
/**
98129825
* Return <code>x + (-1)*y</code>
98139826
*
@@ -10648,6 +10661,10 @@ public static IAST TrueQ(final IExpr expr) {
1064810661
return new AST1(TrueQ, expr);
1064910662
}
1065010663

10664+
public static IAST Tuples(final IExpr x, final IExpr y) {
10665+
return new AST2(Tuples, x, y);
10666+
}
10667+
1065110668
/**
1065210669
* Create a function <code>head(arg)</code> with 1 argument without evaluation.
1065310670
*

symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CombinatoricTestCase.java

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,80 @@ public void testFindPermutation() {
100100
"Cycles({{2,3},{4,6,5}})");
101101
}
102102

103+
@Test
104+
public void testIntegerPartitions() {
105+
// TODO
106+
check("IntegerPartitions(1,7,{-1,-2,3})", //
107+
"IntegerPartitions(1,7,{-1,-2,3})");
108+
109+
check("IntegerPartitions(8, All, {1, 2, 5})", //
110+
"{{5,2,1},{5,1,1,1},{2,2,2,2},{2,2,2,1,1},{2,2,1,1,1,1},{2,1,1,1,1,1,1},{1,1,1,1,\n" //
111+
+ "1,1,1,1}}");
112+
113+
check("IntegerPartitions(5)", //
114+
"{{5},{4,1},{3,2},{3,1,1},{2,2,1},{2,1,1,1},{1,1,1,1,1}}");
115+
check("IntegerPartitions(8,3)", //
116+
"{{8},{7,1},{6,2},{6,1,1},{5,3},{5,2,1},{4,4},{4,3,1},{4,2,2},{3,3,2}}");
117+
check("IntegerPartitions(8,{3})", //
118+
"{{6,1,1},{5,2,1},{4,3,1},{4,2,2},{3,3,2}}");
119+
check("IntegerPartitions(8, All, {1, 2, 5})", //
120+
"{{5,2,1},{5,1,1,1},{2,2,2,2},{2,2,2,1,1},{2,2,1,1,1,1},{2,1,1,1,1,1,1},{1,1,1,1,\n" //
121+
+ "1,1,1,1}}");
122+
check("IntegerPartitions(8, All, All, 3)", //
123+
"{{8},{7,1},{6,2}}");
124+
check("IntegerPartitions(4, {2}, {-1, 0, 1, 4, 5})", //
125+
"{{5,-1},{4,0}}");
126+
127+
// message Maximum AST dimension 2147483647 exceededs
128+
check("IntegerPartitions(2147483647)", //
129+
"IntegerPartitions(2147483647)");
130+
131+
// TODO improve performance
132+
// check("IntegerPartitions(1009,2)", //
133+
// "{{1009}}");
134+
check("IntegerPartitions(1009,1)", //
135+
"{{1009}}");
136+
check("IntegerPartitions(1009,0)", //
137+
"{}");
138+
139+
check("IntegerPartitions(50, All, {6, 9, 20})", //
140+
"{{20,9,9,6,6},{20,6,6,6,6,6}}");
141+
// https://oeis.org/A214772 - McNugget partitions - Number of partitions of n into parts 6, 9 or
142+
// 20.
143+
check("Table(Length(IntegerPartitions(i, All, {6, 9, 20})), {i,0, 100, 1})", //
144+
"{1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,2,0,1,1,0,0,2,0,1,2,0,1,2,0,1,2,0,1,3,0,2,2,\n"
145+
+ "1,1,3,0,2,3,1,2,3,1,2,3,1,2,4,1,3,3,2,2,5,1,3,4,2,3,5,2,3,5,2,3,6,2,4,5,3,3,7,2,\n"
146+
+ "5,6,3,4,7,3,5,7,3,5,8,3,6,7,4,5,9,3,7,8,5}");
147+
148+
// check("IntegerPartitions(50, All, {6, 9, 20})", //
149+
// "{{20,9,9,6,6},{20,6,6,6,6,6}}");
150+
check("IntegerPartitions(156, {9,10}, {1, 5, 10, 25})", //
151+
"{{25,25,25,25,25,10,10,10,1},{25,25,25,25,25,10,10,5,5,1}}");
152+
check("IntegerPartitions(156, 10, {1, 5, 10, 25})", //
153+
"{{25,25,25,25,25,25,5,1},{25,25,25,25,25,10,10,10,1},{25,25,25,25,25,10,10,5,5,1}}");
154+
check("IntegerPartitions(4)", //
155+
"{{4},{3,1},{2,2},{2,1,1},{1,1,1,1}}");
156+
check("IntegerPartitions(6)", //
157+
"{{6},{5,1},{4,2},{4,1,1},{3,3},{3,2,1},{3,1,1,1},{2,2,2},{2,2,1,1},{2,1,1,1,1},{\n" //
158+
+ "1,1,1,1,1,1}}");
159+
check("IntegerPartitions(6, {3,4})", //
160+
"{{4,1,1},{3,2,1},{3,1,1,1},{2,2,2},{2,2,1,1}}");
161+
check("IntegerPartitions(10,2)", //
162+
"{{10},{9,1},{8,2},{7,3},{6,4},{5,5}}");
163+
check("IntegerPartitions(10,{2})", //
164+
"{{9,1},{8,2},{7,3},{6,4},{5,5}}");
165+
check("IntegerPartitions(0)", //
166+
"{{}}");
167+
check("IntegerPartitions(1)", //
168+
"{{1}}");
169+
check("IntegerPartitions(-1)", //
170+
"{}");
171+
check("IntegerPartitions(.5)", //
172+
"IntegerPartitions(0.5)");
173+
check("IntegerPartitions(1/2)", //
174+
"{}");
175+
}
176+
103177
@Test
104178
public void testPermute() {
105179
check("Permute(CharacterRange(\"v\", \"z\"), Cycles({{1, 5, 3}}))", //

0 commit comments

Comments
 (0)