|
| 1 | +=begin |
| 2 | +Codewars. 28/04/20. 'Length of missing array'. 6kyu. Here we create a method |
| 3 | +that takes an array of arrays, if you sort the sub-arrays by length you'll see |
| 4 | +that their length values are consecutive, but one is missing, our method must |
| 5 | +return the missing array length. If the array of arrays is empty or nil, we |
| 6 | +return 0. If any sub-array is empty or nill, we return 0. Here is the solution |
| 7 | +I developed to solve the challenge. |
| 8 | +1) We define our method missing_array_length_ms, which takes aoa, an array of |
| 9 | + arrays as its argument. |
| 10 | +2) First we handle our error checking. We return 0 if aoa is nil or aoa is |
| 11 | + empty or aoa includes a nil sub-array or aoa includes an empty sub-array. |
| 12 | +3) We map! over each sub-array and convert them from their values, to their |
| 13 | + lengths. Now our array of arrays has become an array holding lengths. The |
| 14 | + exclamation mark is important as this permanently changes aoa, without it |
| 15 | + the method wouldn't work. |
| 16 | +4) We permanently sort! aoa, so now aoa is a sorted array of consecutive |
| 17 | + lengths with one length missing. Once again, the exclamation mark is crucial. |
| 18 | +5) We call each_with_index and if the next element in aoa is not equal to the |
| 19 | + successor (size+1) of the current element, we return the successor, in other |
| 20 | + words, the missing length. The succ method returns the integer equal to |
| 21 | + int + 1. |
| 22 | +=end |
| 23 | + |
| 24 | +def missing_array_length_ms(aoa) |
| 25 | + return 0 if aoa.nil? || aoa.empty? || aoa.include?(nil) || aoa.include?([]) |
| 26 | + aoa.map!(&:size).sort!.each_with_index do |s,i| |
| 27 | + return s.succ if aoa[i+1] != s.succ |
| 28 | + end |
| 29 | +end |
| 30 | + |
| 31 | +=begin |
| 32 | +Here is another solution, submitted by a Codewars user. It is very similar to |
| 33 | +mine in that it converts the sub-arrays to their lengths and then sorts them. |
| 34 | +The difference is that it uses each_cons to iterate 2 elements of the array of |
| 35 | +lengths at a time, if the difference between the next and current is 2, we |
| 36 | +return the current + 1. This returns the missing length. |
| 37 | +=end |
| 38 | + |
| 39 | +def missing_array_length(aoa) |
| 40 | + return 0 if aoa.nil? || aoa.empty? || aoa.include?(nil) || aoa.include?([]) |
| 41 | + aoa.map(&:size).sort.each_cons(2) do |a, b| |
| 42 | + return a + 1 if b - a == 2 |
| 43 | + end |
| 44 | +end |
| 45 | + |
| 46 | +=begin |
| 47 | +Here is another solution, it is not an efficient solution, but it makes use of |
| 48 | +some unfamiliar language features. |
| 49 | +1) We check if the array of arrays contains any empty sub-arrays, in which case |
| 50 | + we return 0. |
| 51 | +2) If not, we run the following sequence of code inside a single parenthesis |
| 52 | + (must be in parenthesis to work). |
| 53 | +3) We map! (exclamation necessary) over the array of arrays and convert the |
| 54 | + sub-arrays to their lengths. Now aoa is an array of lengths. |
| 55 | +4) We use Range.new to create a range and pass in *aoa.minmax. |
| 56 | +5) Range.new normally takes at least 2 arguments in the form Range.new(1, 10) |
| 57 | + or Range.new(aoa.min, aoa.max). |
| 58 | +6) The enumerable method minmax returns a 2 element array with the minimum |
| 59 | + value and maximum value of the enumerable object it's called on. So if aoa |
| 60 | + were [1,5,3,4] it would return [1,5]. |
| 61 | +7) Range.new(*aoa.minmax) with the splat operator essentially uses the min |
| 62 | + value as the start of the range and the max value as the end of the range. |
| 63 | + Hence this range will include the missing length. |
| 64 | +8) We convert the range to an array and subtract aoa from it, leaving us with |
| 65 | + the missing length, we use [0] to return it. |
| 66 | +9) rescue returns 0 if any errors are encountered during our code in |
| 67 | + parenthesis, which will be a nil array, an empty array or a sub-array that's |
| 68 | + a nil value. |
| 69 | +=end |
| 70 | + |
| 71 | +def missing_array_length_r(aoa) |
| 72 | + aoa.any?(&:empty?) ? 0 : ( aoa.map!(&:size) ; |
| 73 | + (Range.new(*aoa.minmax).to_a - aoa)[0] ) rescue 0 |
| 74 | +end |
0 commit comments