Count number of elements that increase or decrease by a factor of 10 with recursion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;
int factorsOf10(int arr[], int value)
{
    int count = 0;
    int len = sizeof(arr) / sizeof(0);
    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < len; j++)
        {
            if (arr[i] * 10 = arr[j])
                count++;
            else
                return(arr[] + 1, value);
        }
    }
}
int main()
{
    int arr[] = { 1,10,20 };
    int result = factorsOf10(arr, 0);
    cout << result;
    return 0;
}


This is what I have done so far but it went wrong. Can anybody give me some idea, please?
I need to compute recursively the number of consecutive elements that increase or decrease by a factor of 10.
For example:
factorsOf10([1, 10, 20], 0) → 1
factorsOf10([100, 10, 20, 200], 0) → 2
factorsOf10([1000, 100, 10, 1, 10], 0) → 4
factorsOf10([10, 20, 33, 340], 0) → 0
Last edited on
I see no recursive call.

If you were using recursion to go through the array you would only compare one element with the NEXT at each recursion (your problem states "consecutive").

You look at multiplication by 10, but not division by 10.
Last edited on
@lastchance yes that's what I'm stucking :(. I just learned recursion few days ago and still on my way to improve. Can you help me, please?
(1) Pass either the size of the array or the number of remaining elements from main() if you are using a standard array.

(2) The recursive call should (i) identify a criteria for stopping the recursion; (ii) call your function (factorsOf10) if required.


Actually, I suggest that you try to do the problem without recursion first (a single-pass loop seems more natural here, anyway). Once that is working you could refactor for recursion.

Look at each of the examples and observe how you would do it by hand.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;
int factorsOf10(int arr[], int value)
{
    int count = 0;
    int len = sizeof(arr) / sizeof(0);
    for (int i = 0; i + 1 < len; i++)
    {
        if (arr[i] / arr[i + 1] == 10 || arr[i + 1] / arr[i] == 10)
            count++;
    }
    return count;
}
int main()
{
    int arr[] = { 1,10,20 };
    int result = factorsOf10(arr, 0);
    cout << result;
    return 0;
}

I'm trying to do it without using recursion but I think it's wrong :(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int factorsOf10( int *arr, int remaining )
{
   if ( remaining <= 0 ) return 0;
   else return ( *arr == 10 * *(arr+1) || *(arr+1) == 10 * *arr ) + factorsOf10( arr + 1, remaining - 1 );
}

int main()
{
    int arr[] = { 1000, 100, 10, 1, 10 };
    cout << factorsOf10(arr, sizeof arr / sizeof arr[0] ) << '\n';
}



Using a line like
if (arr[i] / arr[i + 1] == 10 || arr[i + 1] / arr[i] == 10)
will fail, because of the truncation associated with integer division.
Last edited on
I'm trying to understand what you did. Thank you so much for your help!
Also, the requirement is writing base on the function int factorsOf10(int arr[], int value).
Does anyway that I can do it without using pointer?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <initializer_list>

// return true if a and b increase or decrease by a factor of 10
bool increase_or_decrease_by_10( int a, int b )
{
    return a == b*10 || b == a*10 ;
}

// return true if elements at pos and pos+1 increase or decrease by a factor of 10
bool increase_or_decrease_by_10( const int array[], std::size_t pos )
{
    return increase_or_decrease_by_10( array[pos], array[pos+1] ) ;
}

std::size_t cnt_consecutive_increase_or_decrease_by_10( const int array[], std::size_t num_elements )
{
     if( num_elements < 2 ) return 0 ; // nothing more to be done; end of recursion

     // handle the elements at positions zero and one here, 
     // handle the rest of the array (elements at positions one and two etc. ) recursively
     return increase_or_decrease_by_10( array, 0 ) // 1 if the first two items increase or decrease by a factor of 10
            + cnt_consecutive_increase_or_decrease_by_10( array+1, num_elements-1 ) ; // count for the rest of the array (recursive)
}

void test_it( std::initializer_list<int> ilist )
{
    std::cout << "[ " ;

    constexpr std::size_t MAX_SZ = 100'000 ;
    int array[MAX_SZ] ;

    if( ilist.size() > MAX_SZ )
        return void( std::cerr << "*** error *** too many elements\n" ) ;

    std::size_t pos = 0 ;
    for( int v : ilist )
    {
        array[pos++] = v ;
        std::cout << v << ' ' ;
    }

    std::cout << "]  ==> " << cnt_consecutive_increase_or_decrease_by_10( array, ilist.size() ) << '\n' ;
}

int main()
{
    test_it( { 1, 10, 20 } ) ; // 1
    test_it( { 100, 10, 20, 200 } ) ; // 2
    test_it( { 1000, 100, 10, 1, 10 } ) ; // 4
    test_it( { 10, 20, 33, 340 } ) ; // 0
    test_it( { 1, 10, 200, 2000, 200, 20, 2, 400, 4000, 400, 40, 4, 90 } ) ; // 9
} 


http://coliru.stacked-crooked.com/a/7b96d35d5f4863ac
Does anyway that I can do it without using pointer?


Sure, but you were implicitly using pointers with your original return(arr[] + 1, value);. Essentially you were always pointing to something you could equally well reference as arr[0]. Do it like the below and you might as well have used a loop rather than recursion.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int factorsOf10( int arr[], int i, int n )
{
   if ( i + 1 >= n ) return 0;
   else return ( arr[i] == 10 * arr[i+1] || arr[i+1] == 10 * arr[i] ) + factorsOf10( arr, i + 1, n );
}

int main()
{
    int arr[] = { 1000, 100, 10, 1, 10 };
    cout << factorsOf10(arr, 0, sizeof arr / sizeof arr[0] ) << '\n';
}
Last edited on
Again. I have to do it with the function
1
2
3
4
int factorsOf10(int arr[], int value)
{
...
}


It can not be
1
2
3
4
int factorsOf10( int arr[], int i, int n )
{

}


I'm so sorry about that :(
But I can assure you the recursive call is using pointers!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int factorsOf10( int arr[], int value )
{
   if ( value <= 0 ) return 0;
   else return ( arr[0] == 10 * arr[1] || arr[1] == 10 * arr[0] ) + factorsOf10( arr + 1, value - 1 );
}

int main()
{
    int arr[] = { 1000, 100, 10, 1, 10 };
    cout << factorsOf10(arr, sizeof arr / sizeof arr[0] ) << '\n';
}
OK.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

int factorsOf10(int arr[], int n)
{
	if (n > 1)
		return (arr[0] == 10 * arr[1] || arr[1] == 10 * arr[0]) + factorsOf10(arr + 1, n - 1);
	else
		return 0;
}

int main()
{
	int arr2[] {1, 10, 20}; // 1
	int arr3[] {100, 10, 20, 200}; // 2
	int arr4[] {1000, 100, 10, 1, 10}; // 4
	int arr5[] {10, 20, 33, 340}; // 0
	int arr6[] {1, 10, 200, 2000, 200, 20, 2, 400, 4000, 400, 40, 4, 90}; // 9

	cout << factorsOf10(arr2, sizeof arr2 / sizeof arr2[0]) << '\n';
	cout << factorsOf10(arr3, sizeof arr3 / sizeof arr3[0]) << '\n';
	cout << factorsOf10(arr4, sizeof arr4 / sizeof arr4[0]) << '\n';
	cout << factorsOf10(arr5, sizeof arr5 / sizeof arr5[0]) << '\n';
	cout << factorsOf10(arr6, sizeof arr6 / sizeof arr6[0]) << '\n';
}



1
2
4
0
9

Last edited on
Thank you for you help @lastchance.
I need to write it in C++ and Java also.
But when I do the same thing in java it went wrong:
1
2
3
4
5
6
7
public static int factorsOf10(int[] array, int value)
    {

        if (value <= 0) 
            return 0;
        else return (array[0] == 10 * array[1] || array[1] == 10 * array[0]) + factorsOf10(array + 1 , value - 1);
    }

Do you know how to fix in Java?
Ah, I learnt Java.
Then I learnt C++, and it was so much better than Java that ... I forgot all my Java. Sorry!
check array each recursive call. I am not 100% sure that array+1 does what you think it does. You just have to debug it. Give it a small example input and print out what you got each iteration.
if array+1 is the issue, you can either make a class variable that holds the offset into the array or, better, iterate the array in reverse, using value-1 and value-2 as the index instead of 0 and 1.
Topic archived. No new replies allowed.