-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNumbersEntry.java
260 lines (225 loc) · 7.94 KB
/
NumbersEntry.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/*
* Student name: Ross Petridis
* Student ID: 1080249
* LMS username: rpetridis
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.Scanner;
/**
* This class facilitates the instation of entries to the LuckyNumbers
* competition.
* This class is an extension to a standard Entry
* by including a list of numbers and a boolean
* to keep track of whether this entry was automatically
* generated or manually generated by user.
*
* @author Ross Petridis
*/
public class NumbersEntry extends Entry {
private ArrayList<Integer> numbers; // Entered number for entry
private boolean auto; // true iff auto generatd the entry.
// Constants
private static final int NUM_ALLOWED_ENTRIES = 7;
private static final int MAX_RANGE = 35;
private static final int MIN_RANGE = 1;
private static final String DIGITS_AND_WHITESPACE_ONLY_REGEX = "[0-9 ]+";
private static final int NUM_WHITE_SPACES_PRINT = 2;
private static final int NUM_ENTRY_WHITE_SPACES = 6;
/**
* Null constructor
*/
public NumbersEntry() {
super();
}
/**
* Sets the value of auto
*
* @param bool true iff this entry was auto generated.
*/
public void setAuto(boolean bool) {
this.auto = bool;
}
/**
* Copy constructor
*
* @param entry An object of NumberEntry to make a copy of.
*/
public NumbersEntry(NumbersEntry entry) {
super((Entry) entry);
this.auto = entry.auto;
this.numbers = entry.getNumbers(); // set to a copy to prevent data leaks.
}
/**
* Constructor for making a new NumberEntry from user input
*
* @param entryId Entry ID for this new entry
* @param billId Bill associated with this entry
* @param memberId Member associated with this entry
* @param auto Whether or not to auto generate the numbers for this entry.
*/
public NumbersEntry(
int entryId,
String billId,
String memberId,
boolean auto) {
super(entryId, billId, memberId);
if (!auto) {
this.numbers = getManualEntryNumbers();
} // else, numbers are generated and set in subclass for AutoNumbersEntry.
this.auto = auto;
// This had to be im
}
/**
* Set this objects arraylist of numbers. Useful if using an
* external tool to calculate them.
*
* @param numbers The numbers to set this.numbers to.
*/
public void setNumbers(ArrayList<Integer> numbers) {
this.numbers = numbers;
}
/**
* Overriding of default toString method to print according to
* design spec.
*
* @return The string mostly sued for printing.
*/
@Override // the default toString in Entry.
public String toString() {
String returnString = String.format("Entry ID: %-"+NUM_ENTRY_WHITE_SPACES+"d Numbers:", getEntryiD()) + getEntriesString();
return returnString;
}
/**
* Return the numbers used to make this entry in print format.
*
* @return The numbers
*/
public String getEntriesString() {
String numbs = "";
Iterator<Integer> iter = getNumbers().iterator();
while (iter.hasNext()) {
numbs += String.format(" %"+NUM_WHITE_SPACES_PRINT+"d", iter.next());
}
if (auto) {
numbs += " [Auto]";
}
return numbs;
}
/**
*
* @return a copy of the numbers of this entry.
*/
public ArrayList<Integer> getNumbers() {
return new ArrayList<Integer>(numbers);
}
/**
* contains logic for setting numbers of this entry from user input.
* Ensures the formatting of input to be valid.
*
* @return The inputted numbers, sorted.
*/
private ArrayList<Integer> getManualEntryNumbers() {
boolean validResponse = false;
String entryNumbersStr;
String[] entryNumbersStrArr;
int[] entryNumbers = null;
Scanner scanner = SimpleCompetitions.getScanner();
while (!validResponse) {
// prompt and read from input.
System.out.println("Please enter "+NUM_ALLOWED_ENTRIES+" different numbers (from the range 1 to" +
" " + MAX_RANGE + ") separated by whitespace.");
entryNumbersStr = scanner.nextLine().trim();
// Need numbers seperated by white space only
if (!entryNumbersStr.matches(DIGITS_AND_WHITESPACE_ONLY_REGEX)) {
System.out.println("Invalid input! Numbers are expected. Please try again!");
continue;
}
// we have a string of numbers seperated by white space.
// convert to arr to check size.
entryNumbersStrArr = entryNumbersStr.split("\\s+"); // split by white space.
if (entryNumbersStrArr.length < NUM_ALLOWED_ENTRIES) { // not enough numbers
System.out.println("Invalid input! Fewer than "+NUM_ALLOWED_ENTRIES+" numbers are provided. Please try again!");
continue;
}
if (entryNumbersStrArr.length > NUM_ALLOWED_ENTRIES) { // too many.
System.out.println("Invalid input! More than "+NUM_ALLOWED_ENTRIES+" numbers are provided. Please try again!");
continue;
}
// convert to int array to check values.
entryNumbers = convertStringIntArrayToIntArray(entryNumbersStrArr);
if (notAllDifferent(entryNumbers)) { // duplicates
System.out.println("Invalid input! All numbers must be different!");
continue;
}
if (notAllInRange(entryNumbers, MIN_RANGE, MAX_RANGE)) { // out of range.
System.out.println("Invalid input! All numbers must be in the range from "+MIN_RANGE+" to "+MAX_RANGE+"!");
continue;
}
// done all checks - OK
validResponse = true;
}
ArrayList<Integer> arrList = arrayToArrayList(entryNumbers);
Collections.sort(arrList); // inplace sorting.
return arrList;
}
/**
* convert array of int to arrayList of int.
*
* @param arr input array to be converted
* @return the converted array.
*/
public ArrayList<Integer> arrayToArrayList(int[] arr) {
ArrayList<Integer> arrList = new ArrayList<Integer>();
for (int i : arr) {
arrList.add(i);
}
return arrList;
}
/**
* checks if an inputted array of numbers are all within a specified range.
*
* @param numbers Numbers to checks the values of.
* @param min min value allowed.
* @param max max value allowed.
* @return true iff all in range.
*/
private boolean notAllInRange(int[] numbers, int min, int max) {
for (int num : numbers) {
if (num < min || num > max) {
return true; // a number not in range, i.e. they are not all in range.
}
}
return false;
}
/**
* returns true if array contains unique set of numbers.
*
* @param numbers
* @return
*/
private boolean notAllDifferent(int[] numbers) {
ArrayList<Integer> currentNumbers = new ArrayList<Integer>();
for (int num : numbers) {
if (currentNumbers.contains(num)) {
return true; // found a duplciate num. i.e., they are not all different.
}
currentNumbers.add(num);
}
return false;
}
/**
* converts array of strings representing digits to actual integers.
*
* @param strArr array to convert
* @return int array.
*/
private int[] convertStringIntArrayToIntArray(String[] strArr) {
int[] intArr = new int[strArr.length];
for (int i = 0; i < strArr.length; i++) {
intArr[i] = Integer.parseInt(strArr[i]);
}
return intArr;
}
}