Interview Question that got me confused

There was an interview question a while back, which got me confused for a while and at the moment.

Create a function such that Every time I call it, it must return an incremented value by 1(start from 0), until it reaches a certain value k, then decrease till it reaches 0.

No passing of arguments(Constraint).

I gave a straightforward solution:

Declare a global variable which increments each time the function is called until it reaches k, then decrement it.

Then they modified the question and added that, after they call the function, they call another function which changes the value of the global variable. Now what.

So I simply said, we store the value elsewhere, but again they said what if the stored value is manipulated again... Any solutions guys ??

So basically, a function that returns an incremented value each time it's called until it reaches k, then decreases,can't use arguments, and can't store the result somewhere.
Last edited on
You can do it with static values inside the function.

What's meant to happen once it gets back to zero?

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
#include <iostream>

int function()
{
  // Let's say k =12, because I need it to be an actual number
  static bool ascending = true;
  static int value = 0;

  int returnValue = value;

  if (value == 12)
  {
    ascending = false;
  }

  if (ascending) { value++;}
  else {value--;}

  return returnValue;
}

int main()
{
    for (int i = 0; i < 25; ++i)
    {
      std::cout << function() << ' ';
    }
}




Last edited on
If it can't use arguments, it has to store its state somewhere, because it isn't a pure function.

If the interviewers didn't like the use of a global variable, the two other alternatives are to use class-scope variables, and have the function be a member function of a class, or to use static variables within the function.

It's unclear what you want the initial return value of the function to be, but here's two possible implementations

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>

int foo()
{
	const int k = 5;
	static int i = 0;
	static bool increasing = true;
	
	if (increasing)
	{
		i++;
		if (i == k)
		{
			increasing = false;
		}
	}
	else
	{
		i--;
		if (i == 0)
		{
			increasing = true;
		}
	}
	
	return i;
}

class Foo {
  public:
	Foo(int k)
	: k(k), i(0), increasing(true)
	{
		
	}
	
	int operator()()
	{
		if (increasing)
		{
			i++;
			if (i == k)
			{
				increasing = false;
			}
		}
		else
		{
			i--;
			if (i == 0)
			{
				increasing = true;
			}
		}
		return i;
	}
	
  private:
	int k;
	int i;
	bool increasing;
};

int main()
{
	using std::cout;
	
	// using free function with local static variables:
	for (int i = 0; i < 12; i++)
	{
		cout << foo() << '\n';
	}
	
	cout << '\n';
	
	// using class member function:
	Foo foo_obj(5);
	for (int i = 0; i < 12; i++)
	{
		cout << foo_obj() << '\n';
	}
	return 0;
}


If you want 0 to be the first return value, set the initial value of i to be -1.
Last edited on
thanks guys, this was helpful. :)
Wouldnt recursion work? Keep global variable K reference thats the number you want to go up to in the recursive function and when you hit that number recursive go to 0 in the same function. Even if the global variable is changed after the function is called the recursion would have to finish before any other function was called since a recursive function calls itself until the base case is reached.
No,we need the value at the moment of calling the function, we are not printing it..
So we need the value to be returned after calling it. When I heard the question recursion was my first guess also, but I cleared this with the interviewer and he said Don't use recursion here.
I never said to print the number and you would have the value at the moment of calling... but if the interviewer said not to use recursion then guess it doesnt work.
It can be a little shorter. We don't need to track whether we're in the ascending or descending stage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

const int k = 10;

int foo()
{
    static int counter = -1;
    return (++counter <= k ? counter : 2*k-counter);
}

int main()
{
    for (int i = 0; i <= 2*k; i++)
        std::cout << foo() << '\n';
    return 0;
}

Last edited on
It's not periodic then :( but being periodic wasn't explicitly mentioned in the OP, so yeah that's fine.

Just a general note to Noonoob... watch out for any function that has non-const variables with static duration (or globals) if you ever go into a multi-threaded process. You don't want race conditions.
https://en.wikipedia.org/wiki/Race_condition
What's the difference between declaring as global and declaring as static? I used to think it was the same exact thing..
Ganado wrote:
It's not periodic then :( but being periodic wasn't explicitly mentioned in the OP, so yeah that's fine.


It wasn't clear what was supposed to happen when 0 is reached again. I like making the function periodic and it's easy to modify my solution to be so with modular arithmetic.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

const int k = 5;

int foo()
{
    static int counter = -1;
    return ((++counter)%(2*k) <= k ? counter%(2*k) : 2*k-(counter)%(2*k));
}

int main()
{
    for (int i = 0; i <= 8*k; i++)
        std::cout << foo() << '\n';
    return 0;
}
That's very nice too :)

Edit:
Grime,
There's a few differences between global, global static, and local static variables.

A local static variable is, of course, only accessible within the function. The first time the function is called, the local static variable will be initialized, and will stay initialized in subsequent calls.
A global variable (both static and not static) is initialized before main begins (will be initialized to 0 if not specified, unlike non-static local variables).
Also, a static variable is only visible to the translation unit it's defined it (i.e. no external linkage).

Some links to browse:
https://en.cppreference.com/w/cpp/language/storage_duration
https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables


In general (not just talking about global/static variables), create things close to where they are used so as to avoid confusion about the state of something. More state = more things the programmer has to keep track of as they work = more chance of the programmer forgetting something = bug.
Last edited on
Topic archived. No new replies allowed.