Connecting Tech Pros Worldwide Forums | Help | Site Map

How many lockers are opened and how many are closed. C++ array.

Newbie
 
Join Date: Oct 2008
Posts: 5
#1: Oct 26 '08
This is the question. I'm not sure as to where my program is going wrong. I'm just confused. Help please.

I'm to write a program in which the user enters the amount of lockers in a school in which the number of lockers equal the amount of students. The principal then asks the 1st student to open all the lockers. then the second student close all even numbered lockers, then the 3rd student checks every third locker and if it is open the student closes it, however if it is closed the student opens it . The rest of the students then continue in this manner- nth student checks every nth locker. At the end there are an amount of lockers both opened and closed. The principal wants to know how many of these lockers are opened.
This is what I've been doing so far:

Expand|Select|Wrap|Line Numbers
  1. using namespace std;
  2.  
  3. int main()
  4.  
  5. {
  6.  int which_Cell=1;
  7.  int array[i];
  8.  
  9. cout<<"Please enter the amount of lockers in the school."<<endl;
  10. cin>>lockers;
  11.   int array[lockers]=1;//declares an array with cell amount based on the amount of lockers the user enters. Each cell has the value of 1.
  12.  
  13.  
  14.  for(int i=0;i<lockers;i=i+which_Cell)//i is the counter.
  15.         if (array[i]=0)
  16.          array[i]=1;
  17.         else array[i]=0;
  18.  
  19.   //Returns count of the amount of times the number appears
  20. int no(int n=1,int array[i],int lockers){
  21. int i;
  22. int count=0;
  23. for(i=0;i<lockers;i++)
  24. {
  25. if(array[i]==n)
  26. count++;}
  27. return count;
  28. }
  29.  
  30. return 0;
  31. }
  32.  

Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,366
#2: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


I don't see any functions in your code. It's all stream-of-consciousness in main().

Start thinking in code blocks:

1) Write a function that returns the number of closed lockers.
2) Write a funciton that returns the number of open lockers.
3) Write a function that opens every nth locker if it is closed and opens it if it is open. The locker array and the n are the function arguiments.
4) Write a function that closes all the lockers
5) Write a function that opens all the lockers.
6) etc...

Call these functions from main().

Post again and show me what you got.
archonmagnus's Avatar
Member
 
Join Date: Jun 2007
Location: The Interweb
Posts: 115
#3: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


One thing I see that may help is in your comparison argument. You have:

Quote:

Originally Posted by babe20042004

Expand|Select|Wrap|Line Numbers
  1.          if (array[i]=0)
  2.           array[i]=1;
  3.          else array[i]=0;
  4.  

You should have *two* "equal" signs for comparisons. Also, while they may not be necessary, brackets and spacing can help to make code a bit more readable. Try changing your statement to:

Expand|Select|Wrap|Line Numbers
  1. for(int i = 0; i < lockers; i += which_Cell)
  2. {
  3.     if (array[i] == 0) // Note that two '=' are used for comparisons
  4.         array[i] = 1;
  5.     else array[i] = 0;
  6. }
  7.  
Also, as weaknessforcats stated, work on function separation. Believe it or not, but it can really make a difference in code readability.
Member
 
Join Date: Aug 2008
Posts: 81
#4: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


You just need two functions.
The first one for opening and closing lockers, and the second one for counting the number of opened lockers.
the first function should be similar to waht you wrote, but you forgot to put the condition that tells which locker the nth student is allowed to close/open. For this use the % operator, and two for loops.

PS: line 11 is all wrong. You cannot give the array the size of a variable(meaning write array[1000] instead for example), and you cannot say the array is equal to an integer like that: array[lockers]=1 because the array is not an integer, and if you did it correctly,(meaning array[1000]={1}) it would put 1 in the array[0] and zeros in the rest.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#5: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


Here's another observation: locker #i has been changed by student #j if i can be
divided by j. So for a locker #i it is enough to find all divisors and check whether or
not there are an even or odd number of divisors. The number 1 and i itself are
considered divisors of number i.

kind regards,

Jos
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 831
#6: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


Quote:

Originally Posted by JosAH

Here's another observation: locker #i has been changed by student #j if i can be
divided by j. So for a locker #i it is enough to find all divisors and check whether or
not there are an even or odd number of divisors. The number 1 and i itself are
considered divisors of number i.

kind regards,

Jos

Instead of "divisors", let's use the word "factor". Generally, factors come in pairs ... so how can you get an odd number of factors? Or another way to phrase this riddle: when does a pair contain only one thing?
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#7: Oct 27 '08

re: How many lockers are opened and how many are closed. C++ array.


Quote:

Originally Posted by donbock

Instead of "divisors", let's use the word "factor". Generally, factors come in pairs ... so how can you get an odd number of factors? Or another way to phrase this riddle: when does a pair contain only one thing?

'Divisor' and 'factor' are synonyms. And yes some numbers can have an odd
number of divisors but let's not spoil the fun.

kind regards,

Jos
Familiar Sight
 
Join Date: Jan 2007
Posts: 189
#8: Oct 28 '08

re: How many lockers are opened and how many are closed. C++ array.


Say for arguement sake there were 25 students and 25 lockers.
You could use a for loop to load the first 25 elements of array l [100]={0}
with 1 (all elements have been initialized to 0)
When printed you would get 1111111111111111111111111 (ie 25 1's)
This would represent the first student opening all doors
Then you could write a for loop that would change every second element to 0.
You would get 1010101010101010101010101 even doors 2,4,6 etc are now closed (0)by the second student. Then you could use a for loop to check the third door (and every 3rd door there after) and if open as in this case (1)change element 3,6,9,12 etc to '0' or '1' as the case may require. The loop might look something like this:
Expand|Select|Wrap|Line Numbers
  1. for(int i=2;i<lockers;i+=3)//check every 3rd locker and change 0/1 status
  2. if(i>0  && l[i]==1)l[i]=0;
  3. else if (i>0 && l[i]==0)l[i]=1;
The print out would maybe look like this:-1000111000111000111000111
Now write a similar loop for the 4th door and every 4th door there after and so on. By printing out each row you can easily check for accuracy.
You could then play with reducing code repetition. The fact that 0 and 1 represent closed and open respectfully might allow boolian controlled loops.
I can`t help thinking that there is a simple and direct mathematical solution which would cut out all this loop code but can`t see it.
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 831
#9: Oct 28 '08

re: How many lockers are opened and how many are closed. C++ array.


I suggest you try to solve this problem with pencil and paper for a smaller number of lockers, say 10. Start with all lockers closed, then add a row showing the result after each student makes their changes. Now write a program that does the same thing.
Member
 
Join Date: Aug 2008
Posts: 81
#10: Oct 29 '08

re: How many lockers are opened and how many are closed. C++ array.


what's wrong with you people, just use the % operator:
Expand|Select|Wrap|Line Numbers
  1. for(int student=1 ; student<=lockers ; student++)
  2.   {
  3.  
  4.     for(int locker=1 ; locker<=lockers ; locker++)
  5.         if(locker%student==0)
  6.            {
  7.               if(array[locker]==0)  array[locker]=1;
  8.               else  array[locker]=0;
  9.            }
  10.  
  11.   }
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 831
#11: Oct 29 '08

re: How many lockers are opened and how many are closed. C++ array.


Quote:

Originally Posted by curiously enough

what's wrong with you people, just use the % operator:
<code snipped out>

Casual inspection suggests that your implementation will work just fine ... if you add an initialization loop before the first line. However, your algorithm has the slowest execution time of the several approaches that occur to me. Execution time isn't much of an issue for a homework assignment, but can be of vital importance in the real world, where there's an execution-time budget that can't be squandered on one function.

There are two strategies for speeding up this function:
1. Analyze the problem carefully to find an algorithm that minimizes the number of iterations. Your algorithm has N^2 iterations; you can get it down to less than 2N.
2. Find an elegant way to toggle the state of a locker that doesn't involve an explicit (or implicit) if-then-else. Conditional statements contain a conditional branch; and branches break the pipeline, which slows down the processor.
Expert
 
Join Date: Mar 2008
Location: Naperville, Illinois U.S.
Posts: 831
#12: Oct 29 '08

re: How many lockers are opened and how many are closed. C++ array.


I'm going to digress into how you compare algorithms.

There are N students and there are N lockers.

Post #10 describes an algorithm you can visualize as each student in turn stops at each locker, decides whether or not it is "one of his", and if so, toggles the door position. Each student makes a decision at each locker. The number of decisions is N*N = N^2. This is called an O(N^2) [pronounced order-N-squared] algorithm.

Posts #3 and #8 describe a similar algorithm. The difference is that each student goes directly to the lockers assigned to them. There is no need for each student to assess each locker. Instead, the students go directly to the appropriate lockers and unconditionally toggle the door positions. The number of toggle operations is N + N/2 + N/3 + ... 1 = N(1/1 + 1/2 + 1/3 + ... + 1/N). This summation has a name: it is the harmonic series. The value of the harmonic series summation can be approximated by (lnN + 0.5772). As a result, this is called an O(NlogN) [pronounced order-N-log-N) algorithm.

Note that these two algorithms have the same number of toggle operations, but the larger number of decisions in the first algorithm sets the order of that algorithm.

Posts #5, #6, and #7 hint at an O(N) [pronounced order-N] algorithm.

A correct implementation of any of these algorithms should yield the same correct answer. However, correct answers are not the only relevant factor; consider what happens if you multiply the number of lockers by 10.
... the O(N^2) algorithm will run somewhere on the order of 100 times slower;
... the O(NlogN) algorithm will run somewhere on the order of 23 times slower;
... the O(N) algorithm will run somewhere on the order of 10 times slower.
Reply