How to find out if an arithmetic sequence exists in an array - arrays

If there is an array that contains random integers in ascending order, how can I tell if this array contains a arithmetic sequence (length>3) with the common differece x?
Example:
Input: Array=[1,2,4,5,8,10,17,19,20,23,30,36,40,50]
x=10
Output: True
Explanation of the Example: the array contains [10,20,30,40,50], which is a arithmetic sequence (length=5) with the common differece 10.
Thanks!
I apologize that I have not try any code to solve this since I have no clue yet.
After reading the answers, I tried it in python.
Here are my codes:
df = [1,10,11,20,21,30,40]
i=0
common_differene=10
df_len=len(df)
for position_1 in range(df_len):
for position_2 in range(df_len):
if df[position_1] + common_differene == df[position_2]:
position_1=position_2
i=i+1
print(i)
However, it returns 9 instead of 4.
Is there anyway to prevent the repetitive counting in one sequence [10,20,30,40] and also prevent accumulating i from other sequences [1,11,21]?

You can solve your problem by using 2 loops, one to run through every element and the other one to check if the element is currentElement+x, if you find one that does, you can continue form there.
With the added rule of the sequence being more than 2 elements long, I have recreated your problem in FREE BASIC:
DIM array(13) As Integer = {1, 2, 4, 5, 8, 10, 17, 19, 20, 23, 30, 36, 40, 50}
DIM x as Integer = 10
DIM arithmeticArrayMinLength as Integer = 3
DIM index as Integer = 0
FOR position As Integer = LBound(array) To UBound(array)
FOR position2 As Integer = LBound(array) To UBound(array)
IF (array(position) + x = array(position2)) THEN
position = position2
index = index + 1
END IF
NEXT
NEXT
IF (index <= arithmeticArrayMinLength) THEN
PRINT false
ELSE
PRINT true
END IF
Hope it helps
Edit:
After reviewing your edit, I have come up with a solution in Python that returns all arithmetic sequences, keeping the order of the list:
def arithmeticSequence(A,n):
SubSequence=[]
ArithmeticSequences=[]
#Create array of pairs from array A
for index,item in enumerate(A[:-1]):
for index2,item2 in enumerate(A[index+1:]):
SubSequence.append([item,item2])
#finding arithmetic sequences
for index,pair in enumerate(SubSequence):
if (pair[1] - pair[0] == n):
found = [pair[0],pair[1]]
for index2,pair2 in enumerate(SubSequence[index+1:]):
if (pair2[0]==found[-1] and pair2[1]-pair2[0]==n):
found.append(pair2[1])
if (len(found)>2): ArithmeticSequences.append(found)
return ArithmeticSequences
df = [1,10,11,20,21,30,40]
common_differene=10
arseq=arithmeticSequence(df,common_differene)
print(arseq)
Output: [[1, 11, 21], [10, 20, 30, 40], [20, 30, 40]]
This is how you can get all the arithmetic sequences out of df for you to do whatever you want with them.
Now, if you want to remove the sub-sequences of already existing arithmetic sequences, you can try running it through:
def distinct(A):
DistinctArithmeticSequences = A
for index,item in enumerate(A):
for index2,item2 in enumerate([x for x in A if x != item]):
if (set(item2) <= set(item)):
DistinctArithmeticSequences.remove(item2)
return DistinctArithmeticSequences
darseq=distinct(arseq)
print(darseq)
Output: [[1, 11, 21], [10, 20, 30, 40]]
Note: Not gonna lie, this was fun figuring out!

Try from 1: check the presence of 11, 21, 31... (you can stop immediately)
Try from 2: check the presence of 12, 22, 32... (you can stop immediately)
Try from 4: check the presence of 14, 24, 34... (you can stop immediately)
...
Try from 10: check the presence of 20, 30, 40... (bingo !)
You can use linear searches, but for a large array, a hash map will be better. If you can stop as soon as you have found a sequence of length > 3, this procedure takes linear time.

Scan the list increasingly and for every element v, check if the element v + 10 is present and draw a link between them. This search can be done in linear time as a modified merge operation.
E.g. from 1, search 11; you can stop at 17; from 2, search 12; you can stop at 17; ... ; from 8, search 18; you can stop at 19...
Now you have a graph, the connected components of which form arithmetic sequences. You can traverse the array in search of a long sequence (or a longest), also in linear time.
In the given example, the only links are 10->-20->-30->-40->-50.

Related

Discord py limit instead of requirement on range

I'm having List index out of range error and the issue is that I'm trying to show 25 results of players on a squad. Squads don't require 25, but only have a limit of 25. So when the squad doesn't contain 25 players, I get the out of range error. My question is, how do I display a list of squad members up to 25, but not requiring 25? Here is the line that is causing issues:
e = discord.Embed(title=f"{x2[0]['squadName']} ({squadnumber})", color=discord.Colour(value=235232), description='\n'.join([f"{c} <#{x[c-1]['player']}> - {int(x[c-1]['points']):,d} Score"]) for c in range(1+(25*(0)), 26+(25*(0)))]))
I used this method to get the range:
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [x[i] for i in range(0, 5 if len(x) >= 5 else len(x))]
# this will get the first 5 elements of the list, and if the list isn't long enough
# it will get the length of the list
Here's the concept in use:
And applying this method will get you this:
e = discord.Embed(title=f"{x2[0]['squadName']} ({squadnumber})",
color=0x396E0,
description='\n'.join([f"{c} <#{x[c-1]['player']}> - {int(x[c-1]['points']):,d} Score" for c in range(1, 26 if len(x.keys()) > 25 else len(x.keys()))]))
Also, I noticed another thing with the code, such as discord.Color(value=some_value), you could just do 0xHEXCODE for example, to get the hex code, so I edited it in to make it easier on the eyes.
Please let me know if you need clarification on anything.
References:
0x usage in python
Using if/else in list comprehension
Getting hex colour codes

Find an algorithm to sort an array given its status after sorting

Let A be an array with n elements. A is not sorted, nonetheless, after sorting the array, the difference between any two adjacent elements would be either k1, k2 or k3.
It should be noted that k1, k2 and k3 are not given, and all of them are natural!
For example, given the array:
A = { 25, 7, 5, 9, 32, 23, 14, 21}
After sorting the array, we would get -
A = { 5, 7, 9, 14, 21, 23, 25, 32}
The difference between the first pair (5, 7) is 2; so k1=2, the difference between the third pair (9,14) is 5, so k2=5, whereas the difference between the fourth pair (14, 21) is 7, so k3=7. The difference between other adjacent pairs is also 2, 5 and 7.
The algorithm for sorting the array should be as best as possible (obviously below O(nlogn)).
I managed to answer a similar question where the difference between any two adjacent elements was either k, 2k or 3k, where k is real. But I couldn't find an appropriate algorithm following a similar method, by finding k, dividing by it and doing bucket sort.
By finding the minimum and second minimum we can find one of the k's. But k could be n2 — so finding the maximum does not help either... I am really lost!
Disclaimer: This question has been asked before, but no answer was given to the problem, and the question was not easy to understand.
Here is a O(n) that only doesn't look efficient.
The idea is simple. Given the minimum element and a list of values for k, you construct the biggest sorted set with the values of k that you already have found, find the smallest missing thing not in the set, and find a new value of k. If there are K values of k, this operation is O((1+K) * n).
Repeating this K times is therefore O((1+K)^2 * n).
In our case K is constant, so we get O(n).
Here it is in Python.
def special_sort (array):
# special cases first.
if 0 == len(array):
return array
elif 1 == len(array):
return array
elif 2 == len(array):
return [min(array), max(array)]
min_value = min(array)
values_of_k = []
leftovers = array
while len(leftovers):
values_of_k = sorted(values_of_k)
values = set(array)
sorted_array = [min_value]
values.remove(min_value)
found = True
while found:
found = False
for k in values_of_k:
if sorted_array[-1] + k in values:
found = True
sorted_array.append(sorted_array[-1] + k)
values.remove(sorted_array[-1])
break
leftovers = list(values)
if 0 == len(leftovers):
return sorted_array
else:
first_missing = min(leftovers)
# Find the first element of the array less than that.
i = -1
while i+1 < len(sorted_array) and sorted_array[i+1] < first_missing:
i = i+1
values_of_k.append(first_missing - sorted_array[i])
print(special_sort([25, 7, 5, 9, 32, 23, 14, 21]))

Element by Element Comparison of Multiple Arrays in MATLAB

I have a multiple input arrays and I want to generate one output array where the value is 0 if all elements in a column are the same and the value is 1 if all elements in a column are different.
For example, if there are three arrays :
A = [28, 28, 43, 43]
B = [28, 43, 43, 28]
C = [28, 28, 43, 43]
Output = [0, 1, 0, 1]
The arrays can be of any size and any number, but the arrays are also the same size.
A none loopy way is to use diff and any to advantage:
A = [28, 28, 43,43];
B = [28, 43, 43,28];
C = [28, 28, 43,43];
D = any(diff([A;B;C])) %Combine all three (or all N) vectors into a matrix. Using the Diff to find the difference between each element from row to row. If any of them is non-zero, then return 1, else return 0.
D = 0 1 0 1
There are several easy ways to do it.
Let's start by putting the relevant vectors in a matrix:
M = [A; B; C];
Now we can do things like:
idx = min(M)==max(M);
or
idx = ~var(M);
No one seems to have addressed that you have a variable amount of arrays. In your case, you have three in your example but you said you could have a variable amount. I'd also like to take a stab at this using broadcasting.
You can create a function that will take a variable number of arrays, and the output will give you an array of an equal number of columns shared among all arrays that conform to the output you're speaking of.
First create a larger matrix that concatenates all of the arrays together, then use bsxfun to take advantage of broadcasting the first row and ensuring that you find columns that are all equal. You can use all to complete this step:
function out = array_compare(varargin)
matrix = vertcat(varargin{:});
out = ~all(bsxfun(#eq, matrix(1,:), matrix), 1);
end
This will take the first row of the stacked matrix and see if this row is the same among all of the rows in the stacked matrix for every column and returns a corresponding vector where 0 denotes each column being all equal and 1 otherwise.
Save this function in MATLAB and call it array_compare.m, then you can call it in MATLAB like so:
A = [28, 28, 43, 43];
B = [28, 43, 43, 28];
C = [28, 28, 43, 43];
Output = array_compare(A, B, C);
We get in MATLAB:
>> Output
Output =
0 1 0 1
Not fancy but will do the trick
Output=nan(length(A),1); %preallocation and check if an index isn't reached
for i=1:length(A)
Output(i)= ~isequal(A(i),B(i),C(i));
end
If someone has an answer without the loop take that, but i feel like performance is not an issue here.

Append new variables to IDL for loop array

If I have the following array:
x = double([1, 1, 1, 10, 1, 1, 50, 1, 1, 1 ])
I want to do the following:
Group the array into groups of 5 which will each be evaluated separately.
Identify the MAX value each of the groups of the array
Remove that MAX value and put it into another array.
Finally, I want to print the updated array x without the MAX values, and the new array containing the MAX values.
How can I do this? I am new to IDL and have had no formal training in coding.
I understand that I can write the code to group and find the max values this way:
FOR i = 1, (n_elements(x)-4) do begin
print, "MAX of array", MAX( MAX(x[i-1:1+3])
ENDFOR
However, how do I implement all of what I specified above? I know I have to create an empty array that will append the values found by the for loop, but I don't know how to do that.
Thanks
I changed your x to have unique elements to make sure I wasn't fooling myself. It this, the number of elements of x must be divisible by group_size:
x = double([1, 2, 3, 10, 4, 5, 50, 6, 7, 8])
group_size = 5
maxes = max(reform(x, group_size, n_elements(x) / group_size), ind, dimension=1)
all = bytarr(n_elements(x))
all[ind] = 1
x_without_maxes = x[where(all eq 0)]
print, maxes
print, x_without_maxes
Lists are good for this, because they allow you to pop out values at specific indices, rather than rewriting the whole array again. You might try something like the following. I've used a while loop here, rather than a for loop, because it makes it a little easier in this case.
x = List(1, 1, 1, 10, 1, 1, 50, 1, 1, 1)
maxValues = List()
pos = 4
while (pos le x.length) do begin
maxValues.add, max(x[pos-4:pos].toArray(), iMax)
x.Remove, iMax+pos-4
pos += 5-1
endwhile
print, "Max Values : ", maxValues.toArray()
print, "Remaining Values : ", x.toArray()
This allows you to do what you want I think. At the end, you have a List object (which can easily be converted to an array) with the max values for each group of 5, and another containing the remaining values.
Also, please tag this as idl-programming-language rather than idl. They are two different tags.

How to find max in Ruby without using "max" function

I need to find the max value of an array without using the max method. Right now I have:
def max(arr)
largest_num = arr(1)
arr.each do |num|
if element >= largest_num
largest_num = num
else
largest_num = largest_num
end
puts largest_num
end
my_numbers = [20, 30, 40, 50]
puts max(my_numbers)
end
Why don't you just use sort and last?
array = [3,7,2,4,6,1,8,5]
array.sort.last
#=> 8
i was told i should use .sort and .last but not quite sure where to even start
It's really important to be a self-starter when programming. It's an essential characteristic, because the field and all technologies are moving quickly. I'd suggest reading "How much research effort is expected of Stack Overflow users?" also, especially if you want to use Stack Overflow as a resource.
Here's how to learn to experiment with Ruby and to teach yourself:
Ruby has IRB bundled with it. Type irb at the command-line and it should open and present you with a prompt. At that prompt you can enter Ruby expressions and see the result. My prompt is probably not the same as yours because mine is customized, but you can figure out how to work with that:
$ irb
irb(main):001:0>
To assign an array to a variable:
irb(main):001:0> my_numbers = [20, 30, 40, 50]
=> [20, 30, 40, 50]
I can look at the value assigned to my_numbers by entering the name of the variable and pressing Return or Enter:
irb(main):002:0> my_numbers
=> [20, 30, 40, 50]
I can experiment using methods on my_numbers:
irb(main):003:0> my_numbers.shuffle
=> [50, 30, 40, 20]
That took the array and randomized it. It didn't change my_numbers, it only shuffled the array and output a new array in the shuffled order:
irb(main):004:0> my_numbers
=> [20, 30, 40, 50]
Each time shuffle is run it randomizes the array and returns another array:
irb(main):005:0> my_numbers.shuffle
=> [50, 20, 30, 40]
irb(main):006:0> my_numbers.shuffle
=> [40, 20, 30, 50]
Since you want to use sort and last to find the maximum value, it'd be good to start with an out-of-order array. Testing sort:
irb(main):009:0> my_numbers.shuffle.sort
=> [20, 30, 40, 50]
The array is sorted after shuffling.
Here's what last does:
irb(main):010:0> my_numbers.last
=> 50
Now you know enough to figure it out for yourself.
If you are required to use sort and last, then the answer below will not work for you.
arr.sort.last is inefficient, since it requires sorting the whole array when all you need is the biggest. Try something like:
arr.reduce{|largest, num| if num > largest then num else largest end}
The reduce function (also aliased as inject) is used to "reduce" an array down to a single object. To implement a sum, you could do something like:
num_arr = [1,2,3,4,5]
num_arr.reduce(0){|sum, num| sum + num} #=> 15
0 is the starting value of the sum, and then for each element the block is run with the sum so far and the element in the array. Then the result of the block (sum + num is returned since in ruby the last statement is implicitly returned) is set as the new value of sum for the next element. The final value of sum is what is returned.
This is similar to doing:
sum = 0
sum = sum + num_arr[0]
sum = sum + num_arr[1]
sum = sum + num_arr[2]
sum = sum + num_arr[3]
sum = sum + num_arr[4]
If you don't specify a starting value, then the first element is taken as the starting value. So, in my reduce solution, the first element is set as the "largest", and then for each element in turn the largest is either passed on or if the element is bigger than the current largest, it becomes the new largest.
If you were really told that you should use sort and last then the answer is quite simple:
2.1.1 :003 > [2,3,1,4,8,6].sort.last
=> 8
If you want it in method:
def max(arr); arr.sort.last; end
2.1.1 :004 > def max(arr); arr.sort.last; end
=> :max
2.1.1 :005 > max([2,1,3])
=> 3
First sort the array without using the sort method if you are trying to solve this without the default function
asc = [45,34,12,4,5,32,54,76]
asc.each do |a|
i = 0
asc.each do |b|
if b > asc[i +1]
asc[i], asc[i + 1] = asc[i + 1], asc[i]
end
i += 1 if i < asc.size - 2
end
end
p asc.last
This will give the largest number from the sorted array

Resources