InternBootcamp/internbootcamp/bootcamp/cguessyourwayout/cguessyourwayout.py
2025-05-23 15:27:15 +08:00

179 lines
5.3 KiB
Python
Executable file

"""#
### 谜题描述
Amr bought a new video game \"Guess Your Way Out!\". The goal of the game is to find an exit from the maze that looks like a perfect binary tree of height h. The player is initially standing at the root of the tree and the exit from the tree is located at some leaf node.
Let's index all the leaf nodes from the left to the right from 1 to 2h. The exit is located at some node n where 1 ≤ n ≤ 2h, the player doesn't know where the exit is so he has to guess his way out!
Amr follows simple algorithm to choose the path. Let's consider infinite command string \"LRLRLRLRL...\" (consisting of alternating characters 'L' and 'R'). Amr sequentially executes the characters of the string using following rules:
* Character 'L' means \"go to the left child of the current node\";
* Character 'R' means \"go to the right child of the current node\";
* If the destination node is already visited, Amr skips current command, otherwise he moves to the destination node;
* If Amr skipped two consecutive commands, he goes back to the parent of the current node before executing next command;
* If he reached a leaf node that is not the exit, he returns to the parent of the current node;
* If he reaches an exit, the game is finished.
Now Amr wonders, if he follows this algorithm, how many nodes he is going to visit before reaching the exit?
Input
Input consists of two integers h, n (1 ≤ h ≤ 50, 1 ≤ n ≤ 2h).
Output
Output a single integer representing the number of nodes (excluding the exit node) Amr is going to visit before reaching the exit by following this algorithm.
Examples
Input
1 2
Output
2
Input
2 3
Output
5
Input
3 6
Output
10
Input
10 1024
Output
2046
Note
A perfect binary tree of height h is a binary tree consisting of h + 1 levels. Level 0 consists of a single node called root, level h consists of 2h nodes called leaves. Each node that is not a leaf has exactly two children, left and right one.
Following picture illustrates the sample test number 3. Nodes are labeled according to the order of visit.
<image>
Here is a reference code to solve this task. You can use this to help you genereate cases or validate the solution.
```python
# grr fuck python, give me php_gmp :)
def exit_is_at_branch(h, n, level, direction):
exitBit = n & (2**(h - level - 1))
if direction == 'L':
return (exitBit == 0)
else:
return (exitBit != 0)
def solve(h, n, level = 0, direction = \"L\"):
toBottom = h - level
if toBottom <= 1:
if exit_is_at_branch(h, n, level, direction):
return 0
else:
return 1
else:
if exit_is_at_branch(h, n, level, direction):
if direction == 'L':
newdir = 'R'
else:
newdir = 'L'
return 1 + solve(h, n, level + 1, newdir)
else:
return 2**toBottom -1 + 1 + solve(h, n, level + 1, direction)
(h, n) = raw_input().split(' ')
h = int(h)
n = int(n) - 1
print solve(h, n) + 1
```
请完成上述谜题的训练场环境类实现,包括所有必要的方法。
"""
from bootcamp import Basebootcamp
import random
import re
from bootcamp import Basebootcamp
class Cguessyourwayoutbootcamp(Basebootcamp):
def __init__(self, max_h=50, min_h=1):
super().__init__()
self.max_h = max_h
self.min_h = min_h
def case_generator(self):
h = random.randint(self.min_h, self.max_h)
max_n = 2 ** h
n = random.randint(1, max_n)
return {'h': h, 'n': n}
@staticmethod
def prompt_func(question_case):
h = question_case['h']
n = question_case['n']
return f"""You are playing a game on a perfect binary tree of height {h} where the exit is at the {n}th leaf node.
Amr follows these rules:
1. Uses LRLRLR... command sequence
2. Skips already visited nodes
3. Moves back if two skips occur
4. Returns immediately from wrong leaves
Calculate how many nodes (excluding exit) are visited before reaching the exit.
Put your final answer in [answer]...[/answer], like [answer]5[/answer]."""
@staticmethod
def extract_output(output):
matches = re.findall(r'\[answer\](.*?)\[/answer\]', output, re.DOTALL)
if not matches:
return None
last_match = matches[-1].strip()
numbers = re.findall(r'-?\d+', last_match)
return int(numbers[-1]) if numbers else None
@classmethod
def _verify_correction(cls, solution, identity):
try:
h = identity['h']
n = identity['n'] - 1 # Adjust to 0-based index
def exit_is_at_branch(level, direction):
bit_mask = 1 << (h - level - 1)
expected = 0 if direction == 'L' else bit_mask
return (n & bit_mask) == expected
def solve(level=0, direction='L'):
remaining_levels = h - level
if remaining_levels == 0:
return 0
if remaining_levels == 1:
return 0 if exit_is_at_branch(level, direction) else 1
if exit_is_at_branch(level, direction):
new_dir = 'R' if direction == 'L' else 'L'
return 1 + solve(level+1, new_dir)
else:
return (2 ** remaining_levels) + solve(level+1, direction)
return solution == solve() + 1 # Original code adds 1 in print
except:
return False