# puzzle.rb # author: Greg Peairs # We begin with 1 2 3 4 5 6 7 8 9 10 11 12 in some order # L = (1 11 10 8 4 5 3 7 2 9 6) # R = (1 2 4 8 9 7 11 3 6 12) (5 10) \$L = [11, 9, 7, 5, 3, 1, 2, 4, 6, 8, 10, 12] \$R = [2, 4, 6, 8, 10, 12, 11, 9, 7, 5, 3, 1] print "Commands: q: quit l: \'left\' move r: \'right\' move L: invert l by doing l ten times R: invert r by doing r nine times u, v, w, x, y, z, a: combinations of r and l that fix certain elements s: solve it for me! i: input your own jumble " # print an array out neatly def print_array(arr) arr.each do |num| print "#{num} " end print "\n" end # Execute a move on an array def permute(arr, permuter) new = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 12.times do |n| new[n] = arr[permuter[n] - 1] end return new end # Execute the 'c' move def permute_c(array) 10.times do array = permute(array, \$L) end 9.times do array = permute(array, \$R) end array = permute(array, \$L) array = permute(array, \$R) return array end # get position of a number in the array (the first position is 1) def position_of(num, array) array.length.times do |i| if array[i] == num return i + 1 end end return -1 end # express string as only c's, l's, and r's def to_clr_form(instruction) instruction.gsub!("u", "llrlll") instruction.gsub!("v", "lrlllrllll") instruction.gsub!("w", "llllrrlll") instruction.gsub!("x", "lrlllllllrrllllllrl") instruction.gsub!("y", "llrllllrrlllllllrll") instruction.gsub!("z", "rlrlrllllrllllll") instruction.gsub!("a", "lllllrrllrlllrllllll") return instruction end # express string as l's and r's def to_lr_form(instruction) instruction = to_clr_form(instruction) instruction.gsub!("c", "llllllllllrrrrrrrrrlr") instruction.gsub!("lllllllllll", "") instruction.gsub!("rrrrrrrrrr", "") return instruction end # express string as (e.g.) "3l 4r 2l r 10l ..." def to_short_form(instruction) instruction = to_lr_form(instruction) instruction.gsub!("rrrrrrrrr", "9r") instruction.gsub!("rrrrrrrr", "8r") instruction.gsub!("rrrrrrr", "7r") instruction.gsub!("rrrrrr", "6r") instruction.gsub!("rrrrr", "5r") instruction.gsub!("rrrr", "4r") instruction.gsub!("rrr", "3r") instruction.gsub!("rr", "2r") instruction.gsub!("r", "R ") instruction.gsub!("llllllllll", "10l") instruction.gsub!("lllllllll", "9l") instruction.gsub!("llllllll", "8l") instruction.gsub!("lllllll", "7l") instruction.gsub!("llllll", "6l") instruction.gsub!("lllll", "5l") instruction.gsub!("llll", "4l") instruction.gsub!("lll", "3l") instruction.gsub!("ll", "2l") instruction.gsub!("l", "L ") return instruction end # Get an array from the user def input_array array = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] print "Enter your numbers in the order they appear, separated by spaces\n" STDOUT.flush numbers = gets.chomp n = 0 numbers.split(" ").each do |word| array[n] = word.to_i n += 1 end print_array(array) return array end # Execute an instruction on an array def exec_instruction(instruction, array) instruction = to_clr_form(instruction) instruction.each_char do |c| if c == 'l' array = permute(array, \$L) elsif c == 'L' 10.times do array = permute(array, \$L) end elsif c == 'r' array = permute(array, \$R) elsif c == 'R' 9.times do array = permute(array, \$R) end elsif c == 'c' array = permute_c(array) elsif c == '-' array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] else print "Invalid command\n" return array end print_array(array) end return array end =begin u = (1)(2 9 3 5 11 8 4 10 12 7 6) llrll v = (1)(2)(3 9 4 12 7)(5 8 10 6 11) lrlllrllll w = (1)(2)(3 6 4 7 3)(8 9 10 11 12) llllrrlll x = (1)(2)(3)(4 9 11 12)(5 8 10 7)(6) lrlllllllrrllllllrl y = (1)(2)(3)(4 8 5 10)(6 7 9 11)(12) llrllllrrlllllllrll z = (1)(2)(3)(4 8 12 11)(5)(6 9 10 7) rlrlrllllrllllll a = (1)(2)(3)(4 9 12 7)(5)(6 11 10 8) lllllrrllrlllrllllll =end # solve the puzzle automatically, print out the solution in various forms def solve_puzzle(array) pos = position_of(1,array) instruction = " " # place 1 if pos == 12 array = exec_instruction("r", array) instruction += "r" end while position_of(1, array) != 1 array = exec_instruction("l", array) instruction += "l" end # place 2 while position_of(2, array) != 2 array = exec_instruction("u", array) instruction += "u" end # place 3 while position_of(3, array) != 3 p = position_of(3, array) if p == 8 or p == 11 array = exec_instruction("v", array) instruction += "v" else array = exec_instruction("w", array) instruction += "w" end end # place 5 while position_of(5, array) != 5 p = position_of(5, array) if p == 7 or p == 10 or p == 12 array = exec_instruction("x", array) instruction += "x" else array = exec_instruction("y", array) instruction += "y" end end # place 4 while position_of(4, array) != 4 p = position_of(4, array) if p == 7 or p == 6 array = exec_instruction("a", array) instruction += "a" else array = exec_instruction("z", array) instruction += "z" end end if array != [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] print "Can't solve this one!\n" print "But to get this far:
" print to_short_form(instruction) + "
" else print instruction + "\n" print " = " + to_short_form(instruction) + "\n" end return array end start = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] array = start print_array(array) while true do puts 'Enter a command: ' STDOUT.flush instruction = gets.chomp if instruction == "q" exit 0 elsif instruction == "s" array = solve_puzzle(array) elsif instruction == "i" array = input_array else array = exec_instruction(instruction, array) end end