patternrubyMinor
"Can a given array be made strictly increasing by removing one number?"
Viewed 0 times
cannumbermadestrictlyremovingarrayoneincreasinggiven
Problem
The premise of the problem is that given an array of numbers, can you remove only one to make it a strictly increasing sequence?
For
and so on....
My questions
I've clearly made this code too complex, but it does work. Below my code is the tests that I used to check it with the expected returns commented out next to each.
How can I refactor this code to simplify it? Is there a way to do this without using
```
def almost_increasing_sequence(sequence)
array_of_arrays = sequence.chunk_while {|i, j| i 2
puts false
else
if (array_of_arrays[0].last array_of_arrays[1].first) == 1
if (array_of_arrays[0][-2] array_of_arrays[1][0]) == -1
puts true
elsif (array_of_arrays[0].last array_of_arrays[1][1]) == -1
puts true
elsif (array_of_arrays[0][-2]) == nil
puts true
else
puts false
end
else
puts true
end
end
end
almost_increasing_sequence([1, 2, 3, 4, 99, 5, 6]) #true
almost_increasing_sequence([1, 3, 2]) #true
almost_increasing_sequence([10, 1, 2, 3, 4, 5]) #true
almost_increasing_sequence([0, -2, 5, 6]) #true
almost_increasing_sequence([1, 2, 3, 4, 3, 6]) #true
almost_increasing_sequence([1, 1]) #true
almost_increasing_sequence([100, 200, 300, 400, 99, 50
[1, 1, 1, 2, 3]would befalsebecause if you remove one of the1s the array would still start off non-increasing because of the other two remaining1s before it increased.
[1, 2, 3, 4, 99, 5, 10]would betruebecause you can remove the99and the remaining array[1, 2, 3, 4, 5, 10]would be strictly increasing.
[1, 88, 2, 3, 4, 99, 5, 6]would befalsebecause removing any number would still leave an array that would not strictly increase.
For
[1, 1] it would return true because even though removing one of the 1s would only leave one 1 which by definition can't increase sequentially because it is only one thing, I did not write the problem and this is the response they wanted.and so on....
My questions
I've clearly made this code too complex, but it does work. Below my code is the tests that I used to check it with the expected returns commented out next to each.
How can I refactor this code to simplify it? Is there a way to do this without using
chunk_while?```
def almost_increasing_sequence(sequence)
array_of_arrays = sequence.chunk_while {|i, j| i 2
puts false
else
if (array_of_arrays[0].last array_of_arrays[1].first) == 1
if (array_of_arrays[0][-2] array_of_arrays[1][0]) == -1
puts true
elsif (array_of_arrays[0].last array_of_arrays[1][1]) == -1
puts true
elsif (array_of_arrays[0][-2]) == nil
puts true
else
puts false
end
else
puts true
end
end
end
almost_increasing_sequence([1, 2, 3, 4, 99, 5, 6]) #true
almost_increasing_sequence([1, 3, 2]) #true
almost_increasing_sequence([10, 1, 2, 3, 4, 5]) #true
almost_increasing_sequence([0, -2, 5, 6]) #true
almost_increasing_sequence([1, 2, 3, 4, 3, 6]) #true
almost_increasing_sequence([1, 1]) #true
almost_increasing_sequence([100, 200, 300, 400, 99, 50
Solution
I'm not completely sure I've interpreted the requirements correctly, but I think this should do it:
The tolerance is extra but it basically says this:
It looks like it works for all cases.
You could easily simplify by removing the tolerance argument (hard coding 1).
Weaknesses:
Strengths:
def almost_increasing_array?(array, tolerance)
unmatched = 0
array[1..-1].each_with_index do |item, index|
unmatched += 1 if array[index] >= item
return false if unmatched > tolerance
end
true
endThe tolerance is extra but it basically says this:
- Ignore the first item in the array
- For the rest, compare them to the previous item
- If the previous item was more than this, increment 'unmatched' count.
- If more than the tolerance didn't increase, false. It's not 'almost increasing'
It looks like it works for all cases.
almost_increasing_array?([1, 3, 5], 1) # true
almost_increasing_array?([5, 4, 3, 2, 1], 1) # false
almost_increasing_array?([1, 2, 5, 4], 1) # true (only one decrease)
almost_increasing_array?([1, 7, 5, 4], 1) # false (two decreases)
almost_increasing_array?([1, 7, 5, 4], 2) # true (two decreases, but we said that's okay)You could easily simplify by removing the tolerance argument (hard coding 1).
def almost_increasing_array?(array)
unmatched = 0
array[1..-1].each_with_index do |item, index|
unmatched += 1 if array[index] >= item
return false if unmatched > 1
end
true
endWeaknesses:
- This includes an array which is fully increasing, too.
- This will fail as soon as an issue is found, but it may run slowly on huge arrays where there's a decrease right at the end.
Strengths:
- It's pretty simple to understand.
- This doesn't even have to be an array, it'll work for an instance of any Ennumerable class. Such as ActiveRecord::Relation, or Hash.
Code Snippets
def almost_increasing_array?(array, tolerance)
unmatched = 0
array[1..-1].each_with_index do |item, index|
unmatched += 1 if array[index] >= item
return false if unmatched > tolerance
end
true
endalmost_increasing_array?([1, 3, 5], 1) # true
almost_increasing_array?([5, 4, 3, 2, 1], 1) # false
almost_increasing_array?([1, 2, 5, 4], 1) # true (only one decrease)
almost_increasing_array?([1, 7, 5, 4], 1) # false (two decreases)
almost_increasing_array?([1, 7, 5, 4], 2) # true (two decreases, but we said that's okay)def almost_increasing_array?(array)
unmatched = 0
array[1..-1].each_with_index do |item, index|
unmatched += 1 if array[index] >= item
return false if unmatched > 1
end
true
endContext
StackExchange Code Review Q#158658, answer score: 2
Revisions (0)
No revisions yet.