program crashes in android studio while writing funtion with loops - kotlin

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?

Related

Fizz-Buzz solution is not working properly in kotlin

In the Fizz-Buzz problem, we replace a number multiple of 3 with the word fizz and a number divisible by 5 with the word buzz. If a number is divisible by both three and five, we replace it with the word"FizzBuzz." in a counting incremental loop.
But my code is not working properly. Please take a look and let me know what I am doing wrong.
for (i in 1..100){
if ( i%5 == 0 || i%3 == 0) {
println("FizzBuzz")}
else if(i%5 == 0) {
println("Buzz")}
else if(i%3 == 0){
println("Fizz")}
else {
println(i)
}
}
You are using || instead of &&.
Replace:
if (i%5 == 0 || i%3 == 0) {
println("FizzBuzz")
}
With:
if (i%5 == 0 && i%3 == 0) {
println("FizzBuzz")
}
Or with:
if (i%15 == 0) {
println("FizzBuzz")
}
The more elegant solution is:
fun fizzBuzz(currentNumber: Int) = when {
currentNumber % 15 == 0 -> "FizzBuzz"
currentNumber % 3 == 0 -> "Fizz"
currentNumber % 5 == 0 -> "Buzz"
else -> "$currentNumber"
}
for (currentNumber in 1..100) {
print(fizzBuzz(currentNumber))
}

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)

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]}")

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

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

Calculating size of Google Firestore documents

Firestore docs give details of how to manually calculate the stored size of a document, but there does not seem to be a function provided for this on any of document reference, snapshot, or metadata.
Before I attempt to use my own calculation, does anyone know of an official or unofficial function for this?
Here is my (completely untested) first cut for such a function from my interpretation of the docs at https://firebase.google.com/docs/firestore/storage-size
function calcFirestoreDocSize(collectionName, docId, docObject) {
let docNameSize = encodedLength(collectionName) + 1 + 16
let docIdType = typeof(docId)
if(docIdType === 'string') {
docNameSize += encodedLength(docId) + 1
} else {
docNameSize += 8
}
let docSize = docNameSize + calcObjSize(docObject)
return docSize
}
function encodedLength(str) {
var len = str.length;
for (let i = str.length - 1; i >= 0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) {
len++;
} else if (code > 0x7ff && code <= 0xffff) {
len += 2;
} if (code >= 0xDC00 && code <= 0xDFFF) {
i--;
}
}
return len;
}
function calcObjSize(obj) {
let key;
let size = 0;
let type = typeof obj;
if(!obj) {
return 1
} else if(type === 'number') {
return 8
} else if(type === 'string') {
return encodedLength(obj) + 1
} else if(type === 'boolean') {
return 1
} else if (obj instanceof Date) {
return 8
} else if(obj instanceof Array) {
for(let i = 0; i < obj.length; i++) {
size += calcObjSize(obj[i])
}
return size
} else if(type === 'object') {
for(key of Object.keys(obj)) {
size += encodedLength(key) + 1
size += calcObjSize(obj[key])
}
return size += 32
}
}
In Android, if you want to check the size of a document against the maximum of 1 MiB (1,048,576 bytes), there is a library that can help you with that:
https://github.com/alexmamo/FirestoreDocument-Android/tree/master/firestore-document
In this way, you'll be able to always stay below the limit. The algorithm behind this library is the one that is explained in the official documentation regarding the Storage Size.