Ruby Input Array, Output Array without duplicates - arrays

# creating empty array (array1)
array1 = []
i = 0
# taking 10 numbers from user and storing them in the array
while array1.size < 10
print "Enter a number: "
array[i] = gets.chomp.to_i
i += 1
end
# pushing only the unique elements into a new array (array2)
k = 0
j = 0
array2 = []
while k < array1.size
if array1[k] != array1[j]
if array2.include? (array1[k])
puts "Element already exists"
else
array2.push(array1[k])
end
j += 1
end
k += 1
end
puts array2
It only works in some situations, but at all times, the first element that is unique is not being added to the new array for some reason, should I be starting j or k at 1, rather than 0?
I know that i can use .uniq and turn the array into a set and then back to an array, or just intersect the array with &, but i wanted to make it without ruby "shortcuts", any advice?

Sure.
k and j are both equal to 0 at startup.
So array1[k] == array1[j] is true, and you get k+=1.
k is now 1, and you missed the first element of array1.
Nothing specially Rubyish about this solution :
array2 = []
array1 = [1, 2, 3, 3, 2, 4, 5, 6]
i=0
while i<array1.size do
element = array1[i]
if !array2.include?(element) then
array2.push(element)
end
i += 1
end
puts array2.inspect

Related

In Ruby, why does plugging in a variable assigned to an array index return undefined?

I am learning Ruby and just solved this pyramid problem. For whatever reason, I tried to change twoD[0] to the variable twoDidx (see third line).
However, when I try replacing while twoD[0].length != 1 with while twoDidx.length != 1, I get "undefined." What am I not understanding about how variables work? Thanks.
def pyramid_sum(base)
twoD = [base]
twoDidx = twoD[0]
while twoD[0].length != 1
arr = twoD[0].map.with_index do |num, idx|
if idx != twoD[0].length - 1
num + twoD[0][idx + 1]
end
end
arr = arr.compact
twoD.unshift(arr)
end
return twoD
end
print pyramid_sum([1, 4, 6]) #=> [[15], [5, 10], [1, 4, 6]]
There's a big difference between twoDidx and twoD[0]. twoDidx is a reference to a first element of twoD at the time you made an assignment while twoD[0] is the reference to the first element of twoD array at the time of execution.
To make it more obvious:
array = [1]
first = array[0] # Here you just assign 1 to the variable
array = [100]
first #=> 1
array[0] #=> 100

Why doesn't my python code remove all elements that equal the target?

I am trying to remove all elements in an array that equal a target, a fairly simple procedure. For some reason though, it only removes the first element of the target in the array and I am not sure why. This is my code (python)
arr = [1,2,2,3,4,5,5]
for num in arr:
if num == 2:
arr.remove(num)
print(arr)
and it prints the array as [1,2,3,4,5,5]. If any of you know what went wrong that would be great. Thanks
Your code does not delete all elements because the index of the list reduces by 1 when the 1st element is deleted. And your pointer has already moved ahead.
Instead you can do this:
In [249]: arr = [1,2,2,3,4,5,5]
In [251]: list(filter(lambda a: a != 2, arr))
Out[251]: [1, 3, 4, 5, 5]
With my comment noted above:
arr = [1,2,2,3,4,5,5]
narr = [x for x in arr if x != 2]
print(narr)
In your code after removing the first occurrence of 2 indexes of elements changed it will now move to point 3 not 2 that's why 2nd occurrence of 2 is not removed.
arr = [1,2,2,3,4,5,5]
i = 0
while arr and i < len(arr):
if arr[i] == 2:
arr.remove(arr[i])
i -= 1
i += 1
print(arr)

Find all ascending triplets in array

I'm trying to exctract all the ascending triplets in an array of arbitrary dimension. For example if i have an array like [1 2 3 4] i'd like to obtain [1 2 3] , [1 2 4] , [2 3 4]
Here's a simple "graphical" example with 5 elements:
The arrows are the indexes used to iterate, each step is a found triplet.
So far i've just implemented a simple sorting algorithm, which will give me the ordered array.
Once i have the ordered array, I iterate with 3 possible pointers (or just indexes) increasing the pointer starting at the third element until it reaches the end of the array.
Once it reaches the end, i'll increase the second pointer and reset the third to the position right next to the pointer 2 and so on.
array = [ 3 2 1 5 ];
array = sort(array);
//Now i should iterate over the 3 indexes, but i'm totally lost about how to place them
for i=1:length(array-2)
for j=2:length(array-1)
for k=3:length(array)
//storing triplet
end
end
end
Right now i'm able to iterate over the array, and i can extract all the triplets until the k index reaches the end of the array.
The problem is once i reach for the end, i have to increment the j index starting point and reset the k index to be right next to the second index.
To make it clear: right now once k reaches the end, it will start again from 3 and j will also be 3, but i need them to be j = 3 and k = 4 after the first iteration of k is completed and so on (this is valid also for j compared to i , look at the image for a clearer explanation).
How do i fix the indexes in order to extract the triplets correctly?
Seems to me like your inner iterations start one after your outer one:
for j=(i+1):length(array-1)
for k=(j+1):length(array-1)
Generalizing the first loop to the rest.
const arrayTotal = [3, 2, 1, 5];
let combinationArray = [];
arrayTotal.sort();
for (let i = 0; i < (arrayTotal.length - 2); i++) {
for (let j = (i + 1); j < (arrayTotal.length - 1); j++) {
for (let k = (j + 1); k < arrayTotal.length; k++) {
combinationArray.push([arrayTotal[i], arrayTotal[j], arrayTotal[k]])
}
}
}
console.log(combinationArray);

How to find the index of the last array element

In a situation where you have to deal with array indices (and can't just use an enumerator), how do you find the index of the last element?
These two options come to mind, but I'm hoping there's an answer that is more self documenting (like Array#last(), but for the index instead of the element):
a = [0, 1, 2, 3]
# option 1
last_index = a.length - 1
# option 2
last_index = a.rindex { true }
arr = [1,2,3,4,5,6]
def last_index(arr)
counter = -1
arr.each do |i|
i
counter += 1
end
counter
end
last_index(arr)

what is the way to find if array contain Arithmetic progression (sequence)

i have sorted array of numbers like
1, 4, 5 , 6, 8
what is the way to find out if this array contain Arithmetic progression (sequence) ?
like in this example
4,6,8
or
4,5,6
remark : the minimum numbers in sequence is 3
You can solve this recursively, by breaking it into smaller problems, which are:
Identify the pairs {1,4},{1,5}...{6,8}
For each pair, look for sequences with the same interval
First create the scaffolding to run the problems:
Dim number(7) As Integer
Dim result() As Integer
Dim numbers As Integer
Sub FindThem()
number(1) = 1
number(2) = 4
number(3) = 5
number(4) = 6
number(5) = 8
number(6) = 10
number(7) = 15
numbers = UBound(number)
ReDim result(numbers)
Dim i As Integer
For i = 1 To numbers - 2
FindPairs i
Next
End Sub
Now iterate over the pairs
Sub FindPairs(start As Integer)
Dim delta As Integer
Dim j As Integer
result(1) = number(start)
For j = start + 1 To numbers
result(2) = number(j)
delta = result(2) - result(1)
FindMore j, 2, delta
Next
End Sub
Finding sequences as you go
Sub FindMore(start As Integer, count As Integer, delta As Integer)
Dim k As Integer
For k = start + 1 To numbers
step = number(k) - result(count)
result(count + 1) = number(k) ' should be after the if statement
' but here makes debugging easier
If step = delta Then
PrintSeq "Found ", count + 1
FindMore k, count + 1, delta
ElseIf step > delta Then ' Pointless to search further
Exit Sub
End If
Next
End Sub
This is just to show the results
Sub PrintSeq(text As String, count As Integer)
ans = ""
For t = 1 To count
ans = ans & "," & result(t)
Next
ans = text & " " & Mid(ans, 2)
Debug.Print ans
End Sub
Results
findthem
Found 1,8,15
Found 4,5,6
Found 4,6,8
Found 4,6,8,10
Found 5,10,15
Found 6,8,10
Edit: Oh, and of course, the array MUST be sorted!
HTH
First, I will assume that you only want arithmetic sequences of three terms or more.
I would suggest checking each number a[i] as the start of an arithmetic sequence, and a[i+n] as the next one.
Now that you have the first two terms in your series, you can find the next. In general, if x is your first term and y is your second, your terms will be x + i*(y-x), with the first term at i = 0. The next term will be x + 2*(y-x). Search your array for that value. If that value is in your array, you have an arithmetic sequence of three items or more!
You can continue with i=3, i=4, etc. until you reach one that is not found in your array.
If l is the size of your array, do this for all i from 0 to l-2, and all n from 0 to l-i-1
The only major caveat is that, in the example, this will find both sequences 4,6,8 as well as 6,8. Technically, both of them are arithmetic sequences in your series. You will have to more specifically define what you want there. In your case, it might be trivial to just check and eliminate all progressions that are totally contained inside others.
The general idea is to pick an element as your a_1, then any element after that one as your a_2, compute the difference and then see if any other elements afterwards that match that difference. As long as there are at least 3 elements with the same difference, we consider it a progression.
progression (A, n)
for i = 1 ... n - 2
a_1 = A[i]
for j = i + 1 ... n - 1
a_2 = A[j]
d = a_2 - a_1
S = [ i, j ]
for k = j + 1 ... n
if ( d == ( a[k] - a[S.last] ) )
/* Append the element index to the sequence so far. */
S += k
if ( |s| > 2 )
/* We define a progression to have at least 3 numbers. */
return true
return false
You can modify the algorithm to store each set S before it is lost, to compute all the progressions for the given array A. The algorithm runs in O(n^3) assuming appending to and getting the last element of the set S are in constant time.
Although I feel like there might be a more efficient solution...
Certainly not the optimal way to solve your problem, but you can do the following:
Iterate through all pairs of numbers in your array - each 2 numbers fully define arithmetic sequence if we assume that they're 1st and 2nd progression members. So knowing those 2 numbers you can construct further progression elements and check if they're in your array.
If you want just find 3 numbers forming arithmetic progression then you can iterate through all pairs of non-adjacent numbers a[i] and a[j], j > i+1 and check if their arithmetic mean belongs to array - you can do that using binary search on interval ]i,j[.
Here's the code in Swift 4:
extension Array where Element == Int {
var isArithmeticSequence: Bool {
let difference = self[1] - self[0]
for (index, _) in self.enumerated() {
if index < self.count-1 {
if self[index + 1] - self[index] != difference {
return false
}
}
}
return true
}
var arithmeticSlices: [[Int]] {
var arithmeticSlices = [[Int]]()
var sliceSize = 3
while sliceSize < self.count+1 {
for (index, _) in self.enumerated() {
if (index + sliceSize-1) <= self.count - 1 {
let currentSlice = Array(self[index...index + sliceSize-1])
if currentSlice.isArithmeticSequence {
arithmeticSlices.append(currentSlice)
}
}
}
sliceSize+=1
}
return arithmeticSlices
}
}
let A = [23, 24, 98, 1, 2, 5]
print(A.arithmeticSlices) // []
let B = [4, 7, 10, 4,5]
print(B.arithmeticSlices) //[[1, 2, 3], [2, 3, 4], [3, 4, 5], [1, 2, 3, 4], [2, 3, 4, 5], [1, 2, 3, 4, 5]]
let C = [4, 7, 10, 23, 11, 12, 13]
print(C.arithmeticSlices) // [[4, 7, 10], [11, 12, 13]]

Resources