Circular Walk in a string - string

You are given a string in which 'A' means you can move 1 step clockwise, 'C' means you can move one step anticlockwise and '?' means you can move one step either clockwise or anti clockwise. So Given a string find maximum distance from inital position at any given point of time.
for eg:-
input : - AACC?CC
output :- 3
explanation : - if ? is replaced with C then max distance will become 3
optimal approach to solve this problem?

str = "AACC?CC"
count = 0
extra = 0
for i in str:
if i == 'A':
count -= 1
elif i == 'C':
count += 1
else:
extra += 1
dist = abs(count) + extra
if count < 0:
print "AntiClockwise:",
else:
print "ClockWise:",
print dist
Just try this out. however 'A', 'C' movements must be taken place, so you should go left and right. the '?'is optional. You can just count How many '?' are there and add it to the final answer.

Related

The algorithm receives a natural number N > 1 as input and builds a new number R from it as follows:

Python.
It's a problem:
The algorithm receives a natural number N > 1 as input and builds a new number R from it as follows:
We translate the number N into binary notation.
Invert all bits of the number except the first one.
Convert to decimal notation.
Add the result with the original number N.
The resulting number is the desired number R. Indicate the smallest odd number N for which the result of this algorithm is greater than 310. In your answer, write this number in decimal notation.
This is my solution:
for n in range(2, 10000):
s = bin(n)[2:]
for i in range(len(s)):
if s[i+1] == 0:
s[i] = '1'
else:
s[i] = 'k'
for i in range(len(s)):
if s[i] == 'k':
s[i] = '0'
h = int(s, 2)
r = h + n
if n % 2 == 1 and r > 310:
print(n)
break
So it doesn't work and i dont know why. I am now preparing for the exam, so I would be grateful if you could explain the reason to me
the bin function returns a string and my idea is to go through the binary elements of this string, starting from the second element, to replace 0 with 1, and 1 with k. Then iterate over the elements of a new line again and replace k with 0
Took me longer than I expected but feels good.
Comments might make it look chaotic but will make it easily understandable.
#since N is supposed to be odd and >1 the loop is being run from 3
for N in range(3, 10000,2):
#appending binary numbers to the list bin_li
bin_li=[]
bin_li.append((bin(N)[2:]))
for i in bin_li:
#print("bin_li item :",i)
#storing 1st digit to be escaped in j
j=i[:1]
#reversing the digits
for k in i[1:]:
if k=='0':
#putting together the digits after reversing
j=j+'1'
else:
j=j+'0'
#print("reversed item :",j) #note first digit is escaped
#converting back to decimal
dec=int(j,2)
R=dec+N
#print("current sum:---------" ,R)
if R > 310:
print("The number N :",N)
print("The reversed binary number:",dec)
print("Sum :",R)
break
#break will only break the inner loop
# for reference https://www.geeksforgeeks.org/how-to-break-out-of-multiple-loops-in-python/
else:
continue
break

Iterate a list to find a specific order of letters

I am working on this problem: https://dmoj.ca/problem/coci18c3p1
Basically, iterate a list of capital letters and find how many times the letters 'H', 'O', 'N' and 'I',
in that exact order, there are.
Anything in between the first 'H' and the first 'O' gets ignored, even if it one of the target letters. Same for any letters in between the 'O' and the 'N'. And so on.
You just go from start to finish once. No combinations, permutations, etc.
Find the first 'H'. Then the first 'O', after the previous 'H'. Then the next 'N' after the previous 'O'.
Etc.
They run a bunch of unit tests to make sure your code passes.
They do NOT tell you or show you the unit tests. Just the results.
My code cleanly passes the first six, but fails the last five.
I'm just looking to see if anybody can find a flaw in my logic and point it out to me.
I can't make it fail.
Samples:
input: HHHHOOOONNNNIIII
output: 1
input: PROHODNIHODNIK
output: 2
input: HONIIONIHHONI
output: 2
input: HONIHONIHONI
output: 3
input: HOHONINI
output: 1
input: HIONHION
output: 1
TLE means time limit exceeded. My code is to slow?
My code:
# DMOJ problem coci18c3p1
lst = list(input().upper())
if not 1 <= len(lst) <= 100000:
print(0)
raise SystemExit
filtered = [x for x in lst if x in 'HONI']
# print(filtered)
letters = 'H', 'O', 'N', 'I'
if any(i not in filtered for i in letters):
print(0)
raise SystemExit
count = 0
while True:
if 'H' not in filtered:
break
h = filtered.index("H")
count += 1
if h != 0:
filtered = filtered[h:]
if 'O' not in filtered:
break
o = filtered.index("O")
count += 1
if o != 0:
filtered = filtered[o:]
if 'N' not in filtered:
break
n = filtered.index("N")
count += 1
if n != 0:
filtered = filtered[n:]
if 'I' not in filtered:
break
i = filtered.index("I")
count += 1
if i != 0:
filtered = filtered[i:]
print(count//4)
Yes, TLE means the tests are failing because your solution is not fast enough. Indeed, your solution makes many passes over the input. First, I'll go over the improvements you can make to your approach.
Instead of using a slice to create a new list, you can control the starting position of the search for index(). The second argument of that function is the index for the start of the search.
Instead of checking if the character is in the list, rely on catching the exception index() raises. This will avoid a redundant search (checking if the character exists requires a search).
The above may improve your time a bit, but it may not be good enough. It's actually possible to find the solution in a single pass. The basic idea is to keep track of which character you need to find next. For example, if you already found "H", then you need to look for "O". Once you have found "I", you can increment the count, and then start looking for "H" again.
# No need to convert the input into a list; a string can be indexed directly.
string = input().upper()
count = 0
targets = ["H", "O", "N", "I"]
target = 0
for i in range(len(string)):
# Check if the current character matches the target.
if string[i] == targets[target]:
# There is a match. Move to the next target.
# if the end is reached, cycle back to the first target (H).
target = (target + 1) % len(targets)
# Check if the last target has been found.
if string[i] == targets[-1]:
count += 1
print(count)

pythonic way to convert character position to terminal offset as printed

I am wondering if there is a "pythonic" way to from the a character position in a string to the terminal offset that character will be printed at (i.e including tabs).
For example take the following three strings:
$> python3
>>> print("+\tabc")
+ abc
>>> print("\tabc")
abc
>>> print(" abc")
abc
They are three difference strings, with three different character counts preceding the "abc", but the position of 'a' is different each time.
The only solution I have that works "well enough" is
def get_offset(s, c):
pos = s.find(c)
if pos == -1:
return -1
tablen = 0
ntabs = 0
for i in range(0, pos):
if line[i] == '\t':
tablen += (TABLEN - (i % TABLEN))
ntabs += 1
offset = tablen + (pos - ntabs)
return offset
I am wondering is there a more pythonic way to do this?
Not really.
Because python doesn't know about how its output will be rendered, it cannot tell you the offset resulting from tab characters. From python's point of view, a tab is a character like any other.

Problem with Python Code and the Functions in it

I have a Problem, I have to solve a task in Python and I dont know how to do it. The task is to define a function number_of_vowels, where the output should be the Number of vowels in a Word. With this function I have to write anotherone, many_vowels thats working with a list an a Number and where the number says how many vowels have to be at least in a word to be appended to the result list and then I have to append this Word. Thanks to everybody helping me ;D.
here is the code:
Wort = "parameter"
def number_of_vowels(Word):
result = 0
counter0 = 0
while result < 20:
if Word[counter0] == 'a' or 'e' or 'i' or 'o' or 'u':
result = result + 1
counter0 = counter0 + 1
else:
counter0 = counter0 + 1
return result
Words = []
counter1 = 0
def many_vowels(List , number):
if number_of_vowels(List[counter1]) < number:
counter1 + 1
else:
Words.append(List[counter1])
counter1 + 1
return Words
This code just gives me the answer to the letter a and not to the other vowels. For
print(number_of_vowels(Wort))
the output is: 1
but there are 4 vowels in this word
it also says: line 21, in many_vowels
IndexError: string index out of range
You're trying to call a function with wrong brackets. Function call should use round ones.
Try changing number_of_vowels[List[counter1]] with number_of_vowels(List[counter1])
This code contains some errors:
Calling for function should be using round brackets: number_of_vowels(List[counter1]) instead of number_of_vowels[List[counter1]]
doing result + 1 won't change value of the variable result, since you did not put the calculation result in the variable. use result = result + 1 (same for counters)
in number_of_vowels function, you want to scan the whole word? cause you did not use any loop, so it currently looking only at the first letter. Secondly, you put the compression in result and then add 1 to it. I'm not really sure why
edit:
Word = "parameter"
def number_of_vowels(Word):
result = 0
counter0 = 0
for index, letter in enumerate(Word):
if letter == 'a' or letter == 'e' or letter == 'i' or letter == 'o' or letter == 'u':
result = result + 1
return result
Words = []
counter1 = 0
def many_vowels(List_name , number):
for index, item in enumerate (List_name):
if number_of_vowels(item) >= number:
Words.append(item)
return Words

Lexicographically smallest palindrome in python

I found this question to be interesting and I would like to share this here and find reasonably good codes, specific to py :
Given a string S having characters from English alphabets ['a' - 'z'] and '.' as the special character (without quotes).
Write a program to construct the lexicographically smallest palindrome by filling each of the faded character ('.') with a lower case alphabet.
Definition:
The smallest lexicographical order is an order relation where string s is smaller than t, given the first character of s (s1 ) is smaller than the first character of t (t1 ), or in case they
are equivalent, the second character, etc.
For example : "aaabbb" is smaller than "aaac" because although the first three characters
are equal, the fourth character b is smaller than the fourth character c.
Input Format:
String S
Output Format:
Print lexicographically smallest palindrome after filling each '.' character, if it
possible to construct one. Print -1 otherwise.
Example-1
Input:
a.ba
Output:
abba
Example-2:
Input:
a.b
Output:
-1
Explanation:
In example 1, you can create a palindrome by filling the '.' character by 'b'.
In example 2, it is not possible to make the string s a palindrome.
You can't just copy paste questions from NPTEL assignments and ask them here without even trying!
Anyways,since the "code" is your only concern,try copy pasting the lines below:
word = input()
length = len(word)
def SmallestPalindrome(word, length):
i = 0
j = length - 1
word = list(word) #creating a list from the input word
while (i <= j):
if (word[i] == word[j] == '.'):
word[i] = word[j] = 'a'
elif word[i] != word[j]:
if (word[i] == '.'):
word[i] = word[j]
elif (word[j] == '.'):
word[j] = word[i]
else: # worst case situation when palindrome condition is not met
return -1
i = i + 1
j = j - 1
return "".join(word) # to turn the list back to a string
print(SmallestPalindrome(word, length)) #Print the output of your function
s=input()
s=list(s)
n=len(s)
j=n
c=0
for i in range(n):
j=j-1
if((s[i]==s[j]) and (i==j) and (s[i]=='.' and s[j]=='.')):
s[i]='a'
s[j]='a'
elif(s[i]==s[j]):
continue
elif((s[i]!=s[j]) and (i!=j) and (s[i]=='.' or s[j]=='.')):
if(s[i]!='.'):
s[j]=s[i]
else:
s[i]=s[j]
elif((i==j) and (s[i]=='.')):
s[i]=a
else:
c=c+1
break
if(c<1):
for k in s:
print(k,end="")
else:print("-1")

Resources