I found out I can solve this problem in a better space complexity if I enter inputs one at time. However, python is defeating the purpose of my script.
Because python is outputting O(n) elements that I just gave for input.
0
2
no
See that 0 and 2 for inputs? I only need one line. And it can only have the current input for that one particular line. (not 0,2....) Otherwise, the computer is technically still using O(n) space just for the graphics card to remember what pixels to output.
I tried using os.devnull and other methods. But, the computer still used O(N) space by simply outputting none or null. Outputting space characters still use O(N) space so does every other possible character you can think of. Output must be 100% suppressed excluding the yes or no outputs.
This isn't impossible because I guarantee you that the algorithm works by hand with an auxiliary space better than O(N)
# Decision Problem: Is N in index M?
import sys
import os
M = 2
N = 2
index = -1
while True:
# We are going to enter each element from our list ONE AT A TIME.
# This will improve our space-complexity that is better than O(n)
# Be careful not to enter the elements out of order.
a = int(input(os.devnull))
index = index + 1
if a == N:
if index == M:
print('yes')
break
if index > M:
print('no')
break
if index < M:
if a == N:
print('no')
break
Question
How do I suppress output completely without losing my "yes" or "no" outputs?
Related
I am working on a leetcode question 767. Reorganize String, there are many good answers to it. But I am eager to know where has gone wrong in my own code (learning from my own mistake is also important for preventing similar mistakes in the future). My idea is to generate permutation one by one, and check the result on the fly whether there are two same elements adjacent, if so, then jump to the next permutation, soon as there is one good permutation my code stops. My code failed at 27 / 62 due to Time Limit Exceeded. I don't know why my code takes milliseconds to get a correct permutation for a very long string but take a very long time to handle a much shorter string.
def permutations(S,path):
if len(path)==length:
return "".join(path)
for i in range(len(S)):
if path and S[i]==path[-1]:
continue
else:
p= permutations(S[:i]+S[i+1:],path+[S[i]])
if p:
return p
input 1
S ="kkkkzraaaaaaaaaakatkwpkkkktrbbbbbbbbbbbbbbbbbbbbbbbbbqasffffffffffdffwsssrrrefffdddrgerterg"
path = []
length = len(S)
permutations(S,path)
It takes milliseconds to generate a correct permutation.
input 2
S = "bbbbaaaaababaababab"
path = []
length = len(S)
permutations(S,path)
It takes an extremely long time to handle this string.
Could you please help me understand where I have done wrong or misunderstood?
I had this problem in a coding interview:
# AAABB should return A3B2
This is a classic algorithm interview question. I said that I can solve this in O(n) time and O(1) space.
def compress(s):
output = ''
count = 1
for i in range(len(s)-1):
if s[i] == s[i+1]:
count+=1
else:
output = output + s[i] + str(count)
count=1
output = output +s[i+1] + str(count)
return output
compress('AAABB') #returns A3B2
I understand that O(n) space means that it grows proportionally with the size of input. So I was thinking that O(n) space would look something like
[(A,3),(B,2)].
I am under the impression that A3B2 is in O(1) space since it's not being split up into multiple strings.
I now realized that n == len(s) and my output grows un-proportionally (less) with my input size, so is it correct to say that space is O(log n)?
The length of the output string you store must be counted. In the worst case (no consecutive characters match), it’s actually twice as long as the input. So clearly it’s O(n) in general: it would only be asymptotically better if somehow you knew that long inputs always contained very long runs. (In the best case, all characters are the same, and the length of the one number is O(log n).)
That said, it’s sometimes useful to consider your output as a stream (like print), and then your space complexity (for count and perhaps the current input character) is constant. Of course, even then it’s technically logarithmic, since the number of bits needed to store count is, but that’s often disregarded in practical analyses.
I am working with the code that would read the input of the strings and compute whether the parenthesis (using arbitrary characters for open and close) are balanced. The aim is to prompt user to input the amount of brackets as strings, so the compiler would compute their amount and type(ex. if it is '(' or ')') .
I have been given hints:
Hint1: introduce two counters initialized to zero in the beginning.
Then explore the symbols of the string in a loop. For the current
symbol increment the left counter by 1 if the symbol is '(',
otherwise, increment by 1 the `right' counter
Hint2: call a string math-like if the brackets occur like in a
mathematical formula. For instance, the strings '()', '(())()',
'(()())' are balanced, while the strings '))(())((' and '())(()'
are not.
My code now looks like this:
lefts =str(input("Please enter a left parenthesis: "))
rights =str(input("Please enter a right parenthesis: "))
#token parsing requires paying attention to the order of the parenthesis
def ptest(test): #testing with counters
lefts = 0
rights = 0
balance = 0 #additional counter that will help us determine the amount of strings and their relation to each other
for c in test:
if c == '(':
balance += 1
lefts += 1
elif c == ')':
balance -= 1
rights += 1
print ('testing "'+test+'"')
print ('lefts='+str(lefts)+' rights='+str(rights))
#if there will b a balance between the strings/parenthesis, they will possibly be balanced
if balance == 0: print 'same number of open/close, possibly balanced'
else: print 'different number of open/close, definitely not balanced'
ptest(test1)
ptest(test2)
How could I modify this in order that it would work?
But I think you partly misunderstood the task.
There can be many brackets, but no more ")" than "(" (and at the end the number of both types must be equal)
And I would think, that the input not only consists of brackets
So you should build a loop (as you did) and
test, whether the char is a bracket or not
if a bracket, so increase the matching counter (you could even have one Counter, but it is easier to understand with two of them
Check, whether the closing Counter is smaller than the opening (if not, so you could break the Loop, cause it is not mathematical)
After the end of the loop you must check, whether there were an error in the Loop or both Counters are not equal. In both cases the string is not "mathematical", otherwise it is.
I could do it in your code, but I think, you should do THIS alone. Most of These things you have already done, but it seems as you did not completly understand, what you have done and have to do.
I have a code that takes n inputs and computes the shortest distance between them without ever revisiting the same point twice. I think this the same as the Hamiltonian Path problem.
My code takes n addresses as inputs and iterates over all possible combinations without repeating. Right now I have the 'brute force' method where each loop grabs the start/end location, calcs distance, excludes replicated locations, then adds paths that only visit every point to my Df. Since there are 5 locations, the 5th nested for loop block write the sequence and distance to the DF.
DF with values:
Index Type start_point
0 Start (38.9028613352942, -121.339977998194)
1 A (38.8882610961556, -121.297759)
2 B (38.9017768701178, -121.328815149117)
3 C (38.902337877551, -121.273244306122)
4 D (38.8627754142291, -121.313577618114)
5 E (38.882338375, -121.277366625)
My code goes like:
from geopy.distance import vincenty
import pandas as pd
master=pd.DataFrame()
master['locations']=''
master['distance']=''
n=0
df1a=source[source.Type != source.loc[0,'Type']]
df1a=df1a.reset_index(drop=True)
for i1a in df1a.index:
i1_master=vincenty(source.loc[0,'start_point'],df1a.loc[i1a,'start_point']).mile s
for i2 in df1a.index:
df2a=df1a[df1a.Type != df1a.loc[i2,'Type']]
df2a=df2a.reset_index(drop=True)
for i2a in df2a.index:
if df1a.loc[i1a,'Type']==df2a.loc[i2a,'Type']:
break
else:
i2_master=i1_master+vincenty(df1a.loc[i1a,'start_point'],df2a.loc[i2a,'start_point']).miles
for i3 in df2a.index:
df3a=df2a[df2a.Type != df2a.loc[i3,'Type']]
df3a=df3a.reset_index(drop=True)
for i3a in df3a.index:
if df1a.loc[i1a,'Type']==df3a.loc[i3a,'Type']:
break
if df2a.loc[i2a,'Type']==df3a.loc[i3a,'Type']:
break
else:
i3_master=i2_master+vincenty(df2a.loc[i2a,'start_point'],df3a.loc[i3a,'start_point']).miles
for i4 in df3a.index:
df4a=df3a[df3a.Type != df3a.loc[i4,'Type']]
df4a=df4a.reset_index(drop=True)
for i4a in df4a.index:
if df1a.loc[i1a,'Type']==df4a.loc[i4a,'Type']:
break
if df2a.loc[i2a,'Type']==df4a.loc[i4a,'Type']:
break
if df3a.loc[i3a,'Type']==df4a.loc[i4a,'Type']:
break
else:
i4_master=i3_master+vincenty(df3a.loc[i3a,'start_point'],df4a.loc[i4a,'start_point']).miles
for i5 in df4a.index:
df5a=df4a[df4a.Type != df4a.loc[i5,'Type']]
df5a=df5a.reset_index(drop=True)
for i5a in df5a.index:
if df1a.loc[i1a,'Type']==df5a.loc[i5a,'Type']:
break
if df2a.loc[i2a,'Type']==df5a.loc[i5a,'Type']:
break
if df3a.loc[i3a,'Type']==df5a.loc[i5a,'Type']:
break
if df4a.loc[i4a,'Type']==df5a.loc[i5a,'Type']:
break
if df4a.loc[i4a,'Type']==df5a.loc[i5a,'Type']:
break
else:
i5_master=i4_master+vincenty(df4a.loc[i4a,'start_point'],df5a.loc[i5a,'start_point']).miles
#This loop is special, it calculates distance back to the start.
for i5 in df4a.index:
df5a=df4a[df4a.Type != df4a.loc[i5,'Type']]
df5a=df5a.reset_index(drop=True)
for i5a in df5a.index:
master.loc[n,'locations']=source.loc[0,'Type']+'_'+df1a.loc[i1a,'Type']+'_'+df2a.loc[i2a,'Type']+'_'+df3a.loc[i3a,'Type']+'_'+df4a.loc[i4a,'Type']+'_'+df5a.loc[i5a,'Type']+'_'+source.loc[0,'Type']
master.loc[n,'distance']=i5_master+vincenty(df5a.loc[i5a,'start_point'],df1a.loc[0,'start_point']).miles
n=n+1
Is there a way to use recursive code to build this structure? As a Chemical Engineer I am out of my league ;)
For example: The number of if statements (to check for sequentially repeated start_points ) increases in each section and changes in terms of arguments.
Any other pointers are appreciated.
This is a special case of the Travelling Salesman Problem, which is perhaps the most famous example of an intractable problem - one which cannot be solved in sensible time for any sizable input. Using recursion on this would take O(N!) memory and time, which can only be viable (even on modern systems) for small numbers of inputs (< 10 maybe).
If you are willing to sacrifice perfect solutions for the sake of resources, check out some sub-optimal heuristic solutions here: http://www.math.tamu.edu/~mpilant/math167/Notes/Chapter2.pdf
It prints diga and digb but doesnt work with c! Any help? It's supposed to be a Denary to Binary converter but only 1-64, once i've cracked the code will increase this! Thanks so much
denaryno=int(input("Write a number from 1-64 "))
if 64%denaryno > 0:
diga=0
remaindera=(64%denaryno)
if 32/denaryno<1:
digb=1
remainderb=(denaryno%32)
else:
digb =0
if 16/remainderb<1:
digc=1
remainderc=(denaryno%16)
else:
digc=0
if 8/remainderc<1:
digd=1
remainderd=(denaryno%8)
else:
digd=0
if 4/remainderd<1:
dige=1
remaindere=(denary%4)
else:
dige=0
if 2/remaindere<1:
digf=1
remainderf=(denary%2)
else:
digf=0
if 1/remainderf<1:
digg=1
remainderg=(denary%1)
else:
digg=0
print (str(diga)+str(digb))
You only set digc in one of the top if/else statement. If 32/denaryno<1 is True, you don't set digc at all.
Set digc at the top of the function (to 0 or whatever else you want it to be). This applies to all the digit variables, digd, dige, etc.
What you really should do, instead, is use a list of digits, and append either a 0 or a 1 to that list every time you divide the number by a factor.
You may want to take a look at the divmod() function; it returns both the quotient and the remainder. You could also do with some looping here to slash the number of if statements needed here:
number = int(input("Write a number from 1-64 "))
digits = []
factor = 64
while number:
quotient, number = divmod(number, factor)
digits.append(quotient)
factor //= 2
print(''.join(map(str, digits)))
Wow that was a lot of work, you don't have to do all that.
def bin_convert(x, count=8):
return "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))
here are the functions comprising this one from easy->important
str() returns a string
range() is a way to get a list from 1 number to another. Written like this range(count-1, -1, -1) counts backwards.
"".join() is a way to take an iterable and put the pieces together.
map() is a way to take a function and apply it to an iterable.
lambda is a way to write a function in 1 line. I was being lazy and could have written another def func_name(y) and it would have worked just as well.
>> is a way to shift bits. (which I believe understanding this one is the key component to understanding your problem)