Rails method for checking if a number in a range appears in an array - ruby-on-rails

I have an array (or possibly a set) of integers (potentially non sequential but all unique) and a range of (sequential) numbers. If I wanted to check if any of the numbers in the range existed in the array, what would be the most efficient way of doing this?
array = [1, 2, 5, 6, 7]
range = 3..5
I could iterate over the range and check if the array include? each element but this seems wasteful and both the array and the range could easily be quite large.
Are there any methods I could use to do some sort of array.include_any?(range), or should I look for efficient search algorithms?

I would do
(array & range.to_a).present?
or
array.any? { |element| range.cover?(element) }
I would choose a version depending on the size of the range. If the range is small that the first version is probably faster, because it creates the intersection once and doesn't need to check cover for every single element in the array. Whereas if the range is huge (but the array is small) the second version might be faster, because a few comparisons might be faster that generating an array out of a huge range and building the intersection.

([1, 2, 5, 6, 7] & (3..5).to_a).any?
# => true

Don't need no stinkin' &:
array.uniq.size + range.size > (array + range.to_a).uniq.size

Related

Check if one list contains every element from second list

Honestly I have no idea how to check if list 1 contains every element from 2nd list, but I need it.
EDIT: i want to check if those 2 lists with same length have the same values, just with different indices
Thank you in advance
Something like this?
void main() {
final list1 = [5, 2, 3, 10, 2, 1, 11, 4];
final list2 = [1, 2, 3, 4, 5];
print(list1.toSet().containsAll(list2)); // true
}
First of all, you need to specify what you mean by "same elements". Do you mean equal elements (according to ==) or identical elements (according to the identical function)? I'm going to assume ==, since that's the most common, and if your elements don't override ==, it's the same thing as identity anyway.
The simplest approach, if possible, is to sort both lists, then compare each element of one list to the element of the other list at the same position. That does require that the elements have an ordering that agrees with == (so a.compareTo(b) == 0 if and only if a == b), and that you are allowed to change the ordering of the lists.
If you do almost anything else, you need to consider what happens if the same element occurs more than once in one of the lists.
Just comparing lengths as well is not enough, since [1, 1, 2] and [1, 2, 2] both have three elements, and all elements of either list is also an element of the other list. If duplicate elements can occur, you need to be counting the elements as well.
You can use UnorderedIterableEquality from package:collection. It implements a counting-based equality check on arbitrary iterables, which includes working on lists.
Example:
const unorderedEquals = UnorderedIterableEquality();
// ...
if (unorderedEquals.equals(list1, list2)) {
// ... lists have same elements ...
}

Checking whether an array is a suffix array for any binary string

I'm currently trying to figure out whether a given array, which is a permutation of the numbers 1 to n, is a suffix array of any binary string.
For example for n = 3, A = {2, 1, 3} is valid, since there exists the binary string [101] with [01] < [1] < [101] (using lexicographical ordering). However {2, 3, 1} is not a valid suffix array, as there is no binary string for which the lexicographical order holds.
My current approach simply enumerates all binary strings of length n, and checks whether the suffix array is correctly ordered w.r.t. each string. This is obviously rather slow, as there are 2^n candidate binary strings to be checked in O(n) each.
The obvious approach to this kind of problem would be to look for similarities in the valid suffix arrays, however I've thus far only been able to deduce one property:
If A is a valid suffix array for a binary string, then prefixing A with 1 and incrementing all values of A yields a valid suffix array as well.
This property however does not help me with suffix arrays that do not start with 1, when attempting to validate them.

table size difference. are both examples identical?

tNum={[2]=true , [3]=true,[4]=true, [5]=true ,[6]=true }
#tNum-->0
tNum={}
tNum[2]=true
tNum[3]=true
tNum[4]=true
tNum[5]=true
tNum[6]=true
#tNum-->6
why such a difference in size?
are both examples identical?
Your two tables are semantically identical, but using # on them is ambiguous. Both 0 and 6 are correct lengths. Here's an abridged version of the docs:
The length operator applied on a table returns a border in that table. A border in a table t is any natural number that satisfies the following condition:
(border == 0 or t[border] ~= nil) and t[border + 1] == nil
A table with exactly one border is called a sequence.
When t is not a sequence, #t can return any of its borders. (The exact one depends on details of the internal representation of the table, which in turn can depend on how the table was populated and the memory addresses of its non-numeric keys.)
This is an example of undefined behavior (UB). (That may not be the right word, because the behavior is partially defined. UB in Lua can't launch nuclear weapons, as it can in C.) Undefined behavior is important, because it gives the devs the freedom to choose the fastest possible algorithm without worrying about what happens when a user violates their assumptions.
To find a length, Lua makes, at most, log n guesses instead of looking at every element to find an unambiguous length. For large arrays, this speeds things up a lot.
The issue is that when you define a table as starting at index [2], the length operator breaks because it assumes that tables start at index [1].
The following code works as intended:
tNum = {[1]=false, [2]=true, [3]=true, [4]=true, [5]=true, [6]=true}
#tNum => 6
The odd behaviour is caused because when you initialize an array with tNum={} it initializes by assigning every index to nil, and the first index is [1] (It doesn't actually initialize every value to nil, but it's easier to explain that way).
Conversely, when you initialize an array with tNum={[2]=true} you are explicitly telling the array that tNum[1] does not exist and the array begins at index 2. The length calculation breaks when you do this.
For a more thorough explanation, see this section of the lua wiki near the bottom where it explains:
For those that really want their arrays starting at 0, it is not difficult to write the following:
days = {[0]="Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"}
Now, the first value, "Sunday", is at index 0. That zero does not affect the other fields, but "Monday" naturally goes to index 1, because it is the first list value in the constructor; the other values follow it. Despite this facility, I do not recommend the use of arrays starting at 0 in Lua. Remember that most functions assume that arrays start at index 1, and therefore will not handle such arrays correctly.
The Length operator assumes your array will begin at index [1], and since it does not, it doesn't work correctly.
I hope this was helpful, good luck with your code!

Understanding GameMonkey Script Mixed Arrays

I was just reading some introductory stuff from GameMonkey Script on https://www.gamedev.net/articles/programming/engines-and-middleware/introduction-to-gamemonkey-script-r3297/ and when they were explaining about Mixed Arrays they say that you can access the elements using and index or a key depending on how the value was declared, so for example if i have the next array
myMixedArray = table( 1, 3, 4, KeyV = "Test", 33);
then i can access 1, 2, 4 and 33 using the next indices 0, 1, 2, 3 and
to access "Test" i'll do it like this
myMixedArray["KeyV"] <- ("Test")
now according with the following image that you can find in the above link
The number expected to be at myTest[3] is 7, but that would mean that both regular values and key-val elements are not really separated in the array.
If not then why would 7 be at the index 3 of the array?
While you can treat a gm Table as an Array or Map, you can't effectively do both at the same time.
Internally, the Table is just a hash table, and your index access method is a bit like an iterator.
In your example, because value "Test" is assigned to key 'KeyV', it messes up the otherwise contiguous index order.
Hopefully that gives you an idea of the cause. Try iterating a table with no 'keys' and again with all key value pairs. Observe the different behavior.
If you are serious about arrays, you may be better off using a binding to create an Array type with the behavior you want. GM source has an example of an array container.

Ruby on Rails method to calculate percentiles - can it be refactored?

I have written a method to calculate a given percentile for a set of numbers for use in an application I am building. Typically the user needs to know the 25th percentile of a given set of numbers and the 75th percentile.
My method is as follows:
def calculate_percentile(array,percentile)
#get number of items in array
return nil if array.empty?
#sort the array
array.sort!
#get the array length
arr_length = array.length
#multiply items in the array by the required percentile (e.g. 0.75 for 75th percentile)
#round the result up to the next whole number
#then subtract one to get the array item we need to return
arr_item = ((array.length * percentile).ceil)-1
#return the matching number from the array
return array[arr_item]
end
This looks to provide the results I was expecting but can anybody refactor this or offer an improved method to return specific percentiles for a set of numbers?
Some remarks:
If a particular index of an Array does not exist, [] will return nil, so your initial check for an empty Array is unnecessary.
You should not sort! the Array argument, because you are affecting the order of the items in the Array in the code that called your method. Use sort (without !) instead.
You don't actually use arr_length after assignment.
A return statement on the last line is unnecessary in Ruby.
There is no standard definition for the percentile function (there can be a lot of subtleties with rounding), so I'll just assume that how you implemented it is how you want it to behave. Therefore I can't really comment on the logic.
That said, the function that you wrote can be written much more tersely while still being readable.
def calculate_percentile(array, percentile)
array.sort[(percentile * array.length).ceil - 1]
end
Here's the same refactored into a one liner. You don't need an explicit return as the last line in Ruby. The return value of the last statement of the method is what's returned.
def calculate_percentile(array=[],percentile=0.0)
# multiply items in the array by the required percentile
# (e.g. 0.75 for 75th percentile)
# round the result up to the next whole number
# then subtract one to get the array item we need to return
array ? array.sort[((array.length * percentile).ceil)-1] : nil
end
Not sure if it's worth it, but here is how I did it for the quartiles:
def median(list)
(list[(list.size - 1) / 2] + list[list.size / 2]) / 2
end
numbers = [1, 2, 3, 4, 5, 6]
if numbers.size % 2 == 0
puts median(numbers[0...(numbers.size / 2)])
puts median(numbers)
puts median(numbers[(numbers.size / 2)..-1])
else
median_index = numbers.index(median(numbers))
puts median(numbers[0..(median_index - 1)])
puts median(numbers)
puts median(numbers[(median_index + 1)..-1])
end
If you're calculating both quartiles, you might want to move the "sort" outside the function, so that it only needs to be done once. This also means you aren't modifying your caller's data (sort!), nor making a copy every time the function is called (sort).
I know, premature optimisation and all that. And it's a bit awkward for the function to say, "the array must be sorted before calling this function". So it's reasonable to leave it as it is.
But sorting already-sorted data is going to take considerably longer than the whole rest of the function put together(*). It also has higher algorithmic complexity: O(N) at best, when the function could be O(1) for the second quartile (although O(N log N) for the first one if the data is not already sorted, of course). So it's worth avoiding if performance might ever be an issue for this function.
There are slightly faster ways of finding the two quartiles than a full sort (look up "selection algorithms"). For instance if you're familiar with the way qsort uses pivots, observe that if you need to know the 25th and 75th items out of 100, and your pivot at some stage ends up in position 80, then there's absolutely no point recursing into the block above the pivot. You really don't care what order those elements are in, just that they're in the top quartile. But this will considerably increase the complexity of the code compared with just calling a library to sort for you. Unless you really need a minor performance boost, I think you're good as you are.
(*) Unless ruby arrays have a flag to remember they're already sorted and haven't been modified since. I don't know whether they do, but if so then using sort! a second time is of course free.

Resources