Number of Occurences - python-3.x

I am new to Python and trying to use it for competitive programming.
This is the question:
You are given an unsorted array of characters 'n' and a character 'x'. You have to find the number of times x occurs in character array
Input format:
First line contains an integer T, number of test cases. Then follows T test cases. Each test case consists of two lines. First line contains N, length of the array. Second lines contains N space separated characters. Example
Input
2
4
a b c d
5
a b x c d
Output
0
1
In c++ I know we start like this:
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int arr[n];
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
...
How do we do the same in python?
This is my code:
t = int(input())
while t:
n = int(input())
arr = [x for x in raw_input().split()]
res = 0
for i in arr:
if i == 'x':
res += 1
t -=1
print(res)
Getting runtime error for this
I think the issue is with how I'm taking inputs to run test cases but not sure

#juanpa arrivillaga answered your question, but it may help you understand that answer better to see an actual implementation.
Example:
from io import StringIO
io_buffer = """2
4
abcd
5
abxcd
"""
with StringIO(io_buffer) as buffer:
num_test_cases = int(buffer.readline())
for _ in range(num_test_cases):
num_chars = int(buffer.readline())
char_line = buffer.readline().strip()
# This is the important part - everything else is overhead
x_count = char_line.count("x")
print(f"character string: {char_line:>5}, length: {num_chars}, x count: {x_count}")
Output:
character string: abcd, length: 4, x count: 0
character string: abxcd, length: 5, x count: 1

Related

How to multiply numbers of a string by its position in the string

I am a newby on this. I am trying to multiply every single element of the string below ('10010010') by 2 to the power of the position of the element in the string and sum all the multiplications. So far I am trying to do it like this, but I cannot achieve to figure out how to do it.
def decodingvalue(str1):
# read each character in input string
for ch in str1:
q=sum(2^(ch-1)*ch.isdigit())
return q
Function call
print(decodingvalue('10010010'))
Thanks a lot for your help!
I think you trying convert binary to int. If that so you can do the following:
str = '101110101'
#length is counted 1 to n, decrementing by 1 changes to 0-(n-1)
c = len(str)-1
q = 0
for ch in str:
print(q,c,ch)
q = q + (int(ch)*(2**c)) #in python power is '**'
c = c-1
if c == -1:
break
print(q)
you can of course optimize it and finish in fewer lines.
In python ^ (caret operator) is a Bitwise XOR.

Check how many consecutive times appear in a string

I want to to display a number or an alphabet which appears mostly
consecutive in a given string or numbers or both.
Example:
s= 'aabskeeebadeeee'
output: e appears 4 consecutive times
I thought about set the string then and for each element loop the string to check if equal with element set element if so count =+1 and check if next to it is not equal add counter value to list with same index as in set, if is add counter value to li list if value is bigger than existing.
The problem is error index out or range although I think I am watching it.
s = 'aabskeeebadeeee'
c = 0
t = list(set(s)) # list of characters in s
li=[0,0,0,0,0,0] # list for counted repeats
print(t)
for x in t:
h = t.index(x)
for index, i in enumerate(s):
maximus = len(s)
if i == x:
c += 1
if index < maximus:
if s[index +1] != x: # if next element is not x
if c > li[h]: #update c if bigger than existing
li[h] = c
c = 0
else:
if c > li[h]:
li[h] = c
for i in t:
n = t.index(i)
print(i,li[n])
print(f'{s[li.index(max(li))]} appears {max(li)} consecutive times')
Here is an O(n) time, O(1) space solution, that breaks ties by returning the earlier seen character:
def get_longest_consecutive_ch(s):
count = max_count = 0
longest_consecutive_ch = previous_ch = None
for ch in s:
if ch == previous_ch:
count += 1
else:
previous_ch = ch
count = 1
if count > max_count:
max_count = count
longest_consecutive_ch = ch
return longest_consecutive_ch, max_count
s = 'aabskeeebadeeee'
longest_consecutive_ch, count = get_longest_consecutive_ch(s)
print(f'{longest_consecutive_ch} appears {count} consecutive times in {s}')
Output:
e appears 4 consecutive times in aabskeeebadeeee
Regex offers a concise solution here:
inp = "aabskeeebadeeee"
matches = [m.group(0) for m in re.finditer(r'([a-z])\1*', inp)]
print(matches)
matches.sort(key=len, reverse=True)
print(matches[0])
This prints:
['aa', 'b', 's', 'k', 'eee', 'b', 'a', 'd', 'eeee']
eeee
The strategy here is to find all islands of similar characters using re.finditer with the regex pattern ([a-z])\1*. Then, we sort the resulting list descending by length to find the longest sequence.
Alternatively, you can leverage the power of itertools.groupby() to approach this type of problem (for quick counting for similar items in groups. [Note, this can be applied to some broader cases, eg. numbers]
from itertools import groupby
>>> char_counts = [str(len(list(g)))+k for k, g in groupby(s)]
>>> char_counts
['2a', '1b', '1s', '1k', '3e', '1b', '1a', '1d', '4e']
>>> max(char_counts)
'4e'
# you can continue to do the rest of splitting, or printing for your needs...
>>> ans = '4e' # example
>>> print(f' the most frequent character is {ans[-1]}, it appears {ans[:-1]} ')
Output:
the most frequent character is e, it appears 4
This answer was posted as an edit to the question Check how many consecutive times appear in a string by the OP Ziggy Witkowski under CC BY-SA 4.0.
I did not want to use any libraries.
s = 'aabskaaaabadcccc'
lil = tuple(set(s)) # Set a characters in s to remove duplicates and
then make a tuple
li=[0,0,0,0,0,0] # list for counted repeats, the index of number
repeats for character
# will be equal to index of its character in a tuple
for i in lil: #iter over tuple of letters
c = 0 #counter
h= lil.index(i) #take an index
for letter in s: #iterate ove the string characters
if letter == i: # check if equal with character from tuple
c += 1 # if equal Counter +1
if c > li[lil.index(letter)]: # Updated the counter if present is bigger than the one stored.
li[lil.index(letter)] = c
else:
c=0
continue
m = max(li)
for index, j in enumerate(li): #Check if the are
characters with same max value
if li[index] == m:
print(f'{lil[index]} appears {m} consecutive times')
Output:
c appears 4 consecutive times
a appears 4 consecutive times

Issue with ASCii in Python3

I am trying to convert a string of varchar to ascii. Then i'm trying to make it so any number that's not 3 digits has a 0 in front of it. then i'm trying to add a 1 to the very beginning of the string and then i'm trying to make it a large number that I can apply math to it.
I've tried a lot of different coding techniques. The closest I've gotten is below:
s = 'Ak'
for c in s:
mgk = (''.join(str(ord(c)) for c in s))
num = [mgk]
var = 1
num.insert(0, var)
mgc = lambda num: int(''.join(str(i) for i in num))
num = mgc(num)
print(num)
With this code I get the output: 165107
It's almost doing exactly what I need to do but it's taking out the 0 from the ord(A) which is 65. I want it to be 165. everything else seems to be working great. I'm using '%03d'% to insert the 0.
How I want it to work is:
Get the ord() value from a string of numbers and letters.
if the ord() value is less than 100 (ex: A = 65, add a 0 to make it a 3 digit number)
take the ord() values and combine them into 1 number. 0 needs to stay in from of 65. then add a one to the list. so basically the output will look like:
1065107
I want to make sure I can take that number and apply math to it.
I have this code too:
s = 'Ak'
for c in s:
s = ord(c)
s = '%03d'%s
mgk = (''.join(str(s)))
s = [mgk]
var = 1
s.insert(0, var)
mgc = lambda s: int(''.join(str(i) for i in s))
s = mgc(s)
print(s)
but then it counts each letter as its own element and it will not combine them and I only want the one in front of the very first number.
When the number is converted to an integer, it
Is this what you want? I am kinda confused:
a = 'Ak'
result = '1' + ''.join(str(f'{ord(char):03d}') for char in a)
print(result) # 1065107
# to make it a number just do:
my_int = int(result)

Multiplication Python Script giving wrong output

The Code below gives an answer for almost any number I have tested with, even a 64 digits *64 digits. But when tried with
a = 123456
b = 123456
The final answer is negative.
Up until
a = 12345
b = 12345
The answer is correct.
Not sure where this is going wrong. I am relatively new to python so is there something I am missing out?
import numpy as np
a = int(input("Enter Number 1: "))
b = int(input("Enter Number 2: "))
c = 1
pos_nums = []
while b != 0:
z = b % 10
pos_nums.append(z *c)
b = b // 10
c = c*10
pos_num = np.array([pos_nums])
multiply = pos_num *a
add = np.sum(multiply)
print(add)
I don't know why numpy is playing up, but something like this appears to work, and does the same thing.
All I've done is removed the conversion to a numpy array. Now when you multiply pos_num it essentially makes a copies of it into one list. sum counts the total value of the list, which has a amounts of b stored in it.
Hope this works for you :)
a = int(input("Enter Number 1: "))
b = int(input("Enter Number 2: "))
c = 1
pos_nums = []
while b != 0:
z = b % 10
pos_nums.append(z *c)
b = b // 10
c = c*10
#pos_num = np.array(pos_nums)
pos_num = pos_nums
multiply = pos_num *a
add = sum(multiply)
print(add)
Output:
Enter Number 1: 123456
Enter Number 2: 123456
15241383936
numpy can't guess your next move!
you see when you define a numpy array it will assume a type for the array (like np.int16) and its not will not change unless you multiply it into something with other formats
what happend here?
you have multiplied a dtype=np.int32 array into an int in line:
multiply = pos_num *a
the result will be another np.int32 array (you can see that with print(multiply.dtype))
numpy can not guess that you intend to extend the array into for example np.float64
(not like regular python code, because there is a great performace hit to that)
what to do?
just simply define the type for it! (it a good practice to do this in other codes)
pos_num = np.array(pos_nums, dtype=np.float64)

String lexicographical permutation and inversion

Consider the following function on a string:
int F(string S)
{
int N = S.size();
int T = 0;
for (int i = 0; i < N; i++)
for (int j = i + 1; j < N; j++)
if (S[i] > S[j])
T++;
return T;
}
A string S0 of length N with all pairwise distinct characters has a total of N! unique permutations.
For example "bac" has the following 6 permutations:
bac
abc
cba
bca
acb
cab
Consider these N! strings in lexicographical order:
abc
acb
bac
bca
cab
cba
Now consider the application of F to each of these strings:
F("abc") = 0
F("acb") = 1
F("bac") = 1
F("bca") = 2
F("cab") = 2
F("cba") = 3
Given some string S1 of this set of permutations, we want to find the next string S2 in the set, that has the following relationship to S1:
F(S2) == F(S1) + 1
For example if S1 == "acb" (F = 1) than S2 == "bca" (F = 1 + 1 = 2)
One way to do this would be to start at one past S1 and iterate through the list of permutations looking for F(S) = F(S1)+1. This is unfortunately O(N!).
By what O(N) function on S1 can we calculate S2 directly?
Suppose length of S1 is n, biggest value for F(S1) is n(n-1)/2, if F(S1) = n(n-1)/2, means it's a last function and there isn't any next for it, but if F(S1) < n(n-1)/2, means there is at least one char x which is bigger than char y and x is next to y, find such a x with lowest index, and change x and y places. let see it by example:
S1 == "acb" (F = 1) , 1 < 3 so there is a char x which is bigger than another char y and its index is bigger than y, here smallest index x is c, and by first try you will replace it with a (which is smaller than x so algorithm finishes here)==> S2= "cab", F(S2) = 2.
Now let test it with S2, cab: x=b, y=a, ==> S3 = "cba".\
finding x is not hard, iterate the input, and have a variable name it min, while current visited character is smaller than min, set min as newly visited char, and visit next character, first time you visit a character which is bigger than min stop iteration, this is x:
This is pseudocode in c# (but I wasn't careful about boundaries e.g in input.Substring):
string NextString(string input)
{
var min = input[0];
int i=1;
while (i < input.Length && input[i] < min)
{
min = input[i];
i++;
}
if (i == input.Length) return "There isn't next item";
var x = input[i], y=input[i-1];
return input.Substring(0,i-2) + x + y + input.Substring(i,input.Length - 1 - i);
}
Here's the outline of an algorithm for a solution to your problem.
I'll assume that you have a function to directly return the n-th permutation (given n) and its inverse, ie a function to return n given a permutation. Let these be perm(n) and perm'(n) respectively.
If I've figured it correctly, when you have a 4-letter string to permute the function F goes like this:
F("abcd") = 0
F("abdc") = 1
F(perm(3)) = 1
F(...) = 2
F(...) = 2
F(...) = 3
F(perm(7)) = 1
F(...) = 2
F(...) = 2
F(...) = 3
F(...) = 3
F(...) = 4
F(perm(13)) = 2
F(...) = 3
F(...) = 3
F(...) = 4
F(...) = 4
F(...) = 5
F(perm(19)) = 3
F(...) = 4
F(...) = 4
F(...) = 5
F(...) = 5
F(perm(24)) = 6
In words, when you go from 3 letters to 4 you get 4 copies of the table of values of F, adding (0,1,2,3) to the (1st,2nd,3rd,4th) copy respectively. In the 2nd case, for example, you already have one derangement by putting the 2nd letter in the 1st place; this simply gets added to the other derangements in the same pattern as would be true for the original 3-letter strings.
From this outline it shouldn't be too difficult (but I haven't got time right now) to write the function F. Strictly speaking the inverse of F isn't a function as it would be multi-valued, but given n, and F(n) there are only a few cases for finding m st F(m)==F(n)+1. These cases are:
n == N! where N is the number of letters in the string, there is no next permutation;
F(n+1) < F(n), the sought-for solution is perm(n+(N-1)!), ;
F(n+1) == F(n), the solution is perm(n+2);
F(n+1) > F(n), the solution is perm(n+1).
I suspect that some of this might only work for 4 letter strings, that some of these terms will have to be adjusted for K-letter permutations.
This is not O(n), but it is at least O(n²) (where n is the number of elements in the permutation, in your example 3).
First, notice that whenever you place a character in your string, you already know how much of an increase in F that's going to mean -- it's however many characters smaller than that one that haven't been added to the string yet.
This gives us another algorithm to calculate F(n):
used = set()
def get_inversions(S1):
inv = 0
for index, ch in enumerate(S1):
character = ord(ch)-ord('a')
cnt = sum(1 for x in range(character) if x not in used)
inv += cnt
used.add(character)
return inv
This is not much better than the original version, but it is useful when inverting F. You want to know the first string that is lexicographically smaller -- therefore, it makes sense to copy your original string and only change it whenever mandatory. When such changes are required, we should also change the string by the least amount possible.
To do so, let's use the information that the biggest value of F for a string with n letters is n(n-1)/2. Whenever the number of required inversions would be bigger than this amount if we didn't change the original string, this means we must swap a letter at that point. Code in Python:
used = set()
def get_inversions(S1):
inv = 0
for index, ch in enumerate(S1):
character = ord(ch)-ord('a')
cnt = sum(1 for x in range(character) if x not in used)
inv += cnt
used.add(character)
return inv
def f_recursive(n, S1, inv, ign):
if n == 0: return ""
delta = inv - (n-1)*(n-2)/2
if ign:
cnt = 0
ch = 0
else:
ch = ord(S1[len(S1)-n])-ord('a')
cnt = sum(1 for x in range(ch) if x not in used)
for letter in range(ch, len(S1)):
if letter not in used:
if cnt < delta:
cnt += 1
continue
used.add(letter)
if letter != ch: ign = True
return chr(letter+ord('a'))+f_recursive(n-1, S1, inv-cnt, ign)
def F_inv(S1):
used.clear()
inv = get_inversions(S1)
used.clear()
return f_recursive(len(S1), S1, inv+1, False)
print F_inv("acb")
It can also be made to run in O(n log n) by replacing the innermost loop with a data structure such as a binary indexed tree.
Did you try to swap two neighbor characters in the string? It seems that it can help to solve the problem. If you swap S[i] and S[j], where i < j and S[i] < S[j], then F(S) increases by one, because all other pairs of indices are not affected by this permutation.
If I'm not mistaken, F calculates the number of inversions of the permutation.

Resources