Programming is full of games. This one here is about tensor. Your aim is to use a series of transformations provided by the PyTorch module to transform the given tensor to the target one.
Example play:
--- Puzzle 20 of 32 ---
Initial Tensor:
tensor([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
Target Tensor:
tensor([[ 1, 7],
[ 2, 8],
[ 3, 9],
[ 4, 10],
[ 5, 11],
[ 6, 12]])
Enter your operations: reshape 2 -1, transpose 0 1
Correct! You've transformed the tensor successfully.
Current operations (transpose, unsqueeze, squeeze, view, reshape, permute) are limited.
I will consider to add more:
expand or repeat: These operations can be used to increase the size of a tensor by repeating its elements.
cat or stack: These operations combine multiple tensors along a specified dimension.
split or chunk: These operations divide a tensor into multiple smaller tensors.
flip: This operation reverses the order of elements along a specified dimension.
roll: This operation shifts the elements of a tensor along a dimension.
gather or index_select: These operations can be used for more complex indexing tasks.
masked_select: This operation selects elements from a tensor using a boolean mask.
where: This operation can be used for element-wise conditional selection.
unfold: This operation extracts sliding local blocks from a tensor.
diag: This operation can be used to extract a diagonal or construct a diagonal matrix.
import torch
import tensorlevels as levels # Import the puzzles from levels.py
# Define possible operations
def transpose(tensor, dim0, dim1):
return tensor.transpose(dim0, dim1)
def unsqueeze(tensor, dim):
return tensor.unsqueeze(dim)
def squeeze(tensor, dim=None):
return tensor.squeeze(dim)
def view(tensor, *shape):
return tensor.view(*shape)
def reshape(tensor, *shape):
return tensor.reshape(*shape)
def permute(tensor, *dims):
return tensor.permute(*dims)
# Mapping operation names to functions
operations = {
'transpose': transpose,
'unsqueeze': unsqueeze,
'squeeze': squeeze,
'view': view,
'reshape': reshape,
'permute': permute
}
def print_tensor(tensor):
print(tensor)
def parse_arguments(args_str):
"""
Parses a string of arguments separated by commas or spaces.
Supports mixed separators.
"""
args = []
for part in args_str.replace(',', ' ').split():
# Attempt to convert to integer
if part.lstrip('-').isdigit():
args.append(int(part))
else:
# Attempt to convert to float
try:
args.append(float(part))
except ValueError:
args.append(part)
return args
def game():
print("Welcome to the PyTorch Tensor Transformation Game!")
print("Your goal is to transform the initial tensor into the target tensor using PyTorch operations.")
print("Available operations: transpose, unsqueeze, squeeze, view, reshape, permute")
print("Enter operations in sequence, separated by commas.")
print("For operations with arguments, separate arguments by spaces.")
print("For example: transpose 0 1, squeeze\n")
total_levels = len(levels.puzzles)
start_level = 0
# Prompt user for starting level
user_input = input(f"Enter the level index to start from (1 to {total_levels}), press Enter to start from 1: ")
if user_input.strip():
if user_input.isdigit():
idx = int(user_input)
if 1 <= idx <= total_levels:
start_level = idx - 1
else:
print(f"Invalid level index. Starting from level 1.")
else:
print(f"Invalid input. Starting from level 1.")
# Iterate through levels starting from start_level
for idx in range(start_level, total_levels):
puzzle = levels.puzzles[idx]
print(f"\n--- Puzzle {idx + 1} of {total_levels} ---")
print("Initial Tensor:")
print_tensor(puzzle['initial'])
print("\nTarget Tensor:")
print_tensor(puzzle['target'])
while True:
user_input = input("\nEnter your operations: ").strip()
if not user_input:
print("Please enter at least one operation.")
continue
operations_input = [op.strip() for op in user_input.split(',')]
current_tensor = puzzle['initial']
try:
for op_str in operations_input:
if not op_str:
continue
parts = op_str.split()
op_name = parts[0]
args = parse_arguments(' '.join(parts[1:])) # Handle arguments
if op_name not in operations:
raise ValueError(f"Operation '{op_name}' is not recognized.")
current_tensor = operations[op_name](current_tensor, *args)
if torch.equal(current_tensor, puzzle['target']):
print("Correct! You've transformed the tensor successfully.")
break # Move to the next level
else:
print("Incorrect transformation. Here's what you got:")
print_tensor(current_tensor)
print("Expected target tensor:")
print_tensor(puzzle['target'])
print("Try again.\n")
except Exception as e:
print(f"Error applying operations: {e}")
print("Please check your operations and try again.\n")
print("\nCongratulations! You've completed all the puzzles.")
if __name__ == "__main__":
game()
import torch
puzzles = [
# Original Puzzles
{
'initial': torch.tensor([[1, 2], [3, 4]]),
'target': torch.tensor([1, 2, 3, 4]),
'solution': ['view -1'] # Flatten the tensor
},
{
'initial': torch.tensor([1, 2, 3, 4]),
'target': torch.tensor([[1, 2], [3, 4]]),
'solution': ['view 2 2'] # Reshape to 2x2
},
{
'initial': torch.tensor([[1, 2, 3], [4, 5, 6]]),
'target': torch.tensor([[1, 4], [2, 5], [3, 6]]),
'solution': ['transpose 0 1'] # Transpose the tensor
},
# Additional Puzzles
{
'initial': torch.tensor([1, 2, 3, 4]),
'target': torch.tensor([[1, 2, 3, 4]]),
'solution': ['unsqueeze 0'] # Add a new dimension at position 0
},
{
'initial': torch.tensor([[1, 2, 3, 4]]),
'target': torch.tensor([1, 2, 3, 4]),
'solution': ['squeeze 0'] # Remove the dimension at position 0
},
{
'initial': torch.tensor([[1, 2], [3, 4], [5, 6]]),
'target': torch.tensor([1, 3, 5, 2, 4, 6]),
'solution': ['permute 1 0', 'view -1'] # Permute and flatten
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6]),
'target': torch.tensor([[1, 2, 3], [4, 5, 6]]),
'solution': ['view 2 3'] # Reshape to 2x3
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6]),
'target': torch.tensor([[1], [2], [3], [4], [5], [6]]),
'solution': ['view -1 1'] # Reshape to 6x1
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6]),
'target': torch.tensor([[1, 4], [2, 5], [3, 6]]),
'solution': ['view 2 3', 'transpose 0 1'] # Reshape to 2x3 and transpose to 3x2
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'target': torch.tensor([[1, 5], [2, 6], [3, 7], [4, 8]]),
'solution': ['view 2 4', 'transpose 0 1'] # Reshape to 2x4 and transpose to 4x2
},
{
'initial': torch.tensor([[1, 2], [3, 4], [5, 6], [7, 8]]),
'target': torch.tensor([1, 3, 5, 7, 2, 4, 6, 8]),
'solution': ['permute 1 0', 'view -1'] # Permute and flatten
},
{
'initial': torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]),
'target': torch.tensor([1, 5, 2, 6, 3, 7, 4, 8]),
'solution': ['transpose 0 1', 'view -1'] # Transpose and flatten
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'target': torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]),
'solution': ['view 2 4'] # Reshape to 2x4
},
{
'initial': torch.tensor([[1], [2], [3], [4]]),
'target': torch.tensor([1, 2, 3, 4]),
'solution': ['squeeze 1'] # Remove the second dimension
},
{
'initial': torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),
'target': torch.tensor([[1, 5], [2, 6], [3, 7], [4, 8]]),
'solution': ['permute 1 0 2', 'view -1 2'] # Permute and reshape
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'target': torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),
'solution': ['view 2 2 2'] # Reshape to 2x2x2
},
{
'initial': torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),
'target': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'solution': ['view -1'] # Flatten the tensor
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'target': torch.tensor([[1], [2], [3], [4], [5], [6], [7], [8]]),
'solution': ['view 8 1'] # Reshape to 8x1
},
{
'initial': torch.tensor([[1, 2], [3, 4], [5, 6], [7, 8]]),
'target': torch.tensor([1, 3, 5, 7, 2, 4, 6, 8]),
'solution': ['view 2 4', 'permute 1 0'] # Reshape and permute
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
'target': torch.tensor([[1, 7], [2, 8], [3, 9], [4, 10], [5, 11], [6, 12]]),
'solution': ['view 2 6', 'transpose 0 1'] # Reshape to 2x6 and transpose to 6x2
},
{
'initial': torch.tensor([[1, 2, 3], [4, 5, 6]]),
'target': torch.tensor([1, 4, 2, 5, 3, 6]),
'solution': ['transpose 0 1', 'view -1'] # Transpose and flatten
},
{
'initial': torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]),
'target': torch.tensor([1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]),
'solution': ['permute 1 0', 'view -1'] # Permute and flatten
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]),
'target': torch.tensor([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]]),
'solution': ['view 2 2 3'] # Reshape to 2x2x3
},
{
'initial': torch.tensor([1, 2, 3, 4]),
'target': torch.tensor([[[1, 2], [3, 4]]]),
'solution': ['view 1 2 2'] # Reshape to 1x2x2
},
{
'initial': torch.tensor([[[1, 2], [3, 4]]]),
'target': torch.tensor([1, 2, 3, 4]),
'solution': ['squeeze 0'] # Remove the first dimension
},
{
'initial': torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]),
'target': torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]),
'solution': ['view 2 4'] # Reshape to 2x4
},
{
'initial': torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]),
'target': torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),
'solution': ['view 2 2 2'] # Reshape to 2x2x2
},
{
'initial': torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]),
'target': torch.tensor([[1, 2], [3, 4], [5, 6], [7, 8]]),
'solution': ['view -1 2'] # Reshape to 4x2
},
{
'initial': torch.tensor([1, 2, 3, 4]),
'target': torch.tensor([1, 2, 3, 4, 1, 2, 3, 4]),
'solution': ['view 2 4'] # Reshape to 2x4 (Alternatively, use repeat)
},
{
'initial': torch.tensor([1, 2, 3, 4]),
'target': torch.tensor([[1, 1], [2, 2], [3, 3], [4, 4]]),
'solution': ['unsqueeze 1', 'repeat 1 2'] # Add dimension and repeat
},
{
'initial': torch.tensor([[1, 2], [3, 4]]),
'target': torch.tensor([1, 2, 3, 4, 1, 2, 3, 4]),
'solution': ['view -1', 'repeat 2'] # Flatten and repeat
},
{
'initial': torch.tensor([[1, 2, 3], [4, 5, 6]]),
'target': torch.tensor([[[1, 4], [2, 5], [3, 6]]]),
'solution': ['transpose 0 1', 'unsqueeze 0'] # Transpose and add dimension
},
]
import torch
# Create two 1D tensors
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
# Stack along a new dimension (dim=0)
stacked = torch.stack([a, b], dim=0)
print(stacked)
# Output:
# tensor([[1, 2, 3],
# [4, 5, 6]])
# Stack along a new dimension (dim=1)
stacked_dim1 = torch.stack([a, b], dim=1)
print(stacked_dim1)
# Output:
# tensor([[1, 4],
# [2, 5],
# [3, 6]])