I would like the increase the minimum 'distance' between values in an array. For example, if I have the array
44,45,47,51,65,66
I would like the minimum 'distance' to be 2. So, the desired output would be
44,46,48,51,65,67
I've tried doing something like
prevValue = array[0]
array.pop(0)
for a in array:
if(prevValue + 1 >= a):
a += 1
this wasn't the entire code as I had create temp arrays to not mess up the original one. But, this logic does not work.
Has anybody done anything similar? I was looking at np.arrange() but that wasn't the desired use case.
Thank you!
The line a += 1 only modifies your local variable named a; it would not modify any elements in a list. Here is one way to do what you want:
list1 = [44, 45, 47, 51, 65, 66]
list2 = []
prev = None
for a in list1:
if prev and prev + 1 >= a:
a = prev + 2
list2.append(a)
prev = a
print(list2)
They are actually called "lists", not "arrays", in Python. Using the correct search terms might help you find answers better on your own.
Try (assuming the lst is sorted):
lst = [44, 45, 47, 51, 65, 66]
distance = 2
for i in range(1, len(lst)):
diff = lst[i] - lst[i - 1]
if diff < distance:
lst[i] += distance - diff
print(lst)
Prints:
[44, 46, 48, 51, 65, 67]
For distance = 5:
[44, 49, 54, 59, 65, 70]
Related
I feel like I'm close but not quite sure why my while loop stops executing, I want it to run/ increase the counter then the conditions are true, then when it runs into numbers out of order, swap them, then decrease the counter, then run the while loop again until all the numbers are in order. So like it slides the number that's out of order backwards until it's higher than the number before it but lower than then number after it. If that makes sense.Probably an easy one for most of you but I'm just new to python. Here is my code so far;
arr = [7, 14, 21, 32, 17, 48, 69, 78, 72]
count = 0
while (count < len(arr) - 1) and (arr[count] < arr[count+1]):
count += 1
if (arr[count] > arr[count+1]):
arr[count], arr[count+1] = arr[count+1], arr[count]
count -= 1
continue
print(count)
print(arr)
below my code with some pseudocode to make it clearer.
# list of numbers out of order
arr = [7, 14, 21, 32, 17, 48, 69, 78, 72]
# first position in index
count = 0
# loop to check first if value of index position is less than length of array -1 (9-1 = 8)
# or if value of index position is less than index position + 1 (next index position)
while (count < len(arr) - 1) and (arr[count] < arr[count+1]):
# if true loop should continue + 1 on the next index
count += 1
# if the value of number in the current index position is greater than the next number it swaps them.
if (arr[count] > arr[count+1]):
arr[count], arr[count+1] = arr[count+1], arr[count]
count -= 1
continue
print(count)
print(arr)
I've tried various different things, I think I'm just stuck on how while loops actually work and I need to get the loop to run again after it hits it's first false statement.
This would work in the way that is required in the question:
finds the first two numbers that are out of order.
switched those numbers only and exit.
arr = [7, 14, 21, 32, 17, 48, 69, 78, 72]
for i, v in enumerate(arr):
if i == len(arr) -1:
print('reached the end')
break
if v > arr[i+1]:
print('out of order index', i, 'value:',v)
# do the switch
arr[i], arr[i+1] = arr[i+1], v
break
print(arr)
the result is this:
out of order index 3 value: 32
[7, 14, 21, 17, 32, 48, 69, 78, 72]
You could also achieve the same with a while loop so long as a break condition existed.
So, I have this array:
numbers = [5, 9, 3, 19, 70, 8, 100, 2, 35, 27]
What I want to do is to create another array from this one, but now each value of this new array must be equal to the corresponding value
in the numbers array multiplied by the following.
For example: the first value of the new array should be 45, as it is the multiplication
of 5 (first value) and 9 (next value). The second value of the new array should be 27, as it is the multiplication of 9 (second
value) and 3 (next value), and so on. If there is no next value, the multiplication must be done by 2.
So, this array numbers should result in this other array: [45, 27, 57 ,1330, 560, 800, 200, 70, 945, 54]
I only managed to get to this code, but I'm having problems with index:
numbers = [5,9,3,19,70,8,100,2,35,27]
new_array = []
x = 0
while x <= 8: # Only got it to work until 8 and not the entire index of the array
new_array.append(numbers[x] * numbers[x + 1])
x += 1
print(new_array)
How can I make it work no matter what is index of the array and then if there's no next number, multiply it by 2? I've tried everything but this was the closest I could get.
Try:
numbers = [5, 9, 3, 19, 70, 8, 100, 2, 35, 27]
out = [a * b for a, b in zip(numbers, numbers[1:] + [2])]
print(out)
Prints:
[45, 27, 57, 1330, 560, 800, 200, 70, 945, 54]
Andrej Kesely's approach is totally fine and would be the way to go for an experienced python developer.
But I assume you are kind of new to python, so here is a more simple approach if you are a bit familiar with other programming languages:
#function called multiply, taking an int[], returns int[]
def multiply(values):
newData = []
valuesLength = len(values) - 1
for i in range(valuesLength):
newData.append(values[i] * values[i+1])
newData.append(values[valuesLength] * 2)
return newData
#init int[], calling multiply-function and printing the data
numbers = [5,9,3,19,70,8,100,2,35,27]
newData = multiply(numbers)
print(newData)
The multiply-Function basically initiates an empty array, then loops over the passed values, multiplying them with the following value, leaves the loop one value too early and finally adds the last value by multiplying it with 2.
With the same approach as you did, making use of len(numbers):
numbers = [5,9,3,19,70,8,100,2,35,27]
new_array = []
x = 0
while x < len(numbers):
nxt = 2 if x+1 >= len(numbers) else numbers[x+1]
new_array.append(numbers[x] * nxt)
x += 1
print(new_array)
NOTE: The shorthand for nxt = 2.... is explained in the first comment of this answer: https://stackoverflow.com/a/14461963/724039
When the search number is 12, why does it return -6 instead of -1?
int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};
System.out.println("1. Index is " + Arrays.binarySearch(list, 11));
System.out.println("2. Index is " + Arrays.binarySearch(list, 12));
Result:
1. Index is 4
2. Index is -6
Update
Now I understand because
Arrays.binarySearch will return
(-(insertion point) - 1)
if the number is not in the array.
i.e
12 is at insertion of 5, so return (-(5) - 1) = -6.
Thanks for the help.
You may refer to the Javadoc : Arrays.binarySearch(int[] a,int key)
It returns :
index of the search key, if it is contained in the array;
otherwise : (-(insertion point) - 1).
Here the insertion point would be :
int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};
// 1^ 2^ 3^ 4^ 5^
The position 5 so (-5-1) = -6
Extracted from BinarySearch
Return value:
This method returns index of the search key, if it is contained in the array, else it returns (-(insertion point) - 1). The insertion point is the point at which the key would be inserted into the array: the index of the first element greater than the key, or a.length if all elements in the array are less than the specified key.
From the return value explanation, it returns the negation of the position the element will be in the array (that is -5) minus 1, which would be -6.
This is a common return type for BinarySearch() methods.
If you would like to print the index of an integer a :
int[] list = {2, 4, 7, 10, 11, 45, 50, 59, 60, 66, 69, 70, 79};
int a =12; //Value can be updated or read through Scanner
int temp = Arrays.binarySearch(list,a);
if(temp>=0){
System.out.println("Index of a is : " + temp)
}else{
System.out.println("Insertion point for a is : " + (-1)*(temp+1);
}
I want change order in arr if the next element is bigger than current.
Hot to modify the code, so it will be work?
arr = [5, 22, 29, 39, 19, 51, 78, 96, 84]
i = 0
while (i < arr.size-1)
if arr[i].to_i < arr[i+1].to_i
arr[i]
elsif arr[i].to_i > arr[i + 1].to_i
arr[i+1], arr[i] = arr[i], arr[i+1]
end
puts arr[i]
i += 1
end
Returns: [5, 22, 29, 39, 19, 51, 78, 96, 84]
Instead: [5, 19, 22, 29, 39, 51, 78, 84, 96]
You can use any of sorting algorithms depending on the size of array (n),
For Bubble Sort, Time Complexity is O(n^2)
For Merge Sort, Time Complexity is O(nlogn)
For Counting Sort, Time Complexity is O(n) but number in array must be 0.upto 10^6
Bubble Sort: It runs pairwise in one iteration and put the maximum element in last, In second iteration, put the second maximum element in second last position and so on till array is sorted.
Iterate (n-1) times [to find (n-1) max numbers]
Iterate (n-idx-1) times to swap pair of numbers if (first number is
greater than next number)
If swapping stopped in inner loop means that array becomes sorted,
so break the outer loop
Ruby Code:
def bubble_sort(arr)
n = arr.size
(n-1).times do |idx|
swapped = false
(n-idx-1).times do |i|
if arr[i] > arr[i+1]
arr[i], arr[i+1] = arr[i+1], arr[i]
swapped = true
end
end
break unless swapped
end
arr
end
p bubble_sort([5, 22, 29, 39, 19, 51, 78, 96, 84])
Merge Sort: It runs on divide and conquer strategy, i.e if you know two halves of array is sorted then you can sort whole array by using two pointer strategy in O(n).
For Instance,
#first half : [4,5,7,9]
#second half : [1,2,10,15]
1. Take two pointer l and r assigned to starting index of both halves i.e 0
2. Iterate over l and r upto their lengths to consume both arrays
if element at first_half[l] < second_half[r]
Put first_half[l] in result_array
Increment l pointer
else
Put second_half[r] in result_array
Increment r pointer
This merge operation will take O(n) to sort whole array.
Now, if we divide whole array into two halves recursively, we will get binary tree of height log(n) and each level will take O(n) to sort the subproblems (halves), resulting in O(nlogn) Time Complexity.
Base case would be : single element array is always sorted
Ruby Code:
def merge(left_sorted, right_sorted)
res = []
left_size, right_size = left_sorted.size, right_sorted.size
l = r = 0
loop do
break if r == right_size and l == left_size # break if both halves processed
if r == right_size or (l < left_size and left_sorted[l] < right_sorted[r])
res << left_sorted[l]; l += 1
else
res << right_sorted[r]; r += 1
end
end
res
end
def merge_sort(arr)
size = arr.size
return arr if size <= 1 # base case
mid = arr.size/2 - 1
left_half, right_half = arr[0..mid], arr[mid+1..-1]
left_sorted = merge_sort(left_half)
right_sorted = merge_sort(right_half)
return merge(left_sorted, right_sorted)
end
p merge_sort([5, 22, 29, 39, 19, 51, 78, 96, 84])
Counting Sort: It works in O(n) by counting numbers appearance in array if numbers in array lies in range(0..10^6)
Keep count of each number of array in count_array.
Iterate from min_element to max_element of array, and put element in
sorted_array if appeared i.e its count > 0
Ruby Code:
def counting_sort(arr)
min, max = arr.min, arr.max
count_arr = [0] * (max - min + 1) # initialize count_array with all 0s
arr.each do |num|
count_arr[num - min] += 1
end
res = []
size = count_arr.size
size.times do |i|
count_arr[i].times do
res << i + min
end
end
res
end
p counting_sort([5, 22, 29, 39, 19, 51, 78, 96, 84])
Notice that as you sort you are rearranging the array. Don't modify it, use it as a reference and place the sorted items in a new array.
If you want to study algotirthms use C or C++.
def bubble_sort(array)
sorted = array.dup
i = 0
l = sorted.length
while i < (l - 1)
j = 0
while j < l - i - 1
if sorted[j] > sorted[j + 1]
tmp = sorted[j]
sorted[j] = sorted[j + 1]
sorted[j + 1] = tmp
end
j += 1
end
i += 1
end
sorted
end
puts bubble_sort([5, 22, 29, 39, 19, 51, 78, 96, 84])
I have two arrays, I want to return the larger number from the same position in each array.
def get_larger_numbers(a, b)
c = []
count = 0
while count < 10 #assumes there are less than 10 elements in an array, not an ideal solution.
if a[count] > b[count]
c << a[count]
elsif b[count] > a[count]
c << b[count]
else #if numbers are the same
c << a[count]
end
count+= 1
end
return c
end
a = [13, 64, 15, 17, 88]
b = [23, 14, 53, 17, 80]
should return:
c == [23, 64, 53, 17, 88]
Clearly, my code doesn't work, what's the best way to refer to increasing index positions?
Also interested to know simpler ways of doing this.
Your code isn't working because of the static 10 you have as the length. Instead I suggest you make your code more dynamic with regards to how often you loop.
def get_larger_numbers(a,b)
c = []
[a.length, b.length].min.times do |i|
if a[i] > b[i]
c << a[i]
else
c << b[i]
end
end
c
end
a = [13, 64, 15, 17, 88]
b = [23, 14, 53, 17, 80]
get_larger_numbers(a,b)
#=> [23, 64, 53, 17, 88]
This solution assumes that if the arrays are not equal size, you want to throw the rest away.
Okay... Here's what you should do:
def get_larger_numbers(a, b)
c = [] #declare empty array for answer
for i in 0...(a.length < b.length ? a.length : b.length) #see EDIT note
c << (a[i] > b[i] ? a[i] : b[i])
end
c #this is an implicit return
end
a = [13, 64, 15, 17, 88]
b = [23, 14, 53, 17, 80]
puts get_larger_numbers(a,b)
This'll do a for loop that'll run from 0 to the length of a. Yes, it assumes that they're the same length. I figure this is what you want.
Anyway, there's a simple ternary that compares the value of each element in both arrays, one index at a time.
It'll push the bigger value to the c array, leaving you with the greater values in the c array to be returned.
EDIT: Added the ternary expression so that for loops through only the smaller array, because comparing with nil (which is what is at any n index beyond the array, presumably) would raise an error.
A compact solution would be:
def get_larger_numbers(a, b)
return a.zip(b).map{|x, y| (x >= y) ? x : y } # Return optional, added for clarity
end
a = [13, 64, 15, 17, 88]
b = [23, 14, 53, 17, 80]
p get_larger_numbers(a, b)
Note that this assumes the input arrays are of the same length. If arrays are of unequal length, you can truncate to the length of the shorter array, or pad the end with the unpaired elements of the larger array. The current code will throw an error, letting you know you've hit this unspecified case.
As for how it works, the zip pairs the elements of the two arrays, so a.zip(b) becomes:
[[13, 23], [64, 14], [15, 53], [17, 17], [88, 80]]
It then loops over the array with map to produce a new array, passing each pair into the block, which returns the larger of the two elements to fill the output array.
Assuming the two arrays are the same size, simply:
def largest_by_position(a,b)
a.zip(b).map(&:max)
end
largest_by_position([13, 64, 15, 17, 88], [23, 14, 53, 17, 80])
#=> [23, 64, 53, 17, 88]
Alternatively, make the operative line:
[a,b].transpose.map(&:max)
For equal-size arrays a and b, Enumerable#zip and Array#transpose always have this yin and yang relationship:
a.zip(b) == [a,b].transpose #=> true