Skip to content

Instantly share code, notes, and snippets.

@Neverik
Created November 23, 2018 14:28
Show Gist options
  • Save Neverik/10b89fcadf2fc758f39abe5033567258 to your computer and use it in GitHub Desktop.
Save Neverik/10b89fcadf2fc758f39abe5033567258 to your computer and use it in GitHub Desktop.
A puzzle solution (I will maybe refactor this)
import kotlinx.coroutines.*
import java.util.Random
import kotlin.system.exitProcess
// We have a worker who makes machines every 800ms as long as there is less than 5 of them
// Every machine produces a code using `produce` function every second. It saves this code to shared space. In case of an error, it ends working.
// We have a single manager that once a 2 seconds takes all produced codes and prints them all. After 5 times it ends all jobs (including machines and worker).
class Message(val id: String, val txt: String, var new: Boolean = true) {
override fun toString(): String {
return "$id: $txt."
}
}
private fun main(): Unit = runBlocking {
val machines = mutableListOf<Job>()
val messages = mutableListOf<Message>()
coroutineScope {
val creator = launch {
while (machines.filter { it.isActive }.size < 5) {
delay(800L)
machines.add(launch {
val id = this.hashCode().toString().substring(0, 4)
messages.add(Message(id, "born"))
try {
while (true) {
delay(1000)
val code = produce()
messages.add(Message(id, code))
}
} catch (_: RandomError) {
messages.add(Message(id, "died"))
}
})
}
}
launch {
var n = 0
repeat(5) {
delay(2000L)
messages.filter { a -> a.new }.forEach { a ->
print("$a ")
a.new = false
}
println()
n += 1
}
creator.cancelAndJoin()
machines.forEach { it.cancelAndJoin() }
}
machines.forEach { it.join() }
}
while (true) {
print("Would you like to get some more info (y/n)?")
val yn = readLine()!!.toLowerCase()
if (yn == "y") {
print("Which machine's life would you like to explore (enter id)? ")
val worker = readLine()
println("Here you go:")
messages.filter { it.id == worker }.forEach {
println(it.txt)
}
} else if (yn == "n") {
println("Goodbye!")
exitProcess(0)
}
}
}
class RandomError : Throwable()
private val letters = ('a'..'z') + ('0'..'9')
private val random = Random()
private fun produce(): String = when (random.nextInt(8)) {
0 -> throw RandomError()
else -> (1..5).map { letters[random.nextInt(letters.size)] }.joinToString(separator = "")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment