twisty_puzzles 0.0.25 → 0.0.29

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: 2bdb18c89f68fabb32390a700b044586d879472b35a120fa953daf9dd8fe92c6
4
- data.tar.gz: 59033222dd6581dc53383e05a2f5886aee43beeb93578d2db8a7b455133ad07a
3
+ metadata.gz: 4a36579770d4f4a738e61f718667325433469a295d7f131f7fa3b3ea770f7917
4
+ data.tar.gz: fc9f222127a4ab7f3af88cd6fd41b5ca18005e02e531eaba4be3fbbaa5030fde
5
5
  SHA512:
6
- metadata.gz: 0aabba50c1c8d8a5edec9359a06be002fc13bf9a9171578920357eafbbb90d96e82fe8c3f3455e95c70080e1e86d974a9ab260fbc0d7e6827c5c1cd2d9c13086
7
- data.tar.gz: 8c9004e6132a9174c5f1e92c8b116bd3d7cc6158e858bcff762f8b7d42a1656795af73243664b0e4186c212536ac43628820e37a8b9ae9b61f5b4db9d9a2af16
6
+ metadata.gz: 8bfe24af1bbc9d601ef76c7838167c126a223248a87086bc516d78adcee3ab82f64545a173b3e9774bab5b40a4fce6498a21b659d4b92f45654802e251ec97d2
7
+ data.tar.gz: e8e21f651133dc55e41d099ea3c9f484ff0ad49a7d9375ce7aef27ae3eb143fa70dc24c47788bf43463bc25063ce6aa9cbe0e35a0cb94c1e5260d1dc7a257f54
@@ -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
@@ -20,7 +20,9 @@ module TwistyPuzzles
20
20
  @moves = moves
21
21
  end
22
22
 
23
- EMPTY = Algorithm.new([])
23
+ def self.empty
24
+ Algorithm.new([])
25
+ end
24
26
 
25
27
  # Creates a one move algorithm.
26
28
  def self.move(move)
@@ -43,7 +43,7 @@ module TwistyPuzzles
43
43
  raise TypeError unless algorithm.is_a?(Algorithm)
44
44
 
45
45
  CubeState.check_cube_size(cube_size)
46
- alg = Algorithm::EMPTY
46
+ alg = Algorithm.empty
47
47
  algorithm.moves.each do |m|
48
48
  alg = push_with_cancellation(alg, m, cube_size)
49
49
  end
@@ -107,7 +107,7 @@ module TwistyPuzzles
107
107
  def self.rotation_sequences
108
108
  @rotation_sequences ||=
109
109
  begin
110
- trivial_rotation_algs = [Algorithm::EMPTY]
110
+ trivial_rotation_algs = [Algorithm.empty]
111
111
  single_rotation_algs = Rotation::NON_ZERO_ROTATIONS.map { |e| Algorithm.move(e) }
112
112
  combined_rotation_algs = self.combined_rotation_algs
113
113
  rotation_algs = trivial_rotation_algs + single_rotation_algs + combined_rotation_algs
@@ -57,7 +57,7 @@ module TwistyPuzzles
57
57
  end
58
58
 
59
59
  def colors
60
- @face_symbols_to_colors.values
60
+ @face_symbols_to_colors.to_a.sort_by(&:first).map(&:last)
61
61
  end
62
62
 
63
63
  def turned(top_color, front_color)
@@ -173,6 +173,10 @@ module TwistyPuzzles
173
173
  @native = native
174
174
  end
175
175
 
176
+ def to_s
177
+ "#{self.class}(#{face}, #{cube_size}, #{x}, #{y})"
178
+ end
179
+
176
180
  attr_reader :native
177
181
 
178
182
  def face
@@ -72,6 +72,11 @@ module TwistyPuzzles
72
72
  true
73
73
  end
74
74
 
75
+ def self.exists_on_cube_size?(cube_size)
76
+ cube_size >= min_cube_size && cube_size <= max_cube_size &&
77
+ (cube_size % 2 == 0 ? self.exists_on_even_cube_sizes? : self.exists_on_odd_cube_sizes?)
78
+ end
79
+
75
80
  def num_incarnations(_cube_size)
76
81
  1
77
82
  end
@@ -286,7 +291,7 @@ module TwistyPuzzles
286
291
  # lie where the given other face currently is.
287
292
  def rotation_to(other)
288
293
  if other == self
289
- Algorithm::EMPTY
294
+ Algorithm.empty
290
295
  else
291
296
  # There can be multiple solutions.
292
297
  axis_face =
@@ -470,7 +475,6 @@ module TwistyPuzzles
470
475
  # Represents one wing or the position of one wing on the cube.
471
476
  class Wing < Part
472
477
  extend EdgeLike
473
- WING_BASE_INDEX_INVERTED_FACE_SYMBOLS = %i[U R B].freeze
474
478
  FACES = 2
475
479
 
476
480
  ELEMENTS = generate_parts
@@ -479,10 +483,6 @@ module TwistyPuzzles
479
483
  4
480
484
  end
481
485
 
482
- def self.exists_on_odd_cube_sizes?
483
- false
484
- end
485
-
486
486
  def self.max_parseable_face_symbols
487
487
  FACES + 1
488
488
  end
@@ -543,8 +543,7 @@ module TwistyPuzzles
543
543
 
544
544
  # One index of such a piece on a on a NxN face.
545
545
  def base_index_on_other_face(face, _cube_size, incarnation_index)
546
- # TODO: Make this more elegant than hardcoding
547
- inverse = WING_BASE_INDEX_INVERTED_FACE_SYMBOLS.include?(face.face_symbol)
546
+ inverse = face.piece_index.even?
548
547
  coordinates = [0, 1 + incarnation_index]
549
548
  inverse ? coordinates.reverse : coordinates
550
549
  end
@@ -17,16 +17,19 @@ module TwistyPuzzles
17
17
 
18
18
  RAW_DATA_RESERVED = [' ', '(', ')'].freeze
19
19
 
20
- def initialize(parts)
20
+ def initialize(parts, twist=0)
21
21
  raise ArgumentError if parts.empty?
22
+ raise TypeError unless twist.is_a?(Integer)
23
+ raise ArgumentError if twist.negative?
22
24
 
23
25
  check_types(parts, Part)
24
26
  check_type_consistency(parts)
25
27
 
26
28
  @parts = parts
29
+ @twist = twist
27
30
  end
28
31
 
29
- attr_reader :parts
32
+ attr_reader :parts, :twist
30
33
 
31
34
  def eql?(other)
32
35
  self.class.equal?(other.class) && @parts == other.parts
@@ -79,6 +82,21 @@ module TwistyPuzzles
79
82
  end.min
80
83
  end
81
84
 
85
+ # Note that this returns the same answer for all rotations of one part.
86
+ def contains?(part)
87
+ @parts.any? { |p| p.turned_equals?(part) }
88
+ end
89
+
90
+ # Returns an equivalent cycle that starts with the given part.
91
+ # Raises an error if the cycle doesn't contain the given part.
92
+ def start_with(part)
93
+ raise ArgumentError unless contains?(part)
94
+
95
+ index = @parts.find_index { |p| p.turned_equals?(part) }
96
+ map_rotate_by_number = @parts[index].rotations.index(part)
97
+ rotate_by(@parts.length - index).map_rotate_by(map_rotate_by_number)
98
+ end
99
+
82
100
  def equivalent?(other)
83
101
  self == other || canonicalize == other.canonicalize
84
102
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TwistyPuzzles
4
- VERSION = '0.0.25'
4
+ VERSION = '0.0.29'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twisty_puzzles
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.25
4
+ version: 0.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernhard F. Brodowsky
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-10 00:00:00.000000000 Z
11
+ date: 2021-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize