scanner in kotlin to read in 2 lines - kotlin

Here is the code. n continually outputs 50 and not 2:
import java.util.*
fun main(args: Array<String>) {
val scanner = Scanner(System.`in`)
val n = scanner.next().first().toInt()
val array1 = readLine()!!.split(" ").map { it.toInt() }
var product:Int=0
println(n)
println(array1[0])
println(array1[1])
if (n ==2) {
product = array1[0] * array1[1]
}
println(product)
}
Sample Input:
2
5 3
Output:
2
5 3
50
5
3
0
How do I use scanner in kotlin to read in 2 lines?

Short form
Use scanner.nextInt() instead of scanner.next().first().toInt().
Explanation
By calling scanner.next() you receive the next complete token of the Scanner as a String. Then you take the first character using first(). The problem is, that calling toInt() on a Char will not parse the string as an integer value but return the ASCII char code of the char.
Example: '2'.toInt() returns 50 and not 2 since the ASCII char code of 2 is 50. (See https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html)
Conclusion: In your case, directly read the integer value from the Scanner using scanner.nextInt(), but if you want to convert a char to an integer by "parsing", convert it to a string first: '2'.toString().toInt() will return an integer with the value 2
Addition
It is probably nice to know that you can also use this the other way round: 50.toChar() returns a character with the value '2'.
👍

Related

Is it valid to use readLine()!! without adding toInt() if the input is an Int?

Sorry for this dumb question:
It says readLine()!! reads line as a string, but if I enter an integer without adding .toInt(), it runs fine?:
Sample input: 55
fun main() {
println("Enter any number here: ")
val a = readLine()!!
print(a)
}
//prints 55
I am a bit confused, because it prints 55 without any issues. So, readLine()!! can read any type of data and return 55, even if it's not a String?
Actually the 55 you entered is a string and it was printed as string representation also. You couldn't use the 55 to do arithmetic computation eg. 55 - 10 without make it as integer or other number representation like double.
You can check the type like this
if (a is String) {
print("It's string")
}

String "2" toInt returns 50

Im just working through some simple practice problems in kotlin. In my code below I'm taking a number and attempting to add the number members together. Ex. 29, return 2 + 9 = 11. There could be a better way to accomplish this but, I'm taking the numbers, converting to string, and then putting them into a list, ie ["2","9"] when I attempt to convert list[0].toInt() it returns 50. It appears there is some rounding taking place but I have not found another kotlin method to work with. Can anyone offer some insights? TIA
fun main(args: Array<String>) {
fun addTwoDigits(n: Int): Int {
val sliced = n.toString().toList()
val int1 = sliced[0].toInt()
println(sliced[0]) //returns "2"
println(int1) // returns 50
return sliced[0].toInt() + sliced[1].toInt()
}
println(addTwoDigits(29))
}
Koltin Char.toString(), which you are using in line:
val int1 = sliced[0].toInt()
converts the character using the ASCII Code table.
You can simply add a toString() call before the toInt() call:
val int1 = sliced[0].toString().toInt()

Format a number to string, fill 0 when it's not enough two characters

I want to format the number to String and fill 0 when it's not enough two characters
fun formatDuration(val duration):String {
val minutes = duration.toInt() / 60
return "$minutes"
}
For example, if minutes is 6, it should displayed 06 rather than 6.
You can padStart the toString() result of minutes.
I tried your code in the Kotlin Playground and it wasn't compilable / runnable. For the following example, I had to change parts of your fun:
fun main() {
println(formatDuration(364.34))
}
fun formatDuration(duration: Double): String {
val minutes = duration.toInt() / 60
// fill the result to be of 2 characters, use 0 as padding char
return minutes.toString().padStart(2, '0')
}
Executing this results in the output 06.
Alternatively, you can simply use String.format() from Java, just
return "%02d".format(minutes)
instead of return minutes.toString().padStart(2, '0'), the result stays the same.
You can achive this with padStart
Example:
val padWithSpace = "125".padStart(5)
println("'$padWithSpace'") // ' 125'
val padWithChar = "a".padStart(5, '.')
println("'$padWithChar'") // '....a'
// string is returned as is, when its length is greater than the specified
val noPadding = "abcde".padStart(3)
println("'$noPadding'") // 'abcde'

How to convert digit to character in Kotlin?

I'm trying to find the simplest way to convert a digit (0..9) into the respective character '0'..'9' in Kotlin.
My initial attempt was to write the following code:
fun convertToCharacter() {
val number = 0
val character = number.toChar()
println(character)
}
Of course, after running, I quickly saw that this produces \u0000, and not '0' like I expected. Then, remembering from how to do this in Java, I modified the code to add '0', but then this would not compile.
fun convertToCharacter() {
val number = 0
val character = number.toChar() + '0'
println(character)
}
What is the appropriate way to convert a number into its respective character counterpart in Kotlin? Ideally, I'm trying to avoid pulling up the ASCII table to accomplish this (I know I can add 48 to the number since 48 -> '0' in ASCII).
val character = '0' + number
is the shortest way, given that the number is in range 0..9
Kotlin stdlib provides this function since 1.5.0.
fun Int.digitToChar(): Char
Returns the Char that represents this decimal digit. Throws an exception if this value is not in the range 0..9.
If this value is in 0..9, the decimal digit Char with code '0'.code + this is returned.
Example
println(5.digitToChar()) // 5
println(3.digitToChar(radix = 8)) // 3
println(10.digitToChar(radix = 16)) // A
println(20.digitToChar(radix = 36)) // K
Like you said, probably the easiest way to convert an Int to the Char representation of that same digit is to add 48 and call toChar():
val number = 3
val character = (number + 48).toChar()
println(character) // prints 3
If you don't want to have the magic 48 number in your program, you could first parse the number to a String and then use toCharArray()[0] to get the Char representation:
val number = 3
val character = number.toString().toCharArray()[0]
println(character) // prints 3
Edit: in the spirit of the attempt in your question, you can do math with '0'.toInt() and get the result you were expecting:
val number = 7
val character = (number + '0'.toInt()).toChar()
println(number) // prints 7
How about 0.toString() instead of 0.toChar() ? If you are specifically after single digits, then 0.toString()[0] will give you a Char type
You can use an extension like this:
fun Int.toReadableChar(): Char {
return ('0'.toInt() + this).toChar()
}
You can apply this to any other class you want :)
Example:
println(7.toReadableChar())
>> 7

What happens with toInt()

I currently start to learn Kotlin and I was making this code
val a = "1"
val b = a[0]
val c = b.toInt()
println(c)
When I run the code, the result is 49. What really happened? Because I think the result will be 1.
a is a String, which is a CharSequence. That is why you can access a[0] in the first place. a.get(0) or a[0] then returns a Char. Char on the other hand returns its character value when calling toInt(), check also the documentation of toInt().
So your code commented:
val a = "1" // a is a String
val b = a[0] // b is a Char
val c = b.toInt() // c is (an Int representing) the character value of b
If you just want to return the number you rather need to parse it or use any of the answers you like the most of: How do I convert a Char to Int?
(one simple way being b.toString().toInt()).
a is String,
when you get a[index] return type is char,
in kotlin char.toInt method return ASCII code of the character and it's 49
if you want to get the integer value of "1" just use toString method
val a = "1"
val b = a[0].toString()
val c = b.toInt()
println(c)
prints:1
In your example a is a String, but String. String is under the hood an Array of Char. And by accessing your String using a[0] operator, you get first element of this Char Array. So you get Char '1', not String "1". And now, when you run '1'.toInt() function on Char - it will return ASCII code of that Char. When you run "1".toInt() on String - it will convert this String into Int "1". When you need to get Int value of first letter in your String, you need to convert it first into String:
val a = "123"
val b = a[0].toString() // returns first Char of String "123" and converts to String
val c = b.toInt() // returns Int: 1
or in one line:
"123"[0].toString().toInt()