I was going through this problem on SPOJ.
It is a problem about binary search.
I tried to implement this in python:
x,yu= input().split()
bu=int(yu)
y=int(yu)
array=input().split()
while y>0:
qquery=input()
y=y-1
query=int(qquery)
b= int(x)
left=1
right= b
while left <= right and bu>0:
pmid=((right+left)/2-1)
mid=int(pmid)
fir=array[mid]
fire=int(fir)
if fire== query:
bu=bu-1
if query < fire:
left=mid+1
else :
right=mid-1
this is the input:
5 4
2 4 7 7 9
7
10
4
2
I am getting an infinite loop with 3.
I have been stuck on this problem for a long time. I would really like someone to point out my mistake, the solution and the explanation.
Thank you!!
Try this code if you're looking for the binary search algorithm.
def binary_search(seq, t):
min = 0
max = len(seq) - 1
while True:
if max < min:
return -1
m = (min + max) // 2
if seq[m] < t:
min = m + 1
elif seq[m] > t:
max = m - 1
else:
return m
seq = [1, 2, 3, 4]
t = 2
binary_search(seq, t)
Related
Got task to find indexes of value and double that value in input list.
In input first line we get list range, second - list of values, third - value to find.
The output is 2 numbers - indexes of equal or higher value and double the value. If there is none, return -1
Example input:
6
1 2 4 4 6 8
3
Example output:
3 5
What i got so far is standart binary search func, but i dont get how to make it search not only for exact number but nearest higher.
def binarySearch(arr, x, left, right):
if right <= left:
return -1
mid = (left + right) // 2
if arr[mid] >= x:
return mid
elif x < arr[mid]:
return binarySearch(arr, x, left, mid)
else:
return binarySearch(arr, x, mid + 1, right)
def main():
n = int(input())
k = input().split()
q = []
for i in k:
q.append(int(i))
s = int(input())
res1 = binarySearch(q, s, q[0], (n-1))
res2 = binarySearch(q, (s*2), q[0], (n-1))
print(res1, res2)
if __name__ == "__main__":
main()
The input is:
6
1 2 4 4 6 8
3
And output:
3 4
Here's a modified binary search which will return the base zero index of a value if found or the index of the next highest value in the list.
def bsearch(lst, x):
L = 0
R = len(lst) - 1
while L <= R:
m = (L + R) // 2
if (v := lst[m]) == x:
return m
if v < x:
L = m + 1
else:
R = m - 1
return L if L < len(lst) else -1
data = list(map(int, '1 2 4 4 6 8'.split()))
for x in range(10):
print(x, bsearch(data, x))
Output:
0 0
1 0
2 1
3 2
4 2
5 4
6 4
7 5
8 5
9 -1
I'm new to Python and I'm having some trouble. I know if I'm trying to find the number of numbers from 0-1000 that are divisible by 3 or 7 for example I would use the equation np.floor(1000/3)+np.floor(1000/7)-np.floor(1000/21). However, this time the range doesn't start from 0, so what should I replace 1000 with? Thanks! np is numpy btw
O(n) approach:
result = 0
for x in range(1001):
if (x % 3 == 0 and x % 7 == 0):
result += 1
print(result)
More concise:
result = sum(x % 3 == 0 and x % 7 == 0 for x in range(1001))
I'm a beginner and I tried this code to list the sum of all the multiples of 3 or 5 below 100, but it gives a wrong answer and I don't know why.
result = 0
result2 = 0
som = 0
sum2 = 0
below_1000 = True
while below_1000:
result = result+3
if result < 1000:
som += result
else:
below_1000 = False
below_1000 = True
while below_1000:
result2 = result2+5
if result2 < 1000:
sum2 += result2
else:
below_1000 = False
final_result = som+sum2
print(final_result)
Since you first loop over multiples of 3, then again over multiples of 5, you are double-counting a lot of values, specifically values that are multiples of both 3 and 5 (for example 15 or 60).
To write this manually, you can use a for loop over range
total = 0
for i in range(1000):
if i % 3 == 0 or i % 5 == 0:
total += i
>>> total
233168
A more concise way to do this same thing is using a generator expression within the sum function
>>> sum(i for i in range(1000) if i % 3 == 0 or i % 5 == 0)
233168
I have started to implement backwards Dijkstra's algorithm in python:
def backwardsDijkstra(g: DoubleDictGraph, s, t):
q = PriorityQueue()
dist = {}
next = {}
q.add(t, 0)
dist[t] = 0
found = False
while not q.isEmpty() and not found:
x = q.pop()
for y in g.parseNin(x):
if y not in dist.keys() or dist[x] + g.Cost(x, y) < dist[y]:
dist[y] = dist[x] + g.Cost(x, y)
q.add(y, dist[y])
next[y] = x
if x == t:
found = True
return dist[s], next
And I can't figure out why it stops at the second iteration for the next graph for example:
5 7
0 1 5
0 2 20
1 2 10
1 3 30
2 3 5
2 4 20
3 4 10
(number of vertices, number of edges, (start,end,cost)
The bug in you code is at this line:
if x == t:
found = True
Since you are starting from t (target), you should be looking for s (source). Currently you are breaking out of the loop for the first candidate (which is t).
So I wrote a piece of code in pycharm
to solve this problem:
pick any 5 positive integers that add up to 100
and by addition,subtraction or just using one of the five values
you should be able to make every number up to 100
for example
1,22,2,3,4
for 1 I could give in 1
for 2 i could give in 2
so on
for 21 I could give 22 - 1
for 25 I could give (22 + 2) - 1
li = [1, 1, 1, 1, 1]
lists_of_li_that_pass_T1 = []
while True:
if sum(li) == 100:
list_of_li_that_pass_T1.append(li)
if li[-1] != 100:
li[-1] += 1
else:
li[-1] = 1
if li[-2] != 100:
li[-2] += 1
else:
li[-2] = 1
if li[-3] != 100:
li[-3] += 1
else:
li[-3] = 1
if li[-4] != 100:
li[-4] += 1
else:
li[-4] = 1
if li[-5] != 100:
li[-5] += 1
else:
break
else:
if li[-1] != 100:
li[-1] += 1
else:
li[-1] = 1
if li[-2] != 100:
li[-2] += 1
else:
li[-2] = 1
if li[-3] != 100:
li[-3] += 1
else:
li[-3] = 1
if li[-4] != 100:
li[-4] += 1
else:
li[-4] = 1
if li[-5] != 100:
li[-5] += 1
else:
break
this should give me all the number combinations that add up to 100 out of the total 1*10 ** 10
but its not working please help me fix it so it prints all of the sets of integers
I also can't think of what I would do next to get the perfect sets that solve the problem
After #JohnY comments, I assume that the question is:
Find a set of 5 integers meeting the following requirements:
their sum is 100
any number in the [1, 100] range can be constructed using at most once the elements of the set and only additions and substractions
A brute force way is certainly possible, but proving that any number can be constructed that way would be tedious. But a divide and conquer strategy is possible: to construct all numbers up to n with a set of m numbers u0..., um-1, it is enough to build all numbers up to (n+2)/3 with u0..., um-2 and use um-1 = 2*n/3. Any number in the ((n+2)/3, um-1) range can be written as um-1-x with x in the [1, (n+2)/3] range, and any number in the (um-1, n] range as um-1+y with y in the same low range.
So we can use here u4 = 66 and find a way to build numbers up to 34 with 4 numbers.
Let us iterate: u3 = 24 and build numbers up to 12 with 3 numbers.
One more step u2 = 8 and build numbers up to 4 with 2 numbers.
Ok: u0 = 1 and u1 = 3 give immediately:
1 = u0
2 = 3 - 1 = u1 - u0
3 = u1
4 = 3 + 1 = u1 + u0
Done.
Mathematical disgression:
In fact u0 = 1 and u1 = 3 can build all numbers up to 4, so we can use u2 = 9 to build all numbers up to 9+4 = 13. We can prove easily that the sequence ui = 3i verifies sum(ui for i in [0, m-1]) = 1 + 3 + ... + 3m-1 = (3m - 1)/(3 - 1) = (um - 1) / 2.
So we could use u0=1, u1=3, u2=9, u3=27 to build all numbers up to 40, and finally set u4 = 60.
In fact, u0 and u1 can only be 1 and 3 and u2 can be 8 or 9. Then if u2 == 8, u3 can be in the [22, 25] range, and if u2 == 9, u3 can be in the [21, 27] range. The high limit is given by the 3i sequence, and the low limit is given by the requirement to build numbers up to 12 with 3 numbers, and up to 34 with 4 ones.
No code was used, but I think that way much quicker and less error prone. It is now possible to use Python to show that all numbers up to 100 can be constructed from one of those sets using the divide and conquer strategy.