twisty_puzzles 0.0.13 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 440643127a42de2937ef3e1b0205f588a7d8624102dcf2596b3ff24050bf57ef
|
4
|
+
data.tar.gz: 8ef01a9cd10f729ed5bbb0f34a36fe75b5fcff2d8c9ee6cc64d4b7faa72e44a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d247081d421f4b422293dc286e794cda52c04c9cb543d7ac62de8441f94117cbc028ecf7cff0a9c8100e57f1f7f87cfff0dfcfa8932e0fc60b7aa9409fd8d5df
|
7
|
+
data.tar.gz: ff1043f40ba14d3993268b4768ddfc3e8ffc7e84830c21f106a7a64d7b55a774c1120ef880e71feba101ba0f4c48b8ec920711c25a187f93b3412c27bb096002
|
@@ -4,7 +4,7 @@ module TwistyPuzzles
|
|
4
4
|
# Base class for directions.
|
5
5
|
class AbstractDirection
|
6
6
|
include Comparable
|
7
|
-
POSSIBLE_DIRECTION_NAMES = [[''], ['2', '2\''], ['\'', '3']].freeze
|
7
|
+
POSSIBLE_DIRECTION_NAMES = [[''], ['2', '2\''], ['\'', '3', '’']].freeze
|
8
8
|
SIMPLE_DIRECTION_NAMES = (['0'] + POSSIBLE_DIRECTION_NAMES.map(&:first)).freeze
|
9
9
|
POSSIBLE_SKEWB_DIRECTION_NAMES = [['', '2\''], ['\'', '2']].freeze
|
10
10
|
SIMPLE_SKEWB_DIRECTION_NAMES = (['0'] + POSSIBLE_SKEWB_DIRECTION_NAMES.map(&:first)).freeze
|
@@ -133,9 +133,12 @@ module TwistyPuzzles
|
|
133
133
|
|
134
134
|
def *(other)
|
135
135
|
raise TypeError unless other.is_a?(Integer)
|
136
|
-
raise ArgumentError if other.negative?
|
137
136
|
|
138
|
-
|
137
|
+
if other.negative?
|
138
|
+
inverse * -other
|
139
|
+
else
|
140
|
+
self.class.new(@moves * other)
|
141
|
+
end
|
139
142
|
end
|
140
143
|
|
141
144
|
def compiled_for_skewb
|
@@ -83,6 +83,21 @@ module TwistyPuzzles
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
# Slash commutator of the form A B A2 B' A.
|
87
|
+
class SlashCommutator < PureCommutator
|
88
|
+
def inverse
|
89
|
+
SlashCommutator.new(first_part.inverse, second_part)
|
90
|
+
end
|
91
|
+
|
92
|
+
def to_s
|
93
|
+
"[#{@first_part}/#{@second_part}]"
|
94
|
+
end
|
95
|
+
|
96
|
+
def algorithm
|
97
|
+
first_part + second_part + (first_part * 2) + second_part.inverse + first_part
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
86
101
|
# Setup commutator of the form A B A'.
|
87
102
|
class SetupCommutator < Commutator
|
88
103
|
def initialize(setup, inner_commutator)
|
@@ -16,6 +16,12 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
|
|
16
16
|
OPENING_PAREN = '('
|
17
17
|
CLOSING_BRACKET = ']'
|
18
18
|
CLOSING_PAREN = ')'
|
19
|
+
SLASH = '/'
|
20
|
+
COMMA = ','
|
21
|
+
SETUP_SEPARATORS = %w[; :].freeze
|
22
|
+
PURE_SEPARATORS = [SLASH, COMMA].freeze
|
23
|
+
SEPARATORS = (SETUP_SEPARATORS + PURE_SEPARATORS).freeze
|
24
|
+
|
19
25
|
TIMES = '*'
|
20
26
|
|
21
27
|
def initialize(alg_string, move_parser)
|
@@ -89,6 +95,8 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
|
|
89
95
|
while (m = begin skip_spaces; parse_move_internal end)
|
90
96
|
moves.push(m)
|
91
97
|
end
|
98
|
+
skip_spaces
|
99
|
+
moves *= parse_multiplier if @scanner.peek(1) == TIMES
|
92
100
|
Algorithm.new(moves)
|
93
101
|
end
|
94
102
|
|
@@ -156,45 +164,55 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
|
|
156
164
|
parse_open_bracket
|
157
165
|
first_part = parse_nonempty_moves_with_triggers
|
158
166
|
skip_spaces
|
159
|
-
|
167
|
+
separator = parse_pure_separator
|
160
168
|
second_part = parse_nonempty_moves_with_triggers
|
161
169
|
skip_spaces
|
162
170
|
parse_close_bracket
|
163
|
-
|
171
|
+
pseudo_pure_commutator(separator, first_part, second_part)
|
164
172
|
end
|
165
173
|
|
166
174
|
def parse_pure_commutator_no_brackets
|
167
175
|
first_part_or_algorithm = parse_moves_with_triggers
|
168
176
|
skip_spaces
|
169
|
-
if @scanner.eos? ||
|
177
|
+
if @scanner.eos? || !PURE_SEPARATORS.include?(@scanner.peek(1))
|
170
178
|
return FakeCommutator.new(first_part_or_algorithm)
|
171
179
|
end
|
172
180
|
|
173
181
|
first_part = first_part_or_algorithm
|
174
182
|
complain('move') if first_part.empty?
|
175
|
-
|
183
|
+
separator = parse_pure_separator
|
176
184
|
second_part = parse_nonempty_moves_with_triggers
|
177
185
|
skip_spaces
|
178
|
-
|
186
|
+
pseudo_pure_commutator(separator, first_part, second_part)
|
179
187
|
end
|
180
188
|
|
181
|
-
def
|
182
|
-
|
189
|
+
def parse_pure_separator
|
190
|
+
separator = @scanner.getch
|
191
|
+
complain('middle of pure commutator') unless PURE_SEPARATORS.include?(separator)
|
192
|
+
separator
|
183
193
|
end
|
184
194
|
|
185
195
|
def parse_commutator_internal_after_separator(setup_or_first_part, separator)
|
186
|
-
if
|
196
|
+
if SETUP_SEPARATORS.include?(separator)
|
187
197
|
inner_commutator = parse_setup_commutator_inner
|
188
198
|
SetupCommutator.new(setup_or_first_part, inner_commutator)
|
189
|
-
elsif separator
|
199
|
+
elsif PURE_SEPARATORS.include?(separator)
|
190
200
|
second_part = parse_nonempty_moves_with_triggers
|
191
|
-
|
201
|
+
pseudo_pure_commutator(separator, setup_or_first_part, second_part)
|
192
202
|
else
|
193
203
|
complain('end of setup or middle of pure commutator') unless @scanner.eos?
|
194
204
|
end
|
195
205
|
end
|
196
206
|
|
197
|
-
|
207
|
+
def pseudo_pure_commutator(separator, first_part, second_part)
|
208
|
+
if separator == COMMA
|
209
|
+
PureCommutator.new(first_part, second_part)
|
210
|
+
elsif separator == SLASH
|
211
|
+
SlashCommutator.new(first_part, second_part)
|
212
|
+
else
|
213
|
+
complain('middle of pure commutator') unless PURE_SEPARATORS.include?(separator)
|
214
|
+
end
|
215
|
+
end
|
198
216
|
|
199
217
|
def parse_separator
|
200
218
|
separator = @scanner.getch
|