Skip to content

Commit 5fe3c80

Browse files
committed
Sync LeetCode submission Runtime - 188 ms (60.19%), Memory - 19.3 MB (80.64%)
1 parent 4eacdff commit 5fe3c80

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

0353-design-snake-game/README.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<p>Design a <a href="https://en.wikipedia.org/wiki/Snake_(video_game)" target="_blank">Snake game</a> that is played on a device with screen size <code>height x width</code>. <a href="http://patorjk.com/games/snake/" target="_blank">Play the game online</a> if you are not familiar with the game.</p>
2+
3+
<p>The snake is initially positioned at the top left corner <code>(0, 0)</code> with a length of <code>1</code> unit.</p>
4+
5+
<p>You are given an array <code>food</code> where <code>food[i] = (r<sub>i</sub>, c<sub>i</sub>)</code> is the row and column position of a piece of food that the snake can eat. When a snake eats a piece of food, its length and the game&#39;s score both increase by <code>1</code>.</p>
6+
7+
<p>Each piece of food appears one by one on the screen, meaning the second piece of food will not appear until the snake eats the first piece of food.</p>
8+
9+
<p>When a piece of food appears on the screen, it is <strong>guaranteed</strong> that it will not appear on a block occupied by the snake.</p>
10+
11+
<p>The game is over if the snake goes out of bounds (hits a wall) or if its head occupies a space that its body occupies <strong>after</strong> moving (i.e. a snake of length 4 cannot run into itself).</p>
12+
13+
<p>Implement the <code>SnakeGame</code> class:</p>
14+
15+
<ul>
16+
<li><code>SnakeGame(int width, int height, int[][] food)</code> Initializes the object with a screen of size <code>height x width</code> and the positions of the <code>food</code>.</li>
17+
<li><code>int move(String direction)</code> Returns the score of the game after applying one <code>direction</code> move by the snake. If the game is over, return <code>-1</code>.</li>
18+
</ul>
19+
20+
<p>&nbsp;</p>
21+
<p><strong class="example">Example 1:</strong></p>
22+
<img alt="" src="https://assets.leetcode.com/uploads/2021/01/13/snake.jpg" style="width: 800px; height: 302px;" />
23+
<pre>
24+
<strong>Input</strong>
25+
[&quot;SnakeGame&quot;, &quot;move&quot;, &quot;move&quot;, &quot;move&quot;, &quot;move&quot;, &quot;move&quot;, &quot;move&quot;]
26+
[[3, 2, [[1, 2], [0, 1]]], [&quot;R&quot;], [&quot;D&quot;], [&quot;R&quot;], [&quot;U&quot;], [&quot;L&quot;], [&quot;U&quot;]]
27+
<strong>Output</strong>
28+
[null, 0, 0, 1, 1, 2, -1]
29+
30+
<strong>Explanation</strong>
31+
SnakeGame snakeGame = new SnakeGame(3, 2, [[1, 2], [0, 1]]);
32+
snakeGame.move(&quot;R&quot;); // return 0
33+
snakeGame.move(&quot;D&quot;); // return 0
34+
snakeGame.move(&quot;R&quot;); // return 1, snake eats the first piece of food. The second piece of food appears at (0, 1).
35+
snakeGame.move(&quot;U&quot;); // return 1
36+
snakeGame.move(&quot;L&quot;); // return 2, snake eats the second food. No more food appears.
37+
snakeGame.move(&quot;U&quot;); // return -1, game over because snake collides with border
38+
</pre>
39+
40+
<p>&nbsp;</p>
41+
<p><strong>Constraints:</strong></p>
42+
43+
<ul>
44+
<li><code>1 &lt;= width, height &lt;= 10<sup>4</sup></code></li>
45+
<li><code>1 &lt;= food.length &lt;= 50</code></li>
46+
<li><code>food[i].length == 2</code></li>
47+
<li><code>0 &lt;= r<sub>i</sub> &lt; height</code></li>
48+
<li><code>0 &lt;= c<sub>i</sub> &lt; width</code></li>
49+
<li><code>direction.length == 1</code></li>
50+
<li><code>direction</code> is <code>&#39;U&#39;</code>, <code>&#39;D&#39;</code>, <code>&#39;L&#39;</code>, or <code>&#39;R&#39;</code>.</li>
51+
<li>At most <code>10<sup>4</sup></code> calls will be made to <code>move</code>.</li>
52+
</ul>

0353-design-snake-game/solution.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from collections import deque
2+
3+
class SnakeGame:
4+
5+
def __init__(self, width: int, height: int, food: List[List[int]]):
6+
self.snake = deque([(0, 0)])
7+
self.snake_set = {(0, 0): 1}
8+
self.width = width
9+
self.height = height
10+
self.food = food
11+
self.food_index = 0
12+
self.movement = {'U': [-1, 0], 'L': [0, -1], 'R': [0, 1], 'D': [1, 0]}
13+
14+
15+
def move(self, direction: str) -> int:
16+
new_head = (self.snake[0][0] + self.movement[direction][0],
17+
self.snake[0][1] + self.movement[direction][1])
18+
19+
# Boundary conditions
20+
crosses_boundary1 = new_head[0] < 0 or new_head[0] >= self.height
21+
crosses_boundary2 = new_head[1] < 0 or new_head[1] >= self.width
22+
23+
# If snake bites itself
24+
bites_itself = new_head in self.snake_set and new_head != self.snake[-1]
25+
26+
# If any of the terminal conditions are satisfied, then exit
27+
if crosses_boundary1 or crosses_boundary2 or bites_itself:
28+
return -1
29+
30+
next_food_item = self.food[self.food_index] if self.food_index < len(self.food) else None
31+
32+
if self.food_index < len(self.food) and \
33+
next_food_item[0] == new_head[0] and \
34+
next_food_item[1] == new_head[1]:
35+
# Eat Food
36+
self.food_index += 1
37+
38+
else:
39+
# Not eating food; delete tail
40+
tail = self.snake.pop()
41+
del self.snake_set[tail]
42+
43+
# Add new head
44+
self.snake.appendleft(new_head)
45+
self.snake_set[new_head] = 1
46+
47+
return len(self.snake) - 1
48+
49+
50+
51+
52+
# Your SnakeGame object will be instantiated and called as such:
53+
# obj = SnakeGame(width, height, food)
54+
# param_1 = obj.move(direction)

0 commit comments

Comments
 (0)