1. Not finding help here? Sign up for a free 30min tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Matlab Puzzle Assignment

  1. Apr 22, 2012 #1
    1. The problem statement, all variables and given/known data

    (see attached files)

    basically, I have to solve a puzzle game simulated by matlab. In a school of n students with n lockers, each student opens and closes a locker they walk by. all the lockers start the game closed. the first student changes every locker's status (opens them). the second student changes the status of every 2ed locker. the third student changes every third locker etc etc. the goal is to determine the lockers that are left open after n students have gone through

    2. Relevant equations

    The assignment says I will use 2 for loops. one to step through all the students and one inside of the first to step through each nth locker. the 2ed for loop is pretty confusing to me.

    3. The attempt at a solution

    Heres what I have so far.
    students=input('Enter number of students: ')
    locker=zeros(1,students);
    index=1;
    changes=0;
    for num= 1:1:students
    locker(index)=changes+index;
    index=index+1;
    end

    the code here steps through as if each student changes the status of each locker, starting with the next locker from the previous student.

    the array looks like this
    students=8
    1 2 3 4 5 6 7 8
    odd=open
    even=closed


    when it should look like this
    1 2 2 3 2 4 2 4
     

    Attached Files:

    • cap.JPG
      cap.JPG
      File size:
      49 KB
      Views:
      181
    Last edited: Apr 22, 2012
  2. jcsd
  3. Apr 22, 2012 #2
    Hi

    Lets consider first a small example with 3 students. Initially all the lockers are closed:

    locker 1 2 3
    status 0 0 0

    After the first student goes all the lockers are opened cause all are multiple of 1:

    locker 1 2 3
    status 1 1 1

    Then comes the second student which closes the locker 2:

    1 2 3
    1 2 1

    Finally comes the third one:

    1 2 3
    1 2 2

    So you need one loop that can start for example for the student 1, and then a second loop that goes through the lockers and checks if the number of it is multiple of the number of the student, adding one if it is.

    Regarding your code lets see what it does. Initially all lockers are closed:

    1 2 3
    0 0 0

    Then the program enters the for loop. In the first iteration it changes only the locker 1 when it should have changed all(second loop missing):

    1 2 3
    1 0 0

    At the second iteration you have the student number 2. What your program does is adding the value of index that is 2. However it should increase by one( instead of locker(index)=changes+index; you should do locker(index)=locker(index)+1) in order to have odd=closed and even=open. After this iteration you have:

    1 2 3
    1 2 0

    Following the same logic after the third and last iteration you have:

    1 2 3
    1 2 3

    So your program is simple copying the index of the locker to the status vector.
    With this ideas in mind you should be able to do a working program :)
     
  4. Apr 22, 2012 #3
    I don't see any attached files.
     
  5. Apr 22, 2012 #4
    sorry bout that. Just uploaded it
     
  6. Apr 22, 2012 #5
    You should not use a second for loop, because that is just slow and icky for MATLAB. Instead, consider the xor of a bit with 1. If your bit is 0, it changes it to 1. If your bit is 1, it changes it to 0. Hence, we have a way to open and close your lockers.

    Next, consider this sample code:
    Code (Text):

    >> a = zeros(1,10)

    a =

         0     0     0     0     0     0     0     0     0     0


    >> a(4:4:end) = xor(a(4:4:end),1)

    a =

         0     0     0     1     0     0     0     1     0     0
     
    Do you see where I am going with this?

    Edit: It is worth noting, the first student adheres to the same algorithm as the other students, assuming all lockers begin closed. That is, starting at the first locker, he goes to every "1st" locker on the row. This means inside your for loop of students, you needn't put special code for his activities. E.g. consider the output of
    a(1:1:end) = xor(a(1:1:end),1);

    Another approach might be to initialize the lockers to open (e.g. a = ones(1,studentCount)) (since you know the first student will open them all) and just ignore him, beginning your for loop at 2:studentCount. I would do this approach since it is computationally more efficient.

    You might wonder what would happen if studnetCount = 1 (What does MATLAB do with for k = 2:1, code, end ??) Just try it out. You will be pleased to find the for loop is simply skipped.
     
    Last edited: Apr 22, 2012
  7. Apr 22, 2012 #6
    Yea that makes sense.
    I'm still pretty easily confused when it comes to for loops but here's what I think should be closer.
    students=input('Enter number of students: ')
    locker=zeros(1,students);
    index=1;
    for i=1:1:students
    for j=1:1:students​
    if mod (index,students(j))==0
    locker(index)=Locker(index)+1
    end​
    end​
    end


    Gives me this error message:
    ??? Attempted to access students(2); index out of bounds because
    numel(students)=1.

    Error in ==> lockers at 7
    if mod (index,students(j))==0
     
  8. Apr 22, 2012 #7
    You are accessing the 1 by 1 matrix "students" at an index of 2 with students(j), which is out of bounds. numel() gives you the number of elements in a MATLAB array. A 1x1 matrix with 1 element is simply a regular, good-old fashioned constant. It's sort of like I say C = 3; B = c(2). That makes no sense!

    You should consider my code since it is a much better approach.
     
  9. Apr 22, 2012 #8
    @RoshanBBQ
    Probably wouldn't be good if I used your method. The point of the exercise is to practice for loops and arrays.
     
  10. Apr 22, 2012 #9
    You will still use a for loop to cycle through each student. There is still an array. It is not a good idea to use for loops in MATLAB when you can avoid it. Your professor will be impressed with your solution.
     
  11. Apr 22, 2012 #10
    Alright I'll give it a try. Could you possibly explain a little more what xor does exactly? I've never heard of it
     
  12. Apr 22, 2012 #11
    Yes. Let's say you have a function that takes any number (>=2) of 1s and 0s

    f(b_0,b_1,b_2,...)

    Certain examples would be

    f(0,0,1,0)

    or f(0,1)

    The function is an xor if it gives a 1 if there is an odd number of 1s in the input and a 0 if there is an even number of 1s in the input.

    So

    f(0,0) = zero ones which is even => output 0
    f(0,1) or f(1,0) = one one which is odd => output 1
    f(1,1) = two ones which is even => output 0

    If you just look at the output/input characteristics, you should be able to convince yourself through enumeration that if you have f(b,1), it will simply toggle b. If b is 1, it goes to 0. If b is 0, it goes to 1.

    Now, in MATLAB, things work very similarly but are slightly different. xor() can take an array of doubles which is not necessarily either a 0 or a 1. It could be, for example, 1.5 or 3. So MATLAB has the same rules of operation except it outputs a 1 if there is an odd number of nonzero elements else a 0.

    xor(array,1) does the xor for each element in the array. So if a = [1 1 0 0 1 1]
    xor(a,1) = [0 0 1 1 0 0]

    If you need to Google for it, its full name is the logical exclusive or.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook