is there a way to eliminate similar strings without imports? - python

What I've been tasked to do is to take in an input in the form "n m" where n= number of courses and m= number of students. next, i must take in m more inputs, each input being in the form "a b" where a is the number of the course that the student is taking and b is the students name. Then, I must filter out the similar names that are taking the same courses and output the names of students taking each course. For example consider this sample input:
2 4
2 David
1 john
2 davin
1 johnn
I must output:
john johnn
David
in that order as john and johnn took course 1 so they will be outputted in the first line of output (i must output n amount of lines) then David is in the next line of output as he is in course 2. Notice how davin wasn't outputted, this is because he is taking same course as David and name is too similar (similar names meaning both names are same length and only have 1 letter difference so davis and Davit are too similar but davis and daviss aren't)
x = input()
n, m = x.split(' ')
n = int(n)
m = int(m)
data = {}
dict()
for a in range(m):
line = input()
course, name = line.split(' ')
if course not in data:
data[course] = [] # list()
if name not in data[course]:
data[course].append(name)
for key, value in data.items():
print( " ".join(value) )
This is what I've come up with for now, the only issue is, if "
2 davin
1 john
are the inputs, then the outs puts are
davin
john
but i need it to be
john
davin
along with that, I need to find a way to eliminate similar names and only allow the first of the two similar names to be outputted.
Any help would be appreciated thanks.

To get the output in the correct order, loop from 1 to n instead of looping over the elements of the dictionary.
for i in range(1, n+1):
print(" ".join(data.get(str(i), [])))
To handle similar names, write a function that tells if two names are similar:
def similar(name1, name2):
if len(name1) != len(name2):
return false
diffcount = sum(c1 != c2 for c1, c2 in zip(name1, name2))
return diffcount <= 1
Then use it when testing whether the name is already in the course student list:
if not any(similar(name, s) for s in data[course]):
data[course].append(name)

Related

Is there a way to separate elements of a list by order when theyre in a string format?

x=input()
x=list(x)
amtcrs=''.join(x[0:x.index(' ')])
amtst=''.join(x[x.index(' ')+1:])
a=0
b=''
while a<int(amtst):
crsname=input()
crsname=list(crsname)
crs=''.join(crsname[0:crsname.index(' ')])
st=''.join(crsname[crsname.index(' ')+1:])
st=st.lower()
a=a+1
b=b+crs+st+' '
b=b.strip()
z=b.split(' ')
z.sort()
for l in range(0,int(amtcrs)):
print(z)
This is what I've come up with for now. It's incomplete but I'm getting there.
Basically what I've been tasked to do is to first take an input "n m" such that n is the amount of courses that will be taught, and m is the amount of students that will be applying to the courses.
Then I have to take in m lines of input so that each line is a number followed by a name, the number being which course the student wants to take (number will be 1<= x >=n) and the name of student.
for example:
if the input is 2 4, there will be 4 more inputs, lets say they are (1 david, 2 john, 2 Kevin, 1 jennifer)
What I must output is, in this case, 2 lines of the names of people enrolling in each course, with the people enrolling in course 1 being the first line of output and so on.
so the output here should be:
david jennifer
john Kevin
The tricky part is that if a person's name is similar to another person's name (i.e same length and at most 1 character different, mike and tike are similar, Mike and mime are similar (M and m count as the same char)) and they're applying to the same course, then whoever's name was inputted first would be registered for the course while the other one isn't.
For example: input is 3 4, then the next 4 inputs are ( 1 david, 1 davin, 2 john, 2 lola)
then the output should be:
david
john lola
also notice how the third line is empty because there is a third course but no one is signing up for it.
You overcomplicated it - and all code seems useless.
You should get text from input() and directly use .split(' ') (without using list())
And later you could put data in dictionary to create ie.{'1': ['david', 'jennifer'], '2': ['john', 'Kevin']} and next you should use for-loop to get lists with names and display them in line using " ".join(list).
Something like this (but not tested)
# --- get numbers ---
x = input()
n, m = x.split(' ')
#n = int(n)
m = int(m)
# --- get courses and names ---
data = {} # dict()
for _ in range(m)
line = input()
course, name = line.split(' ')
if course not in data:
data[course] = [] # list()
if name not in data[course]:
data[course].append(name)
#print(data)
# --- display results ---
#for key, value in data.items():
# print( " ".join(value) )
for key in sorted(data.keys()):
value = data[key]
print( " ".join(value) )
print("Enter course number,max student number ") # 3 4
course_student = str(input())
total_number_of_courses=course_student.split()[0]
max_student = course_student.split()[1]
hash_list= {str(course_id):[] for course_id in range( 1,int(total_number_of_courses))}
print("Enter course_id and name")
stu_course_ids=str(input()) #1 John, 2 Doe, 2 Johny
for stu_course_id in stu_course_ids.split(","):
course_stu = stu_course_id.split(" ")
course_stu = [ item for item in course_stu if item]
if hash_list[course_stu[0]]:
hash_list[course_stu[0]].append(course_stu[1])
else:
hash_list[course_stu[0]] = [course_stu[1]]
for key, value in hash_list.items():
print( f"course_id: {key} students: {' '.join(value)}")
my result:
course_id: 1 students: John
course_id: 2 students: Doe Johny

How to print multiple inputs that are gathered into a dictionary horizontally

Im trying to figure out how to print multiple inputs from one dictionary. The way i have it, it only prints the last input sequence instead of printing all three inputs.
For reference:
The program asks for 3 inputs:name, count, and price. It then asks if you want to enter more with the usual y or n input and then you put in another 3, so on and so forth.
However, the print() will only print the last 3 inputs instead of all 3 sets.
What i have looks like this
input name
input count
input price
input more? y or n
a = {name:count}
d = {name:price}
print(a)
print(d)
output
'name',count
'name',price
but it should look like
{'name',count 'name',count 'name',count}
{'name',price 'name',price 'name',price}
is there a function i need to put on the print functions like print a.function()
or is it something in the formatting of the dictionary?
(edit:sorry this board has weird mechanics)
I am bit confused why you want to print same key value pair 3 times in one line. However if you really need that you can print
print(a,a,a)
print(d,d,d)
You cant create a dict with duplicate keys, but one key can have multiple values like
a = {name: [count, price]}
And I think most logical would be
a = {name: name, count: count, price: price}
print("name ", a[name], ", count ", a[count], ", price ", a[price])
def ask_questions(name_list, count_list, price_list):
name_list.append(input("name: "))
count_list.append(input("count: "))
price_list.append(input("price: "))
name_list = []
count_list = []
price_list = []
While input("more? y or n: ") == "y":
ask_questions(name_list, count_list, price_list)
a = dict(zip(name_list,count_list))
d = dict(zip(name_list,price_list))
print(a)
print(d)
So I figured it out and forgot to come back. All I had to do was ADD the value to the key.
So it would be like:
a[name]= count
d[name]= price
This gave me the loops I needed to fill out the whole thing.

Python create a street address table

Very new to programming, very new to Python, I take different tasks online. The goal is to accomplish a lot without relying on external libraries.
One task I couldn't do today is this one:
Given a street name and a user provided number, create a table of user_provided_number columns and output the name of the street. Then, in the same table create the same output but reverse the street address. The space between the street addresses should be replaced with a "|". If the street name is too short to complete the row, render "?" for each remaining space.
Scenario Example:
Street address: Mystreet road, user provided number: 6
Expected output:
M y s t r e
e t | r o a
d | d a o r
| t e e r t
s y M ? ? ?
So far I managed to do the following:
strAddress = input("What's your street address?")
givenNumber = input("What's your favourite number from 1 to 10?")
reverseAddress = strAddress[::-1]
splitAddress = list(strAddress)
for row in range(0,int(len(strAddress)/givenNumber)):
for element in range(0,givenNumber):
print (splitAddress[element], end=' ')
print()
Why is this "array"(?) printing the same elements on each row? Assuming that the user provided "4" as their number, from the code I wrote I expected an output like that:
M y s t
r e e t
r o a
d
however the output is:
M y s t
M y s t
M y s t
First of all you should convert your givenNumber into int() since input() always returns string. Also you could convert your whole strAddress into itself and reversed version of itself to make accessing it easier. splitAddress wont be needed here since you can access string length and elements the same way as list in this example. In your first loop you're iterating over len(strAddress)/givenNumber which isn't enough since we need to print our Address two times (with reversed version) and we need to fill extending characters with ? so we need to round it up, without using math library we could do this like I've shown. Lastly splitAddress[element] here you access element'th index of your Address which will be number 0 - 6 on every iteration so we need take into account row to print more elements.
strAddress = input("What's your street address?")
givenNumber = int(input("What's your favourite number from 1 to 10?"))
strAddress += '|' + strAddress[::-1]
strAddress = strAddress.replace(' ', '|')
lines_to_print = len(strAddress)//givenNumber + (len(strAddress)%givenNumber>0)
for row in range(lines_to_print):
for element in range(givenNumber):
if row*givenNumber + element < len(strAddress):
print(strAddress[row*givenNumber + element], end=' ')
else:
print('? ', end='')
print()
Output for Mystreet road and 6
M y s t r e
e t | r o a
d | d a o r
| t e e r t
s y M ? ? ?
Your issue is that the nested loop starts back at 0 every time and ends at the same place every time. With your current code, the first loop is just declaring how many times to do the second loop, it doesn't have any input on the second loop. To fix this you could do for element in range(givenNumber*(row-1),givenNumber*(row)).
You never progress through the street address. row takes on values 0, 1, 2; but you never use those values to move along the address string. Look at what you print:
for element in range(0,givenNumber):
print (splitAddress[element], end=' ')
This prints the same four characters, regardless of the row value. Instead, you need to truly split the address into rows and print those. Alternately, you can compute the correct indices for each row: givenNumber*row + element.
Another solution would be to just build your string (replace characters, reverse it, ...) and then print this string character by character for each defined row. In order to calculate the number of filling characters for the last row, you could make use of the modulo operator with negative numbers.
Say your final string (chars) is 27 characters long and the given cell number (givenNumber) is 7. This would result in -27 % 7 = 1. So in this case one filling character would need to be added. chars += charFill * numCharFill will then just add the filling character x times at the end.
With an index you can then go through your string step by step and configure the output as required.
# strAddress = input("What's your street address?")
# givenNumber = int(input("What's your favourite number from 1 to 10?"))
strAddress = "Mystreet road"
givenNumber = 6
charFill = "?" # char to fill last row
chars = strAddress.replace(" ","|") # replace spaces in strAddress
chars += "|" + chars[::-1] # add reverse chars
numCharFill = -len(chars)%givenNumber # modulo of negative number
chars += charFill * numCharFill # add fill character x times
index = 0
for char in chars:
if index > 0 and not index%givenNumber:
print()
print(chars[index], end=' ')
index = index + 1
Try:
strAddress = input("What's your street address?\n")
givenNumber = int(input("What's your favourite number from 1 to 10?\n"))
charGroupSize = len(strAddress)/givenNumber
charGroups = [strAddress[i:i+givenNumber] for i in range(0, len(strAddress), givenNumber)]
for group in charGroups:
for char in group:
print (char, end=' ')
print()
Output:
What's your street address?
Mystreet road
What's your favourite number from 1 to 10?
4
M y s t
r e e t
r o a
d

what is incorrect about my solution or my output method for codejam exercise?

I participated in kickstart of google code jam contest and got stuck in problem 1A called Gbus count
My code is passing the sample test case provided in the problem but when I submit the small input by outputting it to a file it gives me an error, incorrect response.
Problem link - https://code.google.com/codejam/contest/4374486/dashboard#s=p0
t=int(input()) #no. of test cases
for test in range(t):
if test==0:
n=int(input())
else:
input() #to cover up the blank line after each test case
n=int(input())
l=list(map(int,input().split()))
buses={} # the route of each bus will be stored in this dictionary
i=1
for d in l: # this loop is used to store the route of each bus in the buses dictionary
if i not in buses:
buses[i]=[d]
elif len(buses[i])<2:
buses[i].append(d)
else:
i=i+1
buses[i]=[d]
p=int(input())
cities={}
#this dictionary will contain the cities which need to be monitored
for _ in range(p): #first each city is initialized to zero
cities[int(input())]=0
for city in cities: #Monitor all buses in each city if it falls in the route range than increment the city
for bus in buses:
if buses[bus][0]<=city<=buses[bus][1]:
cities[city]+=1
result=[]
for city in cities: #store all the cities in a list
result.append(cities[city])
print("Case #{}: {}".format(test+1, ' '.join(map(str,result))))
My logic:
First I took all the test cases in a variable t and for each test case I inputted the no. of buses and inputted routes of all buses in a list l. Then I created a dictionary named buses and divided the list into n lists with each list for each bus nume=beres from 1 to n in the dictionary.
Then I inputted all the cities to be monitored in another dictionary named cities and initialized the value of each city to be monitored to 0.
Finally, I calculated the no. of buses travelling through each city by checking if it falls in the route range of each bus and if it does I incremented the value of the corresponding city by 1 and then stored all the values of the dictionary in a list and outputted it for each test case.
Output methodology:
I used this line to execute my code using cmd in my working directory
python gbus_count.py < A-small-attempt3.in > output.out
My code works fine for the sample test case provided so there might not be a flaw in my logic. I think that there might be a mistake in my output methodology.
I see two problems in your code.
Python standard dictionary is not ordered! Therefore the cities dictionary will not have the elements (keys) in the order you entered.
From Python 3.1 onwards, you can use the OrderedDict for this
If the same city is repeated twice (or more), there will be only one entry in the final result, because a dictionary can't hold repeated keys.
As I see your design has flows. Besides, I think you could have done this much easily without making things too complicated.
Note:
From Python 3.6 onwards, the standard dictionary maintains the insertion order by default.
UPDATE
As requested, following is my attempt to solve the problem.
Please note that this might not be the best solution! And for sure, this is not the most readable solution. This is just my solution.
for case in range(1, int(input())+1):
if case > 1:
input('\n') # consume and print newline
print("Case #{}:".format(case), end='')
bus_count = int(input())
busline = list(map(int, input().strip().split(" ")))
for _ in range(int(input())):
city = int(input())
matches = sum([1 for bid in range(bus_count) if busline[2*bid] <= city <= busline[2*bid+1]])
print(" {}".format(matches), end='')
you can also check out this solution:
def Gbus_Count():
T = int(input())
for i in range(T):
if i == 0:
N = int(input())
else:
input()
N = int(input())
A = list(map(int, input().split()))
P = int(input())
C = list()
D = dict()
for k in range(P):
C.append(int(input()))
for m in range(P):
for n in range(N):
if A[2*n]<=C[m]<=A[2*n+1]:
if C[m] not in D:
D[C[m]] = 1
else:
D[C[m]] += 1
print("Case #{}: {}".format(i+1, ' '.join(str(x) for x in D.values())))
Gbus_Count()

When comparing the values of words in python, why would "Nick" be greater than "George"?

I am studying for an upcoming assignment and trying to figure out what the following program prints:
d = ["Bob", "Tom", "George", "Susan", "Mary"]
n = raw_input("Enter a name: ") # assume user enters Robert
for name in d :
if name < n :
print name
print
size = len( d )
i = 0
while i < (size - 1) :
if d[i] > d[i+1] :
temp = d[i]
d[i] = d[i+1]
d[i+1] = temp
else :
d[i+1] = "Nick"
i += 1
for name in d :
print name
I am very confused because when I run the program it returns:
Enter a name: Robert
Bob
George
Mary
Bob
George
Nick
Mary
Nick
I am clearly confused as to how to calculate the value of words. I thought you assigned the ascii value to the individual letters and added them together to get the value, but using that method would not get these results.
could someone please help me understand?
They are in dictionary order, so the first letter is the only thing that matters if it isn't the same.
To do what you want, use
value=sum([ord(x) for x in name])

Categories

Resources