You are going to build a stone wall. The wall should be straight and N meters long, and its thickness should be constant; however, it should have different heights in different places. The height of the wall is specified by an array H of N positive integers. H[I] is the height of the wall from I to I+1 meters to the right of its left end. In particular, H[0] is the height of the wall's left end and H[N−1] is the height of the wall's right end.
The wall should be built of cuboid stone blocks (that is, all sides of such blocks are rectangular). Your task is to compute the minimum number of blocks needed to build the wall.
Write a function:
def solution(H)
that, given an array H of N positive integers specifying the height of the wall, returns the minimum number of blocks needed to build it.
For example, given array H containing N = 9 integers:
H[0] = 8 H[1] = 8 H[2] = 5 H[3] = 7 H[4] = 9 H[5] = 8 H[6] = 7 H[7] = 4 H[8] = 8the function should return 7. The figure shows one possible arrangement of seven blocks.
Write an efficient algorithm for the following assumptions:
- N is an integer within the range [1..100,000];
- each element of array H is an integer within the range [1..1,000,000,000].
def solution(H):
"""
Codility 100%
https://app.codility.com/demo/results/trainingTJQUQF-HAE/
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
print(" ")
print("Current Height " + str(height))
print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
print(" ")
print("Current Height " + str(height))
print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
print(" ")
print("Current Height " + str(height))
print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
# print(" ")
# print("Current Height " + str(height))
# print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
# print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
# print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
# print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
# print(" ")
# print("Current Height " + str(height))
# print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
# print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
# print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
# print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
def solution(H):
"""
Idea is to use stack concept
Compute the minimum number of blocks needed to build the wall.
To build the wall start taking blocks of height one by one.
We need to take care of -
- the blocked should not be used again
- this is done only up to blocks height is greater than current
- why we are using last 8 height block if there is already 8 height block used in previous step?
reason is 8 is not present in stack top
8,
8,----- can not use because on stack top 8 is already there
5,
7,
9,
8,
7,------ can not use because on stack top 7 is already there
4,
8,
This is just example with height, see steps of output for details
skip8 skip7
| |
| | | |
| | | | |
| | | | |
| | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
| | | | | | |
Used blocks-
8
5
7
9
8
4
8
"""
block_count = 0
# stack is used to hold height used to building and remove all the blocks from it,
# if any of the block of stack is greater than current block(to be added for building)
stack = []
for height in H:
# print(" ")
# print("Current Height " + str(height))
# print("Current stack " + str(stack))
# Remove all blocks that are bigger than current height, stack should not be empty
while stack and stack[-1] > height:
stack.pop()
# print("After remove bigger blocks than current height " + str(stack))
# stack is not empty and top item of stack is equal to current height
if stack and stack[-1] == height:
# Already used this size of block
# print("Already used this size of block " + str(height))
continue
else:
# new block is required, push it's size to the stack
block_count += 1
stack.append(height)
# print("Add this block.... " + str(height) + " Minimum Blocks " + str(block_count))
return block_count
The solution obtained perfect score.