Binary search code not working - python-3.x

Good afternoon everyone,
I'm trying to sort out names which are already sorted in alphabetical order. I can't figure out why my program isn't working. Any tips or pointers would be nice. Thanks.
def main():
names = ['Ava Fiscer', 'Bob White', 'Chris Rich', 'Danielle Porter', 'Gordon Pike', 'Hannah Beauregard', 'Matt Hoyle', 'Ross Harrison', 'Sasha Ricci', 'Xavier Adams']
input('Please enter the name to be searched: ', )
binarySearch
main()
def binarySearch(names):
first = 0
last = len(names) - 1
position = -1
found = False
while not found and first <= last:
middle = (first + last) / 2
if names[middle] == value:
found = True
position = middle
elif arr[middle] > value:
last = middle -1
else:
first = middle + 1
return position

What does it mean that the program isn't working? Is it a syntax error or is the problem in the wrong results?
With the code you pasted, there are several indentation problems, but besides that, lines:
input('Please enter the name to be searched: ', )
binarySearch
are also syntactically incorrect, the comma is redundant and only the function name appearing just like that is plain wrong. If you are interested in the correctness of your algorithm, it seems alright, but the boundaries can always be tricky. My code below is working and syntactically correct, if you find it helpful. (names are numbers, but that is irrelevant in this case)
names = [1,2,4,5,6,8,9]
def bs(n):
start = 0
end = len(names)
while end - start > 0:
m = (start+end)/2
if names[m] == n:
return m
elif n < names[m]:
end = m
else:
start = m + 1
return -1
print (bs(1))
print (bs(6))
print (bs(9))
print (bs(3))
print (bs(10))
print (bs(-8))
Another thing I would like to point out is that this kind of binary search is already in the python standard library, the bisect module. However, if you are writing your own for practice or for any other reason that is just fine.

if you are using python 3.* then you are going to want to change
m = (start+end)/2
to
m = (start+end)//2
When you do /2 it outputs a float in 3.*

Related

Why does my solution to problem 3 of the CodeJam 2020 Qualification Round not work?

I would like to receive help in understanding why my solution to Problem 3 of the Google CodeJam 2020 Qualifier does not work.
Link to problem: https://codingcompetitions.withgoogle.com/codejam/round/000000000019fd27/000000000020bdf9
My solution:
High-level overview:
take input
figure out if the given input is impossible by sorting according to start times and then checking if more than 2 subsequent activities are 'active' at once (which is impossible)
if it is, output accordingly; if it isn't, proceed with the procedure below
arbitrarily assign the first person: in my solution I choose Cameron (C).
next, since we know that a solution exists, and the array I iterate through is sorted according to start times, if the very next activity interval (chronologically) overlaps in its duration with the current, assign it to the person who is not currently busy. This is purely because a solution exists, and it clearly cannot be the current person, so it must be the other.
moreover, if the very next activity interval (chronologically) does not overlap with the current activity, then assign it to the person who is currently busy (because he will not be busy for the next activity)
in addition, quoted directly from the problem's official analysis: "If an assignment is possible, there cannot be any set of three activities that pairwise overlap, so by the contrapositive of the the previous argument, we will be able to assign the activity to at least one of Jamie or Cameron at every step."
At this moment, I believe that these arguments suffice to show that my logic is valid, although my code evidently does not always produce the correct answer. I would greatly appreciate any help on this, since I have spent hours trying to debug, un-reason, or find a counter-example to my code to no avail. I have included my code, for reference, below.
Code:
for p in range(int(input())):
s = int(input())
l = []
for i in range(s):
l.append(list(map(int, list(input().split()))))
unsort = l.copy()
l = sorted(l, key=lambda tup: (tup[0],tup[1]))
enumerated = list(enumerate(unsort))
enumerated.sort(key=lambda x: x[1][0])
impossible = False
endings = sorted([(x[1], False) for x in unsort])
startings = sorted([(x[0], True) for x in unsort])
total = sorted(endings + startings, key=lambda tup: (tup[0], tup[1]))
size = 0
for i in total:
if i[1] == True:
size += 1
else:
size -= 1
if size > 2:
impossible = True
def overlap(a,b):
if not max(a[0], b[0]) >= min(a[1], b[1]):
return True
else:
return False
ans = "C"
def opp(a):
if a == "C":
return "J"
else:
return "C"
if impossible == True:
print("Case #" + str(p+1) + ": " + "IMPOSSIBLE")
else:
for i in range(0, s-1):
if overlap(l[i], l[i+1]) == True:
ans = ans + opp(ans[len(ans)-1])
else:
ans = ans + opp(opp(ans[len(ans)-1]))
#the stuff below is to order the activity assignments according to input order
key_value = [(ans[i], l[i]) for i in range(s)]
fans = ""
for i in range(s):
for j in range(s):
if enumerated[j][0] == i:
fans = fans + key_value[j][0]
print("Case #" + str(p + 1) + ": " + fans)

Use Python to reverse the words in a sentence

The question was: Return a sentence with the words reversed
>>> master_yoda('I am home')
'home am I'
It will eventually reverse the words of the line.
I am learning and performing Python in Jupyter Notebook.
def master_yoda(string):
l = string.split()``
p = len(string) - 1
final = ''
while p<0:
final = final + ' ' + s[p]
p = p-1
print (final)
master_yoda('Hello my name is Aryan')
The output is nothing..
No syntax errors , but still no output ...
Perhaps you should try this.
def master_yoda(string):
reversed_list = string.split(' ')
reversed_list.reverse()
reversed_string = ' '.join(reversed_list)
print(reversed_string)
master_yoda("i am home")
The big problem with the code is that you were testing for p < 0 but since p starts off with a positive value, the code never enters the while loop. You should really have been testing for p >= 0. The following code should do what you want, they way you seem to want it to:
def master_yoda(string):
l = string.split()
p = len(l) - 1
final = l[p]
p -= 1
while p >= 0:
final += ' ' + l[p]
p -= 1
return final
Note that this implementation fails if an empty string is passed as input. I tried to keep the code in the spirit of your own code and checking for an empty string would make it more complex. The simplest and most robust solution would be:
def master_yoda(string):
return ' '.join(reversed(string.split()))

Check if number has a digit multiple times

I've come across a puzzling challenge. I have to check if a number contains the same digit multiple times ex. 11, 424, 66 and so on. at first this seems easy enough but i'm having trouble coming up with a logic to check for this. any ideas?
This is what I've got so far. the function takes in a list. (updated)
arr = [[1,20],[1,10]]
for i in arr:
l = list(range(i[0],i[1]))
for num in l:
if num < 11: continue
for c in str(num):
if str(num).count(c) > 1:
# dont know why code is popping off 12 and 13
print(l.pop(num))
If your ultimate goal is simply detecting if there's a double, this function may help:
def has_doubles(n):
return len(set(str(n))) < len(str(n))
The best way I can think about is converting the number to a string and doing a Counter on it
from collections import Counter
a = 98
c = Counter(str(a))
if any(value > 1 for value in c.values()):
print "The number has repeating digits"
#Two-BitAlchemist thanks for the suggestion
looks like you wanted to create your own algorithm probably researching or a student practice well you just have to understand the properties of numbers divided by 10 where 1/10 = 0.1 10/10 = 1 13/10 = 1 reminder 3 13013/10 = 1301 rem 3 hence we can create a function that stores the reminders in an array an check them against the reminder of next number here is the algorithm in python using recursion, you can achieve the same via loops
def countNumber(foundDigits,number):
next_number = int(number/10);
reminder = number % 10;
if(next_number < 1):
for num in foundDigits:
if(num == number or num == reminder):
return True
return False;
foundDigits.append(reminder);
return countNumber(foundDigits,next_number)
example in interpreter could be
digitsFound = list()
countNumber(digitsFound, 435229)
Solved this! I didn't know pop executes based on position not value! remove is a better fit here.
arr = [[1,40],[1,10]]
for i in arr:
l = list(range(i[0],i[1]))
for num in l:
if num < 11: continue
for char in str(num):
if str(num).count(char) < 2: continue
l.remove(num)
break
print(l)
Here is my solution, its simple and works for 2 digit numbers.
nums = list(input().rstrip().split())
def has_doubles(nums):
for number in nums:
if number[0] == number[1]:
print(number)
else:
continue
has_doubles(nums)

IndexError: string index out of range, can't figure out why

I want in this part of my code, to cut out any non alphabetical symbol in the words I get from a read file.
I get that there is probably an empty string being tested on, that the error is happening,
but I can't figure out why after numerous different codes I tried.
Here's what I have now for it:
for i in given_file:
cut_it_out = True
while cut_it_out:
if len(i) == 0:
cut_it_out = False
else:
while (len(i) != 0) and cut_it_out:
if i.lower()[0].isalpha() and i.lower()[len(i) - 1].isalpha():
cut_it_out = False
if (not i.lower()[len(i) - 1].isalpha()):
i = i[:len(i) - 2]
if (not i.lower()[0].isalpha()):
i = i[1:]
Can anyone help me figure this out?
thanks.
Thanks for the interesting answers :), I want it to be even more precise, but there is an endless loop problem on I can't seem to get rid of.
Can anyone help me figure it out?
all_words = {} # New empty dictionary
for i in given_file:
if "--" in i:
split_point = i.index("--")
part_1 = i[:split_point]
part_2 = i[split_point + 2:]
combined_parts = [part_1, part_2]
given_file.insert(given_file.index(i)+2, str(part_1))
given_file.insert(given_file.index(part_1)+1, str(part_2))
#given_file.extend(combined_parts)
given_file.remove(i)
continue
elif len(i) > 0:
if i.find('0') == -1 and i.find('1') == -1 and i.find('2') == -1 and i.find('3') == -1 and i.find('4') == -1\
and i.find('5') == -1 and i.find('6') == -1 and i.find('7') == -1 and i.find('8') == -1 and i.find('9') == -1:
while not i[:1].isalpha():
i = i[1:]
while not i[-1:].isalpha():
i = i[:-1]
if i.lower() not in all_words:
all_words[i.lower()] = 1
elif i.lower() in all_words:
all_words[i.lower()] += 1
I think your problem is a consequence of an over complicated solution.
The error was pointed by #tobias_k. And anyway your code can be very inefficient.
Try to simplify, for example try: (I have not tested yet)
for i in given_file:
beg=0
end=len(i)-1
while beg<=end and not i[beg].isalpha():
beg=beg+1
while beg<=end and not i[end].isalpha():
end=end-1
res=""
if beg<=end:
res=i[beg:end]
There are a few problems with your code:
The immediate problem is that the second if can strip away the last character in a string of all non-alpha characters, and then the third if will produce an exception.
If the last character is non-alpha, you strip away the last two characters.
There is no need for those two nested loops, and you can use break instead of that boolean variable
if i.lower()[x] is non-alpha, so is i[x]; also, better use i[-1] for the last index
After fixing those issues, but keeping the general idea the same, your code becomes
while len(i) > 0:
if i[0].isalpha() and i[-1].isalpha():
break
if not i[-1].isalpha():
i = i[:-1]
elif not i[0].isalpha(): # actually, just 'else' would be enough, too
i = i[1:]
But that's still a bit hard to follow. I suggest using two loops for the two ends of the string:
while i and not i[:1].isalpha():
i = i[1:]
while i and not i[-1:].isalpha():
i = i[:-1]
Or you could just use a regular expression, somethink like this:
i = re.sub(r"^[^a-zA-Z]+|[^a-zA-Z]+$", "", i)
This reads: Replace all (+) characters that are not ([^...]) in the group a-zA-Z that are directly after the start of the string (^) or (|) before the string's end ($) with "".

Finding the additive and multiplicative roots of a number using python

http://www.cs.uni.edu/~diesburg/courses/cs1510_sp15/homework/PA04/index.htm
So I have this assignment. I have been trying to work out the code to find the additive and multiplicative roots of a user given input. I am new to python and know how to work the problem out, but without the tools (coding know how) have been just running in circles for quite a while now. So if anyone could be so kind as to help me figure out the coding. I have tried slicing the list, but keep getting an error if I try to make the string an int and if I leave it as an string it just doesn't seem to run. I know there is probably a way using modulous as well, but have yet to quite master it.
Thank you for any help any of you are able to leave me.
Edit
Here is the code I have so far.
import sys
userStr = input("What number should I use for my \
calculations? ")
userInt = int (userStr)
original = userStr #Save Copy of original value
originalTwo = userStr #Save second Copy of original value
addCount = 0
mulCount = 0
#Stop the program if the integer is less than or equal to 0
while userInt <= 0:
print ("Thanks for playing along!")
sys.exit()
#Use a while loop to repeat the process of splitting an integer into single digits and then adding the individual digits.
print = ("Addition")
while userInt > 9:
userInt = sum(map(int, userStr))
print("New Value: ",userStr)
addCount = addCount + 1
#Use a while loop to repeat the process of splitting an integer into single digits and then multiplying the individual digits.
print = ("Multiplication")
while original > 9:
original = (map (int, original))
print("New Value: ",original)
mulCount = mulCount + 1
#Print the outputs to the screen for the user.
print("For the Integer: ",userInt)
print(" Additive Persistence= ",addCount,", Additive Root= ", userInt)
print(" Multiplicative Persistence= ",mulCount,",
Multiplicative Root= ", original)

Resources