• Welcome to SpeedSolving.com — the world’s largest puzzle community!

    You’re currently browsing as a guest, which means you have limited access to discussions, resources, member profiles, and community features.

    Join 50,000+ cubers and puzzle enthusiasts from around the world to ask questions, share solves, improve faster, and be part of the community.

    Registration is free, fast, and easy — create your account today.

    Already a member? Log in here to hide this message and start participating.

Square-1 scrambler (in ruby)

tim

Veteran
Joined
Nov 22, 2006
Messages
1,692
Location
Karlsruhe, Germany
WCA
2007HABE01
YouTube
Visit Channel
I had to write a sq-1 scrambler for cubemania, but couldn't find anyone on the web. Except for Jaap's Javascript scrambler. I first tried to convert his scrambler, but it was so boring and didn't make fun at all. So i wrote my own one.

i use up_layer and down_layer for the two layers and both arrays describe the permutation of corners/edges with the numbers 30/60. So each layer array has the sum 360.
Since i used my own notation during the scrambler ("(1,0) means turning the upper face by one piece"), i had to convert it back. That's what "humanize_sq_one_move" is for.

Code:
    def square1_scramble
      scramble = []
    	up_layer = (0..7).map{|i| i%2 == 0 ? 30 : 60}
    	down_layer = [up_layer].flatten!
    	length = 0
      begin
        up_moves = possible_moves up_layer
        down_moves = possible_moves down_layer
        up_move = up_moves.rand
        down_moves.delete 0 if up_move == 0
        down_move = down_moves.rand
        scramble << [humanize_sq_one_move(up_layer, up_move), humanize_sq_one_move(down_layer, down_move) * -1]
        do_move up_layer, up_move
        do_move down_layer, down_move
        length += up_move == 0 ? 0 : 1
        length += down_move == 0 ? 0 : 1
        do_slice(up_layer, down_layer)
        length += 1
      end while length <= scramble_length + 1
      scramble.map {|s| "(#{s.join(',')})"}.join(' ')
    end
    
    def humanize_sq_one_move(layer, move)
      move = layer[0..move - 1].inject(0){|sum, x| x == 30 ? sum + 1 : sum + 2} unless move == 0
      move > 6 ? move - 12 : move
    end
    
    def possible_moves(layer)
      layer_moves = []
      layer.length.times do |start|
        sum = 0
        possible = false
        layer.length.times do |i|
          sum += layer[(start + i) % layer.length]
          possible = true if sum == 180
        end
        layer_moves << start if possible
      end
      layer_moves
    end
    
    def do_move(layer, l)
      l %= layer.length
      l.times do
        layer << layer.shift
      end
      layer
    end

    def do_slice(up, down)
      sum = 0
      small_up, big_up = up.partition {|n| sum += n; sum <= 180}
      small_down, big_down = down.partition {|n| sum += n; sum <= 540}
      up.replace(small_down.reverse + big_up)
      down.replace(small_up.reverse + big_down)
    end

P.S.: Yeah, it looks ugly for ruby code.
 
Code:
def do_slice(up, down)
      sum = 0
      small_up, big_up = up.partition {|n| sum += n; sum <= 180}
      small_down, big_down = down.partition {|n| sum += n; sum <= 540}
      up.replace(small_down.reverse + big_up)
      down.replace(small_up.reverse + big_down)
    end
I like that bit :P
 
Code:
def do_slice(up, down)
      sum = 0
      small_up, big_up = up.partition {|n| sum += n; sum <= 180}
      small_down, big_down = down.partition {|n| sum += n; sum <= 540}
      up.replace(small_down.reverse + big_up)
      down.replace(small_up.reverse + big_down)
    end
I like that bit :P

Yeah, some guy (who's name i forgot) showed me the partition method :P.
 
Back
Top