Your job is to help estimate the "strength" of various combination configurations. Sure, you could just calculate the total number of possible combinations with a bit of math and use that to estimate the strength of a configuration, but it'll be more fun to write a program to test it! Your program will generate random combinations, and count how many attempts it take before it correctly guesses a specific combination. This will also give us a chance to practice some more with projects consisting of multiple classes, and with topics we've seen so far like loops and equals
methods.
Combination
class that represents the sequence of integers that make up a combination (via an array), and a ComboGuesser
class that repeatedly creates Combination
instances and compares them to the "right answer" until it guesses the combination:
I've created a new project to get you started, but it only contains the beginnings of the Combination
class. You'll need to create a new class for ComboGuesser
when the time comes, but I'm recommending that you start by getting the Combination
class working before writing the ComboGuesser
class. Your Combination
class should contain the following methods:
Combination
instance to hold random values within the appropriate range for each of the values in the sequence. (As shown in the interactions below, the random values should include 0 and the specified maximum in their range.)
getMax
method that returns the largest possible value that could be found in the combination. (Note, this isn't the largest value that is in the combination — it's the maximum value passed to the constructor.)
getLength
method that returns the length of the combination.
toString
that builds and returns a string containing the values in the combination. For full credit, the values should be separated by commas, with square brackets around the entire thing, and you should write the code for creating the string yourself. (If you poke around enough you could find a built-in method that formats it like that for you, but it'll be good practice to write it yourself.) There should not be a comma after the last value. For example, if the combination contains the values 1, 2, and 3, the output from your method should be "[1, 2, 3]
". The sample interactions below illustrate the creation of several different Combination
objects, and output from toString
for each:
> Combination c = new Combination(4, 2); > c.getMax() 2 (int) > c.getLength() 4 (int) > c.toString() "[2, 1, 2, 0]" (String) > c = new Combination(4, 2); > c.toString() "[1, 1, 0, 2]" (String) > c = new Combination(6, 10); > c.toString() "[1, 6, 10, 8, 7, 0]" (String) > c = new Combination(1, 2); > c.toString() "[2]" (String)
setValue
method that takes two integers: The (zero-based) index of the value within the sequence to be changed, and the new value to be stored there. The value should only be changed if the index is valid, and the specified value is within the allowed range.
> Combination c = new Combination(4, 2); > c.toString() "[1, 0, 0, 2]" (String) > c.setValue(0,2); > c.toString() "[2, 0, 0, 2]" (String) > c.setValue(3,1); > c.toString() "[2, 0, 0, 1]" (String) > c.setValue(3,3); > c.toString() "[2, 0, 0, 1]" (String) > c.setValue(4,0); > c.toString() "[2, 0, 0, 1]" (String)
equals
that takes a Combination
instance as its argument, and returns a boolean value: If the Combination
instance passed in has the same length and contents as the instance on which the method is invoked, the method should return true
. It should return false
if the length or contents differ. For full credit, your method should use a loop to compare the contents of the two arrays within the two instances, assuming they have the same length.
> Combination c1 = new Combination(4, 2); > Combination c2 = new Combination(4, 2); > c1.toString() "[0, 0, 0, 1]" (String) > c2.toString() "[2, 0, 2, 1]" (String) > c1.equals(c2) false (boolean) > c1.equals(c1) true (boolean) > c2.setValue(0,0); > c2.setValue(2,0); > c2.toString() "[0, 0, 0, 1]" (String) > c1.equals(c2) true (boolean)
Combination
class thoroughly, create a new ComboGuesser
class. The ComboGuesser
class will create and remember a specific Combination
(we'll call it the "key"), then repeatedly create random Combination
instances until it finds one that matches. (Creating random Combination
instances should be easy now, since there's a constructor in the Combination
class that does just that. If you find yourself calling nextInt
in any of the methods below, you're on the wrong track!) Your ComboGuesser
class should contain the following methods:
int
inputs: The length of the combination sequence to be tested, and the maximum value in each position. It generates a random Combination
instance as the key.
Combination
instance to use as the key. This constructor would be called if the user already had a Combination
instance that they wanted you to guess, so you don't need to create a random one yourself when this constructor is called.
guessCombo
that generates random Combination
instances until it finds one that matches the key. (It doesn't need any inputs.) It should then print information about the key and the number of guesses required, as shown below.
The sample outputs below show ComboGuesser
instances searching for matches. The first ComboGuesser
, g1
, creates a random key of length 5. The call to guessCombo()
ends up generating roughly 8 million random Combination
instances before it finds one that matches the random key. (The output from guessCombo
would appear in the terminal window, not the codepad.) After that, the interactions show a Combination
, key
, being created and used as the key for a second ComboGuesser
object to guess. (Using setValue
to set values within the key to the maximimum and minimum possible values helps ensure thorough testing of guessCombo
.)
> ComboGuesser g1 = new ComboGuesser(5, 20); > g1.guessCombo(); It took 8160758 guesses to guess [13, 10, 4, 3, 11] > Combination key = new Combination(5, 10); > key.toString() "[5, 3, 9, 4, 4]" (String) > key.setValue(0, 10); > key.setValue(4, 0); > key.toString() "[10, 3, 9, 4, 0]" (String) > ComboGuesser g2 = new ComboGuesser(key); > g2.guessCombo(); It took 116561 guesses to guess [10, 3, 9, 4, 0]
guessCombo
method is only required to find the key once, then quit. It's possible that we'll get lucky on our first effort, and stumble upon the key after relatively few guesses. You could extend the method so that it tries a few times and averages the number of guesses required each time.
@param
and @return
tags
Combination
fields and constructor
getMax()
and getLength()
ComboGuesser
fields and constructors