mirror of
https://github.com/open-thought/reasoning-gym.git
synced 2026-04-19 12:58:07 +00:00
rotate matrix
This commit is contained in:
parent
def66e0d40
commit
fe83bee725
5 changed files with 362 additions and 0 deletions
161
GALLERY.md
161
GALLERY.md
|
|
@ -24,6 +24,7 @@ This gallery shows examples from all available datasets using their default conf
|
|||
- [gsm_symbolic](#gsm_symbolic)
|
||||
- [intermediate_integration](#intermediate_integration)
|
||||
- [isomorphic_strings](#isomorphic_strings)
|
||||
- [rotate_matrix](#rotate_matrix)
|
||||
- [largest_island](#largest_island)
|
||||
- [lcm](#lcm)
|
||||
- [leg_counting](#leg_counting)
|
||||
|
|
@ -1167,6 +1168,166 @@ Metadata: {'words': ['hogtytyof', 'kgqwfwfgh'], 'solution': True, 'solvable': Tr
|
|||
|
||||
````
|
||||
|
||||
|
||||
### rotate_matrix
|
||||
Rotate a matrix by 90 degrees clockwise
|
||||
|
||||
Default configuration:
|
||||
```python
|
||||
max_n: int = 10 # Maximum size of the matrix
|
||||
```
|
||||
|
||||
````
|
||||
Sample 1:
|
||||
Question: Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
3 1
|
||||
2 0
|
||||
|
||||
Answer:
|
||||
2 3
|
||||
0 1
|
||||
|
||||
Metadata: {'matrix': [[3, 1], [2, 0]], 'solution': [[2, 3], [0, 1]]}
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
Sample 2:
|
||||
Question: Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
0
|
||||
|
||||
Answer:
|
||||
0
|
||||
|
||||
Metadata: {'matrix': [[0]], 'solution': [[0]]}
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
Sample 3:
|
||||
Question: Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
28 17 38 29 8 15 26
|
||||
35 13 37 39 27 40 20
|
||||
4 30 23 16 3 5 48
|
||||
9 25 2 46 47 21 22
|
||||
31 12 41 43 19 32 10
|
||||
6 0 36 45 42 1 18
|
||||
14 24 11 7 44 34 33
|
||||
|
||||
Answer:
|
||||
14 6 31 9 4 35 28
|
||||
24 0 12 25 30 13 17
|
||||
11 36 41 2 23 37 38
|
||||
7 45 43 0 16 39 29
|
||||
44 42 19 47 3 27 8
|
||||
34 1 32 21 5 40 15
|
||||
33 18 10 22 48 20 26
|
||||
|
||||
Metadata: {'matrix': [[28, 17, 38, 29, 8, 15, 26], [35, 13, 37, 39, 27, 40, 20], [4, 30, 23, 16, 3, 5, 48], [9, 25, 2, 46, 47, 21, 22], [31, 12, 41, 43, 19, 32, 10], [6, 0, 36, 45, 42, 1, 18], [14, 24, 11, 7, 44, 34, 33]], 'solution': [[14, 6, 31, 9, 4, 35, 28], [24, 0, 12, 25, 30, 13, 17], [11, 36, 41, 2, 23, 37, 38], [7, 45, 43, 0, 16, 39, 29], [44, 42, 19, 47, 3, 27, 8], [34, 1, 32, 21, 5, 40, 15], [33, 18, 10, 22, 48, 20, 26]]}
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
Sample 4:
|
||||
Question: Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
20 3 6 19 22
|
||||
5 7 17 11 16
|
||||
24 14 12 4 1
|
||||
18 23 21 0 10
|
||||
9 2 8 15 13
|
||||
|
||||
Answer:
|
||||
9 18 24 5 20
|
||||
2 23 14 7 3
|
||||
8 21 0 17 6
|
||||
15 0 4 11 19
|
||||
13 10 1 16 22
|
||||
|
||||
Metadata: {'matrix': [[20, 3, 6, 19, 22], [5, 7, 17, 11, 16], [24, 14, 12, 4, 1], [18, 23, 21, 0, 10], [9, 2, 8, 15, 13]], 'solution': [[9, 18, 24, 5, 20], [2, 23, 14, 7, 3], [8, 21, 0, 17, 6], [15, 0, 4, 11, 19], [13, 10, 1, 16, 22]]}
|
||||
|
||||
--------------------------------------------------
|
||||
|
||||
Sample 5:
|
||||
Question: Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
1 2
|
||||
0 3
|
||||
|
||||
Answer:
|
||||
0 1
|
||||
3 2
|
||||
|
||||
Metadata: {'matrix': [[1, 2], [0, 3]], 'solution': [[0, 1], [3, 2]]}
|
||||
|
||||
--------------------------------------------------
|
||||
````
|
||||
|
||||
### largest_island
|
||||
Generates Largest Island exercises with configurable difficulty
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ See the [Dataset Gallery](https://github.com/open-thought/reasoning-gym/blob/mai
|
|||
- `WordLadderDataset`: Generate word ladder puzzles where one word is transformed into another by changing one letter at a time
|
||||
- `GroupAnagramsDataset`: Group anagrams together in a list of words
|
||||
- `IsomorphicStrings`: Check if two strings are isomorphic (have the same character mapping)
|
||||
- `RotateMatrix`: Rotate a matrix by 90 degrees clockwise
|
||||
|
||||
### <small>Code Tasks</small>
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from .letter_jumble import LetterJumbleConfig, LetterJumbleDataset
|
|||
from .number_filtering import NumberFilteringConfig, NumberFilteringDataset
|
||||
from .number_sorting import NumberSortingConfig, NumberSortingDataset
|
||||
from .palindrome_generation import PalindromeConfig, PalindromeDataset
|
||||
from .rotate_matrix import RotateMatrixConfig, RotateMatrixDataset
|
||||
from .sentence_reordering import SentenceReorderingConfig, SentenceReorderingDataset
|
||||
from .spell_backward import SpellBackwardConfig, SpellBackwardDataset
|
||||
from .word_ladder import WordLadderConfig, WordLadderDataset
|
||||
|
|
@ -51,4 +52,6 @@ __all__ = [
|
|||
"GroupAnagramsDataset",
|
||||
"IsomorphicStringsConfig",
|
||||
"IsomorphicStringsDataset",
|
||||
"RotateMatrixConfig",
|
||||
"RotateMatrixDataset",
|
||||
]
|
||||
|
|
|
|||
97
reasoning_gym/algorithmic/rotate_matrix.py
Normal file
97
reasoning_gym/algorithmic/rotate_matrix.py
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
"""Rotate a square matrix by 90 degrees clockwise.
|
||||
|
||||
A popular Leetcode problem:
|
||||
https://leetcode.com/problems/rotate-image/description/
|
||||
"""
|
||||
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from random import Random
|
||||
from typing import Optional
|
||||
|
||||
from ..factory import ProceduralDataset, register_dataset
|
||||
|
||||
QUESTION_TEMPLATE = """Given a square matrix, your job is to rotate it by 90 degrees clockwise.
|
||||
|
||||
Example:
|
||||
|
||||
Input:
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
|
||||
Output:
|
||||
7 4 1
|
||||
8 5 2
|
||||
9 6 3
|
||||
|
||||
Rotate the matrix below by 90 degrees clockwise:
|
||||
{matrix}
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class RotateMatrixConfig:
|
||||
"""Configuration for Rotate Matrix dataset generation"""
|
||||
|
||||
max_n: int = 10 # Maximum size of the matrix
|
||||
|
||||
size: int = 500 # Virtual dataset size
|
||||
seed: Optional[int] = None
|
||||
|
||||
def validate(self):
|
||||
"""Validate configuration parameters"""
|
||||
assert 1 <= self.max_n, "max_n must be at least 1"
|
||||
|
||||
|
||||
class RotateMatrixDataset(ProceduralDataset):
|
||||
"""Generates Rotate Matrix exercises with configurable difficulty"""
|
||||
|
||||
def __init__(self, config: RotateMatrixConfig):
|
||||
super().__init__(config=config, seed=config.seed, size=config.size)
|
||||
|
||||
def _get_matrix(self, rng: Random) -> list[list[int]]:
|
||||
"""Generate a random matrix"""
|
||||
n = rng.randint(1, self.config.max_n)
|
||||
numbers = list(range(n**2))
|
||||
rng.shuffle(numbers)
|
||||
matrix = [numbers[i * n : (i + 1) * n] for i in range(n)]
|
||||
return matrix
|
||||
|
||||
def _get_rotated(self, matrix: list[list[int]]) -> list[list[int]]:
|
||||
"""Rotate the matrix by 90 degrees clockwise"""
|
||||
n = len(matrix)
|
||||
output = deepcopy(matrix)
|
||||
|
||||
for l in range(n // 2):
|
||||
for i in range(l, n - 1 - l):
|
||||
(output[l][i], output[i][n - 1 - l], output[n - 1 - l][n - 1 - i], output[n - 1 - i][l]) = (
|
||||
matrix[n - 1 - i][l],
|
||||
matrix[l][i],
|
||||
matrix[i][n - 1 - l],
|
||||
matrix[n - 1 - l][n - 1 - i],
|
||||
)
|
||||
|
||||
return output
|
||||
|
||||
def _matrix_to_str(self, matrix: list[list[int]]) -> str:
|
||||
"""Get a string representation of the matrix"""
|
||||
return "\n".join(" ".join(str(x) for x in row) for row in matrix)
|
||||
|
||||
def __getitem__(self, idx: int) -> dict:
|
||||
"""Generate a single Spiral Matrix question"""
|
||||
rng = Random(self.seed + idx)
|
||||
|
||||
matrix = self._get_matrix(rng)
|
||||
matrix_str = self._matrix_to_str(matrix)
|
||||
answer = self._get_rotated(matrix)
|
||||
answer_str = self._matrix_to_str(answer)
|
||||
|
||||
return {
|
||||
"question": QUESTION_TEMPLATE.format(matrix=matrix_str),
|
||||
"answer": answer_str,
|
||||
"metadata": {"matrix": matrix, "solution": answer},
|
||||
}
|
||||
|
||||
|
||||
register_dataset("rotate_matrix", RotateMatrixDataset, RotateMatrixConfig)
|
||||
100
tests/test_rotate_matrix.py
Normal file
100
tests/test_rotate_matrix.py
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
"""Tests for Rotate Matrix questions generation"""
|
||||
|
||||
import pytest
|
||||
|
||||
from reasoning_gym.algorithmic.rotate_matrix import RotateMatrixConfig, RotateMatrixDataset
|
||||
|
||||
|
||||
def test_rotate_matrix_config_validation():
|
||||
"""Test that invalid configs raise appropriate errors"""
|
||||
with pytest.raises(AssertionError):
|
||||
config = RotateMatrixConfig(max_n=-1) # Negative not allowed
|
||||
config.validate()
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
config = RotateMatrixConfig(max_n=0) # Zero not allowed
|
||||
config.validate()
|
||||
|
||||
|
||||
def test_rotate_matrix_dataset_deterministic():
|
||||
"""Test that dataset generates same items with same seed"""
|
||||
config = RotateMatrixConfig(seed=42, size=10)
|
||||
dataset1 = RotateMatrixDataset(config)
|
||||
dataset2 = RotateMatrixDataset(config)
|
||||
|
||||
for i in range(len(dataset1)):
|
||||
assert dataset1[i] == dataset2[i]
|
||||
|
||||
|
||||
def test_rotate_matrix_dataset_items():
|
||||
"""Test basic properties of generated items"""
|
||||
config = RotateMatrixConfig(max_n=7, size=10, seed=42)
|
||||
dataset = RotateMatrixDataset(config)
|
||||
|
||||
for i in range(len(dataset)):
|
||||
item = dataset[i]
|
||||
# Check item structure
|
||||
assert isinstance(item, dict)
|
||||
assert "question" in item
|
||||
assert "answer" in item
|
||||
assert "metadata" in item
|
||||
|
||||
# Check metadata
|
||||
assert "matrix" in item["metadata"]
|
||||
assert "solution" in item["metadata"]
|
||||
|
||||
matrix = item["metadata"]["matrix"]
|
||||
solution = item["metadata"]["solution"]
|
||||
|
||||
# Verify matrix dimensions
|
||||
assert len(matrix) <= config.max_n
|
||||
assert all(len(row) <= config.max_n for row in matrix)
|
||||
assert len(solution) <= config.max_n
|
||||
assert all(len(row) <= config.max_n for row in solution)
|
||||
assert set(e for row in matrix for e in row) == set(e for row in solution for e in row)
|
||||
|
||||
|
||||
def test_rotate_matrix_dataset_iteration():
|
||||
"""Test that iteration respects dataset size"""
|
||||
config = RotateMatrixConfig(size=5, seed=42)
|
||||
dataset = RotateMatrixDataset(config)
|
||||
|
||||
items = list(dataset)
|
||||
assert len(items) == config.size
|
||||
|
||||
# Test multiple iterations yield same items
|
||||
assert items == list(dataset)
|
||||
|
||||
|
||||
def test_rotate_matrix_answer():
|
||||
"""Test the _get_rotated method"""
|
||||
config = RotateMatrixConfig(seed=42)
|
||||
dataset = RotateMatrixDataset(config)
|
||||
|
||||
# n = 1
|
||||
matrix = [[8]]
|
||||
expected = [[8]]
|
||||
assert dataset._get_rotated(matrix) == expected
|
||||
|
||||
# n = 2
|
||||
matrix = [
|
||||
[0, 1],
|
||||
[2, 3],
|
||||
]
|
||||
expected = [
|
||||
[2, 0],
|
||||
[3, 1],
|
||||
]
|
||||
assert dataset._get_rotated(matrix) == expected
|
||||
|
||||
# n = 3
|
||||
matrix = [
|
||||
[0, 1, 2],
|
||||
[3, 4, 5],
|
||||
[6, 7, 8],
|
||||
]
|
||||
expected = [
|
||||
[6, 3, 0],
|
||||
[7, 4, 1],
|
||||
[8, 5, 2],
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue