Question: Python Pilling Up [Collections]
There is a horizontal row of n cubes. The length of each cube is given. You need to create a new vertical pile of cubes. The new pile should follow these directions: if cube[i]
is on top of cube[j]
then sideLength[j] >= sideLength[i]
.
When stacking the cubes, you can only pick up either the leftmost or the rightmost cube each time. Print "Yes" if it is possible to stack the cubes. Otherwise, print "No". Do not print the quotation marks.
Input Format:
The first line contains a single integer T, the number of test cases.
For each test case, there are 2 lines.
The first line of each test case contains n, the number of cubes.
The second line contains n space separated integers, denoting the sideLengths of each cube in that order.
Constraints:
1 <= T <= 5
1 <= n <= 10^5
1 <= sideLength <= 2^31
Output Format:
For each test case, output a single line containing either "Yes" or "No" without the quotes.
Sample Input:
2
6
4 3 2 1 3 4
3
1 3 2
Sample Output:
Yes
No
Explanation:
In the first test case, pick in this order: left -4 , right -4 , left -3 , right - 3, left - 2, right - 1. In the second test case, no order gives an appropriate arrangement of vertical cubes. 3 will always come after either 1 or 2.
Possible solutions
Now we will discuss different possible solutions. Here we will go through the following solutions and explain each of them in detail.
- Using collection module
- Using loops
- Using if-else statement
Now let us go through each of the solutions
Solution-1: Using collection module
Now let us solve the problem using collection module
from collections import deque
t = int(input())
for i in range(t):
size = int(input())
top = 2**31
d = deque(list(map(int,input().split())))
for j in range(len(d)):
if d[0]>=d[len(d)-1] and d[0]<=top:
top = d.popleft()
elif d[len(d)-1]<=top:
top = d.pop()
else:
print('No')
break
if len(d) == 0:
print('Yes')
Here,
- The code takes in an integer size as input and discards it. It also takesĀ in a space-separated list of integers and stores them in a deque called d.
- The code then initializes a variable top to the maximum value that an integer can take on (2147483647) and enters a loop that iterates over the elements of d.
- In each iteration, it checks whether the front or back element of d is smaller than or equal to top. If the front element is smaller, it removes it from the front of d and updates top to the value of the element. If the back element is smaller, it removes it from the back of d and updates top to the value of the element. If neither element is smaller, it prints 'No' and breaks out of the loop. After the loop, it checks whether d is empty. If it is, it prints 'Yes'.
Solution-2: Using loops
Now we will solve the problem using the for loop and while loop.
t = int(input())
for _ in range(t):
num, cubes = int(input()), list(map(int,input().split()))
yes_no = "Yes"
while len(cubes) > 1:
if cubes[0] >= cubes[-1]:
larger_num = cubes[0]
cubes.pop(0)
else:
larger_num = cubes[-1]
cubes.pop(-1)
if larger_num < cubes[0] or larger_num < cubes[-1]:
yes_no = 'No'
break
print(yes_no)
Similar to the first solution, this solution also takes an integer value as input. It then takes a space-separated list of integers and stores them in a list called cubes.
The code then enters a loop that continues until cubes has fewer than two elements. In each iteration, it compares the front and back elements of cubes and removes the larger of the two. It stores the value of the larger element in a variable larger_num. It checks whether larger_num is smaller than the front or back element of cubes. If it is, it sets yes_no to 'No' and breaks out of the loop.
After the loop, it prints yes_no. This code determines whether it is possible to remove elements from the front and back of a list of integers such that the remaining elements are in non-decreasing order. If it is possible, it prints 'Yes'; otherwise, it prints 'No'.
Solution-3: Using if-else statements
Now we will use the if-else statements to solve the problem.
from collections import *
def piling(d):
while d:
large = None
if d[-1]>d[0]:
large = d.pop()
else:
large = d.popleft()
if len(d)==0:
return "Yes"
if d[-1]>large or d[0]>large:
return "No"
for i in range(int(input())):
n = int(input())
d = deque(map(int,input().split()))
print(piling(d))
The first few steps are similar to the previous codes where it is simply taking input from the user. This code is different from the first one in that it stores the input list of integers in a deque instead of a list and uses the popleft and pop methods of the deque to remove elements from the front and back, respectively. It also implements the solution as a function with the deque as an argument and calls the function t times in a loop.
Summary
In this short article, we learned how we can solve the Pilling up from HackerRank. We solve the problem using various different techniques
Further Reading
Question on Hackerrank: Python Piling Up [Collections]