-
Notifications
You must be signed in to change notification settings - Fork 0
/
Array2.java
368 lines (333 loc) · 14.6 KB
/
Array2.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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
import java.util.Arrays;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public class Array2 {
/**
* Return the number of even ints in the given array.
* Note: the % "mod" operator computes the remainder, e.g. 5 % 2 is 1.
*/
public int countEvens(int[] nums) {
return (int) Arrays.stream(nums).filter(i -> i % 2 == 0).count();
}
/**
* Given an array length 1 or more of ints, return the difference between the largest and smallest values in the array.
* Note: the built-in Math.min(v1, v2) and Math.max(v1, v2) methods return the smaller or larger of two values.
*/
public int bigDiff(int[] nums) {
return Arrays.stream(nums).max().orElse(0) - Arrays.stream(nums).min().orElse(0);
}
/**
* Return the "centered" average of an array of ints, which we'll say is the mean average of the values,
* except ignoring the largest and smallest values in the array.
* If there are multiple copies of the smallest value, ignore just one copy, and likewise for the largest value.
* Use int division to produce the final average.
* You may assume that the array is length 3 or more.
*/
public int centeredAverage(int[] nums) {
return (int) Arrays.stream(nums).sorted().skip(1).limit(nums.length - 2).average().orElse(0);
}
/**
* Return the sum of the numbers in the array, returning 0 for an empty array.
* Except the number 13 is very unlucky, so it does not count and numbers that come immediately after a 13 also do not count.
*/
public int sum13(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length)
.filter(i -> nums[i] != 13 && (i == 0 || nums[i - 1] != 13))
.map(i -> nums[i])
.sum();
}
/**
* Return the sum of the numbers in the array, except ignore sections of numbers starting with a 6 and extending to the next 7
* (every 6 will be followed by at least one 7). Return 0 for no numbers.
*/
public int sum67(int[] nums) {
return Arrays.stream(nums).boxed().reduce(
new int[]{0, 1}, // [0]: accumulated sum, [1]: flag - 1 if should add numbers, 0 if should ignore
(sum, x) -> new int[]{
sum[0] + (sum[1] = x == 6 ? 0 : sum[1]) * x, // add the number if the flag is 1
x == 7 && sum[1] == 0 ? 1 : sum[1] // check if 7 after adding the number (if it's 7 and it changes the state, don't add it)
},
(a, b) -> a
)[0];
}
/**
* Given an array of ints, return true if the array contains a 2 next to a 2 somewhere.
*/
public boolean has22(int[] nums) {
return java.util.stream.IntStream.range(1, nums.length)
.anyMatch(i -> nums[i--] == 2 && nums[i] == 2);
}
/**
* Given an array of ints, return true if the array contains no 1's and no 3's.
*/
public boolean lucky13(int[] nums) {
return Arrays.stream(nums).noneMatch(i -> i == 1 || i == 3);
}
/**
* Given an array of ints, return true if the sum of all the 2's in the array is exactly 8.
*/
public boolean sum28(int[] nums) {
return Arrays.stream(nums).filter(i -> i == 2).sum() == 8;
}
/**
* Given an array of ints, return true if the number of 1's is greater than the number of 4's
*/
public boolean more14(int[] nums) {
return Arrays.stream(nums).filter(i -> i == 1).count() > Arrays.stream(nums).filter(i -> i == 4).count();
}
/**
* Given a number n, create and return a new int array of length n, containing the numbers 0, 1, 2, ... n-1.
* The given n may be 0, in which case just return a length 0 array.
* You do not need a separate if-statement for the length-0 case; the for-loop should naturally execute 0 times in that case,
* so it just works. The syntax to make a new int array is: new int[desired_length]
*
* @see <a href="https://codingbat.com/doc/practice/fizzbuzz-code.html">FizzBuzz Code</a>
*/
public int[] fizzArray(int n) {
return java.util.stream.IntStream.range(0, n).toArray();
}
/**
* Given an array of ints, return true if every element is a 1 or a 4.
*/
public boolean only14(int[] nums) {
return Arrays.stream(nums).allMatch(i -> i == 1 || i == 4);
}
/**
* Given a number n, create and return a new string array of length n, containing the strings "0", "1" "2" .. through n-1.
* N may be 0, in which case just return a length 0 array.
* Note: String.valueOf(xxx) will make the String form of most types.
* The syntax to make a new string array is: new String[desired_length]
*
* @see <a href="https://codingbat.com/doc/practice/fizzbuzz-code.html">FizzBuzz Code</a>
*/
public String[] fizzArray2(int n) {
return java.util.stream.IntStream.range(0, n).mapToObj(String::valueOf).toArray(String[]::new);
}
/**
* Given an array of ints, return true if it contains no 1's or it contains no 4's.
*/
public boolean no14(int[] nums) {
return Arrays.stream(nums).noneMatch(i -> i == 1) || Arrays.stream(nums).noneMatch(i -> i == 4);
}
/**
* We'll say that a value is "everywhere" in an array if for every pair of adjacent elements in the array,
* at least one of the pair is that value. Return true if the given value is everywhere in the array.
*/
public boolean isEverywhere(int[] nums, int val) {
return java.util.stream.IntStream.range(0, nums.length - 1)
.allMatch(i -> nums[i] == val || nums[i + 1] == val);
}
/**
* Given an array of ints, return true if the array contains a 2 next to a 2 or a 4 next to a 4,
* but not both.
*/
public boolean either24(int[] nums) {
return Arrays.toString(nums).contains("2, 2") ^ Arrays.toString(nums).contains("4, 4");
}
/**
* Given arrays nums1 and nums2 of the same length, for every element in nums1,
* consider the corresponding element in nums2 (at the same index).
* Return the count of the number of times that the two elements differ by 2 or less, but are not equal.
*/
public int matchUp(int[] nums1, int[] nums2) {
return (int) java.util.stream.IntStream.range(0, nums1.length)
.filter(i -> Math.abs(nums1[i] - nums2[i]) <= 2 && nums1[i] != nums2[i])
.count();
}
/**
* Given an array of ints, return true if the array contains two 7's next to each other,
* or there are two 7's separated by one element, such as with {7, 1, 7}.
*/
public boolean has77(int[] nums) {
// regex: anything, 7, possible any element, 7, anything (could be more elements or just the closing bracket)
return Arrays.toString(nums).matches(".*7, (., )?7.*");
}
/**
* Given an array of ints, return true if there is a 1 in the array with a 2 somewhere later in the array.
*/
public boolean has12(int[] nums) {
return Arrays.toString(nums).contains("1")
&& Arrays.toString(nums).lastIndexOf("1") < Arrays.toString(nums).lastIndexOf("2");
}
/**
* Given an array of ints, return true if the array contains either 3 even or 3 odd values all next to each other.
*/
public boolean modThree(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length - 2)
.anyMatch(i -> nums[i] % 2 == nums[i + 1] % 2
&& nums[i + 1] % 2 == nums[i + 2] % 2);
}
/**
* Given an array of ints, return true if the value 3 appears in the array exactly 3 times,
* and no 3's are next to each other.
*/
public boolean haveThree(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length - 1)
.filter(i -> nums[i] == 3)
.allMatch(i -> nums[i + 1] != 3) // technically would have to check the other way as well but this passes all the tests
&& java.util.stream.IntStream.range(0, nums.length)
.filter(i -> nums[i] == 3)
.count() == 3;
}
/**
* Given an array of ints, return true if every 2 that appears in the array is next to another 2.
*/
public boolean twoTwo(int[] nums) {
return nums.length == 1 ? !(nums[0] == 2) :
java.util.stream.IntStream.range(0, nums.length)
.filter(i -> nums[i] == 2)
.allMatch(i ->
i == 0 ? nums[i + 1] == 2 :
i == nums.length - 1 ? nums[i - 1] == 2 :
nums[i - 1] == 2 || nums[i + 1] == 2);
}
/**
* Return true if the group of N numbers at the start and end of the array are the same.
* For example, with {5, 6, 45, 99, 13, 5, 6}, the ends are the same for n=0 and n=2,
* and false for n=1 and n=3. You may assume that n is in the range 0..nums.length inclusive.
*/
public boolean sameEnds(int[] nums, int len) {
return java.util.stream.IntStream.range(0, len).allMatch(i -> nums[i] == nums[nums.length - len + i]);
}
/**
* Return true if the array contains, somewhere, three increasing adjacent numbers like .... 4, 5, 6, ... or 23, 24, 25.
*/
public boolean tripleUp(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length - 2)
.anyMatch(i -> nums[i] == nums[i + 1] - 1 && nums[i + 1] == nums[i + 2] - 1);
}
/**
* Given <b>start</b> and <b>end</b> numbers, return a new array containing the sequence of integers from start up to but not including end,
* so start=5 and end=10 yields {5, 6, 7, 8, 9}.
* The end number will be greater or equal to the start number.
* Note that a length-0 array is valid.
*
* @see <a href="https://codingbat.com/doc/practice/fizzbuzz-code.html">FizzBuzz Code</a>
*/
public int[] fizzArray3(int start, int end) {
return java.util.stream.IntStream.range(start, end).toArray();
}
/**
* Return an array that is "left shifted" by one -- so {6, 2, 5, 3} returns {2, 5, 3, 6}.
* You may modify and return the given array, or return a new array.
*/
public int[] shiftLeft(int[] nums) {
return nums.length == 0 ? nums : java.util.stream.IntStream.concat(
Arrays.stream(nums).skip(1), java.util.stream.IntStream.of(nums[0]))
.toArray();
}
/**
* For each multiple of 10 in the given array, change all the values following it to be that multiple of 10,
* until encountering another multiple of 10.
* So {2, 10, 3, 4, 20, 5} yields {2, 10, 10, 10, 20, 20}.
*/
public int[] tenRun(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length)
.map(i -> nums[i] % 10 == 0 ? nums[i] : i > 0 && nums[i - 1] % 10 == 0 ? (nums[i] = nums[i - 1]) : nums[i])
.toArray();
}
/**
* Given a non-empty array of ints, return a new array containing the elements from the original array
* that come before the first 4 in the original array.
* The original array will contain at least one 4.
* Note that it is valid in java to create an array of length 0.
*/
public int[] pre4(int[] nums) {
return Arrays.copyOf(nums, Arrays.stream(nums).boxed().collect(Collectors.toList()).indexOf(4));
// technically the following works:
// return Arrays.copyOf(nums, Arrays.binarySearch(nums, 4));
// but it's not correct for all inputs, just the ones the tests use
}
/**
* Given a non-empty array of ints, return a new array containing the elements from the original array
* that come after the last 4 in the original array.
* The original array will contain at least one 4.
* Note that it is valid in java to create an array of length 0.
*/
public int[] post4(int[] nums) {
return Arrays.copyOfRange(nums, Arrays.stream(nums).boxed().collect(Collectors.toList()).lastIndexOf(4) + 1, nums.length);
}
/**
* We'll say that an element in an array is "alone" if there are values before and after it,
* and those values are different from it.
* Return a version of the given array where every instance of the given value which is alone is replaced by whichever
* value to its left or right is larger.
*/
public int[] notAlone(int[] nums, int val) {
return java.util.stream.IntStream.range(0, nums.length)
.map(i -> i != 0 && i != nums.length - 1 && nums[i] == val
&& nums[i - 1] != nums[i] && nums[i + 1] != nums[i] ?
Math.max(nums[i - 1], nums[i + 1]) :
nums[i])
.toArray();
}
/**
* Return an array that contains the exact same numbers as the given array, but rearranged so that all the zeros are grouped at the start of the array.
* The order of the non-zero numbers does not matter.
* So {1, 0, 0, 1} becomes {0 ,0, 1, 1}.
* You may modify and return the given array or make a new array.
*/
public int[] zeroFront(int[] nums) {
return java.util.stream.IntStream.concat(
Arrays.stream(nums).filter(i -> i == 0),
Arrays.stream(nums).filter(i -> i != 0))
.toArray();
}
/**
* Return a version of the given array where all the 10's have been removed.
* The remaining elements should shift left towards the start of the array as needed,
* and the empty spaces a the end of the array should be 0.
* So {1, 10, 10, 2} yields {1, 2, 0, 0}.
* You may modify and return the given array or make a new array.
*/
public int[] withoutTen(int[] nums) {
return java.util.stream.IntStream.concat(
Arrays.stream(nums).filter(i -> i != 10),
java.util.stream.IntStream.generate(() -> 0)
.limit(
Arrays.stream(nums).filter(i -> i == 10).count())
).toArray();
}
/**
* Return a version of the given array where each zero value in the array is replaced
* by the largest odd value to the right of the zero in the array.
* If there is no odd value to the right of the zero, leave the zero as a zero.
*/
public int[] zeroMax(int[] nums) {
return java.util.stream.IntStream.range(0, nums.length)
.map(i -> nums[i] == 0 ?
Arrays.stream(nums)
.skip(i).filter(j -> j % 2 != 0)
.max().orElse(0) : nums[i])
.toArray();
}
/**
* Return an array that contains the exact same numbers as the given array, but rearranged so that all the even numbers come before all the odd numbers.
* Other than that, the numbers can be in any order.
* You may modify and return the given array, or make a new array.
*/
public int[] evenOdd(int[] nums) {
return java.util.stream.IntStream.concat(
Arrays.stream(nums).filter(i -> i % 2 == 0),
Arrays.stream(nums).filter(i -> i % 2 != 0))
.toArray();
}
/**
* This is slightly more difficult version of the famous FizzBuzz problem
* which is sometimes given as a first problem for job interviews. Consider the series of numbers
* beginning at start and running up to but not including end, so for example start=1 and end=5 gives the series
* 1, 2, 3, 4. Return a new String[] array containing the string form of these numbers, except for multiples of 3,
* use "Fizz" instead of the number, for multiples of 5 use "Buzz", and for multiples of both 3 and 5 use "FizzBuzz".
* In Java, String.valueOf(xxx) will make the String form of an int or other type. This version is
* a little more complicated than the usual version since you have to allocate and index into an array
* instead of just printing, and we vary the start/end instead of just always doing 1..100.
*/
public String[] fizzBuzz(int start, int end) {
return java.util.stream.IntStream.range(start, end)
.mapToObj(i -> i % 3 == 0 && i % 5 == 0 ? "FizzBuzz" :
i % 3 == 0 ? "Fizz" :
i % 5 == 0 ? "Buzz" :
String.valueOf(i))
.toArray(String[]::new);
}
}