-1

There is a wall built from numbers. 0 means there is a hole and blocks can't sit on holes. Someone has a special gun that fires all blocks with a number in one shot.
So I have a matrix called wall and have to write a gun. I wrote the program, but I have a problem and I do not understand why it is happening. In my code

#include <iostream>
#include <cstdio>

using namespace std;

int createWall( int &height, int &length, int wall[][ 100 ], int shots )
{
    int i;
    int j;
    cin >> height;
    cin >> length;
    cin >> shots;
    for ( i = 0; i < height; i++ )
    {
        for ( j = 0; j < length; j++ )
        {
            cin >> wall[ i ][ j ];
        }
    }
    return shots;
}


void wallNow( int height, int length, int wall[][ 100 ] )
{
    int i;
    int j;
    for ( i = 0; i < height; i++ )
    {
        for ( j = 0; j < length; j++ )
        {
            cout << wall[ i ][ j ] << " ";
        }
        cout << "\n";
    }
}

void destroyWall( int height, int length, int wall[][100], int shots )
{
    int i;
    int j;
    int k;
    int x;
    int aimedBlocks;//number to be "destroyed"
    //set all aimedBlocks to 0
    for ( x = 0; x < shots; x++ )
    {
        cin >> aimedBlocks;
        for ( i = 0; i < height; i++ )
        {
            for ( k = 0; k < length; k++ )
            {
                if ( wall[ i ][ k ] == aimedBlocks )
                {
                    wall[ i ][ k ] = 0;
                }
            }
        }
    }

    int counter;//I use this variable because at some point I have a 0 followed only by 0's
    for ( i = 0; i < length; i++ )
    {
        j = height - 1;
        counter = 0;
        //if I find a 0 then I move all elements higher that it one step down
        while ( counter < height )
        {
            if ( wall[ j ][ i ] == 0 ) 
            {
                for ( k = j; k > 0; k-- )
                {
                    wall[ k ][ i ] = wall[ k - 1 ][ i ];
                }
                wall[ height - j - 1 ][ i ] = 0;
            }
            else
                j--;//I don't always go up ene step because the "block" droped in place of 0 may be 0
            counter++;
        }
    }
}

int main()
{
    int height;
    int length;
    int wall[ 100 ][ 100 ];
    int shots = 0;
    shots = createWall( height, length, wall, shots );
    destroyWall( height, length, wall, shots );
    wallNow( height, length, wall );
}

I really do not understand why line wall[ height - j - 1 ][ i ] = 0; is working for the first 4 columns in the following example and it does not work for the last one.

Format input:

height length shots
wall_0_0 ... wall_0_length
... ... ...
wall_height  ... wall_height_length
shot_0 ... shot_shots

Input:

4 5 3
3 5 4 5 1 
2 1 1 5 3 
1 1 5 5 1 
5 5 1 4 3
1 5 1

Remove all values that matches with 1, 5, 1. And wall remains must drop into the bottom.

Output:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 0 
2 0 4 4 3

Expected:

0 0 0 0 0 
0 0 0 0 0 
3 0 0 0 3 
2 0 4 4 3

Please help me solve this problem. I could not find it debugging the code.

Stargateur
  • 24,473
  • 8
  • 65
  • 91
Timʘtei
  • 753
  • 1
  • 8
  • 21

1 Answers1

2

Your algorithm is strange, I don't understand what you try to do.

A simple way to achieve your purpose is to iterate from the left to the right of your wall, then for each you iterate from the bottom to the top. Each time you get a 0, you search for a non zero value to the top and swap their if you found it.

Example (very basic could be improve):

for (size_t i = 0; i < length; i++) { // i is for iterate from left(0) to right(length - 1)
  size_t j = height; // j is for iterate from bot(height - 1) to top(0)
  while (j-- > 0) {
    if (wall[j][i] == 0) {
      size_t k = j; // k is for found a non zero value from j - 1 to the top(0)
      while (k-- > 0) {
        if (wall[k][i] != 0) {
          wall[j][i] = wall[k][i];
          wall[k][i] = 0;
          break;
        }
      }
    }
  }
}

Note:

  1. I use size_t because this is the type for index.
  2. I recommend you to switch for std::vector and use iterator on it in C++.
Stargateur
  • 24,473
  • 8
  • 65
  • 91
  • I am learning this is why I write strange algorithms. Thanks! And why is `size_t` the type for index? – Timʘtei Jun 17 '17 at 17:37
  • @Timʘtei http://en.cppreference.com/w/cpp/types/size_t. Remember that this type is unsigned. Can be strange to manipulate for a beginner. But you should learn how to use it. https://stackoverflow.com/a/22587575/7076153 – Stargateur Jun 17 '17 at 17:40
  • What I understood from the 2nd link is not to use unsigned in loops. – Timʘtei Jun 17 '17 at 17:48
  • @Timʘtei Yes, this is my point, I don't want to influence you. Some people disagree to use unsigned type. I don't want that you think that you must use `size_t` because some people will disagree. By the way, like you code in C++, this problem should disappear because you should use `std::vector` and `iterator` that will hide this for you. – Stargateur Jun 17 '17 at 17:53
  • `size_t` happens to be the return type for all stl containers `size()` and of course is used for indexing. Still, signed indices have some advantages in error detection and have negative values that can be used to mean uninitialized. I prefer myself to store my indices as signed, most of the times. – ceztko Jun 17 '17 at 18:05