Question
In Java please We describe the position of each disc as the number of degrees that its tooth is rotated counterclockwise from the zero position
In Java please
We describe the position of each disc as the number of degrees that its tooth is rotated counterclockwise from the zero position at the top. In general, we require the position angle to be "normalized" so it is always a number in the range from 0 through 359. For the front disc, its position always matches the number at the top of the dial; i.e., we assume the tooth is right behind the number 0. Each disc also has an offset, in degrees, which is based on the angle between its tooth and the notch. If the notch is in the correct final alignment position when the disc's position is D degrees, then we say the offset is D. Notice we don't care what the actual angle is between the tooth and the notch; we care what the offset is: when every disc's current position is equal to its offset, that means the notches are all correctly aligned and the lock can be opened.
The values of these offsets are determined by the combination. The way we interpret a combination X, Y, Z is according to the package directions, like this:
- rotate the dial two complete revolutions clockwise and then stop at X - rotate the dial one complete revolution counterclockwise and then stop at Y - rotate the dial clockwise and stop at Z
It would be convenient if when the combination is X, Y, Z the offsets for discs 1, 2, and 3, respectively, would simply be X, Y, and Z. However, if we turn the dial several complete revolutions counterclockwise and stop when the dial is at, say, 100 degrees, the other two discs will not be rotated 100 degrees. We also have to account for the width of the tooth itself. If, for example, the tooth is wide enough to occupy two degrees worth of the disc's rotation, then in this scenario our disc 2 would be at 102 degrees and disc 1 would be at 104 degrees. Similarly, if we then rotate the dial clockwise a full revolution and stop at 100 degrees, disc 2 would be at 98. In general to get combination X, Y, Z, the offsets would be X - 2 * TOOTH for disc 1, Y + TOOTH for disc 2, and Z for disc 3, where TOOTH is
There is one public constant, declared as follows, representing the width of the tooth on each disc, expressed in degrees of rotation. public static final int TOOTH = 2;
There is one constructor: Padlock(int n1, int n2, int n3) Constructs a padlock whose combination will be n1, n2, n3
There are the following public methods:
void close() closes the lock, regardless of whether the discs are aligned
int getDiscPosition(int which) returns the current position of the given disc (1, 2, or 3) boolean isAligned() returns true if the three discs are aligned in position for the lock to open boolean isOpen() returns true if the lock is currently open
void open() opens the lock, if possible
void randomizePositions(Random rand) sets the disc positions to randomly generated, valid values
void setPositions(int n1, int n2, int n3) sets the disc positions to the given values (as closely as possible)
void turn(int degrees) turns the dial the given number of degrees, where a positive number indicates a counterclockwise rotation and a negative number indicates a clockwise rotation
void turnLeftTo(int number) turns the dial counterclockwise until the given number is at the top
void turnRightTo(int number) turns the dial clockwise until the given number is at the top
You could start by first making sure you can set and get the current rotation of each disc. According to the constructor, assuming that the tooth width is 2 degrees, the initial position of the discs is always 0 degrees for disc 3, 2 degrees for disc 2, and 4 degrees for disc 1. (This is true regardless of the constructor arguments.). So you should be able to set up a simple test class with the following:
Padlock p = new Padlock(10, 20, 30); printPositions(p); // expected 4 2 0 p.setPositions(42, 137, 17); // order is disc 1, 2, 3 printPositions(p); // expected 42 137 17
Padlock p = new Padlock(10, 20, 30); printPositions(p); // expected 4 2 0 p.setPositions(42, 137, 17); // order is disc 1, 2, 3 printPositions(p); // expected 42 137 17
The key piece is determining whether the discs are "aligned", as specified in the isAligned method. For that we need to know the offset for each disc, that is, the angle of rotation that will put its notch in the right position for the lock to open. According to the general description of the lock internals, if the combination is 10, 20, 30, then the offsets are 6, 22, and 30, for discs 1, 2, and 3, respectively. The isAligned method should return true if the current positions of all three discs match their offsets.
So, the behavior we expect is something like this (according to the constructor, the lock should initially be open):
System.out.println(p.isOpen()); // expected true System.out.println(p.isAligned()); // expected false p.close(); System.out.println(p.isOpen()); // expected false p.open(); // does nothing; it's locked System.out.println(p.isOpen()); // expected false p.setPositions(6, 22, 30); printPositions(p); // expected 6, 22, 30 System.out.println(p.isAligned()); // expected true // now we should be able to open it! p.open(); System.out.println(p.isOpen()); // expected true System.out.println();
To start thinking about what happens when you rotate the dial, first think about just disc 3, the front one that is attached to the dial. You could start by just making sure you can get disc 3 to end up in the correct position
p.setPositions(4, 2, 0); p.turn(10); // 10 degrees ccw System.out.println(p.getDiscPosition(3)); // expected 10 p.turn(-100); // 100 degrees cw System.out.println(p.getDiscPosition(3)); // expected 270 p.turn(800); System.out.println(p.getDiscPosition(3)); // expected 350 System.out.println();
Now it gets interesting. How does disc 3 affect disc 2? Suppose disc 3 is at 30 degrees and disc 2 is at 90 degrees, and we rotate disc 3 counterclockwise (ccw) 70 degrees.
p.setPositions(0, 90, 30); p.turn(70); printPositions(p); // expected 0 102 100
Here, (disc 2 position) - (disc 3 position) = 90 - 30 = 60 degrees, the counterclockwise rotation from disc 3 to disc 2. There is also the tooth width to account for, so disc 3 can rotate 58 degrees before it starts pushing disc 2. We're rotating disc 3 a total of 70 degrees ccw, so disc 2 will be pushed 12 degrees ccw, ending up at position 102.
Maybe we should try one where the subtraction comes out negative:
p.setPositions(0, 20, 350); p.turn(50); printPositions(p); // expected 0 42 40
In this case, (disc 2 position) - (disc 3 position) = -330 degrees, which normalizes to 30 degrees. With the tooth width, disc 3 can rotate 28 degrees ccw before affecting disc 2. We're rotating 50 degrees, so disc 2 is pushed 22 degrees.
Then try going clockwise: p.setPositions(0, 350, 20); p.turn(-40); printPositions(p); // expected 0 338 340
Here, (disc 2 position) - (disc 3 position) = 330 degrees, but we want the complement of this angle since we're rotating the opposite direction, which is 30 degrees. (Equivalently, just perform the subtraction in the opposite order and normalize.) Less the tooth width that's 28 degrees. Disc 3 is rotating a total of 40 degrees clockwise (cw), so disc 2 will move 12 degrees cw. New disc 3 position = 20 - 40 = -20, which normalizes to 340. New disc 2 position = 350 - 12 = 338.
Try another one: p.setPositions(45, 40, 30); p.turn(-400); printPositions(p); // expected 45 348 350
Here, (disc 2 position) - (disc 3 position) = 10 degrees, but we want the complement of this angle since we're rotating the opposite direction, which is 350 degrees; less the tooth width that's 348 degrees. Disc 1 is rotating 400 degrees cw, so disc 2 will be pushed 52 degrees. New disc 3 position = 30 - 400 = -370, which normalizes to 350. New disc 2 position = 40 - 52 = -12, which normalizes to 348
Accounting for the effect of disc 2 on disc 1 is similar. In the test case above, for example, we can tell that the difference, (disc 1 position) - (disc 2 position) = 45 - 40 = 5 degrees, the complement of which is 355, less the tooth width is 353; but disc 2 is only rotating 52 degrees cw, so disc 1 is unaffected. If we instead had the same example but with disc 1 at 10 degrees:
p.setPositions(10, 40, 30); p.turn(-400); printPositions(p); // expected 346 348 350
Now, (disc 1 position) - (disc 2 position) = -30 degrees, normalized to 330, but we want the complement which is 30, and allowing for the tooth width, we get 28 degrees cw from disc 2 to disc 1. Disc 2 is moving 52 degrees cw as in previous example, so disc 1 will be pushed 24 degrees cw. New disc 1 position is 10 - 24 = -14 or 346 degrees.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Heres a Java implementation of the Padlock class based on the provided specifications import javautilRandom public class Padlock public static final int TOOTH 2 Width of the tooth on each disc express...Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started