I´m new to Kotlin so first I start with a Password Generator. I do use IntelliJIDea
fun main() {
var helper = Int
var counter = 0
val counterOfPwCha = 10
var pwString = ""
val opportunityArray = arrayOf('A','C','a','c','B','b','D','d','E','e','F','f','#','+','*','$','%','&','§','G','g','H','h','I','i','J','j','k','K','1','2','3','4','5','6','7','8','9',
'l','L','M','m','N','n','O','o','P','p','Q','q','R','r','S','s','T','t','U','u','V','v','W','w','Y','y','X','x','Z','z','<','>','|','?','!',)
while (counter <= counterOfPwCha)
{
helper = (0..73).random()
pwString += opportunityArray[helper]
counter++
}
println(pwString)
}
it workes fine, but the output isn´t what I expected.
Example: +3�2L%II>J�
So it cant handle some of my Chars, I can debug it until I know what kind of Char he can´t handle with and delete them from the Array, but they are all some typical PW Chars, so my question is:
How can I let Kotlin know, how to Handle these ASCI2 chars?
Or is it because of the $?
Avoid hardcoded numbers like the "73" in your range, it's way too error prone!
If you still get funny characters, put in some println that shows each character's numeric value so that you can lookup it using "man ascii".
A more Kotlin-like code would be:
fun pwgen() {
val counterOfPwCha = 10
val charset = ('A'..'Z') + ('a'..'z') + ('0'..'9') + listOf('#', '+', '*', '$', '%', '&', '§', '<', '>', '|', '?', '!')
val pwString = (1..counterOfPwCha)
.map {
val randomArrayIndex = charset.indices.random()
charset[randomArrayIndex]
}
.onEach { c -> println("Character $c = " + c.toInt()) }
.joinToString("")
println(pwString)
}
fun main() {
var helper = Int
var counter = 0
val counterOfPwCha = 10
var pwString = ""
val opportunityArray = arrayOf('A','C','a','c','B','b','D','d','E','e','F','f','#','+','*','$','%','&','§','G','g','H','h','I','i','J','j','k','K','1','2','3','4','5','6','7','8','9',
'l','L','M','m','N','n','O','o','P','p','Q','q','R','r','S','s','T','t','U','u','V','v','W','w','Y','y','X','x','Z','z','<','>','|','?','!',)
while (counter <= counterOfPwCha)
{
helper = (0..73).random()
pwString += opportunityArray[helper]
counter++
}
println(pwString)
}
I'm struggling with types with my program, I've been asked to do it in JS first and it worked fine but now I can't achieve the result.
Do you think I should make another 'algorithm' ? In advance, thank you for your time.
fun main(){
// the idea is to put numbers in a box
// that cant be larger than 10
val data = "12493419133"
var result = data[0]
var currentBox = Character.getNumericValue(data[0])
var i = 1
while(i < data.length){
val currentArticle = Character.getNumericValue(data[i])
currentBox += currentArticle
println(currentBox)
if(currentBox <= 10){
result += Character.getNumericValue(currentArticle)
}else{
result += '/'
//var resultChar = result.toChar()
// result += '/'
currentBox = Character.getNumericValue(currentArticle)
result += currentArticle
}
i++
}
print(result) //should print 124/9/341/91/33
}
The result is actually of a Char type, and the overload operator function + only accepts Int to increment ASCII value to get new Char.
public operator fun plus(other: Int): Char
In idomatic Kotlin way, you can solve your problem:
fun main() {
val data = "12493419133"
var counter = 0
val result = data.asSequence()
.map(Character::getNumericValue)
.map { c ->
counter += c
if (counter <= 10) c.toString() else "/$c".also{ counter = c }
}
.joinToString("") // terminal operation, will trigger the map functions
println(result)
}
Edit: If the data is too large, you may want to use StringBuilder because it doesn't create string every single time the character is iterated, and instead of using a counter of yourself you can use list.fold()
fun main() {
val data = "12493419133"
val sb = StringBuilder()
data.fold(0) { acc, c ->
val num = Character.getNumericValue(c)
val count = num + acc
val ret = if (count > 10) num.also { sb.append('/') } else count
ret.also { sb.append(c) } // `ret` returned to ^fold, next time will be passed as acc
}
println(sb.toString())
}
If you want a result in List<Char> type:
val data = "12493419133"
val result = mutableListOf<Char>()
var sum = 0
data.asSequence().forEach {
val v = Character.getNumericValue(it)
sum += v
if (sum > 10) {
result.add('/')
sum = v
}
result.add(it)
}
println(result.joinToString(""))
The program works, however, I still get a logical error: the final letter doesn't run through. For example, when I enter aaaabbbbccccdddd the output I get is a4b4c4 but there is no d4.
fun main () {
val strUser = readLine()!!.toLowerCase()
val iLength = strUser!!.length
var iMatch : Int = 0
var chrMatch : Char = strUser[0]
for (i in 0..iLength) {
if (strUser[i] == chrMatch) {
iMatch += 1
}else {
print("$chrMatch$iMatch")
chrMatch = strUser[i]
iMatch = 1
}
}
}
There are many solutions, but the best is RegExp
fun encode(input: String): String =
input.replace(Regex("(.)\\1*")) {
String.format("%d%s", it.value.length, it.groupValues[1])
}
demo
Test result
println(encode("aaaabbbbccccdddd")) // 4a4b4c4d
strUser contains chars by indexes from 0 to iLength - 1 so you have to write for (i in 0 until iLength) instead of for (i in 0..iLength)
But Tenfour04 is completely right, you can just iterate strUser without indexes:
fun main() {
val strUser = readLine()!!.toLowerCase()
var iMatch: Int = 0
var chrMatch: Char = strUser[0]
for (char in strUser) {
if (char == chrMatch) {
iMatch += 1
} else {
print("$chrMatch$iMatch")
chrMatch = char
iMatch = 1
}
}
}
fun main () {
val strUser = readLine()!!.toLowerCase()
var iMatch : Int = 0
var chrMatch : Char = strUser[0]
for (char in strUser+1) {
if (char == chrMatch) {
iMatch += 1
}else {
print("$chrMatch$iMatch")
chrMatch = char
iMatch = 1
}
}
}
fun runLengthEncoding(inputString: String): String {
val n=inputString.length
var i : Int =0
var result : String =""
while(i<n){
var count =1
while(i<n-1 && inputString[i] == inputString[i+1]){
count ++
i++
}
result=result.toString()+count.toString()+inputString[i].toString()
i++
}
return result
}