Created
October 12, 2024 15:33
-
-
Save shadowdevnotreal/7b0b18b6376361b09cc9bba9065b48b9 to your computer and use it in GitHub Desktop.
bit-reversal permutation prompt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Here's how we can design a clear prompt and provide the corresponding code while ensuring that we strictly follow the rules laid out earlier. This prompt will guide the LLM step by step through the process of inverting the tree and verifying the correctness by using the truth table testing method. | |
| Final Prompt: Bit-Reversal Tree Inversion | |
| Objective: Implement an invert function that performs a bit-reversal permutation on a perfect binary tree. Follow the rules and verify the solution using a truth table-like test to ensure that the original tree is restored after double inversion. | |
| Constraints: | |
| 1. Only use the invert function: You are not allowed to define or use any additional functions other than invert. | |
| 2. Use the following types: | |
| Nat: A natural number type. | |
| Bit: A type representing bits (O for 0, I for 1). | |
| Tree (A : Set) : Nat → Set: A binary tree where A is the type of values, and Nat represents the depth of the tree. | |
| 3. Recursion only: Loops are not allowed; recursion should be used to traverse and modify the tree. | |
| 4. No mutability: Your function must be pure, meaning no external state or mutable variables. | |
| 5. 1 bit of state: You may use 1 bit (O or I) as extra state to track and guide the inversion process. | |
| 6. Pattern-matching and constructors: You are allowed to use pattern matching and tree constructors (N for nodes, L for leaves). | |
| Data Types: | |
| data Nat : Set where | |
| Z : Nat -- Base case for zero depth | |
| S : Nat → Nat -- Successor case for depth | |
| data Bit : Set where | |
| O : Bit -- Bit 0 | |
| I : Bit -- Bit 1 | |
| data Tree (A : Set) : Nat → Set where | |
| N : ∀ {d} → Tree A d → Tree A d → Tree A (S d) -- Node with two children | |
| L : Nat → Tree A Z -- Leaf with a value | |
| Task: | |
| Implement the following function: | |
| invert : ∀ {A d} → Bit → Tree A d → Tree A d | |
| This function must invert the tree recursively by swapping left and right subtrees based on the bit value (I or O). | |
| If the bit is O, do not swap the subtrees. | |
| If the bit is I, swap the left and right subtrees. | |
| For leaf nodes (L), return them as-is. | |
| Verification with Double Inversion: | |
| To ensure the correctness of your solution, invert the tree twice: | |
| The first inversion should apply the bit-reversal permutation. | |
| The second inversion should restore the original tree. | |
| Use the truth table concept to exhaustively check if the double inversion returns the original tree for different configurations. | |
| Example of Double Inversion: | |
| -- Original Tree: | |
| N (N (L 0) (L 1)) (N (L 2) (L 3)) | |
| -- After First Inversion (with bit I): | |
| N (N (L 1) (L 0)) (N (L 3) (L 2)) | |
| -- After Second Inversion (with bit I): | |
| N (N (L 0) (L 1)) (N (L 2) (L 3)) -- Should match the original tree | |
| Step-by-Step Instructions: | |
| 1. Base Case (Leaf Node): If the input is a leaf (L), return it unchanged. | |
| 2. Recursive Case (Internal Node): For each internal node (N left right), recursively invert the left and right subtrees: | |
| If the bit is O, do not swap the left and right subtrees. | |
| If the bit is I, swap the left and right subtrees. | |
| 3. Return the New Tree: Return the modified tree with swapped or unswapped children depending on the bit. | |
| 4. Test by Reversing: After inverting the tree once, apply the inversion again and check if the result matches the original tree. | |
| --- | |
| Example Walkthrough (Step-by-Step): | |
| 1. Original Tree: N (N (L 0) (L 1)) (N (L 2) (L 3)) | |
| 2. Inversion with Bit I: | |
| N (N (L 1) (L 0)) (N (L 3) (L 2)) | |
| 3. Second Inversion with Bit I: | |
| N (N (L 0) (L 1)) (N (L 2) (L 3)) -- Matches the original tree | |
| --- | |
| Truth Table Test Code: | |
| Below is the code to implement the invert function and verify its correctness using the truth table approach: | |
| class TreeNode: | |
| """Binary Tree Node with a key and left/right children.""" | |
| def __init__(self, key, left=None, right=None): | |
| self.key = key # The "key" corresponds to the bit or data (Nat in this case) | |
| self.left = left | |
| self.right = right | |
| def invert_tree(bit, node): | |
| """Recursive function to invert the tree by reversing the key bits and swapping children.""" | |
| if node is None: | |
| return None # Base case: no node to invert | |
| if isinstance(node, TreeNode): | |
| if bit == 'I': | |
| # Swap left and right if bit is I | |
| return TreeNode(node.key, invert_tree(bit, node.right), invert_tree(bit, node.left)) | |
| else: | |
| # Do not swap if bit is O | |
| return TreeNode(node.key, invert_tree(bit, node.left), invert_tree(bit, node.right)) | |
| # Function to compare two trees | |
| def are_trees_equal(t1, t2): | |
| if t1 is None and t2 is None: | |
| return True | |
| if t1 is None or t2 is None: | |
| return False | |
| return (t1.key == t2.key) and are_trees_equal(t1.left, t1.left) and are_trees_equal(t1.right, t2.right) | |
| # Helper function to display tree structure | |
| def print_tree(node, level=0, prefix="Root: "): | |
| if node is not None: | |
| print(" " * (level * 4) + prefix + str(node.key)) | |
| print_tree(node.left, level + 1, "L--- ") | |
| print_tree(node.right, level + 1, "R--- ") | |
| # Let's build a simple depth-2 tree for testing | |
| def build_depth2_tree(): | |
| return TreeNode(0, | |
| TreeNode(1, | |
| TreeNode(2), TreeNode(3)), | |
| TreeNode(4, | |
| TreeNode(5), TreeNode(6))) | |
| # Let's build a simple depth-1 tree for testing | |
| def build_depth1_tree(): | |
| return TreeNode(0, TreeNode(1), TreeNode(2)) | |
| # Truth table test for depth 1 and depth 2 trees | |
| def truth_table_test(): | |
| trees = [build_depth1_tree(), build_depth2_tree()] | |
| for i, tree in enumerate(trees): | |
| print(f"\nTesting Tree {i + 1}:") | |
| # Display the original tree | |
| print("Original Tree Structure:") | |
| print_tree(tree) | |
| # First inversion | |
| inverted_tree = invert_tree('I', tree) | |
| print("\nInverted Tree Structure:") | |
| print_tree(inverted_tree) | |
| # Second inversion (should return to original) | |
| double_inverted_tree = invert_tree('I', inverted_tree) | |
| print("\nDouble Inverted Tree Structure (Should match Original):") | |
| print_tree(double_inverted_tree) | |
| # Check if the double inversion matches the original | |
| if are_trees_equal(tree, double_inverted_tree): | |
| print("\nResult: Pass (Tree restored correctly after double inversion)") | |
| else: | |
| print("\nResult: Fail (Tree not restored correctly)") | |
| # Run the truth table test | |
| truth_table_test() | |
| Output: | |
| The truth table test will systematically check whether applying the invert function twice restores the original tree structure. | |
| For each test case (depth-1 and depth-2 trees), it will display the tree before and after inversion, and confirm if the result passes. | |
| This prompt and code will ensure that the LLM follows the given constraints and verifies the correctness of its implementation through structured testing. |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It should produce this python code for testing:
class TreeNode:
"""Binary Tree Node with a key and left/right children."""
def init(self, key, left=None, right=None):
self.key = key # The "key" corresponds to the bit or data (Nat in this case)
self.left = left
self.right = right
def invert_tree(bit, node):
"""Recursive function to invert the tree by reversing the key bits and swapping children."""
if node is None:
return None # Base case: no node to invert
if isinstance(node, TreeNode):
if bit == 'I':
# Swap left and right if bit is I
return TreeNode(node.key, invert_tree(bit, node.right), invert_tree(bit, node.left))
else:
# Do not swap if bit is O
return TreeNode(node.key, invert_tree(bit, node.left), invert_tree(bit, node.right))
Function to compare two trees
def are_trees_equal(t1, t2):
if t1 is None and t2 is None:
return True
if t1 is None or t2 is None:
return False
return (t1.key == t2.key) and are_trees_equal(t1.left, t2.left) and are_trees_equal(t1.right, t2.right)
Helper function to display tree structure
def print_tree(node, level=0, prefix="Root: "):
if node is not None:
print(" " * (level * 4) + prefix + str(node.key))
print_tree(node.left, level + 1, "L--- ")
print_tree(node.right, level + 1, "R--- ")
Let's build a simple depth-2 tree for testing
def build_depth2_tree():
return TreeNode(0,
TreeNode(1,
TreeNode(2), TreeNode(3)),
TreeNode(4,
TreeNode(5), TreeNode(6)))
Let's build a simple depth-1 tree for testing
def build_depth1_tree():
return TreeNode(0, TreeNode(1), TreeNode(2))
Truth table test for depth 1 and depth 2 trees
def truth_table_test():
trees = [build_depth1_tree(), build_depth2_tree()]
Run the truth table test
truth_table_test()