Решение на Втора задача от Мирослав Лалев

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

Към профила на Мирослав Лалев

Резултати

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

Код

def grow(snake, direction)
snake + [ snake.last.zip(direction).map do |new_head_position|
new_head_position.inject(:+)
end ]
end
def move(snake, direction)
grow(snake, direction).drop(1)
end
def obstacle_ahead?(snake, direction, dimensions)
snake_head_after_move = move(snake, direction).last
snake.include?(snake_head_after_move) or
snake_head_after_move[0] >= dimensions[:width] or
snake_head_after_move[1] >= dimensions[:height] or
snake_head_after_move.min < 0
end
def danger?(snake, direction, dimensions)
obstacle_ahead?(snake, direction, dimensions) &&
obstacle_ahead?(move(snake, direction), direction, dimensions)
end
def new_food(food, snake, dimensions)
widths = [*0..(dimensions[:width] - 1)]
heights = [*0..(dimensions[:height] - 1)]
(widths.product(heights) - food - snake).sample
end

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

.................F..

Failures:

  1) #danger? returns true if obstacle in two turns
     Failure/Error: expect(danger?([[6, 6], [7, 6], [8, 6]], [1, 0], dimensions)).to eq true
       
       expected: true
            got: false
       
       (compared using ==)
     # /tmp/d20151026-15631-1vlzu1r/spec.rb:113:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01624 seconds
20 examples, 1 failure

Failed examples:

rspec /tmp/d20151026-15631-1vlzu1r/spec.rb:112 # #danger? returns true if obstacle in two turns

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

Мирослав обнови решението на 16.10.2015 16:24 (преди над 9 години)

+def grow(snake, direction)
+ new_head = []
+ snake.last.map.with_index {
+ |element, index| new_head.push(element + direction[index])
+ }
+ snake + [ new_head ]
+end
+
+def move(snake, direction)
+ grow(snake, direction).drop(1)
+end
+
+def obstacle_ahead?(snake, direction, dimensions)
+ answer = false
+ snake_head_after_move = move(snake, direction).last
+ if snake.include?(snake_head_after_move) or
+ snake_head_after_move.max >= dimensions[:width] or
+ snake_head_after_move.max >= dimensions[:height] then
+ answer = true
+ end
+ answer
+end
+
+def danger?(snake, direction, dimensions)
+ first_move = obstacle_ahead?(snake, direction, dimensions)
+ moved_snake = move(snake, direction)
+ second_move = obstacle_ahead?(moved_snake, direction, dimensions)
+ first_move && second_move
+end
+
+def new_food(food, snake, dimensions)
+ random_food = snake.first
+ while food.include?(random_food) or snake.include?(random_food)
+ random_food = [ Random.rand(dimensions[:width]),
+ Random.rand(dimensions[:height]) ]
+ end
+ random_food
+end

Използваш map по много неправилен начин. Опитай се да си поиграеш в конзолата с нея, и да видиш как точно работи. with_index е хубаво, но когато искаш да обикаляш паралелно през 2 arrays, има доста по-подходящ метод.

Разгледай obstacle_ahead? Наличието на if е излишно. Помисли как можеш да го избегнеш.

При new_food можеш да използваш доста по-ефективен подход. Къде е най-разумно да търсиш свободно поле?

Мирослав обнови решението на 18.10.2015 13:20 (преди над 9 години)

def grow(snake, direction)
- new_head = []
- snake.last.map.with_index {
- |element, index| new_head.push(element + direction[index])
- }
- snake + [ new_head ]
+ snake + [ snake.last.zip(direction).map do |new_head_position|
+ new_head_position.inject(:+)
+ end ]
end
def move(snake, direction)
grow(snake, direction).drop(1)
end
def obstacle_ahead?(snake, direction, dimensions)
- answer = false
snake_head_after_move = move(snake, direction).last
- if snake.include?(snake_head_after_move) or
+ snake.include?(snake_head_after_move) or
snake_head_after_move.max >= dimensions[:width] or
- snake_head_after_move.max >= dimensions[:height] then
- answer = true
- end
- answer
+ snake_head_after_move.max >= dimensions[:height]
end
def danger?(snake, direction, dimensions)
first_move = obstacle_ahead?(snake, direction, dimensions)
moved_snake = move(snake, direction)
second_move = obstacle_ahead?(moved_snake, direction, dimensions)
first_move && second_move
end
def new_food(food, snake, dimensions)
- random_food = snake.first
- while food.include?(random_food) or snake.include?(random_food)
- random_food = [ Random.rand(dimensions[:width]),
- Random.rand(dimensions[:height]) ]
- end
- random_food
+ widths = [*0..(dimensions[:width] - 1)]
+ heights = [*0..(dimensions[:height] - 1)]
+ (widths.product(heights) - food - snake).sample
end

snake_head_after_move.max >= dimensions[:width] Мислиш ли, че това няма да доведе до грешен резултат понякога(заедно с долното)

Освен това изпускаш случаи в функцията

first_move не е добро име за резултата от obstacle_ahead? Можеш и да запишеш малко по-кратко danger?, без толкова много временни променливи.

Иначе, вече изглежда доста добре!

Мирослав обнови решението на 18.10.2015 14:26 (преди над 9 години)

def grow(snake, direction)
snake + [ snake.last.zip(direction).map do |new_head_position|
new_head_position.inject(:+)
end ]
end
def move(snake, direction)
grow(snake, direction).drop(1)
end
def obstacle_ahead?(snake, direction, dimensions)
snake_head_after_move = move(snake, direction).last
snake.include?(snake_head_after_move) or
- snake_head_after_move.max >= dimensions[:width] or
- snake_head_after_move.max >= dimensions[:height]
+ snake_head_after_move[0] >= dimensions[:width] or
+ snake_head_after_move[1] >= dimensions[:height] or
+ snake_head_after_move.min < 0
end
def danger?(snake, direction, dimensions)
- first_move = obstacle_ahead?(snake, direction, dimensions)
- moved_snake = move(snake, direction)
- second_move = obstacle_ahead?(moved_snake, direction, dimensions)
- first_move && second_move
+ obstacle_ahead?(snake, direction, dimensions) &&
+ obstacle_ahead?(move(snake, direction), direction, dimensions)
end
def new_food(food, snake, dimensions)
widths = [*0..(dimensions[:width] - 1)]
heights = [*0..(dimensions[:height] - 1)]
(widths.product(heights) - food - snake).sample
end