├── .gitignore
├── .travis.yml
├── KotlinDiscreteMathToolkit.iml
├── README.md
├── _config.yml
├── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
├── main
└── java
│ └── com
│ └── marcinmoskala
│ └── math
│ ├── CartesianProductExt.kt
│ ├── CombinationsExt.kt
│ ├── FactorialFun.kt
│ ├── IterableMultiplication.kt
│ ├── NumSplitFunc.kt
│ ├── NumbersDivisible.kt
│ ├── PermutationsExt.kt
│ ├── Power.kt
│ ├── PowersetExt.kt
│ ├── ProductExt.kt
│ ├── SetSplitFunc.kt
│ └── SublistsBySplittersExt.kt
└── test
└── java
└── com
└── marcinmoskala
└── math
└── tests
├── CartesianProductPropertyTest.kt
├── CartesianProductTest.kt
├── CombinationTest.kt
├── CombinationWithRepetitionTest.kt
├── FactorialTest.kt
├── IterableMultipliationTest.kt
├── JavaTest.java
├── NumberSplitTest.kt
├── NumbersDivisibleTest.kt
├── PermutationTest.kt
├── PowerTest.kt
├── PowersetTest.kt
├── ProductTest.kt
├── SetSplitTest.kt
├── SublistsBySplittersTest.kt
└── TestUtils.kt
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | *.jar
3 | *.war
4 | *.ear
5 | /.idea/
6 | DiscreteMathToolkit.iml
7 | out/
8 | gradle.properties
9 | *.log
10 | *.ctxt
11 | .mtj.tmp/
12 | *.zip
13 | *.tar.gz
14 | *.rar
15 | hs_err_pid*
16 | .gradle/
17 | build/
18 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
3 | jdk:
4 | - oraclejdk8
5 |
6 | install: true
7 |
8 | script:
9 | - ./gradlew check
10 |
11 | after_success:
12 | - bash <(curl -s https://codecov.io/bash)
--------------------------------------------------------------------------------
/KotlinDiscreteMathToolkit.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DiscreteMathToolkit
2 | Set of extensions for Kotlin that provides Discrete Math functionalities as an Kotlin extension functions.
3 |
4 | [](https://maven-badges.herokuapp.com/maven-central/com.marcinmoskala/DiscreteMathToolkit)
5 | [](https://travis-ci.org/MarcinMoskala/KotlinDiscreteMathToolkit)
6 | [](https://codecov.io/gh/MarcinMoskala/KotlinDiscreteMathToolkit)
7 | [](https://codebeat.co/projects/github-com-marcinmoskala-kotlindiscretemathtoolkit-master)
8 | [](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit)
9 |
10 | To stay current with news about library [](https://twitter.com/marcinmoskala?ref_src=twsrc%5Etfw)
11 |
12 | # Permutations
13 |
14 | ```kotlin
15 | setOf(1, 2, 3).permutations() // {[1, 2, 3], [2, 1, 3], [3, 2, 1], [1, 3, 2], [2, 3, 1], [3, 1, 2]}
16 | setOf(1, 2, 3).permutationsNumber() // 6
17 | listOf(1, 2, 2).permutations() // {[1, 2, 2], [2, 1, 2], [2, 2, 1]}
18 | listOf(1, 2, 2).permutationsNumber() // 3
19 | ```
20 |
21 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/PermutationTest.kt)
22 |
23 | # Combinations
24 |
25 | ```kotlin
26 | setOf(1, 2, 3, 4).combinations(3) // { {1, 2, 3}, {1, 2, 4}, {1, 4, 3}, {4, 2, 3} }
27 | setOf(1, 2, 3, 4).combinationNumber(3) // 4
28 |
29 | setOf(1, 2, 3, 4).combinationsWithRepetitions(2) // [{1=2}, {1=1, 2=1}, {1=1, 3=1}, {1=1, 4=1}, {2=2}, {2=1, 3=1}, {2=1, 4=1}, {3=2}, {3=1, 4=1}, {4=2}]
30 | setOf(1, 2, 3, 4).combinationsWithRepetitionsNumber(2) // 10
31 | ```
32 |
33 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/CombinationTest.kt) and [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/CombinationWithRepetitionTest.kt)
34 |
35 | # Powerset
36 | Powerset of any set S is the set of all subsets of S, including the empty set and S itself.
37 |
38 | ```kotlin
39 | setOf(1, 2, 3).powerset() // { {}, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3} }
40 | setOf(1, 2, 3).powersetSize() // 8
41 | ```
42 | # Product
43 | Product is the result of multiplying.
44 |
45 | ```kotlin
46 | (3..4).product() // 12
47 | listOf(10, 10, 10).product() // 1000
48 | ```
49 |
50 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/ProductTest.kt).
51 |
52 | # Factorial
53 | Factorian of n (n!) is a product of all positive integers less than or equal to n.
54 |
55 | ```kotlin
56 | 3.factorial() // 6L
57 | 10.factorial() // 3628800L
58 | 20.factorial() // 2432902008176640000L
59 | ```
60 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/FactorialTest.kt).
61 |
62 | # Numbers divisible and non-divisible by
63 |
64 | ```kotlin
65 | (1..1000).countNonDivisiveBy(2) // 500
66 | (1..1000).countNonDivisiveBy(3) // 777
67 | (1..1000).countNonDivisiveBy(2, 6, 13) // 462
68 | (1..1000).countNonDivisiveBy(3, 7, 11) // 520
69 |
70 | (1..1000).countDivisiveBy(2) // 500
71 | (1..1000).countDivisiveBy(3) // 333
72 | (1..1000).countDivisiveBy(2, 6, 13) // 538
73 | (1..1000).countDivisiveBy(3, 7, 11) // 480
74 | ```
75 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/NumbersDivisibleTest.kt).
76 |
77 | # Splits of sets and numbers
78 | In Descrete Math there are two functions used to count number of splits:
79 | S(n, k) - Stirling function - number of splits of n different elements to k groups
80 | P(n, k) - number of splits of n identical elements to k groups
81 |
82 | ```kotlin
83 | (1..n).toSet().splitsNumber(1) // 1
84 | (1..n).toSet().splitsNumber(n) // 1
85 | setOf(1, 2, 3).splitsNumber(2) // 3
86 | setOf(1, 2, 3, 4).splitsNumber(2) // 7
87 | setOf(1, 2, 3, 4, 5).splitsNumber(3) // 25
88 | setOf(1, 2, 3, 4, 5, 6, 7).splitsNumber(4) // 350
89 | setOf(1, 2, 3).splits(2) // { { {1, 2}, {3} },{ {1, 3}, {2} },{ {3, 2}, {1} } }
90 | ```
91 |
92 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/SetSplitTest.kt)
93 |
94 | ```kotlin
95 | n.splitsNumber(1) // 1
96 | n.splitsNumber(n) // 1
97 | 7.splitsNumber(4) // 3
98 | 11.splitsNumber(4) // 11
99 | 9.splitsNumber(5) // 5
100 | 13.splitsNumber(8) // 7
101 | ```
102 |
103 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/NumberSplitTest.kt)
104 |
105 | # Iterable multiplication
106 |
107 | Multiplication of iterables returns iterable with pairs of each possible connections of elements from first and iterable:
108 |
109 | ```kotlin
110 | listOf(1, 2) * listOf("A", "B") // returns List>
111 | // [(1, "A"), (1, "B"), (2, "A"), (2, "B")]
112 | listOf('a', 'b') * listOf(1, 2) * listOf("A", "B") // returns List>
113 | // [
114 | // ('a', 1, "A"), ('a', 1, "B"),
115 | // ('a', 2, "A"), ('a', 2, "B"),
116 | // ('b', 1, "A"), ('b', 1, "B"),
117 | // ('b', b, "A"), ('b', 2, "B")
118 | // ]
119 | ```
120 |
121 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/IterableMultipliationTest.kt).
122 |
123 | # Cartesian product of lists
124 |
125 | Similar to iterable multiplication but produces sequence of lists:
126 |
127 | ```kotlin
128 | listOf('A', 'B', 'C', D).cartesianProduct(listOf('x', 'y')) // returns List>
129 | // [
130 | // ['A', 'x'],
131 | // ['A', 'y'],
132 | // ['B', 'x'],
133 | // ['B', 'y'],
134 | // ['C', 'x'],
135 | // ['C', 'y'],
136 | // ['D', 'x'],
137 | // ['D', 'y']
138 | // ]
139 | listOf(0, 1).cartesianProduct(repeat = 2) // returns List>
140 | // [
141 | // [0, 0],
142 | // [0, 1],
143 | // [1, 0],
144 | // [1, 1]
145 | // ]
146 | listOf(1, 2).cartesianProduct(listOf("ABC")) // returns List>
147 | // [
148 | // [1, "ABC"],
149 | // [2, "ABC"]
150 | // ]
151 | ```
152 |
153 | More examples [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/CartesianProductTest.kt).
154 |
155 | # Java support
156 |
157 | Library is fully supporting usage from Java. All functions can be used as static function of DiscreteMath. For example:
158 |
159 | ```java
160 | DiscreteMath.permutationsNumber(set)
161 | DiscreteMath.permutationsNumber(list)
162 | DiscreteMath.factorial(10) // 3628800L
163 | ```
164 |
165 | Returned list and sets are Java standard lists and sets. More examples of Java usage [here](https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit/blob/master/src/test/java/com/marcinmoskala/math/tests/JavaTest.java).
166 |
167 | # Install
168 |
169 | Gradle:
170 | ```groovy
171 | compile "com.marcinmoskala:DiscreteMathToolkit:1.0.3"
172 | ```
173 |
174 | Maven:
175 | ```
176 |
177 | com.marcinmoskala
178 | DiscreteMathToolkit
179 | 1.0.3
180 |
181 | ```
182 |
183 | Jar to download together with sources and javadoc can be found on [Maven Central](http://search.maven.org/#search%7Cga%7C1%7Cmarcinmoskala).
184 |
185 | License
186 | -------
187 |
188 | Copyright 2017 Marcin Moskała
189 |
190 | Licensed under the Apache License, Version 2.0 (the "License");
191 | you may not use this file except in compliance with the License.
192 | You may obtain a copy of the License at
193 |
194 | http://www.apache.org/licenses/LICENSE-2.0
195 |
196 | Unless required by applicable law or agreed to in writing, software
197 | distributed under the License is distributed on an "AS IS" BASIS,
198 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199 | See the License for the specific language governing permissions and
200 | limitations under the License.
201 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-midnight
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'kotlin'
2 | if (project.hasProperty("signing.keyId")) {
3 | apply plugin: 'signing'
4 | }
5 | apply plugin: 'maven-publish'
6 | apply plugin: "jacoco"
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | buildscript {
13 | ext.kotlin_version = '1.3.72'
14 | ext.junit_version = '5.6.1'
15 | ext.kotest_version = '4.0.6'
16 | repositories {
17 | mavenCentral()
18 | }
19 | dependencies {
20 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
21 | }
22 | }
23 |
24 | jacocoTestReport {
25 | reports {
26 | xml.enabled = true
27 | html.enabled = true
28 | }
29 | }
30 |
31 | check.dependsOn jacocoTestReport
32 |
33 | dependencies {
34 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
35 | testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
36 | testImplementation "org.junit.jupiter:junit-jupiter-engine:$junit_version"
37 | testImplementation "io.kotest:kotest-runner-junit5-jvm:$kotest_version"
38 | testImplementation "io.kotest:kotest-property-jvm:$kotest_version"
39 | }
40 |
41 | // Publishing
42 |
43 | test {
44 | // show standard out and standard error of the test JVM(s) on the console
45 | testLogging.showStandardStreams = true
46 | }
47 |
48 | task sourceJar(type: Jar) {
49 | classifier "sources"
50 | from sourceSets.main.allJava
51 | }
52 |
53 | task javadocJar(type: Jar, dependsOn: javadoc) {
54 | classifier "javadoc"
55 | from javadoc.destinationDir
56 | }
57 |
58 | artifacts {
59 | archives sourceJar, javadocJar
60 | }
61 |
62 | signing {
63 | sign configurations.archives
64 | }
65 |
66 | publishing {
67 | publications {
68 | mavenJava(MavenPublication) {
69 | customizePom(pom)
70 |
71 | groupId "com.marcinmoskala"
72 | artifactId "DiscreteMathToolkit"
73 | version '1.0.5'
74 |
75 | from components.java
76 |
77 | // create the sign pom artifact
78 | pom.withXml {
79 | def pomFile = file("${project.buildDir}/generated-pom.xml")
80 | writeTo(pomFile)
81 | def pomAscFile = signing.sign(pomFile).signatureFiles[0]
82 | artifact(pomAscFile) {
83 | classifier = null
84 | extension = 'pom.asc'
85 | }
86 | }
87 |
88 | artifact(sourceJar) {
89 | classifier = 'sources'
90 | }
91 | artifact(javadocJar) {
92 | classifier = 'javadoc'
93 | }
94 |
95 | // create the signed artifacts
96 | project.tasks.signArchives.signatureFiles.each {
97 | artifact(it) {
98 | def matcher = it.file =~ /-(sources|javadoc)\.jar\.asc$/
99 | if (matcher.find()) {
100 | classifier = matcher.group(1)
101 | } else {
102 | classifier = null
103 | }
104 | extension = 'jar.asc'
105 | }
106 | }
107 | }
108 | }
109 | repositories {
110 | maven {
111 | url "https://oss.sonatype.org/service/local/staging/deploy/maven2"
112 | credentials {
113 | username sonatypeUsername
114 | password sonatypePassword
115 | }
116 | }
117 | }
118 | }
119 |
120 | def customizePom(pom) {
121 | pom.withXml {
122 | def root = asNode()
123 |
124 | root.dependencies.removeAll { dep ->
125 | dep.scope == "test"
126 | }
127 |
128 | root.children().last() + {
129 | resolveStrategy = Closure.DELEGATE_FIRST
130 |
131 | name 'DescreteMathToolkit'
132 | description 'Set of extensions for Kotlin that provides Discrete Math functionalities as an Kotlin extension functions.'
133 | url 'https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit'
134 |
135 | scm {
136 | connection 'scm:https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit'
137 | developerConnection 'scm:https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit'
138 | url 'https://github.com/MarcinMoskala/KotlinDiscreteMathToolkit'
139 | }
140 |
141 | licenses {
142 | license {
143 | name 'The Apache License, Version 2.0'
144 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
145 | }
146 | }
147 |
148 | developers {
149 | developer {
150 | id 'MarcinMoskala'
151 | name 'Marcin Moskala'
152 | email 'marcinmoskala@gmail.com'
153 | }
154 | }
155 | }
156 | }
157 | }
158 |
159 | model {
160 | tasks.generatePomFileForMavenJavaPublication {
161 | destination = file("$buildDir/generated-pom.xml")
162 | }
163 | tasks.publishMavenJavaPublicationToMavenLocal {
164 | dependsOn project.tasks.signArchives
165 | }
166 | tasks.publishMavenJavaPublicationToMavenRepository {
167 | dependsOn project.tasks.signArchives
168 | }
169 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarcinMoskala/KotlinDiscreteMathToolkit/17a7329af042c5de232051027ec1155011d57da8/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 08 23:32:02 CEST 2020
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn ( ) {
37 | echo "$*"
38 | }
39 |
40 | die ( ) {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save ( ) {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/src/main/java/com/marcinmoskala/math/CartesianProductExt.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("DiscreteMath")
2 | @file:JvmMultifileClass
3 |
4 | package com.marcinmoskala.math
5 |
6 | /**
7 | * Cartesian product of a list with itself, specify the number of repetitions with the optional repeat keyword argument.
8 | * For example, A.cartesianProduct(repeat=4) means the same as A.cartesianProduct(A, A, A).
9 | * Throws an [IllegalArgumentException]: if [repeat] is less or equals to 0
10 | * Throws an [IllegalArgumentException]: if size of result should exceeds [Int.MAX_VALUE]
11 | */
12 | fun List.cartesianProduct(repeat: Int = 2): Sequence> {
13 | require(repeat > 0) { "Parameter repeat should be greater than 0" }
14 | return product(*Array(repeat) { this })
15 | }
16 |
17 | /**
18 | * Cartesian product of lists.
19 | * Throws an [IllegalArgumentException]: if size of result should exceeds [Int.MAX_VALUE]
20 | */
21 | fun List.cartesianProduct(vararg lists: List): Sequence> =
22 | product(this, *lists)
23 |
24 | private fun product(vararg iterables: List): Sequence> = sequence {
25 |
26 | require(iterables.map { it.size.toLong() }.reduce(Long::times) <= Int.MAX_VALUE) {
27 | "Cartesian product function can produce result whose size does not exceed Int.MAX_VALUE"
28 | }
29 |
30 | val numberOfIterables = iterables.size
31 | val lstLengths = ArrayList()
32 | val lstRemaining = ArrayList(listOf(1))
33 |
34 | iterables.reversed().forEach {
35 | lstLengths.add(0, it.size)
36 | lstRemaining.add(0, it.size * lstRemaining[0])
37 | }
38 |
39 | val nProducts = lstRemaining.removeAt(0)
40 |
41 | (0 until nProducts).forEach { product ->
42 | val result = ArrayList()
43 | (0 until numberOfIterables).forEach { iterableIndex ->
44 | val elementIndex = product / lstRemaining[iterableIndex] % lstLengths[iterableIndex]
45 | result.add(iterables[iterableIndex][elementIndex])
46 | }
47 | yield(result.toList())
48 | }
49 | }
--------------------------------------------------------------------------------
/src/main/java/com/marcinmoskala/math/CombinationsExt.kt:
--------------------------------------------------------------------------------
1 | @file:JvmName("DiscreteMath")
2 | @file:JvmMultifileClass
3 | package com.marcinmoskala.math
4 |
5 | /**
6 | * In mathematics, a combination is a way of selecting items from a collection, such that (unlike permutations) the
7 | * order of selection does not matter.
8 | *
9 | * For set {1, 2, 3}, 2 elements combinations are {1, 2}, {2, 3}, {1, 3}.
10 | * All possible combinations is called 'powerset' and can be found as an
11 | * extension function for set under this name
12 | */
13 | fun Set.combinations(combinationSize: Int): Set> = when {
14 | combinationSize < 0 -> throw Error("combinationSize cannot be smaller then 0. It is equal to $combinationSize")
15 | combinationSize == 0 -> setOf(setOf())
16 | combinationSize >= size -> setOf(toSet())
17 | else -> powerset()
18 | .filter { it.size == combinationSize }
19 | .toSet()
20 | }
21 |
22 | fun Set.combinationsNumber(combinationSize: Int): Long = when {
23 | combinationSize < 0 -> throw Error("combinationSize cannot be smaller then 0. It is equal to $combinationSize")
24 | combinationSize >= size || combinationSize == 0 -> 1
25 | else -> size.factorial() / (combinationSize.factorial() * (size - combinationSize).factorial())
26 | }
27 |
28 | fun Set.combinationsWithRepetitions(combinationSize: Int): Set