alpha = [0,1,2,3,4,5,6,7,8,9]
for a in alpha:
for b in alpha:
for c in alpha:
for d in alpha:
print str(a) + str(b) + str(c) + str(d)
The code above will generate all numbers between 0000 to 9999. However, I do not like the way the code is structured. Let's say I would want to do this to produce numbers up to a ten digit size; that would require 10 for loops. Is there another way the same result could be achieved, without having to insert countless of for loops?
The obvious way:
for i in xrange(10000): # or range if python 3
print "{0:04d}".format(i)
You can also specify the with as an argument:
for i in xrange(10000): # or range if python 3
print "%0*d"%(4,i)
I'm not sure whether you want combinations_with_replacement or product. I think it's the latter, but… try them both with, say, 2 or 3, and see which one is what you're asking for.
for combination in itertools.combinations_with_replacement(alpha, 3):
print ''.join(map(str, combination))
for element in itertools.product(alpha, repeat=3):
print ''.join(map(str, element))
Although I'd probably generate the combinations out of strings, instead of generating them out of integers just to convert them to strings:
alpha = '0123456789'
for combination in itertools.combinations_with_replacement(alpha, 4):
print ''.join(combination)
expect_len = 10
max_val = 10**expected_len -1
my_list = ["%0*d"%(expect_len,val) for val in xrange(0,max_val+1)]
I think at least
Related
I am trying to create a loop where I can generate string using loop. What I am trying to achieve is that I want to create a small collection of strings starting from 1 character to up to 5 characters.
So, starting from sting 1, I want to go to 55555 but this is number so it seems easy if I just add them, but when it comes to alpha numeric, it gets tricky.
Here is explanation,
I have collection of alpha-numeric chars as string s = "123ABC" and what I want to do is that I want to create all possible 1 character string out of it, so I will have 1,2,3,A,B,C and after that I want to add one more digit in length of string so I can get 11, 12, 13 and so on until I get all possible combination out of it up to CA, CB, CC and I want to get it up to CCCCCC. I am confused in loop because I can get it to generate a temp sting but looping inside to rotate characters is tricky,
this is what I have done so far,
i = 0
strr = "123ABC"
while i < len(strr):
t = strr[0] * (i+1)
for q in range(0, len(t)):
# Here I need help to rotate more
pass
i += 1
Can anyone explain me or point me to resource where I can find solution for it?
You may want to use itertools.permutations function:
import itertools
chars = '123ABC'
for i in xrange(1, len(chars)+1):
print list(itertools.permutations(chars, i))
EDIT:
To get a list of strings, try this:
import itertools
chars = '123ABC'
strings = []
for i in xrange(1, len(chars)+1):
strings.extend(''.join(x) for x in itertools.permutations(chars, i))
This is a nested loop. Different depths of recursion produce all possible combinations.
strr = "123ABC"
def prod(items, level):
if level == 0:
yield []
else:
for first in items:
for rest in prod(items, level-1):
yield [first] + rest
for ln in range(1, len(strr)+1):
print("length:", ln)
for s in prod(strr, ln):
print(''.join(s))
It is also called cartesian product and there is a corresponding function in itertools.
A string is palindrome if it reads the same forward and backward. Given a string that contains only lower case English alphabets, you are required to create a new palindrome string from the given string following the rules gives below:
1. You can reduce (but not increase) any character in a string by one; for example you can reduce the character h to g but not from g to h
2. In order to achieve your goal, if you have to then you can reduce a character of a string repeatedly until it becomes the letter a; but once it becomes a, you cannot reduce it any further.
Each reduction operation is counted as one. So you need to count as well how many reductions you make. Write a Python program that reads a string from a user input (using raw_input statement), creates a palindrome string from the given string with the minimum possible number of operations and then prints the palindrome string created and the number of operations needed to create the new palindrome string.
I tried to convert the string to a list first, then modify the list so that should any string be given, if its not a palindrome, it automatically edits it to a palindrome and then prints the result.after modifying the list, convert it back to a string.
c=raw_input("enter a string ")
x=list(c)
y = ""
i = 0
j = len(x)-1
a = 0
while i < j:
if x[i] < x[j]:
a += ord(x[j]) - ord(x[i])
x[j] = x[i]
print x
else:
a += ord(x[i]) - ord(x[j])
x [i] = x[j]
print x
i = i + 1
j = (len(x)-1)-1
print "The number of operations is ",a print "The palindrome created is",( ''.join(x) )
Am i approaching it the right way or is there something I'm not adding up?
Since only reduction is allowed, it is clear that the number of reductions for each pair will be the difference between them. For example, consider the string 'abcd'.
Here the pairs to check are (a,d) and (b,c).
Now difference between 'a' and 'd' is 3, which is obtained by (ord('d')-ord('a')).
I am using absolute value to avoid checking which alphabet has higher ASCII value.
I hope this approach will help.
s=input()
l=len(s)
count=0
m=0
n=l-1
while m<n:
count+=abs(ord(s[m])-ord(s[n]))
m+=1
n-=1
print(count)
This is a common "homework" or competition question. The basic concept here is that you have to find a way to get to minimum values with as few reduction operations as possible. The trick here is to utilize string manipulation to keep that number low. For this particular problem, there are two very simple things to remember: 1) you have to split the string, and 2) you have to apply a bit of symmetry.
First, split the string in half. The following function should do it.
def split_string_to_halves(string):
half, rem = divmod(len(string), 2)
a, b, c = '', '', ''
a, b = string[:half], string[half:]
if rem > 0:
b, c = string[half + 1:], string[rem + 1]
return (a, b, c)
The above should recreate the string if you do a + c + b. Next is you have to convert a and b to lists and map the ord function on each half. Leave the remainder alone, if any.
def convert_to_ord_list(string):
return map(ord, list(string))
Since you just have to do a one-way operation (only reduction, no need for addition), you can assume that for each pair of elements in the two converted lists, the higher value less the lower value is the number of operations needed. Easier shown than said:
def convert_to_palindrome(string):
halfone, halftwo, rem = split_string_to_halves(string)
if halfone == halftwo[::-1]:
return halfone + halftwo + rem, 0
halftwo = halftwo[::-1]
zipped = zip(convert_to_ord_list(halfone), convert_to_ord_list(halftwo))
counter = sum([max(x) - min(x) for x in zipped])
floors = [min(x) for x in zipped]
res = "".join(map(chr, floors))
res += rem + res[::-1]
return res, counter
Finally, some tests:
target = 'ideal'
print convert_to_palindrome(target) # ('iaeai', 6)
target = 'euler'
print convert_to_palindrome(target) # ('eelee', 29)
target = 'ohmygodthisisinsane'
print convert_to_palindrome(target) # ('ehasgidihmhidigsahe', 84)
I'm not sure if this is optimized nor if I covered all bases. But I think this pretty much covers the general concept of the approach needed. Compared to your code, this is clearer and actually works (yours does not). Good luck and let us know how this works for you.
If I have two strings of equal length like the following:
'aaaaabbbbbccccc'
'bbbebcccccddddd'
Is there an efficient way to align the two such that the most letters as possible line up as shown below?
'aaaaabbbbbccccc-----'
'-----bbbebcccccddddd'
The only way I can think of doing this is brute force by editing the strings and then iterating through and comparing.
Return the index which gives the maximum score, where the maximum score is the strings which have the most matching characters.
def best_overlap(a, b):
return max([(score(a[offset:], b), offset) for offset in xrange(len(a))], key=lambda x: x[0])[1]
def score(a, b):
return sum([a[i] == b[i] for i in xrange(len(a))])
>>> best_overlap(a, b)
5
>>> a + '-' * best_overlap(a, b); '-' * best_overlap(a, b) + b
'aaaaabbbbbccccc-----'
'-----bbbebcccccddddd'
Or, equivalently:
def best_match(a, b):
max = 0
max_score = 0
for offset in xrange(len(a)):
val = score(a[offset:], b)
if val > max_score:
max_score = val
max = offset
return max
There is room for optimizations such as:
Early exit for no matching characters
Early exit when maximum possible match found
I'm not sure what you mean by efficient, but you can use the find method on str:
first = 'aaaaabbbbbccccc'
second = 'bbbebcccccddddd'
second_prime = '-'* first.find(second[0]) + second
first_prime = first + '-' * (len(second_prime) - len(first))
print first_prime + '\n' + second_prime
# Output:
# aaaaabbbbbccccc-----
# -----bbbebcccccddddd
I can't see any other way than brute forcing it. The complexity will be quadratic in the string length, which might be acceptable, depending on what string lengths you are working with.
Something like this maybe:
def align(a, b):
best, best_x = 0, 0
for x in range(len(a)):
s = sum(i==j for (i,j) in zip(a[x:],b[:-x]))
if s > best:
best, best_x = s, x
return best_x
align('aaaaabbbbbccccc', 'bbbebcccccddddd')
5
I would do something like the binary & function on each of your strings. Compares each of the strings when they are lined up, counting up the number of times letters match. Then, shift by one and do the same thing, and go on and on with shifting until they are no longer lined up. The shift with the most matching letters in this fashion is the correct output shift, and you can add the dashes when you print it out. You don't actually have to modify the strings for this, just count the number of shifts and offset your comparing of the characters by that shift amount. This is not terribly efficient (O(n^2) = n+(n-2)+(n-4)...), but is the best I could come up with.
I am fairly new to programming and have been learning some of the material through HackerRank. However, there is this one objective or challenge that I am currently stuck on. I've tried several things but still cannot figure out what exactly I am doing wrong.
Objective: Read N and output the numbers between 0 and N without any white spaces or using a string method.
N = int(input())
listofnum = []
for i in range(1, N +1):
listofnum.append(i)
print (*(listofnum))
Output :
1 2 3
N = int(input())
answer = ''
for i in range(1, N + 1):
answer += str(i)
print(answer)
This is the closest I can think of to 'not using any string methods', although technically it is using str.__new__/__init__/__add__ in the background or some equivalent. I certainly think it fits the requirements of the question better than using ''.join.
Without using any string method, just using integer division and list to reverse the digits, print them using sys.stdout.write:
import sys
N = int(input())
for i in range(1,N+1):
l=[]
while(i):
l.append(i%10)
i //= 10
for c in reversed(l):
sys.stdout.write(chr(c+48))
Or as tdelaney suggested, an even more hard-code method:
import os,sys,struct
N = int(input())
for i in range(1,N+1):
l=[]
while(i):
l.append(i%10)
i //= 10
for c in reversed(l):
os.write(sys.stdout.fileno(), struct.pack('b', c+48))
All of this is great fun, but the best way, though, would be with a one-liner with a generator comprehension to do that, using str.join() and str construction:
"".join(str(x) for x in range(1,N+1))
Each number is converted into string, and the join operator just concatenates all the digits with empty separator.
You can print numbers inside the loop. Just use end keyword in print:
print(i, end="")
Try ''.join([str(i) for i in range(N)])
One way to accomplish this is to append the numbers to a blank string.
out = ''
for i in range(N):
out += str(i)
print(out)
You can make use of print()'s sep argument to "bind" each number together from a list comprehension:
>>> print(*[el for el in range(0, int(input())+1)], sep="")
10
012345678910
>>>
You have to do a simple math to do this. What they expect to do is multiply each of your list elements by powers of ten and add them up on each other. As an example let's say you have an array;
a = [2,3,5]
and you need to output;
235
Then you multiply each of loop elements starting from right to left by 10^0, 10^1 and 10^2. You this code after you make the string list.
a = map(int,a)
for i in range(len(a)):
sum += (10**i)*a[-i]
print sum
You are done!
I'm wanting to create a string that will, If Word 1 was CHEESE and Word 2 = HAM, create a string looking something like this...
CHEESEHAMCHEESEHAMCHEESEHAMCHEESEHAM etc...
I then want the ASCII values of each character to be taken and be used in a Caesar cipher program.
Thanks in advance, I'm not too experienced with Python.
To concatenate two strings s1 and s2, you use the + operator:
s = s1 + s2
To repeat a string s n (integer number) times, you use the * operator:
ss = s * n
To get a list of integers representing each character of a string ss, you can use the built-in ord() method in a list comprehension:
l = [ord(c) for c in ss]
So a full program using two strings and the number of repetitions (here hard-coded as constants), and with the snippets above compressed into one line, would look like this:
s1 = "CHEESE"
s2 = "HAM"
n = 5
l = [ord(c) for c in (s1+s2)*n]
print (l)
you can also try this.
wordOne="cheese"
wordTwo="ham"
i=0
n=5
while i<n:
print("wordOne", end="")
print("wordTwo", end="")
i+=1