Google Foobar Challenge Save Beta Rabbit in Python

Coding Challenge Coding Live

Sign uporlog into customize your list.

I only need two loop to solve this problem. Outer loop for each row. Inner loop for each column. Always take the maximum between the sum of adding left element and the sum of adding top element as long as not exceeding the food amount.

Why does \x-1 not work in node name?

Actually, as @Jaime points out in a comment, DP can be a more important thing to try. In the current implementation, some sub-paths are checked multiple times. Using DP will cut down on those, and will surely get you pass the time limit

Each decision (move right or left) is based solely on finding the room that minimizes the amount of food rabbit will have remaining after moving there. (i.e. we need to have a proper comparator for the nodes in the graph)

Making a nail electromagnet with bare copper wire?

I tried, the one without the Memorization. On my computer your method is 20% faster than mine

Which of these two codes are better? Making a local variable or a class variable?

Rabbit can never go to a room that will result in havingfood 0, otherwise hell be eaten!

In the American westthe world of cowboys and cowhandswas ammunition traded for alcoholic shots of a drink?

@Andrew you can find maximum number of food needed and minimum number of food needed by using only two loops (N^2) instead of listing all possible paths. If amount of food Beta Rabbit is less than minimum number of food then return -1 else backtrack maximum path and modify it until equal or less than Betta Rabbit food amount.

def smallest_remainder(total, grid): Return the smallest remainder from total after subtracting the numbers on a path from top left to bottom right of grid, or -1 if there is no path whose sum is less than or equal to total. smallest_remainder(7, [[0, 2, 5], [1, 1, 3], [2, 1, 1]]) 0 smallest_remainder(12, [[0, 2, 5], [1, 1, 3], [2, 1, 1]]) 1 def r(t, i, j): Smallest remainder from t after subtracting the numbers on a path from top left to (i, j) in grid, or total + 1 if there is no path whose sum is less than or equal to t. t -= grid[i][j] if i 0 or j 0 or t 0: return total + 1 elif i == j == 0: return t else: return min(r(t, i – 1, j), r(t, i, j – 1)) remainder = r(total, len(grid) – 1, len(grid) – 1) return remainder if remainder = total else -1

Is a space containing the corpse of a dead creature considered difficult terrain?

Beta Rabbit starts at the top left room of the grid. For each room in the grid, there is a door to the room above, below, left, and right. There is no door in cases where there is no room in that direction. However, the doors are locked in such a way that Beta Rabbit can only ever move to the room below or to the right. Once Beta Rabbit enters a room, the zombie immediately starts crawling towards him, and he must feed the zombie until it is full to ward it off. Thankfully, Beta Rabbit took a class about zombies and knows how many units of food each zombie needs be full.

Inputs: (int) food = 7 (int) grid = [[0, 2, 5], [1, 1, 3], [2, 1, 1]] Output: (int) 0 Inputs: (int) food = 12 (int) grid = [[0, 2, 5], [1, 1, 3], [2, 1, 1]] Output: (int) 1

Ah, thanks. Thats good. Unfortunately, it still surpasses the time limit.

This will cut down on the number of paths that will be evaluated. Hopefully that helps.

Did you measure the performance of your solution? If you dont measure, then youll have no idea how far off you are from a solution thats good enough.

So for a 20 * 20 grid, your algorithm only takes 0.08 second to finish?

Rabbit starts in room[0][0], i.e. the top-left room.

In a post-fossil fuel economy, what could natural gas pipelines be used for?

Given an integer \$1N20\$, an \$NN\$ grid of integers \$1G_ij10\$, a target \$1T200\$,and a position \$(i, j)\$ in the grid, find the path from top left to \$(i, j)\$ (moving right or down at each step) which, when subtracted from \$T\$, leaves the smallest remainder \$r0\$ (if any such path exists).

(Computer scientists will recognize thatrecursionplusmemoizationis very similar to thetabular method, also known asdynamic programming. With the tabular method, you build up a table of values by looping over its cells; with recursion plus memoization you start with an empty table and fill in any cells that you need to compute.)

Help with Method of Undetermined Coefficients

Memoization is most elegantly done using adecorator(this keeps the memoization logic separated from the rest of the code, and makes it reusable too). You could [email protected]_cache, like this:

Detailed answers to any questions you might have

My approach is to generate paths, combinations of 1s/0s (with an equal number of each) representing right/down movement, and following them one by one on the grid, and for each one keeping track of the food the rabbit has left.

How does this explore every possible path if it only moves up and left? Dont you have to move right and down as well?

def answer(food, grid): N = len(grid) ans_grid = [[set() for i in range(N)] for j in range(N)] ans_grid[0][0] = grid[0][0] for (row, row_val) in enumerate(grid): for (col, val) in enumerate(row_val): if row != 0: ans_grid[row][col] = val + x for x in ans_grid[row-1][col] if (val + x) = food if col != 0: ans_grid[row][col] = val + x for x in ans_grid[row][col-1] if (val + x) = food all_ans = sorted(ans_grid[N-1][N-1], reverse=True) for el in all_ans: if el = food: return food-el return -1 food = 7 grid = [[0, 2, 5], [1, 1, 3], [2, 1, 1]] print(answer(food, grid)) food = 12 grid = [[0, 2, 5], [1, 1, 3], [2, 1, 1]] print(answer(food, grid))

Start here for a quick overview of the site

If you dont mind, can you write some example code? Im afraid I still dont understand.

How long does the original code take? Well, it examines all paths from top left to bottom right in the grid, unless it gets lucky and find a path with remainder 0, in which case it exits early. But this test case is carefully designed so that there are no paths with remainder 0 (the maximum sum on any path is \$395 = 195\$).

So lets generate the largest possible test case (given the constraints in the problem description):

Why arent Americans simply called Americans?

Why did Europeans (and not people in other regions) dominate oceans?

@user124384: The problem says, the doors are locked in such a way that Beta Rabbit can only ever move to the room below or to the right.

Learn more about hiring developers or posting ads with us

To avoid this kind of duplicated work, the functionrshould bememoized. That is, it should maintain a table of values that it has already computed, and return an entry from the table if possible.

This is probably easier to understand by reading the code:

The number of rows N will not exceed 20, and the amount of food each zombie requires will be a positive integer not exceeding 10.

To be freed, Beta Rabbit needs to make his way to the bottom right room (which also has a hungry zombie) and have used most of the limited food he has. He decides to take the path through the grid such that he ends up with as little food as possible at the end.

Hmm, Im not sure how this would work. If Im always taking the maximum of those two, then it seems like the food would go down to critical levels quite quickly, and Ill be stuck far from the goal corner with not enough food to continue. Or, if Im not understanding you, then whats the meaning of your solution? How do I determine the food left from those numbers?

What could people notice about someone who is two times as dense as a regular person?

site design / logo 2018 Stack Exchange Inc; user contributions licensed undercc by-sa 3.0withattribution required.rev2018.6.8.30702

Why did Ripley burn the eggs after she rescued Newt?

Justifying the multi-variable chain rule to students

Oh no! The mad Professor Boolean has trapped Beta Rabbit in an NxN grid of rooms. In the center of each room (except for the top left room) is a hungry zombie. In order to be freed, and to avoid being eaten, Beta Rabbit must move through this grid and feed the zombies.

You dont say what the time limit is, but Im guessing that its a few seconds at most. When a program is this far away from meeting the time limit, its no good trying to optimize what youre got: instead, you have to completely rethink the algorithm.

I add an example code in the answer for you @Andrew

from functools import lru_cache def smallest_remainder(total, grid): Return the smallest remainder from total after subtracting the numbers on a path from top left to bottom right of grid, or -1 if there is no path whose sum is less than or equal to total. smallest_remainder(7, [[0, 2, 5], [1, 1, 3], [2, 1, 1]]) 0 smallest_remainder(12, [[0, 2, 5], [1, 1, 3], [2, 1, 1]]) 1 @lru_cache(maxsize=None) def r(t, i, j): Smallest remainder from t after subtracting the numbers on a path from top left to (i, j) in grid, or total + 1 if there is no path whose sum is less than or equal to t. t -= grid[i][j] if i 0 or j 0 or t 0: return total + 1 elif i == j == 0: return t else: return min(r(t, i – 1, j), r(t, i, j – 1)) remainder = r(total, len(grid) – 1, len(grid) – 1) return remainder if remainder = total else -1

Finding the most efficient paths to cover an area from multiple starting locations

food is the amount of food Beta Rabbit starts with, and will be a positive integer no larger than 200.

Thank you! This answer worked great since I couldnt answer it in time, and I

With those things in mind, Ive coded this up in python with the needed tests to verify. Its a basic breadth-first traversal, but we use a min-queue instead of a normal FIFO queue to enforce the constraints.

Given an integer \$1N20\$, an \$NN\$ grid of integers \$1G_ij10\$, and a target \$1T200\$, find the path from top left to bottom right in the grid (moving right or down at each step) which, when subtracted from \$T\$, leaves the smallest remainder \$r0\$ (if any such path exists).

How did the Greeks keep a prytaneum alight in storms?

The trouble with this implementation is that the same subproblems are encountered several times. To solve the subproblem for \$(t=20,i=5,j=5)\$ you may need to solve the subproblems \$(t=18,i=4,j=5)\$ and \$(t=18,i=5,j=4)\$ and both of these may need you to solve the subproblem \$(t=17,i=4,j=4)\$.

Is statistic about Latinos/Hispanic with PhD in USA correct?

We can solve these problems recursively: to find the solution for the parameters \$(T, i, j)\$, consider the last step on the path, which must have been down or right. If the last step was down, then the rest of the path is given by the solution for the parameters \$(T – G_ij, i, j-1)\$; if the last step was right, the rest of the path is given by the solution for the parameters \$(T – G_ij, i-1, j)\$. The direction of the last step is determined by whichever is the better of these two solutions.

Understanding the CMB background as a reference frame and motion of earth w.r.t CMB

That is, you can change the condition to this:

grid will be a list of N elements. Each element of grid will itself be a list of N integers each, denoting a single row of N rooms. The first element of grid will be the list denoting the top row, the second element will be the list denoting second row from the top, and so on until the last element, which is the list denoting the bottom row. In the list denoting a single row, the first element will be the amount of food the zombie in the left-most room in that row needs, the second element will be the amount the zombie in the room to its immediate right needs and so on. The top left room will always contain the integer 0, to indicate that there is no zombie there.

This site uses cookies to deliver our services and to show you relevant ads and job listings. By using our site, you acknowledge that you have read and understand ourCookie PolicyPrivacy Policy, and ourTerms of Service. Your use of Stack Overflows Products and Services, including the Stack Overflow Network, is subject to these policies and terms.

Combinatorial problems like this can often be solved recursively, that is, by breaking them down into subproblems and combining the solutions.

Can I choose to reduce the damage of my attack cantrips?

Im going through the Google Foobar challenges and am currently on the first challenge of level three. Ive come up with a working solution, however, its not an acceptable solution because it runs out of time. How can I optimize it?

Since every zombie requires at least 1 unit of food, if there are \$k\$ moves left, then at that point, if you dont have \$k\$ units of food left, then you can stop, because its clear that you wont reach the exit.

Rooms can only be traversed to the right or below

from random import randrange N = 20 grid = [[randrange(1, 6) for _ in range(N)] for _ in range(N)] T = 200

The rabbit, professor, zombies and food are just set-dressing. They are distractions from the actual problem, which can be stated much more briefly:

Discuss the workings and policies of this site

Humans are Gone: Do the Chickens Make It?

understand it…looking forward to my algorithms class to understand this kind of stuff better.

What are the software logos in MORICONS.DLL?

timeit(lambda:smallest_remainder(T, grid), number=1) 0.91

There are \$2N-2 \choose N-1 = \$ paths through this grid. On my computer I find thatanswerexamines about \$60000\$ paths a second, so it will take about 7 days to finish!

Can you cure pork belly with skin and not replace the water?

Python Code (listing all combination)

And this takes a fraction of a second to solve the test case from 1 above:

Name of novel from the 80s: Brain harvested and forced to fight in a war

Learn more about Stack Overflow the company

Note that Ive defined the helper functionrso that it returnstotal + 1for unsuitable paths, not-1. Thats so the best path can easily be selected by callingmin. (Try adjusting this function to use-1for unsuitable paths: youll see that the selection logic becomes more complex.)

Stack Exchange network consists of 174 Q&A communities includingStack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Write a function answer(food, grid) that returns the number of units of food Beta Rabbit will have at the end, given that he takes a route using up as much food as possible without him being eaten, and ends at the bottom right room. If there does not exist a route in which Beta Rabbit will not be eaten, then return -1.

This problem is a classic shortest-path traversal of a graph and youd do well to make use of Dijkstras algorithm for solving this. The key is in properly defining the vertices (nodes), and also making use of a min-heap (priority-queue) to keep track of the next room which would give you the lowest amount of food remaining from the current position.

import unittest import heapq class Node: def __init__(self, food, position): self.food_remaining = food self.position = position def __lt__(self, other): return self.food_remaining other.food_remaining def ZombieGrid(food, grid): grid_height = len(grid) grid_width = len(grid[0]) pq = [] Rabbit starts in the top-left corner: 0,0 heapq.heappush(pq, Node(food, (0,0))) while len(pq) 0: top = heapq.heappop(pq) once were in the bottom-right corner then we are done if top.position == (grid_height-1, grid_width-1): return top.food_remaining try moving down if top.position[0] grid_height-1: will use the food up for the room below food_for_room_below = grid[top.position[0]+1][top.position[1]] dont go to the room if we will get eaten! if top.food_remaining – food_for_room_below = 0: heapq.heappush(pq, Node(top.food_remaining – food_for_room_below, (top.position[0] + 1, top.position[1]) )) try moving right, same logic as for moving down if top.position[1] grid_width-1: food_for_room_right = grid[top.position[0]][top.position[1]+1] if top.food_remaining – food_for_room_right = 0: heapq.heappush(pq, Node(top.food_remaining – food_for_room_right, (top.position[0], top.position[1] + 1) )) class UnitTests(unittest.TestCase): def test_first(self): self.assertEqual(0, ZombieGrid(7, [[0, 2, 5], [1, 1, 3], [2, 1, 1]])) def test_second(self): self.assertEqual(1, ZombieGrid(12, [[0, 2, 5], [1, 1, 3], [2, 1, 1]]))

Once we get to the bottom-right room, were done!

import itertools def answer(food, grid): dimension of NxN grid n = len(grid) results = [] max coordinate (length – 1) maxdir = n – 1 total moves to navigate to bottom right corner total = maxdir * 2 generator creates combinations of the bits to flip for bits in binations(range(total), maxdir): create path (1 is go right, 0 is go down) path = [0] * total for bit in bits: path[bit] = 1 current food left and coordinates foodleft = food x = 0 y = 0 follow steps in path for step in path: if step: x += 1 else: y += 1 get food needed in cell and subtract from foodleft foodat = grid[y][x] foodleft -= foodat if he runs out of food, hes dead so skip if foodleft 0: break if he makes it to the bottom right cell… if x == maxdir and y == maxdir: if he has 0 food left thats as good as it gets, return 0 if not foodleft: return 0 otherwise keep track of food left and add to results results.append(foodleft) return the minimum food left if there was a survivable path if results: return min(results) else: return -1

By clicking Post Your Answer, you acknowledge that you have read our updatedterms of serviceprivacy policyandcookie policy, and that your continued use of the website is subject to these policies.

Leave a Reply