kotlin Exception in thread "main" java.lang.IndexOutOfBoundsException - kotlin

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index:
62, Size: 62
I can't fix this annoying error. I use indexes = size of List but have this exception
import java.io.File
fun main(args: Array<String>) {
fun markdownToHtmlSimple(inputName: String) {
val writer = File("out.txt").bufferedWriter()
val str = File(inputName).readLines()
var countTagI = 0
var countTagB = 0
var countTagS = 0
var openedTagI = false
var openedTagB = false
var openedTagS = false
writer.write("<html>\n\t<body>\n\t\t<p>")
for (i in 0..str.size) {
if (str[i] == "") writer.newLine()
else {
Regex("""\*\*""").replace(str[i], "☺") //временная замена для облегчения поиcка
Regex("""\~\~""").replace(str[i], "☻") //аналогично
val currentStr = str[i].toList()
for (j in 0..currentStr.size) {
when {
currentStr[j] == '*' -> countTagI++
currentStr[j] == '☺' -> countTagB++
currentStr[j] == '☻' -> countTagS++
}
}
if ((countTagB % 2 == 0) && (countTagI % 2 == 0) && (countTagS % 2 == 0)) for (j in 0..currentStr.size) {
when {
(currentStr[j] == '*') && !openedTagI -> {
writer.write("<i>")
openedTagI = true
}
(currentStr[j] == '*') && openedTagI -> {
writer.write("</i>")
openedTagI = false
}
(currentStr[j] == '☺') && !openedTagB -> {
writer.write("<b>")
openedTagI = true
}
(currentStr[j] == '☺') && openedTagB -> {
writer.write("</b>")
openedTagI = false
}
(currentStr[j] == '☻') && !openedTagS -> {
writer.write("<s>")
openedTagS = true
}
(currentStr[j] == '☻') && openedTagS -> {
writer.write("</s>")
openedTagS = false
}
else -> writer.write(currentStr[j].toString())
}
}
}
}
}
markdownToHtmlSimple("input.txt")
}
I use only three constructions for and they are limited with size of Arrays
Please help where is my error?

Replace
0..str.size
with
0 until str.size

Related

program crashes in android studio while writing funtion with loops

I got a problem in mainActivity.kt
The program starts perfectly but after I click any button(which needs check() function) the program stops responding and it closes. I have created wincombination with mutable list.
and firtsplayer and secondplayer.
var firstPlayer = ArrayList()
var secondPlayer = ArrayList<Int>()
private val wincombination = listOf( listOf(1,2,3), listOf(4,5,6), listOf(7,8,9), listOf(1,4,7), listOf(2,5,8), listOf(3,6,9), listOf(1,5,9), listOf(3,5,7) )
after play game firstplayer and secondplayer have their numbers like this [5, 4, 6]
and in function check(),i have for loop to see if there is match in firstplayer components and wincombination.it's my fun check()
private fun check() {
for (i in 0..7){
if(wincombination[i].contains(secondPlayer[0]) && wincombination[i].contains(secondPlayer[1]) &&
wincombination[i].contains(secondPlayer[2])){
score.add(1,1)
Toast.makeText(this, "0 is winner", Toast.LENGTH_SHORT).show()
}
}
for (i in 0..7){
if(wincombination[i].contains(firstPlayer[0]) && wincombination[i].contains(firstPlayer[1]) &&
wincombination[i].contains(firstPlayer[2])){
score.add(0,1)
Toast.makeText(this, "X is winner", Toast.LENGTH_SHORT).show()
}
}
if (firstPlayer.size+secondPlayer.size==9){
Toast.makeText(this, "it's draw", Toast.LENGTH_SHORT).show()
}
}
i tried writing check function with if statements,where i write some of the combination separately.
programs works fine.
here is check funtion with if statements
private fun check() {
var winnerPlayer=0
if (firstPlayer.contains(1) && firstPlayer.contains(2) && firstPlayer.contains(3)){
winnerPlayer = 1
}
if (secondPlayer.contains(1) && secondPlayer.contains(2) && secondPlayer.contains(3)){
winnerPlayer = 2
}
if (firstPlayer.contains(4) && firstPlayer.contains(5) && firstPlayer.contains(6)){
winnerPlayer = 1
}
if (secondPlayer.contains(4) && secondPlayer.contains(5) && secondPlayer.contains(6)){
winnerPlayer = 2
}
if (firstPlayer.contains(7) && firstPlayer.contains(8) && firstPlayer.contains(9)){
winnerPlayer = 1
}
if (secondPlayer.contains(7) && secondPlayer.contains(8) && secondPlayer.contains(9)){
winnerPlayer = 2
}
if (firstPlayer.contains(1) && firstPlayer.contains(4) && firstPlayer.contains(7)){
winnerPlayer = 1
}
if (secondPlayer.contains(1) && secondPlayer.contains(4) && secondPlayer.contains(7)){
winnerPlayer = 2
}
if (firstPlayer.contains(2) && firstPlayer.contains(5) && firstPlayer.contains(8)){
winnerPlayer = 1
}
if (secondPlayer.contains(2) && secondPlayer.contains(5) && secondPlayer.contains(8)){
winnerPlayer = 2
}
if (firstPlayer.contains(3) && firstPlayer.contains(6) && firstPlayer.contains(9)){
winnerPlayer = 1
}
if (secondPlayer.contains(3) && secondPlayer.contains(6) && secondPlayer.contains(9)){
winnerPlayer = 2
}
if (firstPlayer.contains(1) && firstPlayer.contains(5) && firstPlayer.contains(9)){
winnerPlayer = 1
}
if (secondPlayer.contains(1) && secondPlayer.contains(5) && secondPlayer.contains(9)){
winnerPlayer = 2
}
if (firstPlayer.contains(3) && firstPlayer.contains(5) && firstPlayer.contains(7)){
winnerPlayer = 1
}
if (secondPlayer.contains(3) && secondPlayer.contains(5) && secondPlayer.contains(7)){
winnerPlayer = 2
}
if (winnerPlayer==1){
score.add(0,1)
Toast.makeText(this, "X is winner", Toast.LENGTH_SHORT).show()
}else if(winnerPlayer==2){
score.add(1,1)
Toast.makeText(this, "0 is winner", Toast.LENGTH_SHORT).show()
}
}
how can i work this code with for loop?
does it need some other additional?

I tried to run this code and every time I run it shows this result

private fun moveMarkerAnimation(key: String, newData: AnimationModel, marker: Marker?, from: String, to: String) {
if (!newData.isRun)
{
compositeDisposable.add(
iGoogleAPI.getDirections(
"driving",
"less_driving",
from, to,
getString(R.string.google_api_key1)
)!!.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { returnResult ->
Log.d("API_RETURN",returnResult,)
try {
val jsonObject = JSONObject(returnResult)
val jsonArray = jsonObject.getJSONArray("routes")
for ( i in 0 until jsonArray.length())
{
val route = jsonArray.getJSONObject(i)
val poly = route.getJSONObject("overview_polyLine")
val polyLine = poly.getString("points")
polylineList = Common.decodePoly(polyLine) as java.util.ArrayList<LatLng?>
}
handler = Handler()
index = -1
next = 1
val runnable = object :Runnable{
override fun run() {
if (polylineList!!.size > 1)
{
if (index< polylineList!!.size)
{
index ++
next = index+1
start = polylineList!![index] !!
end = polylineList!![next]!!
}
val valueAnimator = ValueAnimator.ofInt(0,1)
valueAnimator.duration = 3000
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.addUpdateListener { value ->
v = value.animatedFraction
lat = v*end !!.latitude + (1-v) * start!!.latitude
lng = v*end !!.longitude+ (1-v) * start!!.longitude
val newPos = LatLng(lat,lng)
marker!!.position = newPos
marker!!.setAnchor(0.5f,0.5f)
marker!!.rotation = Common.getBearing(start!!,newPos)
}
valueAnimator.start()
if (index < polylineList!!.size-2)
{
handler!!.postDelayed(this,1500)
}else if (index < polylineList!!.size-1)
{
newData.isRun = false
Common.driversSubscrib.put(key,newData)
}
}
}
}
handler!!.postDelayed(runnable,1500)
}
catch (e:java.lang.Exception){
Snackbar.make(requireView(),e.message!!,Snackbar.LENGTH_LONG).show()
}
When the site changes from from firebase this result appears
022-04-26 13:19:30.912 23482-23482/com.example.bustrackerriderapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bustrackerriderapp, PID: 23482
io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading
what should I do to fix this problem

Cannot format given Object as a Number in Kotlin

An error occurred while using the ConverPrice function as follows for information about the price.
The price of the item in the recycler view adapter onBindViewHolder.
As a result of debugging, the error occurs in the following code.
priceText =
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
Please check my code and answer.
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is DataViewHolder -> {
val item = dataList[position]
item.price.let {
holder.price.text = ConvertPrice(item, holder.price)
}
}
}
}
fun ConvertPrice(productDetail: ProductDetail?, tv: TextView? = null, setPrice: Boolean = false): String {
val disableColor = Color.parseColor("#aaaaaa")
val enableColor = Color.parseColor("#3692ff")
tv?.setTextColor(disableColor)
if (ProductDetail != null) {
val priceMin = productDetail.priceMin
val priceMax = productDetail.priceMax
var priceText = ""
val dec = DecimalFormat("##,###")
productDetail.enabledRetail?.let {
if (productDetail.enabledRetail == true) {
if (setPrice) {
priceText = if (priceMin == null || priceMax == null) {
"No pricing information"
} else {
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
}
tv?.setTextColor(disableColor)
}
else {
priceText = dec.format(wineDetail.price).toString()
tv?.setTextColor(enableColor)
}
return priceText
} else if (productDetail.cntRating!! > 0) {
if ((priceMin == null && priceMax == null) || (priceMin == 0 && priceMax == 0)) {
priceText = "No pricing information"
} else {
priceText =
"${dec.format(priceMin)} ~ ${dec.format(priceMax)}"
tv?.setTextColor(disableColor)
}
return priceText
}
}
}
return "No pricing information"
}
DecimalFormat.format() only works fine with long or double. You should convert "priceMin" and "priceMax" to Long.
val priceMin = productDetail.priceMin.toLong()
val priceMax = productDetail.priceMax.toLong()
I recommend to use NumberFormat instead of DecimalFormat because it is locale-sensitive
val decFormat = NumberFormat.getInstance() // or getCurrencyInstance()
decFormat.maximumFractionDigits = 3
decFormat.format(priceMin)
decFormat.format(priceMax)

Kotlin: Run length encoding

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
}

A very basic exercise help-----Kotlin

Im trying to do this exercise
https://www.hackerrank.com/challenges/compare-the-triplets/problem?h_r=next-challenge&h_v=zen
I already wrote the code but the result is not right and for my eyes its all good
Could somebody pls tell me whats wrong??
thx
import java.util.Scanner
fun main(){
var loop = 0
var score = Array<Int>(2){0}
val reader = Scanner(System.`in`)
var alice:String = readLine().toString()
var bob:String = readLine().toString()
val numerosa: List<String> = alice.split(" ")
val numerosb:List<String> = bob.split(" ")
for(a in 3..3) {
when (numerosa[loop].toInt()) {
in numerosb[loop].toInt() + 1..100 -> score[0] += 1
in numerosb[loop].toInt() - 1..0 -> score[1] += 1
}
loop += 1
}
println("${score[0]} ${score[1]}")
}
You could do it something like this, you have multiple variables which were not required so I cleaned up the code.
val score = Array(2) { 0 }
val aliceNumbers = readLine()!!.split(" ").map(String::toInt)
val bobNumbers = readLine()!!.split(" ").map(String::toInt)
require(aliceNumbers.size == 3 && bobNumbers.size == 3) { "There must be 3 numbers for each" }
require(!aliceNumbers.any { it !in 1..100 } || !bobNumbers.any { it !in 1..100 }) { "Numbers must be in range 1 to 100" }
for (a in 0..2) {
if(aliceNumbers[a] > bobNumbers[a]) score[0] += 1
if(aliceNumbers[a] < bobNumbers[a]) score[1] += 1
}
println("${score[0]} ${score[1]}")