mirror of
https://github.com/InsanusMokrassar/PsychomatrixBase.git
synced 2024-11-25 19:48:53 +00:00
first version
This commit is contained in:
parent
c1bd167689
commit
ebdcd372fc
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.idea
|
||||||
|
out/*
|
||||||
|
*.iml
|
||||||
|
target
|
||||||
|
|
||||||
|
settings.xml
|
216
pom.xml
Normal file
216
pom.xml
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.github.insanusmokrassar</groupId>
|
||||||
|
<artifactId>PsychomatrixBase</artifactId>
|
||||||
|
<version>0.1</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<description>${project.artifactId}</description>
|
||||||
|
<url>https://insanusmokrassar.github.io/${project.artifactId}/</url>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Ovsyannikov Alexey</name>
|
||||||
|
<email>ovsyannikov.alexey95@gmail.com</email>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>MIT</name>
|
||||||
|
<url>https://github.com/insanusmokrassar/${project.artifactId}/blob/master/LICENSE</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
<scm>
|
||||||
|
<url>https://github.com/insanusmokrassar/${project.artifactId}</url>
|
||||||
|
<tag>HEAD</tag>
|
||||||
|
<developerConnection>
|
||||||
|
scm:git:[fetch=]https://github.com/insanusmokrassar/${project.artifactId}.git[push=]ssh:git@github.com:insanusmokrassar/${project.artifactId}.git
|
||||||
|
</developerConnection>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<kotlin.version>1.2.61</kotlin.version>
|
||||||
|
<kotlin.coroutines.version>0.24.0</kotlin.coroutines.version>
|
||||||
|
<dokka.version>0.9.16</dokka.version>
|
||||||
|
<gpg.version>1.6</gpg.version>
|
||||||
|
<assembly.version>2.6</assembly.version>
|
||||||
|
<source.version>3.0.1</source.version>
|
||||||
|
<jar.version>3.0.2</jar.version>
|
||||||
|
<gpg.passphraseServerId>bintray-insanusmokrassar-StandardRepository</gpg.passphraseServerId>
|
||||||
|
<main.class>${project.groupId}.${project.artifactId}.ExampleKt</main.class>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<pluginRepositories>
|
||||||
|
<pluginRepository>
|
||||||
|
<id>jcenter</id>
|
||||||
|
<name>JCenter</name>
|
||||||
|
<url>https://jcenter.bintray.com/</url>
|
||||||
|
</pluginRepository>
|
||||||
|
</pluginRepositories>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>${project.basedir}/src/main/res/</directory>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>process-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<args>
|
||||||
|
<arg>-Xcoroutines=enable</arg>
|
||||||
|
</args>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>${jar.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<addClasspath>true</addClasspath>
|
||||||
|
<mainClass>${main.class}</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>${source.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>${assembly.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<mainClass>${main.class}</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.dokka</groupId>
|
||||||
|
<artifactId>dokka-maven-plugin</artifactId>
|
||||||
|
<version>${dokka.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>dokka</goal>
|
||||||
|
<goal>javadocJar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<sourceDirectories>
|
||||||
|
<dir>${project.build.sourceDirectory}</dir>
|
||||||
|
</sourceDirectories>
|
||||||
|
<cacheRoot>default</cacheRoot>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>${gpg.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<repository>
|
||||||
|
<id>bintray-insanusmokrassar-StandardRepository</id>
|
||||||
|
<name>insanusmokrassar-StandardRepository</name>
|
||||||
|
<url>https://api.bintray.com/maven/insanusmokrassar/StandardRepository/${project.artifactId}/;publish=1</url>
|
||||||
|
</repository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlinx</groupId>
|
||||||
|
<artifactId>kotlinx-coroutines-core</artifactId>
|
||||||
|
<version>${kotlin.coroutines.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-test-junit</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>joda-time</groupId>
|
||||||
|
<artifactId>joda-time</artifactId>
|
||||||
|
<version>2.10</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@ -0,0 +1,4 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase.domain.UseCases
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.PsychomatrixBase.domain.entities.Psychomatrix
|
||||||
|
import kotlinx.coroutines.experimental.Deferred
|
||||||
|
import kotlinx.coroutines.experimental.channels.ReceiveChannel
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
interface UserCanCalculatePsychomatrixByDate {
|
||||||
|
suspend fun calculate(date: Long): Deferred<Psychomatrix>
|
||||||
|
suspend fun calculate(date: DateTime): Deferred<Psychomatrix>
|
||||||
|
suspend fun calculate(date: Date): Deferred<Psychomatrix>
|
||||||
|
|
||||||
|
suspend fun openPsychomatrixCreatedSubscription(): ReceiveChannel<Psychomatrix>
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase.domain.entities
|
||||||
|
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
private val dateFormat: DateFormat = SimpleDateFormat("dMyyyy", Locale.ROOT)
|
||||||
|
private fun Int.toDigits(): List<Byte> {
|
||||||
|
return "$this".map { "$it".toByte() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Psychomatrix(val date: DateTime) {
|
||||||
|
private val numbers: ByteArray = ByteArray(10)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always array 4*4 of values. In rows was put columns (
|
||||||
|
*/
|
||||||
|
val asMatrix: Array<Array<Byte>>
|
||||||
|
get() = arrayOf(
|
||||||
|
arrayOf(-1, -1, -1, getUpperDiagSum()),
|
||||||
|
arrayOf(numbers[1], numbers[4], numbers[7], getRowSum(0)),
|
||||||
|
arrayOf(numbers[2], numbers[5], numbers[8], getRowSum(1)),
|
||||||
|
arrayOf(numbers[3], numbers[6], numbers[9], getRowSum(2)),
|
||||||
|
arrayOf(getColumnSum(0), getColumnSum(1), getColumnSum(2), getDownDiagSum())
|
||||||
|
)
|
||||||
|
|
||||||
|
init {
|
||||||
|
val dateDigits = dateFormat.format(date).map { "$it".toByte() }.toMutableList()
|
||||||
|
|
||||||
|
val firstNumber = dateDigits.sum()
|
||||||
|
val firstNumberDigits = firstNumber.toDigits()
|
||||||
|
|
||||||
|
val secondNumber = firstNumberDigits.sum()
|
||||||
|
val secondNumberDigits = secondNumber.toDigits()
|
||||||
|
|
||||||
|
val thirdNumber = firstNumber - dateDigits[0] * 2
|
||||||
|
val thirdNumberDigits = thirdNumber.toDigits()
|
||||||
|
|
||||||
|
val fourthNumber = thirdNumberDigits.sum()
|
||||||
|
val fourthNumberDigits = fourthNumber.toDigits()
|
||||||
|
|
||||||
|
dateDigits.addAll(firstNumberDigits)
|
||||||
|
dateDigits.addAll(secondNumberDigits)
|
||||||
|
dateDigits.addAll(thirdNumberDigits)
|
||||||
|
dateDigits.addAll(fourthNumberDigits)
|
||||||
|
|
||||||
|
(0 until numbers.size).forEach {
|
||||||
|
index ->
|
||||||
|
numbers[index] = dateDigits.count {
|
||||||
|
it == index.toByte()
|
||||||
|
}.toByte()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return count of numbers of `i`
|
||||||
|
*/
|
||||||
|
operator fun get(i: Int): Byte {
|
||||||
|
return numbers[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 4 7 - zero row
|
||||||
|
* 2 5 8 - first row
|
||||||
|
* 3 6 9 - second row
|
||||||
|
*/
|
||||||
|
fun getRowSum(i: Int): Byte {
|
||||||
|
return (i + 1 until numbers.size step 3).map { numbers[it] }.sum().toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 4 7
|
||||||
|
* 2 5 8
|
||||||
|
* 3 6 9
|
||||||
|
* | | |
|
||||||
|
* z f s
|
||||||
|
* e i e
|
||||||
|
* r r c
|
||||||
|
* o s o
|
||||||
|
* t n
|
||||||
|
* d
|
||||||
|
*/
|
||||||
|
fun getColumnSum(i: Int): Byte {
|
||||||
|
val side = sqrt(numbers.size.toDouble() - 1).toInt()
|
||||||
|
val first = side * i + 1
|
||||||
|
return (first until first + side).map { numbers[it] }.sum().toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upper
|
||||||
|
* /
|
||||||
|
* 1 4 7
|
||||||
|
* 2 5 8
|
||||||
|
* 3 6 9
|
||||||
|
*/
|
||||||
|
fun getUpperDiagSum(): Byte {
|
||||||
|
val side = sqrt(numbers.size.toDouble() - 1).toInt()
|
||||||
|
return (side .. numbers.size - side step side - 1).map { numbers[it] }.sum().toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1 4 7
|
||||||
|
* 2 5 8
|
||||||
|
* 3 6 9
|
||||||
|
* \
|
||||||
|
* down
|
||||||
|
*/
|
||||||
|
fun getDownDiagSum(): Byte {
|
||||||
|
val side = sqrt(numbers.size.toDouble() - 1).toInt()
|
||||||
|
return (1 until numbers.size step side + 1).map { numbers[it] }.sum().toByte()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return (" %2d\n" +
|
||||||
|
"%2d %2d %2d %2d\n" +
|
||||||
|
"%2d %2d %2d %2d\n" +
|
||||||
|
"%2d %2d %2d %2d\n" +
|
||||||
|
"%2d %2d %2d %2d").format(
|
||||||
|
getUpperDiagSum(),
|
||||||
|
numbers[1],
|
||||||
|
numbers[4],
|
||||||
|
numbers[7],
|
||||||
|
getRowSum(0),
|
||||||
|
numbers[2],
|
||||||
|
numbers[5],
|
||||||
|
numbers[8],
|
||||||
|
getRowSum(1),
|
||||||
|
numbers[3],
|
||||||
|
numbers[6],
|
||||||
|
numbers[9],
|
||||||
|
getRowSum(2),
|
||||||
|
getColumnSum(0),
|
||||||
|
getColumnSum(1),
|
||||||
|
getColumnSum(2),
|
||||||
|
getDownDiagSum()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase.presentation.presenters
|
||||||
|
|
||||||
|
import com.github.insanusmokrassar.PsychomatrixBase.domain.entities.Psychomatrix
|
||||||
|
import kotlinx.coroutines.experimental.channels.ReceiveChannel
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
|
||||||
|
interface DatePickerPresenter {
|
||||||
|
|
||||||
|
suspend fun openPsychomatrixCreatedSubscription(): ReceiveChannel<Psychomatrix>
|
||||||
|
|
||||||
|
fun userPickDate(date: Long)
|
||||||
|
fun userPickDate(date: DateTime)
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase.utils.extensions
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun Calendar.getYear(): Int = get(Calendar.YEAR)
|
||||||
|
fun Calendar.getMonth(): Int = get(Calendar.MONTH)
|
||||||
|
fun Calendar.getDayOfMonth(): Int = get(Calendar.DAY_OF_MONTH)
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.github.insanusmokrassar.PsychomatrixBase.utils.extensions
|
||||||
|
|
||||||
|
import kotlinx.coroutines.experimental.*
|
||||||
|
import kotlinx.coroutines.experimental.channels.BroadcastChannel
|
||||||
|
import kotlinx.coroutines.experimental.channels.ReceiveChannel
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
fun <T> ReceiveChannel<T>.subscribeChecking(
|
||||||
|
throwableHandler: (Throwable) -> Boolean = {
|
||||||
|
it.printStackTrace()
|
||||||
|
true
|
||||||
|
},
|
||||||
|
by: suspend (T) -> Boolean
|
||||||
|
): Job {
|
||||||
|
return launch {
|
||||||
|
while (isActive && !isClosedForReceive) {
|
||||||
|
try {
|
||||||
|
val received = receive()
|
||||||
|
|
||||||
|
launch {
|
||||||
|
try {
|
||||||
|
if (!by(received)) {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
if (!throwableHandler(e)) {
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: CancellationException) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> ReceiveChannel<T>.subscribe(
|
||||||
|
throwableHandler: (Throwable) -> Boolean = {
|
||||||
|
it.printStackTrace()
|
||||||
|
true
|
||||||
|
},
|
||||||
|
by: suspend (T) -> Unit
|
||||||
|
): Job {
|
||||||
|
return subscribeChecking(throwableHandler) {
|
||||||
|
by(it)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> ReceiveChannel<T>.debounce(delayMs: Long, awaitedSubscriptions: Int = 256): BroadcastChannel<T> {
|
||||||
|
val channel = BroadcastChannel<T>(awaitedSubscriptions)
|
||||||
|
var lastReceived: Pair<Long, T>? = null
|
||||||
|
var job: Job? = null
|
||||||
|
launch {
|
||||||
|
while (isActive && !isClosedForReceive) {
|
||||||
|
val received = receive()
|
||||||
|
|
||||||
|
lastReceived = Pair(System.currentTimeMillis() + delayMs, received)
|
||||||
|
|
||||||
|
job ?:let {
|
||||||
|
job = launch {
|
||||||
|
try {
|
||||||
|
var now = System.currentTimeMillis()
|
||||||
|
while (isActive && lastReceived?.first ?: now >= now) {
|
||||||
|
delay((lastReceived ?.first ?: now) - now, TimeUnit.MILLISECONDS)
|
||||||
|
now = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
|
lastReceived?.second?.also {
|
||||||
|
channel.send(it)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
job = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
return channel
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user