Binary Search Template Leetcode, The meaning of it? - binary-search

I Found a Binary Search Template here in leetcode
def binarySearch(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if len(nums) == 0:
return -1
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid
# Post-processing:
# End Condition: left == right
if left != len(nums) and nums[left] == target:
return left
return -1
They say that "Template #2 is an advanced form of Binary Search. It is used to search for an element or condition which requires accessing the current index and its immediate right neighbor's index in the array."
I am struggling to understand what the information above means. In a usual binary search right would be
right = len(nums) - 1 # before while loop
right = mid - 1 # inside while loop
and the while loop would be
while left <= right:

You are performing a binary search on an array.
Lets say the array has 100 elements.
# left, right = 0, len(nums)
left = 0, right = 99
# mid = (left + right) // 2
mid = 49
# elif nums[mid] < target:
We need to move right.
# left = mid + 1
left = 50 and right = 99
# else:
We need to move left.
# right = mid
Left = 0, right = 49

Related

Check if two lines are intersecting? (if so, not where so)

I saw this asked but I couldn't understand the answers!
I got 4 vector2s, P1 & P2 for line 1, P3 & P4 for line 2.
Code for intersection position works, but how do I check if that intersection is happening?
More specifically, I want to check what side of a polygon an imaginary line is passing through/colliding with
...
...Had something like it working in an old test-script, however I made no annotations and I can't adapt it. I don't know if there's anything here that could be used but thought I'd share:
if rotation_angle > PI/2 && rotation_angle < 3*PI/2:
if rad_overflow(($Position2D.position-position).angle()-PI/2) < rad_overflow(rotation_angle-PI/2) or rad_overflow(($Position2D.position-position).angle()-PI/2) > rad_overflow(rotation_angle+PI/2):
actives.x = 1
else:
actives.x = 0
if rad_overflow(($Position2D2.position-position).angle()-PI/2) < rad_overflow(rotation_angle-PI/2) or rad_overflow(($Position2D2.position-position).angle()-PI/2) > rad_overflow(rotation_angle+PI/2):
actives.y = 1
else:
actives.y = 0
else:
if rad_overflow(($Position2D.position-position).angle()-PI/2) < rad_overflow(rotation_angle-PI/2) && rad_overflow(($Position2D.position-position).angle()-PI/2) > rad_overflow(rotation_angle+PI/2):
actives.x = 1
else:
actives.x = 0
if rad_overflow(($Position2D2.position-position).angle()-PI/2) < rad_overflow(rotation_angle-PI/2) && rad_overflow(($Position2D2.position-position).angle()-PI/2) > rad_overflow(rotation_angle+PI/2):
actives.y = 1
else:
actives.y = 0
var point1 = $Position2D.position
var point2 = $Position2D2.position
var limit3 = Vector2(0,1).rotated(rotation_angle+PI/2)
var limit4 = Vector2(0,1).rotated(rotation_angle-PI/2)
var det = (point1.x - point2.x)*(limit3.y - limit4.y) - (point1.y - point2.y)*(limit3.x - limit4.x)
var new_position = Vector2(
((point1.x*point2.y - point1.y*point2.x) * (limit3.x-limit4.x) - (point1.x-point2.x) * (limit3.x*limit4.y - limit3.y*limit4.x))/det,
((point1.x*point2.y - point1.y*point2.x) * (limit3.y-limit4.y) - (point1.y-point2.y) * (limit3.x*limit4.y - limit3.y*limit4.x))/det)
if actives.x != actives.y:
print("hit")
else:
print("miss")
You ask:
I got 4 vector2s, P1 & P2 for line 1, P3 & P4 for line 2. Code for intersection position works, but how do I check if that intersection is happening?
If you are using Godot, you can use the Geometry class for this, in particular the line_intersects_line_2d method. I quote from the documentation:
Variant line_intersects_line_2d ( Vector2 from_a, Vector2 dir_a, Vector2 from_b, Vector2 dir_b )
Checks if the two lines (from_a, dir_a) and (from_b, dir_b) intersect. If yes, return the point of intersection as Vector2. If no intersection takes place, returns null.
Note: The lines are specified using direction vectors, not end points.
So that gives you both if they intersect (if it returns null they don't intersect) and where (if it does not return null it returns a Vector2 with the position of the intersection).

Pulp solves multiple combinatorial problems

As the title says,
I want to solve a problem similar to the summation of multiple schemes into a fixed constant, However, when I suggest the constrained optimization model, I can't get all the basic schemes well. Part of the opinion is to add a constraint when I get a solution. However, the added constraint leads to incomplete solution and no addition leads to a dead cycle.
Here is my problem description
I have a list of benchmark data detail_list ,My goal is to select several numbers from the benchmark data list(detail_list), but not all of them, so that the sum of these data can reach the sum of the number(plan_amount) I want.
For Examle
detail_list = [50, 100, 80, 40, 120, 25],
plan_amount = 20,
The feasible schemes are:
detail_list[2]=20 can be satisfied, detail_list[1](noly 10) + detail_list[3](only 10) = plan_amount(20) , detail_list[1](only 5) + detail_list[3](only 15) = plan_amount(20) also can be satisfied, and detail_list1 + detail_list2 + detail_list3 = plan_amount(20). But you can't take four elements in the detail_list are combined, because number = 3, indicating that a maximum of three elements are allowed to be combined.
from pulp import *
num = 6 # the list max length
number_max = 3 # How many combinations can there be at most
plan_amount = 20
detail_list = [50, 100, 80, 40, 120, 25] # Basic data
plan_model = LpProblem("plan_model")
alpha = [LpVariable("alpha_{0}".format(i+1), cat="Binary") for i in range(num)]
upBound_num = [int(detail_list_money) for detail_list_money in detail_list]
num_channel = [
LpVariable("fin_money_{0}".format(i+1), lowBound=0, upBound=upBound_num[i], cat="Integer") for i
in range(num)]
plan_model += lpSum(num_channel) == plan_amount
plan_model += lpSum(alpha) <= number_max
for i in range(num):
plan_model += num_channel[i] >= alpha[i] * 5
plan_model += num_channel[i] <= alpha[i] * detail_list[i]
plan_model.writeLP("2222.lp")
test_dd = open("2222.txt", "w", encoding="utf-8")
i = 0
while True:
plan_model.solve()
if LpStatus[plan_model.status] == "Optimal":
test_dd.write(str(i + 1) + "times result\n")
for v in plan_model.variables():
test_dd.write(v.name + "=" + str(v.varValue))
test_dd.write("\n")
test_dd.write("============================\n\n")
alpha_0_num = 0
alpha_1_num = 0
for alpha_value in alpha:
if value(alpha_value) == 0:
alpha_0_num += 1
if value(alpha_value) == 1:
alpha_1_num += 1
plan_model += (lpSum(
alpha[k] for k in range(num) if value(alpha[k]) == 1)) <= alpha_1_num - 1
plan_model.writeLP("2222.lp")
i += 1
else:
break
test_dd.close()
I don't know how to change my constraints to achieve this goal. Can you help me

the object variable in link list reverse codes

Hi this is a link list reverse code. Anyone can help me understand that the differecen between r = Solution().reverseList(n1) and r = Solution().reverseList(ListNode(1)).
I wonder why the output which is [1] and [3,2,1] respectively and what is the purpose of to assign the ListNode object to a variable.
class Solution(object):
def reverseList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
#if not head:
# return None
prev = head
curr = prev.next
while curr:
next =curr.next
curr.next = prev
prev = curr
curr = next
head.next = None
return prev
class ListNode(object):
def __init__(self,x):
self.val = x
self.next = None
def to_list(self):
return[self.val] + self.next.to_list() if self.next else [self.val]
if __name__ == "__main__":
n1 = ListNode(1)
n2 = ListNode(2)
n3 = ListNode(3)
n1.next = n2
n2.next = n3
r = Solution().reverseList(n1)
print r.to_list()
#assert r.to_list() == [3,2,1]
I understood now.
ListNode(1) has no "next" set, so it will forever return 1 as it's list, whereas n1 starts the same way (as just node of 1), but the "next" attribute is set to node of 2 whose "next" is set to node of 3, so n1 carries all of this information with it, and ListNode(1) does not.
welcome any comments.

How to declare constraints with variable as array index in Z3Py?

Suppose x,y,z are int variables and A is a matrix, I want to express a constraint like:
z == A[x][y]
However this leads to an error:
TypeError: object cannot be interpreted as an index
What would be the correct way to do this?
=======================
A specific example:
I want to select 2 items with the best combination score,
where the score is given by the value of each item and a bonus on the selection pair.
For example,
for 3 items: a, b, c with related value [1,2,1], and the bonus on pairs (a,b) = 2, (a,c)=5, (b,c) = 3, the best selection is (a,c), because it has the highest score: 1 + 1 + 5 = 7.
My question is how to represent the constraint of selection bonus.
Suppose CHOICE[0] and CHOICE[1] are the selection variables and B is the bonus variable.
The ideal constraint should be:
B = bonus[CHOICE[0]][CHOICE[1]]
but it results in TypeError: object cannot be interpreted as an index
I know another way is to use a nested for to instantiate first the CHOICE, then represent B, but this is really inefficient for large quantity of data.
Could any expert suggest me a better solution please?
If someone wants to play a toy example, here's the code:
from z3 import *
items = [0,1,2]
value = [1,2,1]
bonus = [[1,2,5],
[2,1,3],
[5,3,1]]
choices = [0,1]
# selection score
SCORE = [ Int('SCORE_%s' % i) for i in choices ]
# bonus
B = Int('B')
# final score
metric = Int('metric')
# selection variable
CHOICE = [ Int('CHOICE_%s' % i) for i in choices ]
# variable domain
domain_choice = [ And(0 <= CHOICE[i], CHOICE[i] < len(items)) for i in choices ]
# selection implication
constraint_sel = []
for c in choices:
for i in items:
constraint_sel += [Implies(CHOICE[c] == i, SCORE[c] == value[i])]
# choice not the same
constraint_neq = [CHOICE[0] != CHOICE[1]]
# bonus constraint. uncomment it to see the issue
# constraint_b = [B == bonus[val(CHOICE[0])][val(CHOICE[1])]]
# metric definition
constraint_sumscore = [metric == sum([SCORE[i] for i in choices ]) + B]
constraints = constraint_sumscore + constraint_sel + domain_choice + constraint_neq + constraint_b
opt = Optimize()
opt.add(constraints)
opt.maximize(metric)
s = []
if opt.check() == sat:
m = opt.model()
print [ m.evaluate(CHOICE[i]) for i in choices ]
print m.evaluate(metric)
else:
print "failed to solve"
Turns out the best way to deal with this problem is to actually not use arrays at all, but simply create integer variables. With this method, the 317x317 item problem originally posted actually gets solved in about 40 seconds on my relatively old computer:
[ 0.01s] Data loaded
[ 2.06s] Variables defined
[37.90s] Constraints added
[38.95s] Solved:
c0 = 19
c1 = 99
maxVal = 27
Note that the actual "solution" is found in about a second! But adding all the required constraints takes the bulk of the 40 seconds spent. Here's the encoding:
from z3 import *
import sys
import json
import sys
import time
start = time.time()
def tprint(s):
global start
now = time.time()
etime = now - start
print "[%ss] %s" % ('{0:5.2f}'.format(etime), s)
# load data
with open('data.json') as data_file:
dic = json.load(data_file)
tprint("Data loaded")
items = dic['items']
valueVals = dic['value']
bonusVals = dic['bonusVals']
vals = [[Int("val_%d_%d" % (i, j)) for j in items if j > i] for i in items]
tprint("Variables defined")
opt = Optimize()
for i in items:
for j in items:
if j > i:
opt.add(vals[i][j-i-1] == valueVals[i] + valueVals[j] + bonusVals[i][j])
c0, c1 = Ints('c0 c1')
maxVal = Int('maxVal')
opt.add(Or([Or([And(c0 == i, c1 == j, maxVal == vals[i][j-i-1]) for j in items if j > i]) for i in items]))
tprint("Constraints added")
opt.maximize(maxVal)
r = opt.check ()
if r == unsat or r == unknown:
raise Z3Exception("Failed")
tprint("Solved:")
m = opt.model()
print " c0 = %s" % m[c0]
print " c1 = %s" % m[c1]
print " maxVal = %s" % m[maxVal]
I think this is as fast as it'll get with Z3 for this problem. Of course, if you want to maximize multiple metrics, then you can probably structure the code so that you can reuse most of the constraints, thus amortizing the cost of constructing the model just once, and incrementally optimizing afterwards for optimal performance.

How to use while loop inside a function?

I decide to modify the following while loop and use it inside a function so that the loop can take any value instead of 6.
i = 0
numbers = []
while i < 6:
numbers.append(i)
i += 1
I created the following script so that I can use the variable(or more specifically argument ) instead of 6 .
def numbers(limit):
i = 0
numbers = []
while i < limit:
numbers.append(i)
i = i + 1
print numbers
user_limit = raw_input("Give me a limit ")
numbers(user_limit)
When I didn't use the raw_input() and simply put the arguments from the script it was working fine but now when I run it(in Microsoft Powershell) a cursor blinks continuously after the question in raw_input() is asked. Then i have to hit CTRL + C to abort it. Maybe the function is not getting called after raw_input().
Now it is giving a memory error like in the pic.
You need to convert user_limit to Int:
raw_input() return value is str and the statement is using i which is int
def numbers(limit):
i = 0
numbers = []
while i < limit:
numbers.append(i)
i = i + 1
print numbers
user_limit = int(raw_input("Give me a limit "))
numbers(user_limit)
Output:
Give me a limit 8
[0, 1, 2, 3, 4, 5, 6, 7]