JAVA
-
public class Padlock extends java.lang.Object
A Padlock models a standard combination padlock. The mechanism consists of three discs mounted on the same axis. Each disc has a notch on its outer edge, and when they are rotated so that the three notches are aligned, the lock can be opened. The front disc, aka disc 3, is connected directly to a dial, which we assume is marked around its outer edge from 0 to 359, ordered clockwise, corresponding to degrees of rotation. The front disk has a small protrusion, or "tooth", on its back side, and the middle disc (disc 2) has a tooth on both its front and back, and the rear disk (disc 1) has a tooth on its front side. Only the front disc can be turned directly by the user, but if turned far enough the tooth will bump into the tooth on the middle disc and force it to turn as well. Likewise, if turned far enough the tooth on the back of the middle disc will contact the tooth on the rear disc and cause it to turn. Thus after turning the dial two complete revolutions clockwise, it will be possible to push the rear disc into any desired position. Then if the dial is turned counterclockwise, discs 1 and 2 will initially remain stationary. After one complete revolution counterclockwise, the tooth on the front disc will again contact the tooth on the middle disc and cause it to rotate counterclockwise, still leaving the rear disc alone. In this way the middle disc can be rotated into a desired position. Finally, the front disc can be rotated clockwise to a desired position without affecting the other two.
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 this number to be "normalized" so it is 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 at the number 0. Each disc also has an offset, in degrees, between its tooth and the notch. If the notch is in the correct alignment position when the disc's position is D degrees, then we say the offset is D. When every disc's current position is equal to its offset, then the notches are aligned and the lock can be opened.
It is the amount of these offsets that determine the combination. The way we interpret a combination X, Y, Z is like this:
- rotate the dial two complete revolutions clockwise and stop at X
- rotate the dial one complete revolution counterclockwise and stop at Y
- rotate the dial clockwise and stop at Z
It would be convenient if when the offsets are X, Y, and Z for discs 1, 2, and 3, respectively, that the combination would simply be X, Y, Z. However, if we turn the dial several complete revolutions clockwise 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 98 degrees and disc 1 would be at 96 degrees. Similarly, if we rotate the dial counterclockwise a full revolution and stop at 100 degrees, the middle disc would be at 102. 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 the width of the tooth expressed in degrees. Note we are assuming that both of the teeth for disc 2 are in the same position.
Fields Modifier and Type Field Description static int TOOTH Width of the teeth on each disc in the mechanism, expressed in degrees of rotation. Constructor Summary Constructors Constructor Description Padlock (int nl, int n2, int n3) Constructs a padlock with the given combination. TOOTH public static final int TOOTH Width of the teeth on each disc in the mechanism, expressed in degrees of rotation. See Also: Constant Field Values Padlock public Padlock (int nl, int n2, int n3) Constructs a padlock with the given combination. Initially the lock is open and the dial is at o, disc 2 is at TOOTH degrees rotation, and disc 1 is at 2 * TOOTH degrees rotation, regardless of the given combination. In general, to be a valid combination, each number in the combination should be between o and 359 and should differ from the others by at least the value of the tooth width. However, this constructor does not throw an error if the given values do not form a valid combination. It will simply construct a lock that may be impossible to open since the discs cannot actually be aligned. Parameters: nl - first number in combination n2 - second number in combination n3 - third number in combination randomizePositions public void randomizePositions (java. util. Random rand) Set the three discs to random, valid positions. Parameters: rand - Random instance to use for selecting the three positions. setPositions public void setPositions (int n, int n2, int n3) Sets the positions of the three discs to given angles, as closely as possible while ensuring the positions are valid. Disc 3 is always set to the given angle n3. If the given angle n2 is within n3 plus or minus the tooth width, then disc 2 will be set to n3 + the tooth width. Similarly, if ni is within (the corrected value of) n2, plus or minus the tooth width, then disc 1 will be set to n2 + the tooth width. All values will be normalized to be between 0 and 359. Note: Realistically, this method would not be part of a public interface, since normally the disc positions could not be directly manipulated by the user of the lock. It is made public to simplify development and testing. Parameters: nl - position for disc 1 n2 - position for disc 2 n3 - position for disc 3 turnLeft To public void turnLeftTo(int number) Turns the dial (disc 3) counterclockwise until its position is the given number. Parameters: number - new dial position turnRight To public void turnRightTo(int number) Turns the dial (disc 3) clockwise until its position is the given number. Parameters: number - new dial position turn public void urn(int degrees) Turns the dial (disc 3) the given number of degrees, where a posilive number represents a counterclockwise rotation and a negative number represents a clockwise rolation. Parameters: degrees - amount to turn the dial getDiscPosition public int getDiscPosition (int which) Returns the current position of the given disc (1, 2, or 3, where disc 3 is the front disc attached to the dial). The value returned is always normalized to be between o and 359, inclusive. If the argument is not equal to 1, 2, or 3, the method returns -1. Note: Realistically, this method would not be part of a public interface, since normally the disc positions would not be directly visible to the user of the lock. It is made public to simplify development and testing. Parameters: which - which disc (1, 2, or 3) to return the position of Returns: current position of the given disc isAligned public boolean isAligned () Returns true if all three discs are aligned, that is, for all discs the current position is equal to the offset. Returns: true if all three discs are aligned for the lock to open, false otherwise open public void open() Opens the lock, if possible. Does nothing unless is Aligned is true. close public void close () Closes the lock, whether or not the discs are aligned. isOpen public boolean isOpen() Determines whether the lock is currently open. Returns: true if the lock is open, false otherwise Fields Modifier and Type Field Description static int TOOTH Width of the teeth on each disc in the mechanism, expressed in degrees of rotation. Constructor Summary Constructors Constructor Description Padlock (int nl, int n2, int n3) Constructs a padlock with the given combination. TOOTH public static final int TOOTH Width of the teeth on each disc in the mechanism, expressed in degrees of rotation. See Also: Constant Field Values Padlock public Padlock (int nl, int n2, int n3) Constructs a padlock with the given combination. Initially the lock is open and the dial is at o, disc 2 is at TOOTH degrees rotation, and disc 1 is at 2 * TOOTH degrees rotation, regardless of the given combination. In general, to be a valid combination, each number in the combination should be between o and 359 and should differ from the others by at least the value of the tooth width. However, this constructor does not throw an error if the given values do not form a valid combination. It will simply construct a lock that may be impossible to open since the discs cannot actually be aligned. Parameters: nl - first number in combination n2 - second number in combination n3 - third number in combination randomizePositions public void randomizePositions (java. util. Random rand) Set the three discs to random, valid positions. Parameters: rand - Random instance to use for selecting the three positions. setPositions public void setPositions (int n, int n2, int n3) Sets the positions of the three discs to given angles, as closely as possible while ensuring the positions are valid. Disc 3 is always set to the given angle n3. If the given angle n2 is within n3 plus or minus the tooth width, then disc 2 will be set to n3 + the tooth width. Similarly, if ni is within (the corrected value of) n2, plus or minus the tooth width, then disc 1 will be set to n2 + the tooth width. All values will be normalized to be between 0 and 359. Note: Realistically, this method would not be part of a public interface, since normally the disc positions could not be directly manipulated by the user of the lock. It is made public to simplify development and testing. Parameters: nl - position for disc 1 n2 - position for disc 2 n3 - position for disc 3 turnLeft To public void turnLeftTo(int number) Turns the dial (disc 3) counterclockwise until its position is the given number. Parameters: number - new dial position turnRight To public void turnRightTo(int number) Turns the dial (disc 3) clockwise until its position is the given number. Parameters: number - new dial position turn public void urn(int degrees) Turns the dial (disc 3) the given number of degrees, where a posilive number represents a counterclockwise rotation and a negative number represents a clockwise rolation. Parameters: degrees - amount to turn the dial getDiscPosition public int getDiscPosition (int which) Returns the current position of the given disc (1, 2, or 3, where disc 3 is the front disc attached to the dial). The value returned is always normalized to be between o and 359, inclusive. If the argument is not equal to 1, 2, or 3, the method returns -1. Note: Realistically, this method would not be part of a public interface, since normally the disc positions would not be directly visible to the user of the lock. It is made public to simplify development and testing. Parameters: which - which disc (1, 2, or 3) to return the position of Returns: current position of the given disc isAligned public boolean isAligned () Returns true if all three discs are aligned, that is, for all discs the current position is equal to the offset. Returns: true if all three discs are aligned for the lock to open, false otherwise open public void open() Opens the lock, if possible. Does nothing unless is Aligned is true. close public void close () Closes the lock, whether or not the discs are aligned. isOpen public boolean isOpen() Determines whether the lock is currently open. Returns: true if the lock is open, false otherwise