Is there a way I can count the number of integers in an array? I have an array whose members come from a-z and 0-9. I want to count the number of integers in said array. I tried:
myarray.count(/\d/)
...but the count method doesn't regex.
a = 'abcdefghijklmnopqrstuvwxyz'.split('')
a << [0,1,2,3,4,5,6,7,8,9]
t = a.sample(10)
p t.count(/\d/) # show me how many integers in here
The following should return the number of integers present within the array:
['a', 'b', 'c', 1, 2, 3].count { |e| e.is_a? Integer }
# => 3
Since #count can accept a block, we have it check if an element is an Integer, if so it will be counted towards our returned total.
Hope this helps!
Related
Working on a project to recreate a game Mastermind. I need to compare two arrays, and running into some struggles.
I need to output two integers for the flow of the game to work,
the first integer is the number of correct choices where the index matches. The code I have for this appears to be working
pairs = #code.zip(guess)
correct_position_count = pairs.select { |pair| pair[0] == pair[1] }.count
Where pairs is equal to a 4 element array and the guess is also a 4 element array
The second part I am having a bit of trouble with on how to do the comparison and return an array. The integer should represent where the two arrays index don't match (the above code block but !=) and confirm whether the guess array excluding any exact index matches has any elements included with the code array once again excluding the exact index matches.
Any help would be greatly appreciated!
I am not completely sure to understand your problem but if I understood well, you've two arrays, solution with the solution and guess with the current guess of the player.
Now, let's assume that the solution is 1234 and that the guess is 3335.
solution = [1, 2, 3, 4]
guess = [3, 3, 3, 5]
an element by element comparison produces an array of booleans.
diff = guess.map.with_index { |x,i| x == solution[i] }
# = [false, false, true, false]
Now, you can easily compute the number of good digits diff.count true and the number of wrong digits diff.count false. And, in case you need the index of the false and/or true values you can do
diff.each_index.select { |i| diff[i] } # indexes with true
# = [2]
diff.each_index.select { |i| !diff[i] } # indexes with false
# = [0, 1, 3]
You can count all digit matches ignoring their positions and then subtract exact matches.
pairs = #code.zip(guess)
correct_position_count = pairs.select { |pair| pair[0] == pair[1]}.count
any_position_count = 0
code_digits = #code.clone # protect #code from modifying
guess.each do |digit|
if code_digits.include?(digit)
code_digits.delete_at(code_digits.find_index(digit)) # delete the found digit not to count it more than once
any_position_count += 1
end
end
inexact_position_count = any_position_count - correct_position_count
puts "The first value: #{correct_position_count}"
puts "The second value: #{inexact_position_count}"
I'm trying to get the average of the values between two indexes in an array. The solution I first came to reduces the array to the required range, before taking the sum of values divided by the number of values. A simplified version looks like this:
let array = [0, 2, 4, 6, 8, 10, 12]
// The aim is to take the average of the values between array[n] and array[.count - 1].
I attempted with the following code:
func avgOf(x: Int) throws -> String {
let avgforx = solveList.count - x
// Error handling to check if x in average of x does not overstep bounds
guard avgforx > 0 else {
throw FuncError.avgNotPossible
}
solveList.removeSubrange(ClosedRange(uncheckedBounds: (lower: 0, upper: avgforx - 1)))
let avgx = (solveList.reduce(0, +)) / Double(x)
// Rounding
let roundedAvgOfX = (avgx * 1000).rounded() / 1000
print(roundedAvgOfX)
return "\(roundedAvgOfX)"
}
where avgforx is used to represent the lower bound :
array[(.count - 1) - x])
The guard statement makes sure that if the index is out of range, the error is handled properly.
solveList.removeSubrange was my initial solution, as it removes the values outside of the needed index range (and subsequently delivers the needed result), but this has proved to be problematic as the values not taken in the average should remain.
The line in removeSubrange basically takes a needed index field (e.g. array[5] to array[10]), removes all the values from array[0] to array[4], and then takes the sum of the resulting array divided by the number of elements.
Instead, the values in array[0] to array[4] should remain.
I would appreciate any help.
(Swift 4, Xcode 10)
Apart from the fact that the original array is modified, the error in your code is that it divides the sum of the remaining elements by the count of the removed elements (x) instead of dividing by the count of remaining elements.
A better approach might be to define a function which computes the average of a collection of integers:
func average<C: Collection>(of c: C) -> Double where C.Element == Int {
precondition(!c.isEmpty, "Cannot compute average of empty collection")
return Double(c.reduce(0, +))/Double(c.count)
}
Now you can use that with slices, without modifying the original array:
let array = [0, 2, 4, 6, 8, 10, 12]
let avg1 = average(of: array[3...]) // Average from index 3 to the end
let avg2 = average(of: array[2...4]) // Average from index 2 to 4
let avg3 = average(of: array[..<5]) // Average of first 5 elements
I have a 1x10 structure array with plenty of fields and I would like to remove from the struct array the element with a specific value on one of the field variables.
I know the value im looking for and the field I should be looking for and I also know how to delete the element from the struct array once I find it. Question is how(if possible) to elegantly identify it without going through a brute force solution ie a for-loop that goes through elements of the struct array to compare with the value I m looking for.
Sample code: buyers as 1x10 struct array with fields:
id,n,Budget
and the variable to find in the id values like id_test = 12
You can use the fact that if you have an array of structs, and you use the dot referencing, this creates a comma-separated list. If you enclose this in [] it will attempt to create an array and if you enclose it in {} it will be coerced into a cell array.
a(1).value = 1;
a(2).value = 2;
a(3).value = 3;
% Into an array
[a.value]
% 1 2 3
% Into a cell array
{a.value}
% [1] [2] [3]
So to do your comparison, you can convert the field you care about into either an array of cell array to do the comparison. This comparison will then yield a logical array which you can use to index into the original structure.
For example
% Some example data
s = struct('id', {1, 2, 3}, 'n', {'a', 'b', 'c'}, 'Budget', {100, 200, 300});
% Remove all entries with id == 2
s = s([s.id] ~= 2);
% Remove entries that have an id of 2 or 3
s = s(~ismember([s.id], [2 3]));
% Find ones with an `n` of 'a' (uses a cell array since it's strings)
s = s(ismember({s.id}, 'a'));
I am trying to multiply every element in an array by the next 12 elements:
array.each do |n|
a = array.index(n)
b = a + 12
product = 1
array[a..b].each { |i| product *= i }
highest = product if product > highest
end
I run into a problem when there are multiple occurrences of the same integer in the array:
[1, 2, 3, 7, 5, 4, 7] # this is not the actual array
When the second 7 runs through my block, its array.index(n) becomes 3 (the index of the first 7) when I want it to be 6 (the index of the particular 7 I am working with). I'm pretty sure this can be solved by giving each element of the array a unique 'id', but I'm not sure how I would go about doing this.
My question is, how do I give every element in an array a unique id? The Array#uniq method is not what I am looking for.
you could simplify your code a little
highest = array.map.with_index do |item, i|
array[i, 13].inject(:*)
end.max
# printing it console
puts highest
or use array.max_by with explicit i counter
The index is the uniq id. Use Enumerable#each_with_index instead:
array.each_with_index do |n, a|
#...
end
Ruby has an each_cons method defined on Enumerable.each_consis short for each_consecutive.
array.each_cons(13).max_by{|slice| slice.inject(:*)}
For more efficiency consider determining the product of the first thirteen numbers; then going through the array multiplying the product by the next number and dividing it by the previous first, while keeping track of the maximum product.
I have a cell array that contains a long list of strings. Most of the strings are in duplicates. I need the indices of instances of a string within the cell array.
I tried the following:
[bool,ind] = ismember(string,var);
Which consistently returns scalar ind while there are clearly more than one index for which the contents in the cell array matches string.
How can I have a list of indices that points to the locations in the cell array that contains string?
As an alternative to Divakar's comment, you could use strcmp. This works even if some cell doesn't contain a string:
>> strcmp('aaa', {'aaa', 'bb', 'aaa', 'c', 25, [1 2 3]})
ans =
1 0 1 0 0 0
Alternatively, you can ID each string and thus have representative numeric arrays corresponding to the input cell array and string. For IDing, you can use unique and then use find as you would with numeric arrays. Here's how you can achieve that -
var_ext = [var string]
[~,~,idx] = unique(var_ext)
out = find(idx(1:end-1)==idx(end))
Breakdown of the code:
var_ext = [var string]: Concatenate everything (string and var) into a single cell array, with the string ending up at the end (last element) of it.
[~,~,idx] = unique(var_ext): ID everything in that concatenated cell array.
find(idx(1:end-1)==idx(end)): idx(1:end-1) represents the numeric IDs for the cell array elements and idx(end) would be the ID for the string. Compare these IDs and use find to pick up the matching indices to give us the final output.
Sample run -
Inputs:
var = {'er','meh','nop','meh','ya','meh'}
string = 'meh'
Output:
out =
2
4
6
regexp would solve this problem better and the easy way.
string = ['my' 'bat' 'my' 'ball' 'my' 'score']
expression = ['my']
regexp(string,expresssion)
ans = 1 6 12