Solving palindromic 'Triangle Quest' puzzle in Python
Question:
I’m trying to solve this programming puzzle:
You are given a positive integer N (0 < N < 10). Your task is to print a
palindromic triangle of size N.
For example, a palindromic triangle of size 5 is:
1
121
12321
1234321
123454321
You can’t take more than two lines. You have to complete the code
using exactly one print statement.
Note: Using anything related to strings will give a score of 0. Using
more than one for-statement will give a score of 0.
I can think only of ‘dumb’ way to do this:
for i in range(1, N+1):
print([0, 1, 121, 12321, 1234321, 123454321, 12345654321, 1234567654321, 123456787654321, 12345678987654321][i])
Is there a more elegant solution?
Answers:
I ended up doing the following (thanks @raina77ow for the idea):
for i in range(1, N+1):
print((111111111//(10**(9-i)))**2)
for i in range(1,6):
print (((10 ** i - 1) // 9) ** 2)
Here’s a wtf one liner:
f=lambda n:n and[f(n-1),print((10**n//9)**2),range(1,n+1)];f(5)
Code golfing and taking advice of simon and rain:
set(map(lambda x:print((10**x//9)**2),range(1,N+1)))
for i in range(1, N + 1):
print(*list(range(1, i + 1)) + list(range(i - 1, 0, -1)), sep = None)
Just because every solution offered so far involves range() which I feel is overused in Python code:
from math import log10
i = 1
while (N > log10(i)): print(i**2); i = i * 10 + 1
I am able to print in list format using below:
for i in range(1,5):
print [j for j in range(1,i+1) ], [j for j in range(i-1,0,-1) ]
Result:
[1] []
[1, 2] [1]
[1, 2, 3] [2, 1]
[1, 2, 3, 4] [3, 2, 1]
[1, 2, 3, 4, 5] [4, 3, 2, 1]
def palindrome(N):
for i in range(1, N + 1):
print(int('1' * i)**2)
palindrome(int(input()))
- 1 * 1 = 1
- 11 * 11 = 121
- 111 * 111 = 12321
for i in range(1,int(input())+1):
print(int((10**i-1)/9)**2)
1 -> ( 10 - 1) / 9 = 1, 1 * 1 = 1
2 -> ( 100 - 1) / 9 = 11, 11 * 11 = 121
3 -> ( 1000 - 1) / 9 = 111, 111 * 111 = 12321
4 -> (10000 - 1) / 9 = 1111, 1111 * 1111 = 1234321
for i in range(2,int(raw_input())+2):
print ''.join(([unicode(k) for k in range(1,i)]))+""+''.join(([unicode(k) for k in range(i-2,0,-1)]))
print ''.join(map(unicode,range(1,i)))+""+''.join(map(unicode,range(i-2,0,-1)))
I hope it will help.
I think the following code should work. I have used the most basic method, so that most people are going to understand it:
N = int(input())
arr = []
for i in range(1,N+1):
arr.append(i)
print(arr+arr[-2: :-1])
Use this code:
prefix = ''
suffix = ''
for i in range(1,n):
middle = str(i)
string = prefix + middle + suffix
print(string)
prefix = prefix + str(i)
suffix = ''.join(reversed(prefix))
for i in range(1,int(input())+1):
print(int(str('1'*i))**2)
Basically on each iteration, the number ‘1’ in string is multiplied by i times then converted to an integer then squared. So e.g.
On the 3rd iteration –> output = 111^2 = 12321
Edit: Noticed constraints was to answer with str() function
So we have a sequence 1, 11, 111, 1111
nth = an + (a(r^(n-1) – 1)) / (r – 1) where |r > 1|
therefore, solution;
for i in range(1,int(input())+1):
print(pow((((10**i - 10))//9) + 1, 2))
for i in range(1,int(input())+1): #More than 2 lines will result in 0 score. Do not leave a blank line also
print(''.join(list(map(lambda x:str(x),list(range(i+1))[1:]))+list(map(lambda x:str(x),list(reversed(list(range(i))[1:]))))))
This is a simple string-less version:
for i in range(1, int(input()) + 1):
print(sum(list(map(lambda x: 10 ** x, range(i)))) ** 2)
I know this has been asked a while ago, but I just stumbled upon this exercise and found an alternative and elegant solution to it.
As suggested by @raina77ow, we know that 11 * 11 = 121
, 111 * 111 = 12321
and so on.
But we also know that:
2**1 - 1 = 1 (is 1 in binary)
2**2 - 1 = 3 (is 11 in binary)
2**3 - 1 = 7 (is 111 in binary)
2**4 - 1 = 15 (is 1111 in binary)
etc.
Now, by doing bin(15)
you get 0b1111
and I hate that I had to transform it to integer using slicing, but I found no other method.
So, using the above, this is my solution:
for i in range(1,int(input())+1): # given line
print(int(bin(2**i - 1)[2:])**2)
Putting in my two cents worth, using unpacking of range
for i in range(1, int(input()) + 1):
print (*range(1, i+1), *range(i-1, 0, -1))
Just noticed Keith Hall has a very similar solution. He should get original credit for this.
I’m trying to solve this programming puzzle:
You are given a positive integer N (0 < N < 10). Your task is to print a
palindromic triangle of size N.For example, a palindromic triangle of size 5 is:
1 121 12321 1234321 123454321
You can’t take more than two lines. You have to complete the code
using exactly one print statement.Note: Using anything related to strings will give a score of 0. Using
more than one for-statement will give a score of 0.
I can think only of ‘dumb’ way to do this:
for i in range(1, N+1):
print([0, 1, 121, 12321, 1234321, 123454321, 12345654321, 1234567654321, 123456787654321, 12345678987654321][i])
Is there a more elegant solution?
I ended up doing the following (thanks @raina77ow for the idea):
for i in range(1, N+1):
print((111111111//(10**(9-i)))**2)
for i in range(1,6):
print (((10 ** i - 1) // 9) ** 2)
Here’s a wtf one liner:
f=lambda n:n and[f(n-1),print((10**n//9)**2),range(1,n+1)];f(5)
Code golfing and taking advice of simon and rain:
set(map(lambda x:print((10**x//9)**2),range(1,N+1)))
for i in range(1, N + 1):
print(*list(range(1, i + 1)) + list(range(i - 1, 0, -1)), sep = None)
Just because every solution offered so far involves range() which I feel is overused in Python code:
from math import log10
i = 1
while (N > log10(i)): print(i**2); i = i * 10 + 1
I am able to print in list format using below:
for i in range(1,5):
print [j for j in range(1,i+1) ], [j for j in range(i-1,0,-1) ]
Result:
[1] []
[1, 2] [1]
[1, 2, 3] [2, 1]
[1, 2, 3, 4] [3, 2, 1]
[1, 2, 3, 4, 5] [4, 3, 2, 1]
def palindrome(N):
for i in range(1, N + 1):
print(int('1' * i)**2)
palindrome(int(input()))
- 1 * 1 = 1
- 11 * 11 = 121
- 111 * 111 = 12321
for i in range(1,int(input())+1):
print(int((10**i-1)/9)**2)
1 -> ( 10 - 1) / 9 = 1, 1 * 1 = 1
2 -> ( 100 - 1) / 9 = 11, 11 * 11 = 121
3 -> ( 1000 - 1) / 9 = 111, 111 * 111 = 12321
4 -> (10000 - 1) / 9 = 1111, 1111 * 1111 = 1234321
for i in range(2,int(raw_input())+2):
print ''.join(([unicode(k) for k in range(1,i)]))+""+''.join(([unicode(k) for k in range(i-2,0,-1)]))
print ''.join(map(unicode,range(1,i)))+""+''.join(map(unicode,range(i-2,0,-1)))
I hope it will help.
I think the following code should work. I have used the most basic method, so that most people are going to understand it:
N = int(input())
arr = []
for i in range(1,N+1):
arr.append(i)
print(arr+arr[-2: :-1])
Use this code:
prefix = ''
suffix = ''
for i in range(1,n):
middle = str(i)
string = prefix + middle + suffix
print(string)
prefix = prefix + str(i)
suffix = ''.join(reversed(prefix))
for i in range(1,int(input())+1):
print(int(str('1'*i))**2)
Basically on each iteration, the number ‘1’ in string is multiplied by i times then converted to an integer then squared. So e.g.
On the 3rd iteration –> output = 111^2 = 12321
Edit: Noticed constraints was to answer with str() function
So we have a sequence 1, 11, 111, 1111
nth = an + (a(r^(n-1) – 1)) / (r – 1) where |r > 1|
therefore, solution;
for i in range(1,int(input())+1):
print(pow((((10**i - 10))//9) + 1, 2))
for i in range(1,int(input())+1): #More than 2 lines will result in 0 score. Do not leave a blank line also
print(''.join(list(map(lambda x:str(x),list(range(i+1))[1:]))+list(map(lambda x:str(x),list(reversed(list(range(i))[1:]))))))
This is a simple string-less version:
for i in range(1, int(input()) + 1):
print(sum(list(map(lambda x: 10 ** x, range(i)))) ** 2)
I know this has been asked a while ago, but I just stumbled upon this exercise and found an alternative and elegant solution to it.
As suggested by @raina77ow, we know that 11 * 11 = 121
, 111 * 111 = 12321
and so on.
But we also know that:
2**1 - 1 = 1 (is 1 in binary)
2**2 - 1 = 3 (is 11 in binary)
2**3 - 1 = 7 (is 111 in binary)
2**4 - 1 = 15 (is 1111 in binary)
etc.
Now, by doing bin(15)
you get 0b1111
and I hate that I had to transform it to integer using slicing, but I found no other method.
So, using the above, this is my solution:
for i in range(1,int(input())+1): # given line
print(int(bin(2**i - 1)[2:])**2)
Putting in my two cents worth, using unpacking of range
for i in range(1, int(input()) + 1):
print (*range(1, i+1), *range(i-1, 0, -1))
Just noticed Keith Hall has a very similar solution. He should get original credit for this.