Enum (New topic) and Array/Function (Review)

So this is my first week in CS265 and between refreshing my memory from a previous semester and grasping this new professor and concepts, I can't seem to figure this out. My prompt is this:

Peter the postman became bored one night and, to break the monotony of the night shift, he carried out the following experiment with a row of mailboxes in the post office. These mailboxes were numbered 1 through 150, and beginning with mailbox 2, he opened the doors of all the even-numbered mailboxes, leaving the others closed. Next, beginning with mailbox 3, he went to every third mail box, opening its door if it were closed, and closing it if it were open. Then he repeated this procedure with every fourth mailbox, then every fifth mailbox, and so on. When he finished, he was surprised at the distribution of closed mailboxes. Write a program to determine which mailboxes these were.

In your program, first declare an enumeration type for mailbox door open or close in global.
Next write a function to initialize all mailbox doors to closed.
Next write a second function that will conduct what Peter did as described above.
Next write another function that will output all of the mailboxes whose doors are closed.
Next write the main function. In your main function, call all of the above three functions to find out the distribution of closed mailboxes for Peter.

I wrote the code from beginning to end in about 2-3 hours, but have yet to get anything to display through my cout loop, besides my test line. Any help is much appreciated. Basically, I am unsure of how to accurately forge the necessary loops to open/close the correct mailboxes.

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
#include <iostream>
using namespace std;
enum mailbox{open, close};
int box[149];
void closeAll();	// this is working. don't change.
void boredPeter();
void coutClosed();	// this is working. don't change.

int main()
{
	closeAll();
	boredPeter();
	coutClosed();

	return 0;
}

void closeAll()	// this is working. don't change.
{
	for (int i = 0; i < 150; i++)
	{
		box[i] = close;
	}
}

void boredPeter()
{
	
}

void coutClosed()	// this is working. don't change.
{
	for (int x = 0; x < 150; x++) //use this to test
	{
		if (box[x] = 1)
		{
			cout << "Mailbox #" << x+1 << " is closed" << endl;
		}
		else
		{
		}
	}
}
Last edited on
void coutClosed()// this is working. don't change.

Actually, it's not. Line 35 of your snippet:

if (box[x] = 1)

This doesn't do what you think it does. Remember, = is for assignment, == is the binary equality operator.

Also, line 4:

int box[149];

You should have 150 elements, not 149. Additionally, I'm sure your teacher meant for you to have an array of 150 mailboxes, not 150 ints.
Last edited on
That actually makes sense to my main problem. See, I have been using a couple different sets of for loops inside my void boredPeter() function, and no matter what I fill that function in with, my program no longer succesfully can cout anything.
Like, I get the concept of what is being done. I am needing to nest for loops in the function in which the mailboxes are supposed to be getting opened/closed. I can make the first, opening even numbers. But I don't quite understand how to increase it to open every 3, 4, etc :/

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
#include <iostream>
using namespace std;
enum mailbox{open, close};
int box[150];
void closeAll();
void boredPeter();
void coutClosed();

int main()
{
	closeAll();
	boredPeter();
	coutClosed();

	return 0;
}

void closeAll()
{
	for (int i = 0; i < 150; i++)
	{
		box[i] = close;
	}
}

void boredPeter()
{
	for (int x = 1; x < 150; (x=x+2) )
	{
		if (box[x] == close)
		{
			box[x] = open;
		}
		else
		{
		}
	}

	for (int y = 3; y < 150; y++) //this is part screwing it up
	{
		for (int z = y; z < 150; z+=z)
		{
			if (box[z] == close)
				box[z] = open;
			else
				box[z] = close;
		}
	}
}

void coutClosed()
{
	for (int index = 0; index < 150; index++)
	{
		if (box[index] == close)
		{
			cout << "Mailbox #" << index+1 << " is closed" << endl;
		}
		else
		{
		}
	}
}
Last edited on
1
2
3
4
5
6
7
8
9
10
	for (int y = 3; y < 150; y++) //this is part screwing it up
	{
		for (int z = y; z < 150; z+=z)
		{
			if (box[z] == close)
				box[z] = open;
			else
				box[z] = close;
		}
	}



What the above turns out to be:
1
2
3
4
5
6
7
8
9
10
11
12
13
First iteration:
y = 3;
z = 3 + 3 = 6;

Second iteration:
y = 3;
z = 6 + 6 = 12;

Third iteration:
y = 3;
z = 12 + 12 = 24;

// etc . . . 


What you want to be doing:
1
2
3
4
5
	for(int i = 2; i < 150; i++) {
		for(int j = i; j < 150; j += i) {
			// do your stuff here
		}
	}


- Use enum classes instead.
http://www.cprogramming.com/c++11/c++11-nullptr-strongly-typed-enum-class.html
- Under "scoped enums" section
http://en.cppreference.com/w/cpp/language/enum
1
2
3
4
5
6
7
// more logical to have close = 0 and open = 1
enum class mailbox : bool { close, open };

// then you can use mailbox as a type
// i used 151 so i can access index 1 to 150, inclusive
// initialise everything to mailbox::close, which is 0 using empty curly braces
mailbox box[151] = {};


Using enum classes:
1
2
3
4
5
6
	// using an array of 151 elements
	for(int i = 2; i <= 150; i++) {
		for(int j = i; j <= 150; j += i) {
			arr[j] = static_cast<mailbox>(!static_cast<bool>(arr[j]));
		}
	}
Last edited on
If you had 30 mailboxes instead of 150, this is what they would look like after every pass (where 'x' is closed and 'o' is open).

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

xoxoxoxoxoxoxoxoxoxoxoxoxoxoxo

xoooxxxoooxxxoooxxxoooxxxoooxx

xooxxxxxooxoxooxxxxxooxoxooxxx

xooxoxxxoxxoxoxxxxxoooxooooxxo


Perhaps this helps to visualize it?

@intergralfx enum classes certainly would be beneficial, though I don't think OP's instructor would approve.
Last edited on
I understand the visual aspect and feel as though my code can't be very far from correct. However, my output is that Mailbox #1 is the only one closed after the 150 repetitions and I believe it should be like 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144 according to my assignment prompt.

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
#include <iostream>
using namespace std;
enum mailbox{close, open};
int box[150];
void closeAll();
void boredPeter();
void coutClosed();

int main()
{
	closeAll();
	boredPeter();
	coutClosed();

	return 0;
}

void closeAll()
{
	for (int i = 0; i < 150; i++)
	{
		box[i] = close;
	}
}

void boredPeter()
{
	for (int x = 1; x < 150; (x=x+2) )
	{
		if (box[x] == close)
		{
			box[x] = open;
		}
		else
		{
		}
	}

	for (int y = 2; y < 150; y++)
	{
		for (int z = y; z < 150; z = z+1)
		{
			if (box[z] == close)
				box[z] = open;
			else
				box[z] = close;
		}
	}
}

void coutClosed()
{
	for (int index = 0; index < 150; index++)
	{
		if (box[index] == close)
		{
			cout << "Mailbox #" << index+1 << " is closed" << endl;
		}
		else
		{
		}
	}
}



Mailbox #1 is closed
Press any key to continue . . .
Again, change line 4 from:

int box[150];

to

mailbox box[150];

You have 150 mailboxes, not 150 integers.

Consider the following:

1
2
3
4
5
6
7
8
9
10
11
12
const int num_passes = 6;

for (int i = 2; i < num_passes; ++i) {

	for (int j = i-1; j < num_mailboxes; ++j) {

		if (!((j + 1) % i)) {
			boxes[j] = boxes[j] ? Open : Closed;
		}

	}
}


A "pass" is each time Peter iterates through (or passes over) the mailboxes. With each pass, the first mailbox to be processed gets incremented. Then, for each mailbox, we check whether or not (j+1) mod i (where "i" is the current pass) leaves a remainder. If it divides cleanly, we know that the current mailbox's current state should be swapped.
Topic archived. No new replies allowed.