diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java
index 5ea479103..891e87ac1 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/builtin/Combinatoric.java
@@ -7,7 +7,6 @@
import java.util.Map;
import java.util.Set;
import org.matheclipse.core.basic.Config;
-import org.matheclipse.core.basic.OperationSystem;
import org.matheclipse.core.combinatoric.KPartitionsIterable;
import org.matheclipse.core.combinatoric.KPartitionsList;
import org.matheclipse.core.combinatoric.KSubsetsIterable;
@@ -821,7 +820,39 @@ public IExpr evaluate(final IAST ast, EvalEngine engine) {
max = range.maximum();
}
if (ast.isAST3()) {
- return frobeniusPartition(ast, engine);
+ IExpr kspec = ast.arg2();
+ if (ast.arg3().equals(S.All)) {
+ // IntegerPartitions(n_Integer, kspec_, All) := IntegerPartitions(n, kspec)
+ return F.IntegerPartitions(F.ZZ(n), kspec);
+ }
+ if (ast.arg3().isList()) {
+ IAST s = (IAST) ast.arg3();
+ if (kspec.isList1() && kspec.first().isInteger()) {
+ IInteger k = (IInteger) kspec.first();
+ // "IntegerPartitions(n_Integer, {k_Integer}, s_List) :=
+ // ReverseSort@Select(Union(ReverseSort /@ Tuples(s, k)), Total(#) == n &),
+ return F.ReverseSort(F.Select(F.Union(F.Map(S.ReverseSort, F.Tuples(s, k))),
+ F.Function(F.Equal(F.Total(F.Slot1), n))));
+ }
+ if (!s.forAll(x -> x.isInteger() && x.isPositive())) {
+ return F.NIL;
+ }
+ }
+ IExpr frobeniusPartition = frobeniusPartition(ast, engine);
+ if (frobeniusPartition.isList()) {
+ IASTMutable mutableList = ((IAST) frobeniusPartition).copy();
+ EvalAttributes.sort(mutableList,
+ Comparators.reversedComparator(Comparators.LEXICAL_COMPARATOR));
+ return mutableList;
+ }
+ return F.NIL;
+ } else if (ast.argSize() == 4) {
+ IExpr kspec = ast.arg2();
+ IExpr sspec = ast.arg3();
+ IExpr m = ast.arg4();
+ // "IntegerPartitions(n_Integer, kspec_, sspec_, m_) := Take(IntegerPartitions(n, k,
+ // sspec), m)",
+ return F.Take(F.IntegerPartitions(F.ZZ(n), kspec, sspec), m);
}
if (n == 0) {
@@ -979,10 +1010,11 @@ private static boolean createFrobeniusSolution(IInteger[] frobeniusSolution,
@Override
public int[] expectedArgSize(IAST ast) {
- return ARGS_1_3;
+ return ARGS_1_4;
}
}
+
/**
*
*
@@ -1055,6 +1087,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}
+
private static final class KOrderlessPartitions extends AbstractFunctionEvaluator {
/** {@inheritDoc} */
@@ -1157,6 +1190,7 @@ private IAST createSinglePartition(final IAST listArg0, final ISymbol symbol,
}
}
+
/**
* Generate a list of all all k-partitions for a given list with N elements.
* See Wikipedia - Partition of a
@@ -1189,6 +1223,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1256,6 +1291,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}
+
/**
*
*
@@ -1352,6 +1388,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1474,6 +1511,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1540,6 +1578,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1595,6 +1634,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1699,6 +1739,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1754,6 +1795,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -1852,6 +1894,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -2068,6 +2111,7 @@ private IAST createPermutationsWithNParts(final IAST list, int parts,
}
}
+
private static final class PolygonalNumber extends AbstractFunctionEvaluator {
@Override
@@ -2093,6 +2137,7 @@ public void setUp(final ISymbol newSymbol) {
}
}
+
/**
*
*
@@ -2174,6 +2219,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}
+
/**
*
*
@@ -2250,6 +2296,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}
+
/**
*
*
@@ -2316,6 +2363,7 @@ public int[] expectedArgSize(IAST ast) {
}
}
+
/**
*
*
@@ -2397,6 +2445,7 @@ public void setUp(final ISymbol newSymbol) {
}
}
+
/**
*
*
@@ -2585,6 +2634,7 @@ public static KSubsetsList createKSubsets(final IAST list, final int k, IAST res
}
}
+
/**
*
*
@@ -2734,6 +2784,7 @@ private void tuplesOfListsRecursive(final IAST originalList, final int k, IASTAp
}
}
+
/**
*
*
@@ -2815,6 +2866,7 @@ public int[] expectedArgSize(IAST ast) {
public void setUp(final ISymbol newSymbol) {}
}
+
/**
* Generate an java.lang.Iterable
for (multiset) permutations
*
@@ -2965,6 +3017,7 @@ public KPermutationsIterable(final int[] data, final int len, final int parts) {
public Iterator iterator() {
return new KPermutationsIterator();
}
+
}
/**
diff --git a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java
index 2bc3327c3..bdb013f8f 100644
--- a/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java
+++ b/symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/expression/F.java
@@ -5318,6 +5318,10 @@ public static IAST IntegerPart(final IExpr a0) {
return new AST1(IntegerPart, a0);
}
+ public static IAST IntegerPartitions(final IExpr n, final IExpr k) {
+ return new AST2(IntegerPartitions, n, k);
+ }
+
public static IAST IntegerPartitions(final IExpr n, final IExpr k, final IExpr p) {
return new AST3(IntegerPartitions, n, k, p);
}
@@ -9017,6 +9021,10 @@ public static IAST Reverse(final IExpr a) {
return new AST1(Reverse, a);
}
+ public static IAST ReverseSort(final IExpr a) {
+ return new AST1(ReverseSort, a);
+ }
+
public static IAST RomanNumeral(final IExpr a) {
return new AST1(RomanNumeral, a);
}
@@ -9808,6 +9816,11 @@ public static IExpr subst(IExpr expr, IExpr subExpr, IExpr replacementExpr) {
.orElse(expr);
}
+ public static IAST SubsetQ(IExpr x, IExpr y) {
+ return new AST2(S.SubsetQ, x, y);
+ }
+
+
/**
* Return x + (-1)*y
*
@@ -10648,6 +10661,10 @@ public static IAST TrueQ(final IExpr expr) {
return new AST1(TrueQ, expr);
}
+ public static IAST Tuples(final IExpr x, final IExpr y) {
+ return new AST2(Tuples, x, y);
+ }
+
/**
* Create a function head(arg)
with 1 argument without evaluation.
*
diff --git a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CombinatoricTestCase.java b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CombinatoricTestCase.java
index ea5db3782..b4bba226b 100644
--- a/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CombinatoricTestCase.java
+++ b/symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/CombinatoricTestCase.java
@@ -100,6 +100,80 @@ public void testFindPermutation() {
"Cycles({{2,3},{4,6,5}})");
}
+ @Test
+ public void testIntegerPartitions() {
+ // TODO
+ check("IntegerPartitions(1,7,{-1,-2,3})", //
+ "IntegerPartitions(1,7,{-1,-2,3})");
+
+ check("IntegerPartitions(8, All, {1, 2, 5})", //
+ "{{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" //
+ + "1,1,1,1}}");
+
+ check("IntegerPartitions(5)", //
+ "{{5},{4,1},{3,2},{3,1,1},{2,2,1},{2,1,1,1},{1,1,1,1,1}}");
+ check("IntegerPartitions(8,3)", //
+ "{{8},{7,1},{6,2},{6,1,1},{5,3},{5,2,1},{4,4},{4,3,1},{4,2,2},{3,3,2}}");
+ check("IntegerPartitions(8,{3})", //
+ "{{6,1,1},{5,2,1},{4,3,1},{4,2,2},{3,3,2}}");
+ check("IntegerPartitions(8, All, {1, 2, 5})", //
+ "{{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" //
+ + "1,1,1,1}}");
+ check("IntegerPartitions(8, All, All, 3)", //
+ "{{8},{7,1},{6,2}}");
+ check("IntegerPartitions(4, {2}, {-1, 0, 1, 4, 5})", //
+ "{{5,-1},{4,0}}");
+
+ // message Maximum AST dimension 2147483647 exceededs
+ check("IntegerPartitions(2147483647)", //
+ "IntegerPartitions(2147483647)");
+
+ // TODO improve performance
+ // check("IntegerPartitions(1009,2)", //
+ // "{{1009}}");
+ check("IntegerPartitions(1009,1)", //
+ "{{1009}}");
+ check("IntegerPartitions(1009,0)", //
+ "{}");
+
+ check("IntegerPartitions(50, All, {6, 9, 20})", //
+ "{{20,9,9,6,6},{20,6,6,6,6,6}}");
+ // https://oeis.org/A214772 - McNugget partitions - Number of partitions of n into parts 6, 9 or
+ // 20.
+ check("Table(Length(IntegerPartitions(i, All, {6, 9, 20})), {i,0, 100, 1})", //
+ "{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"
+ + "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"
+ + "5,6,3,4,7,3,5,7,3,5,8,3,6,7,4,5,9,3,7,8,5}");
+
+ // check("IntegerPartitions(50, All, {6, 9, 20})", //
+ // "{{20,9,9,6,6},{20,6,6,6,6,6}}");
+ check("IntegerPartitions(156, {9,10}, {1, 5, 10, 25})", //
+ "{{25,25,25,25,25,10,10,10,1},{25,25,25,25,25,10,10,5,5,1}}");
+ check("IntegerPartitions(156, 10, {1, 5, 10, 25})", //
+ "{{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}}");
+ check("IntegerPartitions(4)", //
+ "{{4},{3,1},{2,2},{2,1,1},{1,1,1,1}}");
+ check("IntegerPartitions(6)", //
+ "{{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" //
+ + "1,1,1,1,1,1}}");
+ check("IntegerPartitions(6, {3,4})", //
+ "{{4,1,1},{3,2,1},{3,1,1,1},{2,2,2},{2,2,1,1}}");
+ check("IntegerPartitions(10,2)", //
+ "{{10},{9,1},{8,2},{7,3},{6,4},{5,5}}");
+ check("IntegerPartitions(10,{2})", //
+ "{{9,1},{8,2},{7,3},{6,4},{5,5}}");
+ check("IntegerPartitions(0)", //
+ "{{}}");
+ check("IntegerPartitions(1)", //
+ "{{1}}");
+ check("IntegerPartitions(-1)", //
+ "{}");
+ check("IntegerPartitions(.5)", //
+ "IntegerPartitions(0.5)");
+ check("IntegerPartitions(1/2)", //
+ "{}");
+ }
+
@Test
public void testPermute() {
check("Permute(CharacterRange(\"v\", \"z\"), Cycles({{1, 5, 3}}))", //