twisty_puzzles 0.0.12 → 0.0.16

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: 78089ff494b1a687a567d483eb155e9891c69a991e8f4b045bf024e7365c58df
4
- data.tar.gz: 820b61382a22d1c283f552ee637507dd9a511efa1d7f66656decd64f67304c8b
3
+ metadata.gz: 1477b8bdab0eb6f001734d952bb7923c96ded08d2810ad14fc6ada8cbf2976b1
4
+ data.tar.gz: 452de382df3a44d33ede47f7093e8c2204f56c26836b22e16633586e6e396ad9
5
5
  SHA512:
6
- metadata.gz: 063d2c8607b7d7708d0dea3fa78eebe3a883135cf2e2a46e5db7d5e0b80f6d21dd084b7a554718b54d45866eeecddf784857eb247a4a1de4ac924b8293aedd50
7
- data.tar.gz: 9dff522e48073f756d4aa0e2377ff754b8fbefe0caaf8fb830383e47d14be7bb354e55c1ef2355fca1259dc255002e732f5089bd9269727973e2979de6a9d6e2
6
+ metadata.gz: 8adbb4a4d7c3282e18a6c28b73184893aad54e97cf62e96945382a8305bd1638e22d5df3363bea3b0ce2e73d2162632175e836d0e231840964442fa80aab5253
7
+ data.tar.gz: 265ef1e6511c51099b41b8efeaf82b34468bb9bf9ff7e13b549d0adae1022359ec02607f667e53263feb47f076a6ee1538ee451fa831e80aadb564480449aa83
@@ -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
- self.class.new(@moves * other)
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)
@@ -77,8 +83,8 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
77
83
  end
78
84
 
79
85
  # Parses at least one move.
80
- def parse_nonempty_moves
81
- moves = parse_moves
86
+ def parse_nonempty_moves_with_triggers
87
+ moves = parse_moves_with_triggers
82
88
  complain('move') if moves.empty?
83
89
  moves
84
90
  end
@@ -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
 
@@ -117,10 +125,26 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
117
125
  if @scanner.peek(1) == OPENING_BRACKET
118
126
  parse_commutator_internal
119
127
  else
120
- FakeCommutator.new(parse_moves_with_triggers)
128
+ parse_commutator_no_brackets
121
129
  end
122
130
  end
123
131
 
132
+ def parse_commutator_no_brackets
133
+ setup_or_first_part_or_algorithm = parse_moves_with_triggers
134
+ skip_spaces
135
+ if @scanner.eos? || !SEPARATORS.include?(@scanner.peek(1))
136
+ return FakeCommutator.new(setup_or_first_part_or_algorithm)
137
+ end
138
+
139
+ setup_or_first_part = setup_or_first_part_or_algorithm
140
+ complain('move') if setup_or_first_part.empty?
141
+ separator = parse_separator
142
+ comm = parse_commutator_internal_after_separator(setup_or_first_part, separator)
143
+ skip_spaces
144
+ complain('end of commutator') unless @scanner.eos?
145
+ comm
146
+ end
147
+
124
148
  def parse_algorithm
125
149
  skip_spaces
126
150
  parse_moves_with_triggers
@@ -131,40 +155,77 @@ module TwistyPuzzles # rubocop:disable Style/Documentation
131
155
  if @scanner.peek(1) == OPENING_BRACKET
132
156
  parse_pure_commutator
133
157
  else
134
- FakeCommutator.new(parse_moves_with_triggers)
158
+ parse_pure_commutator_no_brackets
135
159
  end
136
160
  end
137
161
 
138
162
  def parse_pure_commutator
139
163
  skip_spaces
140
164
  parse_open_bracket
141
- first_part = parse_nonempty_moves
165
+ first_part = parse_nonempty_moves_with_triggers
142
166
  skip_spaces
143
- complain('middle of pure commutator') unless @scanner.getch == ','
144
- second_part = parse_nonempty_moves
167
+ separator = parse_pure_separator
168
+ second_part = parse_nonempty_moves_with_triggers
145
169
  skip_spaces
146
170
  parse_close_bracket
147
- PureCommutator.new(first_part, second_part)
171
+ pseudo_pure_commutator(separator, first_part, second_part)
172
+ end
173
+
174
+ def parse_pure_commutator_no_brackets
175
+ first_part_or_algorithm = parse_moves_with_triggers
176
+ skip_spaces
177
+ if @scanner.eos? || !PURE_SEPARATORS.include?(@scanner.peek(1))
178
+ return FakeCommutator.new(first_part_or_algorithm)
179
+ end
180
+
181
+ first_part = first_part_or_algorithm
182
+ complain('move') if first_part.empty?
183
+ separator = parse_pure_separator
184
+ second_part = parse_nonempty_moves_with_triggers
185
+ skip_spaces
186
+ pseudo_pure_commutator(separator, first_part, second_part)
187
+ end
188
+
189
+ def parse_pure_separator
190
+ separator = @scanner.getch
191
+ complain('middle of pure commutator') unless PURE_SEPARATORS.include?(separator)
192
+ separator
148
193
  end
149
194
 
150
195
  def parse_commutator_internal_after_separator(setup_or_first_part, separator)
151
- if [':', ';'].include?(separator)
196
+ if SETUP_SEPARATORS.include?(separator)
152
197
  inner_commutator = parse_setup_commutator_inner
153
198
  SetupCommutator.new(setup_or_first_part, inner_commutator)
154
- elsif separator == ','
155
- second_part = parse_nonempty_moves
156
- PureCommutator.new(setup_or_first_part, second_part)
199
+ elsif PURE_SEPARATORS.include?(separator)
200
+ second_part = parse_nonempty_moves_with_triggers
201
+ pseudo_pure_commutator(separator, setup_or_first_part, second_part)
157
202
  else
158
203
  complain('end of setup or middle of pure commutator') unless @scanner.eos?
159
204
  end
160
205
  end
161
206
 
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
216
+
217
+ def parse_separator
218
+ separator = @scanner.getch
219
+ complain('separator between commutator parts') unless SEPARATORS.include?(separator)
220
+ separator
221
+ end
222
+
162
223
  def parse_commutator_internal
163
224
  skip_spaces
164
225
  parse_open_bracket
165
- setup_or_first_part = parse_nonempty_moves
226
+ setup_or_first_part = parse_nonempty_moves_with_triggers
166
227
  skip_spaces
167
- separator = @scanner.getch
228
+ separator = parse_separator
168
229
  comm = parse_commutator_internal_after_separator(setup_or_first_part, separator)
169
230
  skip_spaces
170
231
  parse_close_bracket
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TwistyPuzzles
4
- VERSION = '0.0.12'
4
+ VERSION = '0.0.16'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twisty_puzzles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernhard F. Brodowsky