Skip to content

Instantly share code, notes, and snippets.

@Pentusha
Created June 19, 2017 09:08
Show Gist options
  • Save Pentusha/ba7a2ec4e12f0fa61363fbb8492a5105 to your computer and use it in GitHub Desktop.
Save Pentusha/ba7a2ec4e12f0fa61363fbb8492a5105 to your computer and use it in GitHub Desktop.
import pytest
from water1 import Walls, ListCounter
@pytest.mark.parametrize('walls, expected', (
((2, 5, 1, 2, 3, 4, 7, 7, 6), 10),
((2, 5, 1, 3, 1, 2, 1, 7, 7, 6), 17),
((5, 1, 3, 6, 1, 6, 1, 3, 1, 4), 18),
((1, 2, 3, 4, 5, 5, 4, 3, 2, 1), 0),
((6, 1, 1, 1, 7, 1, 1, 1, 1, 7), 39),
((7, 1, 1, 1, 7, 1, 1, 1, 1, 7), 42),
((1, 2, 3, 4, 5, 6, 7, 8), 0),
((8, 7, 6, 5, 4, 3, 2, 1), 0),
((5, 1, 3, 6, 1, 5, 1, 7, 6, 5), 17),
((7, 1, 3, 6, 1, 5, 1, 7, 6, 5), 25),
((3, 4, 7, 3, 4, 7, 6, 7, 2, 4), 10),
((5, 1, 4, 2, 3), 4),
((6, 1, 5, 2, 1, 4), 9),
((4, 1, 2, 5, 1, 6), 9),
((7, 1, 5, 2, 1, 4), 9),
((7, 1, 5, 2, 1, 4, 2), 9),
((7, 1, 5, 2, 1, 4, 3, 2), 9),
((7, 1, 5, 1, 2, 4, 3, 2), 9),
((5, 1, 5, 1, 5, 1, 5), 12),
((1, 5, 1, 5, 1, 5, 1), 8),
((5, 1, 3), 2),
((0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0), 0),
((0, 1, 1, 1, 0, 1, 1, 1, 1, 0), 1),
((0, 2, 2, 2, 0, 2, 2, 2, 2, 0), 2),
))
def test_volume(walls, expected):
counter = ListCounter(walls)
assert Walls(counter).volume == expected
assert all(count < 2 for count in counter.counter)
from collections import Iterator
class ListCounter(list):
def __init__(self, iterable):
super(ListCounter, self).__init__(iterable)
self.counter = [0] * len(iterable)
def __getitem__(self, y):
self.counter[y] += 1
return super(ListCounter, self).__getitem__(y)
class Walls(Iterator):
def __init__(self, walls):
self.walls = walls
self.left_max = self.right_max = 0
self.first = 0
self.last = len(walls) - 1
def __iter__(self):
return self
def __next__(self):
if self.first > self.last:
raise StopIteration
if self.left_max < self.right_max:
wall = self.walls[self.first]
aqua = max(0, self.left_max - wall)
self.left_max = max(self.left_max, wall)
self.first += 1
else:
wall = self.walls[self.last]
aqua = max(0, self.right_max - wall)
self.right_max = max(self.right_max, wall)
self.last -= 1
return aqua
@property
def volume(self):
return sum(self)
from collections import deque
def volume(walls: deque):
left_max = right_max = 0
first = 0
last = len(walls) - 1
while first <= last:
if left_max < right_max:
wall = walls.popleft()
yield max(0, left_max - wall)
left_max = max(left_max, wall)
first += 1
else:
wall = walls.pop()
yield max(0, right_max - wall)
right_max = max(right_max, wall)
last -= 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment