-1

There's a problem, which I've to solve in c++. I've written the whole code and it's working in the given test cases but when I'm submitting it, It's saying wrong answer. I can't understand that why is it showing wrong answer. I request you to tell me an input for the given code, which will give incorrect output so I can modify my code further.

Shrink The Array

You are given an array of positive integers A[] of length L. If A[i] and A[i+1] both are equal replace them by one element with value A[i]+1. Find out the minimum possible length of the array after performing such operation any number of times.

Note: After each such operation, the length of the array will decrease by one and elements are renumerated accordingly.

Input format:

  • The first line contains a single integer L, denoting the initial length of the array A.
  • The second line contains L space integers A[i] − elements of array A[].

Output format:

  • Print an integer - the minimum possible length you can get after performing the operation described above any number of times.

Example:

Input

7
3 3 4 4 4 3 3

Output

2

Sample test case explanation

3 3 4 4 4 3 3 -> 4 4 4 4 3 3 -> 4 4 4 4 4 -> 5 4 4 4 -> 5 5 4 -> 6 4.

Thus the length of the array is 2.

My code:

#include <bits/stdc++.h>
using namespace std;

int main()
{
  bool end = false;
  int l;
  cin >> l;

  int arr[l];
  for(int i = 0; i < l; i++){

    cin >> arr[i];
  }
  int len = l, i = 0;

  while(i < len - 1){
    if(arr[i] == arr[i + 1]){
        arr[i] = arr[i] + 1;
        if((i + 1) <= (len - 1)){
            for(int j = i + 1; j < len - 1; j++){
                arr[j] = arr[j + 1];
            }
        }
        len--;
        i = 0;
    }
    else{
        i++;
    }
  }
  cout << len;
  return 0;
}

THANK YOU

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 5
    I cannot compile the code, so why bother about input? please read [Why should I not `#include `?](https://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h) – 463035818_is_not_an_ai Sep 18 '20 at 10:01
  • 4
    and [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 463035818_is_not_an_ai Sep 18 '20 at 10:02
  • 5
    and [Why aren't variable-length arrays part of the C++ standard?](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard) – 463035818_is_not_an_ai Sep 18 '20 at 10:02
  • 4
    it is ok to write a weird dialect, but then you should be aware of that. Your code is not standard C++ – 463035818_is_not_an_ai Sep 18 '20 at 10:02
  • Hey @idclev463035818 thanks for telling this but I'm just a beginner, and that's why I'm using #include and "using namespace std". – Yash Malaviya Sep 18 '20 at 10:14
  • 1
    You are performing a simple greedy algorithm. It fails for example on `2 2 2 3` – Damien Sep 18 '20 at 10:14
  • 3
    @YashMalaviya You have the opportunity to learn by following the advice given. Don't do `using namespace std;`, don't `#include ` and don't use VLA:s. – Ted Lyngmo Sep 18 '20 at 10:15
  • @Damien I think it's giving desired output for 2 2 2 3 which is 3 . As 2 2 2 3 -> 3 2 3. – Yash Malaviya Sep 18 '20 at 10:18
  • ohk @TedLyngmo and idclev . Thanks for the advice, I'll keep this in mind. – Yash Malaviya Sep 18 '20 at 10:21
  • 1
    The desired output is 2: 2 2 2 3 -> 2 3 3 -> 2 4 – Damien Sep 18 '20 at 10:21
  • 1
    What @Damien said. Also think of more complex patterns where you can't see the optimal choice without performing _all_ of the choices, possibly recursively. – Ted Lyngmo Sep 18 '20 at 10:25
  • @Damien According to the given problem, if a[i] and a[i + 1] are equal then replace both the elements with a[i] + 1. So in 2 2 2 3 a[0] and a[1] are same, so both of them will be replaced by a[0] + 1 i.e. 3, then it'll become 3 2 3. And after this, no a[i] and a[i + 1] is same. So the output will be 3, and not 2. – Yash Malaviya Sep 18 '20 at 10:27
  • @YashMalaviya Yes, `a[0]` and `a[1]` are the same but so are `a[1]` and `a[2]`. Nothing says that you should go with the first neighbours. "_Find out the minimum possible length of the array after performing such operation any number of times_" - and here the minimum is `2`. – Ted Lyngmo Sep 18 '20 at 10:30
  • 1
    @idclev463035818: I came across that unholy trinity so often I made up a [response template](https://rootdirectory.ddns.net/static/no_please.txt)... you're welcome to copy. – DevSolar Sep 18 '20 at 10:34
  • @TedLyngmo Yeah Yeah!!! The question is asking for minimum length. Thank You so much for helping me out. – Yash Malaviya Sep 18 '20 at 10:36
  • Thank You everyone for helping me out. :-) I understood what's the bug in my code. – Yash Malaviya Sep 18 '20 at 10:37
  • @YashMalaviya: Have you understood idclev's criticism as well? While `using namespace std;` might be a matter of choice, the other two (`bits/stdc++.h` and use of VLAs) make your program non-conforming and non-portable. – DevSolar Sep 18 '20 at 10:39

1 Answers1

0

As noted in the comments: Just picking the first two neighbours that have the same value and combining those will lead to suboptimal results.

You will need to investigate which two neighbours you should combine somehow. When you have combined two neighbours you then need to investigate which neighbours to combine on the next level. The number of combinations may become plentiful.

One way to solve this is through recursion.

If you've followed the advice in the comments, you now have all your input data in std::vector<unsigned> A(L).

You can now do std::cout << solve(A) << '\n'; where solve has the signature size_t solve(const std::vector<unsigned>& A) and is described below:

  • Find the indices of all neighbour pairs in A that has the same values and put the indices in a std::vector<size_t> neighbours. Example: If A contains 2 2 2 3, put 0 and 1 in neighbours.

  • If no neighbours are found (neighbours.empty() == true), return A.size().

  • Define a minimum variable and initialize it with A.size() - 1 which is the worst result you know you can get at this point. So, size_t minimum = A.size() - 1;

  • Loop over all indices stored in neighbours (for(size_t idx : neighbours))

    • Copy A into a new std::vector<unsigned>. Let's call it cpy.
    • Increase cpy[idx] by one and remove cpy[idx+1].
    • Call size_t result = solve(cpy). This is where recursion comes in.
    • Is result less than minimum? If so assign result to minimum.
  • Return minimum.


I don't think I ruined the programming exercise by providing one algorithm for solving this. It should still have plenty of things to deal with. Recursion won't be possible with big data etc.
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108