You are given two strings of length n, you have to find distinct xor values by rearranging the elements in an arbitrary way of the two strings.
Here is what I tried:
String1 = input()
String2 = input()
s1_ones = String1.count('1') #Number of 1's in string1
s2_ones = String2.count('1') #Number of 1's in string2
minimum_overlap = s1_ones+s2_ones-n #minimum overlapping 1's when performing xor
maximum_overlap = min(s1_ones,s2_ones) #maximum overlapping 1's when performing xor
if(minimum_overlap<0):
minimum_overlap = 0
ans = 0
for x in range(minimum_overlap,maximum_overlap+1):
resulting_ones = s1_ones + s2_ones - 2*x #number of ones in resulting string
ans+=(nCr(n,resulting_ones)) #nCr is a function which returns number of possible values of resulting String.
print(ans)
I would like to explain nCr(n,r) funtion a little more. Given that you have string of length 5 in which number of ones are say 3. Here, N = 5 String = '11100' nCr(5,3) will give all the possible values of the provided string which is (5!/3!*2!) = 10.
What is wrong with this approach?
Here is the nCr(n,k):
def nCr(n, k):
if(k > n - k):
k = n - k
res = 1
for i in range(k):
res = res * (n - i)
res = res / (i + 1)
return (res)
I hope, This answers all your questions
import operator as op
from functools import reduce
import operator as op
from functools import reduce
def nCr(n, r):
r = min(r, n-r)
numer = reduce(op.mul, range(n, n-r, -1), 1)
denom = reduce(op.mul, range(1, r+1), 1)
return numer / denom
String1 = input()
String2 = input()
n=len(String1)
s1_ones = String1.count('1')
s2_ones = String2.count('1')
minimum_overlap = max(s1_ones,s2_ones)-min(s1_ones,s2_ones)
zero=n-max(s1_ones,s2_ones)
x=min(s1_ones,s2_ones)
ans = 0
while zero>-1 and x>-1:
zero-=1
x-=1
ans+=nCr(n,minimum_overlap)%1000000007
minimum_overlap+=2
print(int(ans))
now this nCr function is faster than factorial version, but if it still take time to execute, you can use fermat's theorem for nCr%p (also precompute factorial array) which you can find on internet
Related
Example : If my input is 582109 , the output should be (5+8+2+1+0+9)+(8+2+1+0+9)+(2+1+0+9)+(1+0+9)+(0+9)+(9)=25+20+12+10+9+9=85
Code:
def getSum(n):
sum = 0
while (n != 0):
sum = sum + int(n % 10)
n = int(n/10)
return sum
n = int(input("Number : "))
print(getSum(n))
This code is just giving sum of all digits in input. how to make it calculate the sum of sum of digits in cyclic order as mentioned in example?
Try this:
def add_digits(string):
result = 0
for i in range(len(string)):
for char in string[i:]:
result += int(char)
return result
print(add_digits("582109"))
To prevent interating over the digits twice, you can account for the number of times each digit appears in the final sum:
def getSum(n):
n_string = str(n)
sum, mult = 0, 1
for c in n_string:
sum += mult * int(c)
mult += 1
return sum
getSum(582109)
Here's another solution using the same algorithm as Dallan's answer but as a comprehension using enumerate, and with some inspiration from TheOneMusic's answer:
def add_digits_cyclic(digits):
return sum(i * int(c) for i, c in enumerate(digits, 1))
print(add_digits_cyclic('582109')) # -> 85
My Code is below. I want to count the letters in the output
s = string and n is number of times to repeat. n = 10, means the string s = "aba" is repeated over the course of 10 letters. i.e abaabaabaa.
s, n = input().strip(), int(input().strip())
print(s.count("a")
Out = 7
my code is below
a = 'aba'
t = list(a)
n = 3
new_list = []
if n <= len(t):
for i in range(n):
new_list.append(t[i])
m = t + new_list
print (''.join(m))
elif n > len(t):
x,y = divmod(n,len(t))
if y == 0:
new_list.append(a * x)
else:
new_list.append((a * x) + ''.join(map(str,t[:y])))
if n is large then need to loop like len(list(s)) = 3, if n = 10, divide 10/3 and we got 3 equal part and we got 1 remainder
In case the ultimate intention is to iterate over the generated string rather than directly printing it as output, an alternative is to use the itertools library.
from itertools import cycle, islice
s = "aba"
n = 10
for c in islice(cycle(s), n):
... do other stuff ...
Another scenario is that you try to compare the generated string with another string s2 of length n. In that case, islice can be omitted.
for c, c2 in zip(cycle(s), s2): # zip() truncates cycle(s) to the same length as s2
... operate on c and c2 ...
You could use something like this:
def repeat_n(s, n):
return (s * (n // len(s) + 1))[:n]
s = 'aba'
print(repeat_n(s, 2))
# ab
print(repeat_n(s, 10))
# abaabaabaa
print(repeat_n(s, 12))
# abaabaabaaba
n // len(s) gives you the number of times we can repeat s and stay below n characters so n // len(s) + 1 is the number of time we can repeat s to get at least n characters (plus potentially some others).
With that number we just repeat the string with s * (n // len(s) + 1) and then take the first n characters (s * (n // len(s) + 1))[:n].
Hope this helps.
EDIT: fixed for python 3
What are you looking for is modulo (%) operator:
s = 'aba'
n = 10
out = ''
for i in range(n):
out += s[i % len(s)]
print(out)
Prints:
abaabaabaa
Here's another option, using the * operator for strings:
s = 'aba'
n = 10
out = (s * (n // len(s)))[:n]
print(out)
Breaking it down:
n // len(s) => This is just the number of whole times s will need to be repeated
+ 1 => We add one to this, so our string will be a little longer than needed
s * => This repeats s that number of times
[:n] => Takes the first n characters of the string
So while it isn't as readable, it's very fast. Compared to the accepted answer:
def original_calc():
out = ''
for i in range(n):
out += s[i % len(s)]
result = out
def new_calc():
result = (s * (n // len(s)))[:n]
import timeit
s = 'aba'
n = 10
>>> timeit.timeit(original_calc, number=100000)
0.20508930005598813
>>> timeit.timeit(new_calc, number=100000)
0.027835099957883358
This is my implementation, but it not efficient when given 6 digit number.
Input : n = 2
Output : 9009
9009 is the largest number which is product of two
2-digit numbers. 9009 = 91*99.
def isPali(x):
n = str(x)
for i in range(len(n)):
if not n[i] == n[-i-1]:
return False
return True
def isProduct(x,A):
counter = A
while counter > 1:
if x // counter <= A and x % counter == 0:
return True
else:
counter-=1
return False
def largestProduct(A):
for i in range(A*A,1,-1):
if isPali(i) and isProduct(i,A):
return i
return False
largestProduct(999999)
Let x and y be the two n-digit factors of the palindrome number.
You can iterate over them in a descending number.
Key is to stop as soon as possible, which mean, once a first solution has been found, you don't check any product below that solution.
def get_max_palindrome(n):
res = 0
for x in range(10 ** n - 1, 1, -1):
for y in range(10 ** n - 1, 1, -1):
p = x * y
if res > p:
break
if str(p) == str(p)[::-1]:
res = p
break
if (x - 1) ** 2 < res:
break
return res
print(get_max_palindrome(6))
Exec in 0.378s on my laptop.
Codewise, this is not too difficult:
n = 999999
max_pali =0
t = ()
for i in range(1,n+1):
for j in range(i,n+1):
m = i*j
s = str(m)
if s == s[::-1] and m > max_pali:
max_pali = m
t = (i,j)
print(max_pali,t)
However, this is a brute force approach. For numbers with 6 digits, this will not terminate in a reasonable amount of time. Even if it will, I could ask you the same question for 7 or 42 digits. I suggest you look for some structure, or property, of those numbers whose multiple is a palindrome. Could such a pair be any pair of numbers? Is the case 91*99 = 9009 a mere coincidence, or is there a pattern?
Imagine you're trying to allocate some fixed resources (e.g. n=10) over some number of territories (e.g. t=5). I am trying to find out efficiently how to get all the combinations where the sum is n or below.
E.g. 10,0,0,0,0 is good, as well as 0,0,5,5,0 etc., while 3,3,3,3,3,3 is obviously wrong.
I got this far:
import itertools
t = 5
n = 10
r = [range(n+1)] * t
for x in itertools.product(*r):
if sum(x) <= n:
print x
This brute force approach is incredibly slow though; there must be a better way?
Timings (1000 iterations):
Default (itertools.product) --- time: 40.90 s
falsetru recursion --- time: 3.63 s
Aaron Williams Algorithm (impl, Tony) --- time: 0.37 s
Possible approach follows. Definitely would use with caution (hardly tested at all, but the results on n=10 and t=5 look reasonable).
The approach involves no recursion. The algorithm to generate partitions of a number n (10 in your example) having m elements (5 in your example) comes from Knuth's 4th volume. Each partition is then zero-extended if necessary, and all the distinct permutations are generated using an algorithm from Aaron Williams which I have seen referred to elsewhere. Both algorithms had to be translated to Python, and that increases the chance that errors have crept in. The Williams algorithm wanted a linked list, which I had to fake with a 2D array to avoid writing a linked-list class.
There goes an afternoon!
Code (note your n is my maxn and your t is my p):
import itertools
def visit(a, m):
""" Utility function to add partition to the list"""
x.append(a[1:m+1])
def parts(a, n, m):
""" Knuth Algorithm H, Combinatorial Algorithms, Pre-Fascicle 3B
Finds all partitions of n having exactly m elements.
An upper bound on running time is (3 x number of
partitions found) + m. Not recursive!
"""
while (1):
visit(a, m)
while a[2] < a[1]-1:
a[1] -= 1
a[2] += 1
visit(a, m)
j=3
s = a[1]+a[2]-1
while a[j] >= a[1]-1:
s += a[j]
j += 1
if j > m:
break
x = a[j] + 1
a[j] = x
j -= 1
while j>1:
a[j] = x
s -= x
j -= 1
a[1] = s
def distinct_perms(partition):
""" Aaron Williams Algorithm 1, "Loopless Generation of Multiset
Permutations by Prefix Shifts". Finds all distinct permutations
of a list with repeated items. I don't follow the paper all that
well, but it _possibly_ has a running time which is proportional
to the number of permutations (with 3 shift operations for each
permutation on average). Not recursive!
"""
perms = []
val = 0
nxt = 1
l1 = [[partition[i],i+1] for i in range(len(partition))]
l1[-1][nxt] = None
#print(l1)
head = 0
i = len(l1)-2
afteri = i+1
tmp = []
tmp += [l1[head][val]]
c = head
while l1[c][nxt] != None:
tmp += [l1[l1[c][nxt]][val]]
c = l1[c][nxt]
perms.extend([tmp])
while (l1[afteri][nxt] != None) or (l1[afteri][val] < l1[head][val]):
if (l1[afteri][nxt] != None) and (l1[i][val]>=l1[l1[afteri][nxt]][val]):
beforek = afteri
else:
beforek = i
k = l1[beforek][nxt]
l1[beforek][nxt] = l1[k][nxt]
l1[k][nxt] = head
if l1[k][val] < l1[head][val]:
i = k
afteri = l1[i][nxt]
head = k
tmp = []
tmp += [l1[head][val]]
c = head
while l1[c][nxt] != None:
tmp += [l1[l1[c][nxt]][val]]
c = l1[c][nxt]
perms.extend([tmp])
return perms
maxn = 10 # max integer to find partitions of
p = 5 # max number of items in each partition
# Find all partitions of length p or less adding up
# to maxn or less
# Special cases (Knuth's algorithm requires n and m >= 2)
x = [[i] for i in range(maxn+1)]
# Main cases: runs parts fn (maxn^2+maxn)/2 times
for i in range(2, maxn+1):
for j in range(2, min(p+1, i+1)):
m = j
n = i
a = [0, n-m+1] + [1] * (m-1) + [-1] + [0] * (n-m-1)
parts(a, n, m)
y = []
# For each partition, add zeros if necessary and then find
# distinct permutations. Runs distinct_perms function once
# for each partition.
for part in x:
if len(part) < p:
y += distinct_perms(part + [0] * (p - len(part)))
else:
y += distinct_perms(part)
print(y)
print(len(y))
Make your own recursive function which do not recurse with an element unless it's possible to make a sum <= 10.
def f(r, n, t, acc=[]):
if t == 0:
if n >= 0:
yield acc
return
for x in r:
if x > n: # <---- do not recurse if sum is larger than `n`
break
for lst in f(r, n-x, t-1, acc + [x]):
yield lst
t = 5
n = 10
for xs in f(range(n+1), n, 5):
print xs
You can create all the permutations with itertools, and parse the results with numpy.
>>> import numpy as np
>>> from itertools import product
>>> t = 5
>>> n = 10
>>> r = range(n+1)
# Create the product numpy array
>>> prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
>>> prod = prod.view('u1').reshape(-1, t)
# Extract only permutations that satisfy a condition
>>> prod[prod.sum(axis=1) < n]
Timeit:
>>> %%timeit
prod = np.fromiter(product(r, repeat=t), np.dtype('u1,' * t))
prod = prod.view('u1').reshape(-1, t)
prod[prod.sum(axis=1) < n]
10 loops, best of 3: 41.6 ms per loop
You could even speed up the product computation by populating combinations directly in numpy.
You could optimize the algorithm using Dynamic Programming.
Basically, have an array a, where a[i][j] means "Can I get a sum of j with the elements up to the j-th element (and using the jth element, assuming you have your elements in an array t (not the number you mentioned)).
Then you can fill the array doing
a[0][t[0]] = True
for i in range(1, len(t)):
a[i][t[i]] = True
for j in range(t[i]+1, n+1):
for k in range(0, i):
if a[k][j-t[i]]:
a[i][j] = True
Then, using this info, you could backtrack the solution :)
def backtrack(j = len(t)-1, goal = n):
print j, goal
all_solutions = []
if j == -1:
return []
if goal == t[j]:
all_solutions.append([j])
for i in range(j-1, -1, -1):
if a[i][goal-t[j]]:
r = backtrack(i, goal - t[j])
for l in r:
print l
l.append(j)
all_solutions.append(l)
all_solutions.extend(backtrack(j-1, goal))
return all_solutions
backtrack() # is the answer
I'm supposed to write a function which takes two numbers, the first is a given number, and the second is the length for the maximum sublist that I'm supposed to find:
for example input (1234,2)
the output would be 7
this is my code so far, it just computes the sum of the entire digits:
def altsum_digits(n,d):
b=str(n)
c=[]
for digit in b:
c.append(int(digit))
maxthere=0
realmax=0
for a in str(d):
for i in c:
maxthere=max(0,(maxthere+int(i)))
realmax=max(maxthere,realmax)
maxthere==0
print(realmax)
By what i get from question, this should do what you want:
def do(n, d):
print sum(sorted([int(x) for x in str(n)])[-d:])
let's say you get a number n, and a length k.
What you have to do is first turn n into a list of numbers, and then use a sliding window of size k where at each step you add the next number, and substract the first one in the sliding window, and keep track of the max_sum so you can return it at the end.
The function would look something like this
def altsum_digits(n, k):
list_n = [int(x) for x in str(n)]
max_sum = sum(list_n[:k])
for i in range(k, len(list_n)):
current_sum = current_sum + list_n[i] - list_n[i - k]
max_sum = max(current_sum, max_sum)
return max_sum
It's an O(n) solution, so it's a lot better than generating all sublists of size k. Hope it helps!
Let's clarify to make sure we're on the same page.
Inputs: 1) a list li of digits; 2) n
Output: the slice from li of length n that has maximal sum.
li = [4,2,1,7,1,3,8,4,7,8,1]
n = 2
slices = (li[x:x+n] for x in range(len(li)-n+1))
max(map(sum,slices))
Out[113]: 15
def sublists(lst, n):
return (lst[i:i+n] for i in range(len(lst) - n + 1))
def max_sublist_sum(lst, n):
return max(sum(sub) for sub in sublists(lst, n))
max_sublist_sum([1,2,3,4], 2) # => 7
This should do the trick:
def altsum_digits(n, d):
l = list(map(int, str(n)))
m = c = sum(l[:d])
for i in range(0, len(l)-d):
c = c - l[i] + l[i+d]
if c > m: m = c
print m
altsum_digits(1234,2)
>>> 7
I think I understand what you're asking, and here is my solution. I've tested it on your input as well as other inputs with varying lengths of substring. This code finds the maximum sum of adjacent substrings in the input.
def sum_of_sublist(input, maxLength):
input_array = [int(l) for l in str(input)]
tempMax = 0
realMax = 0
for i in range(len(input_array) - (maxLength - 1)):
for inc in range(0, maxLength):
tempMax += input_array[i+inc]
if tempMax > realMax:
realMax = tempMax
tempMax = 0
print realMax
sum_of_sublist(1234, 2)
So, for an input for the call sum_of_sublist(1234, 2), it will print the value 7 because the largest sum of 2 consecutive numbers is 3 + 4 = 7. Similarly, for the callsum_of_sublist(12531, 3), the program will print 10 because the largest sum of 3 consecutive numbers is 2 + 5 + 3 = 10.