Find the alphabet present at that location and determine the no of occurrences of the same alphabet preceding that location n.
Input:
length = 9
string = "abababbsa"
n = 9
Output:
3
Explanation:
Find the alphabet at nth position 9 i.e a. Count all the occurrences before that index which is 3.
Code:
length = int(input())
string = list(input())
n = int(input())
str1 = string[n-1]
print(string[0:n-1].count(str1))
The above code gives TLE. How can I optimize this?
Well It becomes easy if you use re ( regex )
import re
length = int(input())
my_string = input('Enter your string')
n = int(input())
print(len(re.findall(my_string[n-1],my_string[:n-1])))
So what is happening is we are finding all occurences of the character before n by slicing the string at n-1 and just getting the length of the list ( all occurences ).
One way to optimize is to use string as usual in spite of converting it into a list:
string = input()
The complexity would now be O(n) where n is the input position, whereas, in your
case, because the string was explicitly converted to list, the complexity was
O(length of the string).
Related
i just started using python and im a noob.
this is an example of the string i have to work with "--+-+++----------------+-+"
The program needs to find whats the longest ++ "chain", so how many times does + appear, when they are next to eachother. I dont really know how to explain this, but i need it to find that chain of 3 + smybols, so i can print that the longest + chain contains 3 + symbols.
a = "--+-+++----------------+-+"
count = 0
most = 0
for x in range(len(a)):
if a[x] == "+":
count+=1
else:
count = 0
if count > most:
most = count
print(f"longest + chain includes {most} symbols")
there might be a better way but it's more self explanatory
Try this. It uses regular expressions and a list comprehension, so you may need to read about them.
But the idea is to find all the + chains, calculate their lengths and get the maximum length
import re
s = '+++----------------+-+'
occurs = re.findall('\++',s)
print(max([len(i) for i in occurs]))
Output:
3
You can use a regular expression to specify "one or more + characters". The character for specifying this kind of repetition in a regex is itself +, so to specify the actual + character you have to escape it.
haystack = "--+-+++----------------+-+"
needle = re.compile(r"\++")
Now we can use findall to find all the occurrences of this pattern in the original string, and max to find the longest of these.
longest = max(len(x) for x in needle.findall(haystack))
If you instead need the position of the longest sequence in the target string, you can use:
pos = haystack.index(max(needle.findall(haystack), key=len))
A simple solution is to iterate over the string one character at a time. When the character is the same as the last add one to a counter and each time the character is different to the previous the count can be restarted.
s = "--+-+++----------------+-+"
p = s[0]
max, count = 0
for c in s:
if c == p:
count = count + 1
else:
count = 0
if count > max:
max = count
p = c
s is the string, c is the character being checked, p is previous character, count is the counter, and max is the highest found value,
If the only other character in your string is a minus sign, you can split the string on the minus sign and get maximum length of the resulting substrings:
a = "--+-+++----------------+-+"
r = max(map(len,a.split('-')))
print(r) # 3
If I have a string such as:
string = 'Output1[10].mystruct.MyArray[4].mybool'
what I want to do is search the string for the number in the array, decrement by 1 and then replace the found number with my decremented number.
What I have tried:
import string
import re
string = 'Output1[10].mystruct.MyArray[4].mybool'
pattern = r'\[(\d+)\]'
num = re.findall(pattern, string)
So, I can get a list of the numbers, convert to integers but I don't know how to use re.sub to search the string to replace, it should be considered that there might be multiple arrays. If anyone is expert enough to do that, help much appreciated.
Cheers
I don't undestand a thing... If there is more than 1 array, do you want to decrease the number in all arrays? or just in 1 of them?
If you want to decrease in all arrays, you can do this:
import re
string = 'Output1[10].mystruct.MyArray[4].mybool'
pattern = r'\[(\d+)\]'
num = re.findall(pattern, string)
num = [int(elem) for elem in num]
num.sort()
for elem in num:
aux = elem - 1
string = string.replace(str(elem), str(aux))
If you want to decrease just the first array, you can do this
import string
import re
string = 'Output1[10].mystruct.MyArray[4].mybool'
pattern = r'\[(\d+)\]'
num = re.findall(pattern, string)
new_num = int(num[0]) - 1
string = string.replace(num[0], str(new_num), 1)
Thanks to #João Castilho for his answer, based on this I changed it slightly to work exactly how I want:
import string
import re
string = 'Output1[2].mystruct.MyArray[2].mybool'
pattern = r'\[(\d+)\]'
num = re.findall(pattern, string)
num = [int(elem) for elem in set(num)]
num.sort()
for elem in num:
aux = elem - 1
string = string.replace('[%d]'% elem, '[%d]'% aux)
print(string)
This will now replace any number between brackets with the decremented value in all of the conditions that the numbers may occur.
Cheers
ice.
input: ['baNaNa', 7] # string and step size
required output : 'utGtGt' # every character of string shifted backwards by step size
import ast
in_string = input()
lis = ast.literal_eval(in_string)
st = lis[0]
step = lis[1]
alphabets = 'abcdefghijklmnopqrstuvwxyz'
password = ''
for letter in st:
if letter in alphabets:
index_val = alphabets.index(letter) - (step)
password += alphabets[index_val]
print(password)
Output i am getting is 'utgtgt'. I want 'utGtGt'. Help on this would be appreciated a lot.
The string module has methods to create a transformation dictionary and a translate method to do exactly what you want:
st = "baNaNa"
step = 7
alphabets = 'abcdefghijklmnopqrstuvwxyz'
alph2 = alphabets.upper()
# lower case translation table
t = str.maketrans(alphabets, alphabets[-step:]+alphabets[:-step])
# upper case translation table
t2 = str.maketrans(alph2, alph2[-step:]+alph2[:-step])
# merge both translation tables
t.update(t2)
print(st.translate(t))
Output:
utGtGt
You give it the original string and an equal long string to map letters to and apply that dictionary using str.translate(dictionary).
The sliced strings equate to:
print(alphabets)
print(alphabets[-step:]+alphabets[:-step])
abcdefghijklmnopqrstuvwxyz
tuvwxyzabcdefghijklmnopqrs
which is what your step is for.
See Understanding slice notation if you never saw string slicing in use.
by processing each charater and checking it's cardinal no and making calculation accordingly help you to reach the result
def func(string, size):
if size%26==0:
size=26
else:
size=size%26
new_str = ''
for char in string:
if char.isupper():
if ord(char)-size<ord('A'):
new_str+=chr(ord(char)-size+26)
else:
new_str+=chr(ord(char)-size)
elif char.islower():
if ord(char)-size<ord('a'):
new_str+=chr(ord(char)-size+26)
else:
new_str+=chr(ord(char)-size)
return new_str
res =func('baNaNa', 7)
print(res)
# output utGtGt
Here's a simple solution that makes use of the % modulo operator to shift letters backwards.
It basically collects all of the letters in a reverse index lookup dictionary, so looking up letter positions is O(1) instead of using list.index(), which is linear O(N) lookups.
Then it goes through each letter and calculates the shift value from the letter index e.g. for the letter a with a shift value of 7, the calculation will be (0 - 7) % 26, which will give 19, the position of u.
Then once you have this shift value, convert it to uppercase or lowercase depending on the case of the original letter.
At the end we just str.join() the result list into one string. This is more efficient than doing += to join strings.
Demo:
from string import ascii_lowercase
def letter_backwards_shift(word, shift):
letter_lookups = {letter: idx for idx, letter in enumerate(ascii_lowercase)}
alphabet = list(letter_lookups)
result = []
for letter in word:
idx = letter_lookups[letter.lower()]
shifted_letter = alphabet[(idx - shift) % len(alphabet)]
if letter.isupper():
result.append(shifted_letter.upper())
else:
result.append(shifted_letter.lower())
return ''.join(result)
Output:
>>> letter_backwards_shift('baNaNa', 7)
utGtGt
I would probably go with #Patrick Artner's pythonic solution. I just showed the above implementation as a learning exercise :-).
I am wondering how to randomly change n characters in a string, e.g.
orig = 'hello'
mod = 'halle'
that I want to randomly select two positions (orig[1] and orig[4]) in the string, and replace the chars in the positions of the original string (hello) with randomly selected chars (a and e here), results in a new string halle.
import random
import string
orig='hello'
char1=random.choice(string.ascii_lowercase) #random character1
char2=random.choice(string.ascii_lowercase) #random character2
while char1 == char2: # #check if both char are equal
char2=random.choice(string.ascii_lowercase)
ran_pos1 = random.randint(0,len(orig)-1) #random index1
ran_pos2 = random.randint(0,len(orig)-1) #random index2
while ran_pos1 == ran_pos2: #check if both pos are equal
ran_pos2 = random.randint(0,len(orig)-1)
orig_list = list(orig)
orig_list[ran_pos1]=char1
orig_list[ran_pos2]=char2
mod = ''.join(orig_list)
print(mod)
If you just want to change the different characters at random index in a string the below function will help. This script will ask for the input string(i.e., word) and the total places/ indexes ((i.e.,)value or 'n' places) you need to change with random characters, and this will print the modified string as needed.
import random
import string
# Method to change N characters from a string with random characters.
def randomlyChangeNChar(word, value):
length = len(word)
word = list(word)
# This will select the two distinct index for us to replace
k = random.sample(range(0,length),value)
for index in k:
# This will replace the characters at the specified index with
# the generated characters
word[index] = random.choice(string.ascii_lowercase)
# Finally print the string in the modified format.
print("" . join(word))
# Get the string to be modified
string_to_modify = raw_input("Enter the string to be replaced...\n")
# get the number of places that needed to be randomly replaced
total_places = input("Enter the total places that needs to be modified...\n")
# Function to replace 'n' characters at random
randomlyChangeNChar(string_to_modify, total_places)
Output
Enter the string to be replaced...
Hello
Enter the total places that needs to be modified...
3
Hcado
Given a number number such that its digits are grouped into parts of length n (default value of n is 3) where each group represents some ascii value, I want to convert number into a string of those ascii characters. For example:
n number Output
==================================
3 70 F
3 65066066065 ABBA
4 65006600660065 ABBA
Note that there is no leading 0 in number, so the first ascii value will not necessarily be represented with n digits.
My current code looks like this:
def number_to_string(number, n=3):
number = str(number)
segment = []
while number:
segment.append(number[:n])
number = number[n:]
return str(''.join('{:0>{}}'.format(chr(segment), n) for segment in number))
Expected outputs:
number_to_string(70)
'F'
number_to_string(65066066065)
'ABBA'
number_to_string(65006600660065, n=4)
'ABBA'
My current code however returns an empty string. For example, instead of 'F' it returns ' '. Any reason why this is? Thank you!
P.S.:
I'm wanting to reverse the process of this question, i.e. turn an integer into a string based on the ascii values of each character (number) in the string. But reading that question is not a requirement to answer this one.
Try this:
import re
def number_to_string(num, n=3):
num_str = str(num)
if len(num_str) < n:
num_str = '0' * (n-len(num_str)) + num_str
elif len(num_str) % n != 0:
num_str = '0'*(n-len(num_str)%n) + num_str
print(num_str)
chars = re.findall('.'*n, num_str)
l = [chr(int(i)) for i in chars]
return ''.join(l)
First pad the given number (converted into string) with required number of zeros, so that it can be evenly split into equal number of characters each. Then using re split the string into segments of size n. Finally convert each chunk into character using chr, and then join them using join.
def numToStr(inp):
"""Take a number and make a sequence of bytes in a string"""
out=""
while inp!=0:
out=chr(inp & 255)+out
inp=inp>>8
print "num2string:", out
return out
does this help?
Is this what you want?
def num_to_string(num, leng):
string = ""
for i in range(0,len(str(num)),leng):
n = str(num)[i:i+2]
string += chr(int(n))
print string
Output:
>>> ================================ RESTART ================================
>>>
>>> num_to_string(650065006600,4)
AAB
>>> num_to_string(650650660,3)
AAB
>>> num_to_string(656566,2)
AAB
>>>
You can just append \x to number as this prints 'p':
print '\x70'