Home > Net >  Conditional loop repetitively printing wrong output
Conditional loop repetitively printing wrong output

Time:10-12

I wasn't sure how to phrase the title sorry. Basically I'm writing a code that draws up a cinema and seating. The program asks input for how many rows in the cinema and how many seats and returns this: Cinema:

  1 2 3 4 5 6 7 8 9 
1 S S S S S S S S S
2 S S S S S S S S S
3 S S S S S S S S S
4 S S S S S S S S S
5 S S S S S S S S S
6 S S S S S S S S S
7 S S S S S S S S S
8 S S S S S S S S S
9 S S S S S S S S S

The program then asks the user to select a row and seat and should out put the same seating as above but with a 'B' marking their seat:

  1 2 3 4 5 6 7 8 9 
1 S S S S S S S S S
2 S S S S S S S S S
3 S S S S S S S S S
4 S S S B S S S S S
5 S S S S S S S S S
6 S S S S S S S S S
7 S S S S S S S S S
8 S S S S S S S S S
9 S S S S S S S S S

This is working fine unless the user selects row 1 and seat 1 then this is the returned seating:

  1 2 3 4 5 6 7 8 9 
1 B S S S S S S S S
2 B S S S S S S S S
3 B S S S S S S S S
4 B S S S S S S S S
5 B S S S S S S S S
6 B S S S S S S S S
7 B S S S S S S S S
8 B S S S S S S S S
9 B S S S S S S S S

I'm positive this is to do with my for and if conditionals at the end of the code but am confused as to why it will repetitively print the 'B'. Also I understand that i've attempted this in a bad way but just want to understand why I'm having this issue. here is the whole code so you can test on your IDEA:

fun main(args: Array<String>) {


    println("Enter the number of rows:")
    val rows = readln().toInt()

    println("Enter the number of seats in each row:")
    val seats = readln().toInt()
    val total = rows * seats
    var s = 'S'
    var cinemaLayout = mutableListOf<MutableList<Char>>()

    val cinemaSeats = mutableListOf<Char>()
    
    for (x in 1..seats) {
        cinemaSeats.add(s)
    }

    for (x in 1..rows) {
        cinemaLayout.add(cinemaSeats.toMutableList())
    }

    println("Cinema:")
    print("  ")
    for (x in 1..seats) {

        print(x)
        print(" ")
    }
    println()
    var cleanLayout1 = " ${cinemaLayout[0].joinToString().replace("]", "\n").replace("[", "").replace(",", "")}"

    for (i in 1..rows) {
        println("$i$cleanLayout1")
    }

    println("Enter a row number:")
    val selectedRow = readln().toInt()
    println("Enter a seat number in that row:")
    val selectedSeat = readln().toInt()
    if (total < 60) {
        println("Ticket price: $10")
    } else if (total > 60 && selectedRow % 2 === 0 && selectedRow <= rows / 2) {
        println("Ticket price: $10")
    } else {
        println("Ticket price: $8")
    }

    var indexRow = selectedRow - 1
    var indexSeat = selectedSeat - 1


    cinemaLayout[indexRow][indexSeat] = 'B'

    println("Cinema:")
    print("  ")
    for (x in 1..seats) {

        print(x)
        print(" ")
    }
    println()

    for (i in 0 until rows) {
        if (i === indexRow) {
            println(
                "${i   1} ${
                    cinemaLayout[indexRow].joinToString().replace("]", "\n").replace("[", "").replace(",", "")
                }"
            )

        } else {
            println(
                "${i   1} ${
                    cinemaLayout[0].joinToString().replace("]", "\n").replace("[", "").replace(",", "")
                }"
            )
        }
    }
} 

CodePudding user response:

It's because you're always printing the first row, when it's not indexRow

for (i in 0 until rows) {
    if (i === indexRow) {
        println("...cinemaLayout[indexRow]...")
    } else {
        println("...cinemaLayout[0]...")
    }
}

So when i is your target row, you print that row - otherwise you print row 0 instead of the row number that i currently represents. This means that when indexRow is the first row, you're just printing row 0 every single time, and that's why you see it repeated. When it's not the first row, you're still printing row 0 for everything but that row - it's just more obvious when row 0 has a change in it.


You should be printing the current row instead of the first one:

} else {
    // i not 0
    println("...cinemaLayout[i]...")
}

but really, why do you need to care about what indexRow is at this point? Your code is the same for both cases here, and you've added the 'B' to your data - you can just print everything as it is

for (i in 0 until rows) {
    println("${i   1} ${ cinemaLayout[i].joinToString().replace("]", "\n").replace("[", "").replace(",", "") }")
}

or better

cinemaLayout.forEachIndexed { index, row ->
    val seats = row.joinToString()
        .replace("]", "\n")
        .replace("[", "")
        .replace(",", "") 
    println("${index   1} $seats")
}

(and even better ways to things like replacing with the standard library - just showing you how you can do things like looping more cleanly!)

CodePudding user response:

The main issue here comes from bad organization of the code. You should extract functions, and separate business logic from printing logic.

Then you might be able to notice more easily things like the last line which prints cinemaLayout[0] no matter what i we are inspecting.

Also, joinToString takes arguments, you don't have to replace things a posteriori: joinToString(separator = "", prefix = "", postfix = "\n").

  • Related