Hello everybody
I'm learning a new programming language nowadays - Kotlin and could not miss the opportunity to practice it with the BitcoinTalk raw data for merit flow available by
https://bitcointalk.org/merit.txt.xz.
I've got an idea that probably merit is going in circles - one user merits another, then second user merits the third and then third returns merit to the first. For whatever reason.
With the available data it is quite easy to check. I'm not that good at algorithms, so just created a quick and dirty script.
The data result is quite interesting.
There are circles and some of them of different size.
These which are user1 -> user2 - > user1 I call circle size 2, these of type user1 -> user2 -> user3 - > user1 circle of size 3 etc
The example script output:
Circle found: [988147, 521226, 995414, 929472, 995414, 521226, 988147]
Circle found: [988147, 521226, 995414, 929472, 995414, 929472, 995414, 521226, 995414, 521226, 988147]
Circle found: [988147, 521226, 995414, 929472, 995414, 929472, 995414, 521226, 988147]
Circle found: [988147, 521226, 995414, 929472, 995414, 929472, 995414, 929472, 995414, 521226, 988147]
Circle found: [988147, 521226, 988147]
Circle found: [1343594, 1196051, 1343594]
Circle found: [1517809, 658788, 1517809]
The script itself (warning - ugly, inefficient and probably contains bugs):
import java.io.File
// max recursion level
val maxLevel = 10
// minimum circle size
val maxCircleSize = 5
// restrict check only to users who gave merit less than maxMeritedUsers times
val maxMeritedUsers = 5
val events = File("../merit.txt")
.readLines()
.drop(1)
.map { it.split("\t") }
.map { (_, _, _, userFrom, userTo) -> Pair(userFrom, userTo) }
.groupBy { it.first }
.map { (userFrom, events) -> Pair(userFrom, events.map { it.second }) }
.filter { it.second.size < maxMeritedUsers }
.associate { it.first to it.second }
fun checkCircle(userFrom: String, usersTo: List<String>, circle: List<String>, level: Int) {
if (level >= maxLevel) {
return
}
usersTo.forEach { userTo ->
if (userFrom == userTo) {
println("Circle found: ${circle + userTo}")
} else {
checkCircle(userFrom, events[userTo].orEmpty(), circle + userTo, level + 1)
}
}
}
println("Unique user sent merit: ${events.keys.size}")
events.keys.forEach { userFrom ->
val circle = listOf(userFrom)
checkCircle(userFrom, events[userFrom].orEmpty(), circle, 0)
}
In order to run it you need to install Kotlin compiler.
Please feel free to play with it, for whatever goal. I hope it is interesting )