Last active
January 17, 2020 01:37
Revisions
-
mvw revised this gist
Sep 4, 2015 . No changes.There are no files selected for viewing
-
mvw revised this gist
Sep 4, 2015 . 1 changed file with 5 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -174,7 +174,7 @@ def number_to_names(s) p end n = 5 k_show = 20 k_last = 4**n - 1 - k_show @@ -188,13 +188,17 @@ def number_to_names(s) a = p.split('').reverse a.each do |c| rot = Rotation.from_name(c) * rot # add (and normalize) intermediate results known, rot_n = $rots.add(rot) if known rot = rot_n else show = true end end # try to add the original alias rot_orig = Rotation.new(p, rot.perm.s) $rots.add(rot_orig) puts "k = #{k+1}: #{s} #{p} -> #{rot}" if show || k >= k_last end -
mvw created this gist
Sep 4, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,201 @@ #!/usr/bin/ruby # cuberots.rb class Permutation attr_accessor :s attr_accessor :h def initialize(s = '12345678') @s = s a = @s.split('') @h = Hash.new i = '1' a.each do |c| @h[i] = c i.next! end end def to_s return @s end # composition f*g means (f*g)(x) = f(g(x)) def *(g) s = '' c = '1' 8.times do s += @h[g.h[c]] c.next! end Permutation.new(s) end end class Rotation attr_accessor :name attr_accessor :perm def initialize(name = 'e', perm_s = '12345678') @name = name @perm = Permutation.new(perm_s) end def to_s @name + '=' + @perm.to_s end # composition f*g means (f*g)(x) = f(g(x)) def *(g) Rotation.new(@name + g.name, (@perm * g.perm).s) end # exponentiation def **(k) case when k < 0 nil # TODO find out inverse when k == 0 $e when k == 1 self else self * (self**(k-1)) end end # name to rotation def self.from_name(c) case when c == 'e' $e when c == 'x' $x when c == 'y' $y when c == 'z' $z else nil end end end class Rots def initialize @h = Hash.new end def to_s s = "[\n" k = 0 @h.each do |name, value| k += 1 rot, aliases = value s += " k = #{k}: #{rot} #{aliases}\n" end s += "]\n" s end # returns if known (and normalized version) def add(rot) rot_s = rot.perm.s entry = @h[rot_s] if entry.nil? @h[rot_s] = [rot, []] return false, nil end name = rot.name rot_n, aliases = entry if name == rot_n.name return true, rot_n end if aliases.member?(name) return true, rot_n end # new alias aliases << name @h[rot_s] = [rot_n, aliases] return true, rot_n end end # base rotations # / 8 7 / 8 7 # / 5 6 / 5 6 # 4 3 / -> 4 3 / # 1 2/ 1 2/ $e = Rotation.new('e', '12345678') # / 8 7 / 5 6 # / 5 6 / 1 2 # 4 3 / -> 8 7 / # 1 2/ 4 3/ $x = Rotation.new('x', '56218734') # / 8 7 / 5 8 # / 5 6 / 6 7 # 4 3 / -> 1 4 / # 1 2/ 2 3/ $y = Rotation.new('y', '41238567') # / 8 7 / 7 3 # / 5 6 / 6 2 # 4 3 / -> 8 4 / # 1 2/ 5 1/ $z = Rotation.new('z', '26731584') $rots = Rots.new $rots.add($e) $rots.add($x) $rots.add($y) $rots.add($z) puts "rots = #{$rots}" # translate digits into base rotations def number_to_names(s) p = s.dup p.gsub!(/0/, 'e') p.gsub!(/1/, 'x') p.gsub!(/2/, 'y') p.gsub!(/3/, 'z') p end n = 8 k_show = 20 k_last = 4**n - 1 - k_show # iterate in base 4 up to length n (4**n).times do |k| s = k.to_s(4) p = number_to_names(s) # parse string, compose rotations rot = $e show = k < k_show ? true : false a = p.split('').reverse a.each do |c| rot = Rotation.from_name(c) * rot known, rot_n = $rots.add(rot) if known rot = rot_n else show = true end end puts "k = #{k+1}: #{s} #{p} -> #{rot}" if show || k >= k_last end puts "rots = #{$rots}"