Решение на Питоните хапят! от Георги Ангелов

Обратно към всички решения

Към профила на Георги Ангелов

Резултати

  • 6 точки от тестове
  • 0 бонус точки
  • 6 точки общо
  • 12 успешни тест(а)
  • 1 неуспешни тест(а)

Код

import math
class Matrix:
def __init__(self, width, height):
self._width = width
self._height = height
self._matrix = [
[None for y in range(width)]
for x in range(height)
]
def __getitem__(self, index_x):
return self._matrix[index_x]
def __len__(self):
return self._width
class WorldObject:
def __str__(self):
return "??"
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
def __str__(self):
return ":3"
class PythonPart(WorldObject):
def __init__(self):
self.pos = None
def __str__(self):
return "##"
class PythonHead(PythonPart):
def __str__(self):
return "@@"
class Death(Exception):
REASON_OUT_OF_WORLD = "left the world"
REASON_BITE = "ate a python part"
def __init__(self, reason):
self.reason = reason
super().__init__("The python died! Reason: {}. RIP!".format(reason))
class Vec2D:
def __init__(self, x, y):
self.x = x
self.y = y
@property
def reversed(self):
return Vec2D(-self.x, -self.y)
@property
def normalized(self):
length = self.length
return Vec2D(self.x / length, self.y / length)
@property
def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def __add__(self, other):
return Vec2D(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return self + other.reversed
def __mul__(self, scalar):
return Vec2D(self.x * scalar, self.y * scalar)
def __neg__(self):
return self.reversed
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
def __bool__(self):
return (self.x, self.y) != (0, 0)
def __iter__(self):
return iter((self.x, self.y))
class Python:
UP = Vec2D(0, -1)
RIGHT = Vec2D(1, 0)
DOWN = Vec2D(0, 1)
LEFT = Vec2D(-1, 0)
def __init__(self, world, coords, size, direction):
self.world = world
self.size = size
self.direction = direction
if direction not in (self.UP, self.LEFT, self.DOWN, self.RIGHT):
raise ValueError("The python needs a proper direction")
self.head = PythonHead()
self.parts = [PythonPart() for _ in range(self.size)]
self.energy = 0
self._draw_parts(coords, direction)
def _draw_parts(self, position, direction):
self.world.add_object(self.head, position.x, position.y)
pos = position - direction
for part in self.parts:
self.world.add_object(part, pos.x, pos.y)
pos -= direction
def move(self, direction):
current_pos = self.head.pos
new_pos = self.head.pos + direction
if new_pos == self.parts[0].pos:
raise ValueError("Cannot go backwards")
if not self.world.are_coords_inside(new_pos.x, new_pos.y):
raise Death(Death.REASON_OUT_OF_WORLD)
old_contents = self.world[new_pos.x][new_pos.y].contents
if isinstance(old_contents, PythonPart):
raise Death(Death.REASON_BITE)
elif isinstance(old_contents, Food):
self.energy += old_contents.energy
self.parts.append(PythonPart())
self.direction = direction
new_positions = [self.head.pos] + [part.pos for part in self.parts]
self.world.move_object(self.head, new_pos.x, new_pos.y)
for index, part in enumerate(self.parts):
self.world.move_object(part, new_positions[index].x,
new_positions[index].y)
class Cell:
def __init__(self, contents=None):
self.contents = contents
@property
def contents(self):
return self._contents
@contents.setter
def contents(self, value):
if value is not None and not isinstance(value, WorldObject):
raise TypeError("{} is not an instance of WorldObject"
.format(type(value)))
self._contents = value
def is_empty(self):
return not self.contents
def __str__(self):
return ".." if self.contents is None else str(self.contents)
class World:
def __init__(self, width):
self._width = width
self._matrix = Matrix(width, width)
for x in range(width):
for y in range(width):
self._matrix[x][y] = Cell()
def are_coords_inside(self, x, y):
return 0 <= x <= self._width and 0 <= y <= self._width
def add_object(self, obj, x, y):
self._matrix[x][y].contents = obj
obj.pos = Vec2D(x, y)
def move_object(self, obj, new_x, new_y):
self.del_object(obj)
self.add_object(obj, new_x, new_y)
def del_object(self, obj):
if obj.pos is not None:
self._matrix[obj.pos.x][obj.pos.y].contents = None
def __getitem__(self, index_x):
"""
Return cell object for the row and column. Supports double indexing
world[x][y].
Raises IndexError if index is invalid.
"""
return self._matrix[index_x]
def __len__(self):
return len(self._matrix)
def __str__(self):
rows = (
''.join(str(self._matrix[x][y]) for x in range(self._width))
for y in range(self._width)
)
return '\n'.join(rows)
if __name__ == '__main__':
world = World(10)
py = Python(world, Vec2D(5, 5), 3, Python.RIGHT)
print(world)

Лог от изпълнението

F............
======================================================================
FAIL: test_growth (test.PythonTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 60, in thread
    raise it.exc_info[1]
  File "lib/language/python/runner.py", line 48, in run
    self.result = func(*args, **kwargs)
  File "/tmp/d20130606-14014-1qlc6q2/test.py", line 94, in test_growth
    self.assertEqual(py.size, 4)
AssertionError: 3 != 4

----------------------------------------------------------------------
Ran 13 tests in 0.059s

FAILED (failures=1)

История (2 версии и 2 коментара)

Георги обнови решението на 12.05.2013 12:27 (преди почти 11 години)

+import math
+
+
+class Matrix:
+ class IndexProxy:
+ def __init__(self, matrix, index_x):
+ self.matrix = matrix
+ self.index_x = index_x
+
+ def __getitem__(self, index_y):
+ try:
+ return self.matrix[(self.index_x, index_y)]
+ except KeyError:
+ raise IndexError('X or Y coordinate is out of range')
+
+ def __setitem__(self, index_y, value):
+ if (self.index_x, index_y) not in self.matrix:
+ raise IndexError('X or Y coordinate is out of range')
+
+ self.matrix[(self.index_x, index_y)] = value
+
+ def __init__(self, width, height):
+ self._width = width
+ self._height = height
+ self._matrix = {
+ (x, y): None
+ for x in range(width)
+ for y in range(height)
+ }
+
+ def __getitem__(self, index_x):
+ return self.IndexProxy(self._matrix, index_x)
+
+ def __len__(self):
+ return self._width
+
+
+class WorldObject:
+ def __str__(self):
+ return "??"
+
+
+class Food(WorldObject):
+ def __init__(self, energy=0):
+ self.energy = energy
+
+ def __str__(self):
+ return ":3"
+
+
+class PythonPart(WorldObject):
+ def __init__(self):
+ self.pos = None
+
+ def __str__(self):
+ return "##"
+
+
+class PythonHead(PythonPart):
+ def __str__(self):
+ return "@@"
+
+
+class Death(Exception):
+ REASON_OUT_OF_WORLD = "left the world"
+ REASON_BITE = "ate a python part"
+
+ def __init__(self, reason):
+ self.reason = reason
+
+ super().__init__("The python died! Reason: {}. RIP!".format(reason))
+
+
+class DifferentDimensionsError(Exception):
+ pass
+
+
+class Vec2D:
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ @property
+ def reversed(self):
+ return Vec2D(-self.x, -self.y)
+
+ @property
+ def normalized(self):
+ length = self.length
+ return Vec2D(self.x / length, self.y / length)
+
+ @property
+ def length(self):
+ return math.sqrt(self.x ** 2 + self.y ** 2)
+
+ def __add__(self, other):
+ return Vec2D(self.x + other.x, self.y + other.y)
+
+ def __sub__(self, other):
+ return self + other.reversed
+
+ def __mul__(self, scalar):
+ return Vec2D(self.x * scalar, self.y * scalar)
+
+ def __neg__(self):
+ return self.reversed
+
+ def __eq__(self, other):
+ return (self.x, self.y) == (other.x, other.y)
+
+ def __bool__(self):
+ return (self.x, self.y) != (0, 0)
+
+ def __iter__(self):
+ return iter((self.x, self.y))
+
+
+class Python:
+ UP = Vec2D(0, -1)
+ RIGHT = Vec2D(1, 0)
+ DOWN = Vec2D(0, 1)
+ LEFT = Vec2D(-1, 0)
+
+ def __init__(self, world, coords, size, direction):
+ self.world = world
+ self.size = size
+ self.direction = direction
+
+ if direction not in (self.UP, self.LEFT, self.DOWN, self.RIGHT):
+ raise ValueError("The python needs a proper direction")
+
+ self.head = PythonHead()
+ self.parts = [PythonPart() for _ in range(self.size)]
+ self.energy = 0
+
+ self._draw_parts(coords, direction)
+
+ def _draw_parts(self, position, direction):
+ self.world.add_object(self.head, position.x, position.y)
+
+ pos = position - direction
+ for part in self.parts:
+ self.world.add_object(part, pos.x, pos.y)
+ pos -= direction
+
+ def move(self, direction):
+ current_pos = self.head.pos
+ new_pos = self.head.pos + direction
+
+ if new_pos == self.parts[0].pos:
+ raise ValueError("Cannot go backwards")
+
+ if not self.world.are_coords_inside(new_pos.x, new_pos.y):
+ raise Death(Death.REASON_OUT_OF_WORLD)
+
+ old_contents = self.world[new_pos.x][new_pos.y].contents
+
+ if isinstance(old_contents, PythonPart):
+ raise Death(Death.REASON_BITE)
+ elif isinstance(old_contents, Food):
+ self.energy += old_contents.energy
+ self.parts.append(PythonPart())
+
+ self.direction = direction
+ new_positions = [self.head.pos] + [part.pos for part in self.parts]
+
+ self.world.move_object(self.head, new_pos.x, new_pos.y)
+
+ for index, part in enumerate(self.parts):
+ self.world.move_object(part, new_positions[index].x,
+ new_positions[index].y)
+
+
+class Cell:
+ def __init__(self, contents=None):
+ if contents is not None and not isinstance(contents, WorldObject):
+ raise TypeError("{} is not an instance of WorldObject"
+ .format(type(contents)))
+
+ self.contents = contents
+
+ def is_empty(self):
+ return not self.contents
+
+ def __str__(self):
+ return ".." if self.contents is None else str(self.contents)
+
+
+class World:
+ def __init__(self, width):
+ self._width = width
+ self._matrix = Matrix(width, width)
+
+ for x in range(width):
+ for y in range(width):
+ self._matrix[x][y] = Cell()
+
+ def are_coords_inside(self, x, y):
+ return 0 <= x <= self._width and 0 <= y <= self._width
+
+ def add_object(self, obj, x, y):
+ self._matrix[x][y].contents = obj
+ obj.pos = Vec2D(x, y)
+
+ def move_object(self, obj, new_x, new_y):
+ self.del_object(obj)
+ self.add_object(obj, new_x, new_y)
+
+ def del_object(self, obj):
+ if obj.pos is not None:
+ self._matrix[obj.pos.x][obj.pos.y].contents = None
+
+ def __getitem__(self, index_x):
+ """
+ Return cell object for the row and column. Supports double indexing
+ world[x][y].
+
+ Raises IndexError if index is invalid.
+ """
+ return self._matrix[index_x]
+
+ def __len__(self):
+ return len(self._matrix)
+
+ def __str__(self):
+ rows = (
+ ''.join(str(self._matrix[x][y]) for x in range(self._width))
+ for y in range(self._width)
+ )
+
+ return '\n'.join(rows)
+
+if __name__ == '__main__':
+ world = World(10)
+ py = Python(world, Vec2D(5, 5), 3, Python.RIGHT)
+
+ print(world)

Георги обнови решението на 13.05.2013 22:11 (преди почти 11 години)

import math
class Matrix:
- class IndexProxy:
- def __init__(self, matrix, index_x):
- self.matrix = matrix
- self.index_x = index_x
-
- def __getitem__(self, index_y):
- try:
- return self.matrix[(self.index_x, index_y)]
- except KeyError:
- raise IndexError('X or Y coordinate is out of range')
-
- def __setitem__(self, index_y, value):
- if (self.index_x, index_y) not in self.matrix:
- raise IndexError('X or Y coordinate is out of range')
-
- self.matrix[(self.index_x, index_y)] = value
-
def __init__(self, width, height):
self._width = width
self._height = height
- self._matrix = {
- (x, y): None
- for x in range(width)
- for y in range(height)
- }
+ self._matrix = [
+ [None for y in range(width)]
+ for x in range(height)
+ ]
def __getitem__(self, index_x):
- return self.IndexProxy(self._matrix, index_x)
+ return self._matrix[index_x]
def __len__(self):
return self._width
class WorldObject:
def __str__(self):
return "??"
class Food(WorldObject):
def __init__(self, energy=0):
self.energy = energy
def __str__(self):
return ":3"
class PythonPart(WorldObject):
def __init__(self):
self.pos = None
def __str__(self):
return "##"
class PythonHead(PythonPart):
def __str__(self):
return "@@"
class Death(Exception):
REASON_OUT_OF_WORLD = "left the world"
REASON_BITE = "ate a python part"
def __init__(self, reason):
self.reason = reason
super().__init__("The python died! Reason: {}. RIP!".format(reason))
-class DifferentDimensionsError(Exception):
- pass
-
-
class Vec2D:
def __init__(self, x, y):
self.x = x
self.y = y
@property
def reversed(self):
return Vec2D(-self.x, -self.y)
@property
def normalized(self):
length = self.length
return Vec2D(self.x / length, self.y / length)
@property
def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
def __add__(self, other):
return Vec2D(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return self + other.reversed
def __mul__(self, scalar):
return Vec2D(self.x * scalar, self.y * scalar)
def __neg__(self):
return self.reversed
def __eq__(self, other):
return (self.x, self.y) == (other.x, other.y)
def __bool__(self):
return (self.x, self.y) != (0, 0)
def __iter__(self):
return iter((self.x, self.y))
class Python:
UP = Vec2D(0, -1)
RIGHT = Vec2D(1, 0)
DOWN = Vec2D(0, 1)
LEFT = Vec2D(-1, 0)
def __init__(self, world, coords, size, direction):
self.world = world
self.size = size
self.direction = direction
if direction not in (self.UP, self.LEFT, self.DOWN, self.RIGHT):
raise ValueError("The python needs a proper direction")
self.head = PythonHead()
self.parts = [PythonPart() for _ in range(self.size)]
self.energy = 0
self._draw_parts(coords, direction)
def _draw_parts(self, position, direction):
self.world.add_object(self.head, position.x, position.y)
pos = position - direction
for part in self.parts:
self.world.add_object(part, pos.x, pos.y)
pos -= direction
def move(self, direction):
current_pos = self.head.pos
new_pos = self.head.pos + direction
if new_pos == self.parts[0].pos:
raise ValueError("Cannot go backwards")
if not self.world.are_coords_inside(new_pos.x, new_pos.y):
raise Death(Death.REASON_OUT_OF_WORLD)
old_contents = self.world[new_pos.x][new_pos.y].contents
if isinstance(old_contents, PythonPart):
raise Death(Death.REASON_BITE)
elif isinstance(old_contents, Food):
self.energy += old_contents.energy
self.parts.append(PythonPart())
self.direction = direction
new_positions = [self.head.pos] + [part.pos for part in self.parts]
self.world.move_object(self.head, new_pos.x, new_pos.y)
for index, part in enumerate(self.parts):
self.world.move_object(part, new_positions[index].x,
new_positions[index].y)
class Cell:
def __init__(self, contents=None):
- if contents is not None and not isinstance(contents, WorldObject):
+ self.contents = contents
+
+ @property
+ def contents(self):
+ return self._contents
+
+ @contents.setter
+ def contents(self, value):
+ if value is not None and not isinstance(value, WorldObject):
raise TypeError("{} is not an instance of WorldObject"
- .format(type(contents)))
+ .format(type(value)))
- self.contents = contents
+ self._contents = value
def is_empty(self):
return not self.contents
def __str__(self):
return ".." if self.contents is None else str(self.contents)
class World:
def __init__(self, width):
self._width = width
self._matrix = Matrix(width, width)
for x in range(width):
for y in range(width):
self._matrix[x][y] = Cell()
def are_coords_inside(self, x, y):
return 0 <= x <= self._width and 0 <= y <= self._width
def add_object(self, obj, x, y):
self._matrix[x][y].contents = obj
obj.pos = Vec2D(x, y)
def move_object(self, obj, new_x, new_y):
self.del_object(obj)
self.add_object(obj, new_x, new_y)
def del_object(self, obj):
if obj.pos is not None:
self._matrix[obj.pos.x][obj.pos.y].contents = None
def __getitem__(self, index_x):
"""
Return cell object for the row and column. Supports double indexing
world[x][y].
Raises IndexError if index is invalid.
"""
return self._matrix[index_x]
def __len__(self):
return len(self._matrix)
def __str__(self):
rows = (
''.join(str(self._matrix[x][y]) for x in range(self._width))
for y in range(self._width)
)
return '\n'.join(rows)
if __name__ == '__main__':
world = World(10)
py = Python(world, Vec2D(5, 5), 3, Python.RIGHT)
print(world)