From ab20da75568c1b1d6ca7b91311c114c05968f957 Mon Sep 17 00:00:00 2001 From: Ayan Choudhary Date: Mon, 7 Nov 2022 15:20:01 +0530 Subject: [PATCH] add challenges and solutions for level-2 --- Level-2/dont-get-volunteered/challenge.txt | 57 ++++++++++++++++++++++ Level-2/dont-get-volunteered/solution.py | 52 ++++++++++++++++++++ Level-2/ion-flux-relabeling/challenge.txt | 47 ++++++++++++++++++ Level-2/ion-flux-relabeling/solution.py | 47 ++++++++++++++++++ README.md | 3 +- 5 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 Level-2/dont-get-volunteered/challenge.txt create mode 100644 Level-2/dont-get-volunteered/solution.py create mode 100644 Level-2/ion-flux-relabeling/challenge.txt create mode 100644 Level-2/ion-flux-relabeling/solution.py diff --git a/Level-2/dont-get-volunteered/challenge.txt b/Level-2/dont-get-volunteered/challenge.txt new file mode 100644 index 0000000..e886d8b --- /dev/null +++ b/Level-2/dont-get-volunteered/challenge.txt @@ -0,0 +1,57 @@ +Don't Get Volunteered! +====================== + +As a henchman on Commander Lambda's space station, you're expected to be resourceful, smart, and a quick thinker. It's not easy building a doomsday device and ordering the bunnies around at the same time, after all! In order to make sure that everyone is sufficiently quick-witted, Commander Lambda has installed new flooring outside the henchman dormitories. It looks like a chessboard, and every morning and evening you have to solve a new movement puzzle in order to cross the floor. That would be fine if you got to be the rook or the queen, but instead, you have to be the knight. Worse, if you take too much time solving the puzzle, you get "volunteered" as a test subject for the LAMBCHOP doomsday device! + +To help yourself get to and from your bunk every day, write a function called solution(src, dest) which takes in two parameters: the source square, on which you start, and the destination square, which is where you need to land to solve the puzzle. The function should return an integer representing the smallest number of moves it will take for you to travel from the source square to the destination square using a chess knight's moves (that is, two squares in any direction immediately followed by one square perpendicular to that direction, or vice versa, in an "L" shape). Both the source and destination squares will be an integer between 0 and 63, inclusive, and are numbered like the example chessboard below: + +------------------------- +| 0| 1| 2| 3| 4| 5| 6| 7| +------------------------- +| 8| 9|10|11|12|13|14|15| +------------------------- +|16|17|18|19|20|21|22|23| +------------------------- +|24|25|26|27|28|29|30|31| +------------------------- +|32|33|34|35|36|37|38|39| +------------------------- +|40|41|42|43|44|45|46|47| +------------------------- +|48|49|50|51|52|53|54|55| +------------------------- +|56|57|58|59|60|61|62|63| +------------------------- + +Languages +========= + +To provide a Python solution, edit solution.py +To provide a Java solution, edit Solution.java + +Test cases +========== +Your code should pass the following test cases. +Note that it may also be run against hidden test cases not shown here. + +-- Python cases -- +Input: +solution.solution(0, 1) +Output: + 3 + +Input: +solution.solution(19, 36) +Output: + 1 + +-- Java cases -- +Input: +Solution.solution(19, 36) +Output: + 1 + +Input: +Solution.solution(0, 1) +Output: + 3 diff --git a/Level-2/dont-get-volunteered/solution.py b/Level-2/dont-get-volunteered/solution.py new file mode 100644 index 0000000..c323104 --- /dev/null +++ b/Level-2/dont-get-volunteered/solution.py @@ -0,0 +1,52 @@ +def solution(src, dest): + # all possible directions the knight can move + possible_moves = [(2,1), (2,-1), (-2,1), (-2,-1), (1,2), (1,-2), (-1,2), (-1,-2)] + + # check if src and dest in bounds + if src < 0 or src >= 64 or dest < 0 or dest >= 64: + return 0 + + # if src and dest are same return 0 + if src == dest: + return 0 + + # convert src and dest to cartesian system + src = (src//8, src%8) + dest = (dest//8, dest%8) + + queue = list() + queue.append(src) + + visited = [[False for _ in range(9)] for _ in range(9)] + current_moves = 0 + + # bfs to find the dest starting from src + while len(queue) > 0: + # make a copy of the current queue state + current_queue = queue.copy() + + for pos in current_queue: + current = pos + queue.pop(0) # remove current cell from queue + + visited[current[0]][current[1]] = True # set current cell visited status to true + + for move in possible_moves: + new_place = (current[0]+move[0], current[1]+move[1]) # new cell to visit next + new_place_integer = new_place[0]*8 + new_place[1] # convert to integer to check out of bounds + if new_place_integer < 0 or new_place_integer >= 64: + continue + elif new_place == dest: + return current_moves+1 + else: + if not visited[new_place[0]][new_place[1]]: # prevent duplication of computing if cell is visited + queue.append(new_place) # add new cell to the queue + current_moves += 1 + + return 0 + +if __name__ == '__main__': + print(solution(19, 36)) + print(solution(0, 1)) + + diff --git a/Level-2/ion-flux-relabeling/challenge.txt b/Level-2/ion-flux-relabeling/challenge.txt new file mode 100644 index 0000000..7e3fd6d --- /dev/null +++ b/Level-2/ion-flux-relabeling/challenge.txt @@ -0,0 +1,47 @@ +Ion Flux Relabeling +=================== + +Oh no! Commander Lambda's latest experiment to improve the efficiency of the LAMBCHOP doomsday device has backfired spectacularly. The Commander had been improving the structure of the ion flux converter tree, but something went terribly wrong and the flux chains exploded. Some of the ion flux converters survived the explosion intact, but others had their position labels blasted off. Commander Lambda is having her henchmen rebuild the ion flux converter tree by hand, but you think you can do it much more quickly -- quickly enough, perhaps, to earn a promotion! + +Flux chains require perfect binary trees, so Lambda's design arranged the ion flux converters to form one. To label them, Lambda performed a post-order traversal of the tree of converters and labeled each converter with the order of that converter in the traversal, starting at 1. For example, a tree of 7 converters would look like the following: + + 7 + 3 6 +1 2 4 5 + +Write a function solution(h, q) - where h is the height of the perfect tree of converters and q is a list of positive integers representing different flux converters - which returns a list of integers p where each element in p is the label of the converter that sits on top of the respective converter in q, or -1 if there is no such converter. For example, solution(3, [1, 4, 7]) would return the converters above the converters at indexes 1, 4, and 7 in a perfect binary tree of height 3, which is [3, 6, -1]. + +The domain of the integer h is 1 <= h <= 30, where h = 1 represents a perfect binary tree containing only the root, h = 2 represents a perfect binary tree with the root and two leaf nodes, h = 3 represents a perfect binary tree with the root, two internal nodes and four leaf nodes (like the example above), and so forth. The lists q and p contain at least one but no more than 10000 distinct integers, all of which will be between 1 and 2^h-1, inclusive. + +Languages +========= + +To provide a Java solution, edit Solution.java +To provide a Python solution, edit solution.py + +Test cases +========== +Your code should pass the following test cases. +Note that it may also be run against hidden test cases not shown here. + +-- Java cases -- +Input: +Solution.solution(5, {19, 14, 28}) +Output: + 21,15,29 + +Input: +Solution.solution(3, {7, 3, 5, 1}) +Output: + -1,7,6,3 + +-- Python cases -- +Input: +solution.solution(3, [7, 3, 5, 1]) +Output: + -1,7,6,3 + +Input: +solution.solution(5, [19, 14, 28]) +Output: + 21,15,29 diff --git a/Level-2/ion-flux-relabeling/solution.py b/Level-2/ion-flux-relabeling/solution.py new file mode 100644 index 0000000..9cb3088 --- /dev/null +++ b/Level-2/ion-flux-relabeling/solution.py @@ -0,0 +1,47 @@ +def get_parent_index(h, idx): + ## calculate the maximum index first + ## if the input is too large, return a negative 1 + max_idx = 2**h - 1 + if max_idx < idx: + return -1 + + # otherwise, carry on + else: + node_offset = 0 + continue_flag = True + subtree_size = max_idx + result = -1 # default result + + while continue_flag: + if subtree_size == 0: + continue_flag = False + + # right shift is equivalent to dividing by 2 and discarding the remainder. + subtree_size = subtree_size >> 1 + + # predict the left node + left_node = node_offset + subtree_size + + # predict the right node + right_node = left_node + subtree_size + + # calculate my node value + my_node = right_node + 1 + + # if either child is a match, return my node value + if (left_node == idx) or (right_node == idx): + result = my_node + continue_flag = False + + # Make the current left child the offset if the index is greater than the left. + # This effectively searches down the right subtree. + if (idx > left_node): + node_offset = left_node + + return result + +def solution(h, q): + return [ get_parent_index(h, x) for x in q ] + +if __name__ == '__main__': + print(solution(4,[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])) \ No newline at end of file diff --git a/README.md b/README.md index 9df3458..6441116 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# foobar \ No newline at end of file +# foobar +My submission to the google FooBar challenge. \ No newline at end of file