Created
February 13, 2020 03:21
-
-
Save CattenLinger/fdc935448828a51d19f9222c055f4170 to your computer and use it in GitHub Desktop.
CustomBaseNumberKt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.catten.demo | |
import java.util.* | |
import kotlin.math.abs | |
private const val dummy = '_' | |
private val codec = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toSet().toCharArray() | |
private val base = codec.size | |
private val max = Long.MAX_VALUE.toCustomBase() | |
private val maxLength = max.length | |
fun Long.toCustomBase(): String { | |
if (this == 0L) return codec[0].toString() | |
var number = abs(this) | |
var r = "" | |
while (number > 0) { | |
r += codec[(number % base).toInt()] | |
number /= base | |
} | |
return r.reversed() | |
} | |
private val random = Random() | |
fun Long.toCustomBase(length: Int): String { | |
val l = if (length > maxLength) maxLength else length | |
return toCustomBase().let { s -> | |
if (s.length >= l) | |
s | |
else | |
"$dummy$s".let { ls -> | |
if (ls.length == l) | |
ls | |
else | |
(l - ls.length) | |
.downTo(1) | |
.map { codec[random.nextInt(base)] } | |
.joinToString(separator = "") { "$it" } | |
.plus(ls) | |
} | |
} | |
} | |
fun String.parseCustomBaseNumber(): Long { | |
var n = 0L | |
var p = 1L | |
for (c: Char in reversed()) { | |
if (c == dummy) break | |
n += codec.indexOf(c) * p | |
p *= base | |
} | |
return n | |
} | |
fun main() { | |
val bigNumber = abs(random.nextLong()) | |
val encoded = bigNumber.toCustomBase(11) | |
val decoded = encoded.parseCustomBaseNumber() | |
println(""" | |
Base : $base | |
Max : $max | |
Max Length : ${max.length} | |
------------------------------------ | |
Origin : $bigNumber | |
Encoded : $encoded | |
Length : ${encoded.length} | |
Decoded : $decoded | |
""".trimIndent()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
来自 @duangsuse 的点评:
我也 重复了一下
个人建议:下次
iter.joinToString("") { "$it" }
这类可读性不高的还是用iter.joinToString("", Char::toString)
代替好了,尤其是 dollar string 不能滥用。你写了 10 行的
parseCustomNumber()
核心思想其实就两行:用 Kotlin 官方风格写是这样:
我说的另一种顺序是指直接连着 accumulator 去 shift
当然这个也可以写到一行内
个人建议:算法相关的逻辑不要放到 extension fun 里,
算法和框架的扩展一定严格区分开,不然有点怪怪的……
忍不住想到了
readLn >>= \ls -> putStrLn ls
这种代码我不说炫技,但难看是坐实的。
提升 indent level 在这里是很浪费的行为,因为它的缩进已经很深了
Kotlin 的确是强大,但简单却是它不同于其他语言的重要特征