Last active
August 29, 2015 14:20
-
-
Save deepcube/08d2931cd1a2835fcb9b to your computer and use it in GitHub Desktop.
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 characters
#!/usr/bin/env bash | |
# solve Rubik's cube using the Tperm blindfold method. input: http://tomas.rokicki.com/cubecontest/ | |
# idea from Stefan Pochmann's second entry: http://tomas.rokicki.com/cubecontest/winners.html | |
n=0 tperm="R2 U' R2 D B2 L2 U L2 D' B2 U " | |
cube=("$@") solved=(UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR) | |
declare -A inverse=([\']=\ [2]=2 [\ ]=\') setups=( | |
[UF]="R2 U R2 " [UR]="" [UB]="R2 U' R2 " [UL]="" | |
[DF]="D' L2 " [DR]="D2 L2 " [DB]="D L2 " [DL]="L2 " | |
[FR]="U2 R U2 " [FL]="L' " [BR]="U2 R' U2 " [BL]="L " | |
[FU]="R F' L' R' " [RU]="" [BU]="R' B L R " [LU]="L F' D' F L2 " | |
[FD]="R F L' R' " [RD]="D' R F L' R' " [BD]="R' B' L R " [LD]="D R F L' R' " | |
[RF]="U' F' U " [LF]="U' F U " [RB]="U B U' " [LB]="U B' U' " | |
[UFR]="" [URB]="" [UBL]="L2 F2 L2 " [ULF]="F2 D' F2 " | |
[DRF]="D' F2 " [DFL]="F2 " [DLB]="D F2 " [DBR]="D2 F2 " | |
[FRU]="R' D R F D F' " [RBU]="" [BLU]="L' D F2 L " [LFU]="F " | |
[RFD]="F' " [FLD]="D F' " [LBD]="D2 F' " [BRD]="D' F' " | |
[RUF]="R' D2 R F D2 F' " [BUR]="" [LUB]="B D B' F2 " [FUL]="L D L' D' F2 " | |
[FDR]="D' R' D R " [LDF]="R' D R " [BDL]="R' D2 R " [RDB]="D' F D F' ") | |
# print inverse of given move sequence | |
invert() { local seq=$1 move out | |
while IFS= read -N 3 move; do | |
out="${move::1}${inverse["${move:1:1}"]} $out" | |
done <<< "$seq" | |
printf %s "$out" | |
} | |
# change orientation of a piece and print new piece | |
twist() { local piece=$1 ori=$2 i | |
for ((i = 0; i < ori; i++)); do | |
piece=${piece: -1}${piece%?} | |
done | |
printf %s "$piece" | |
} | |
# return 0 if two pieces are same piece and print orientation of first piece as compared to second | |
same() { local p1=$1 p2=$2 i | |
for ((i = 0; i < ${#p1}; i++)); do | |
[[ $p1 == $p2 ]] && printf %d "$i" && return 0 | |
p1=${p1:1}${p1:0:1} | |
done | |
return 1 | |
} | |
# solve $len pieces starting at index $beg, swapping from $from | |
solve() { local beg=$1 len=$2 from=$3 piece ori tmp i | |
while piece=${cube[from]}; [[ ${cube[*]:$beg:$len} != ${solved[*]:$beg:$len} ]] && ((++n)); do | |
if same "$piece" "${solved[from]}" >/dev/null; then | |
# 'from' piece is in place, find first piece that's not solved to break into new cycle | |
for ((i = beg; i < beg + len; i++)); do | |
((i != from)) && [[ ${cube[i]} != ${solved[i]} ]] && break | |
done | |
piece=${solved[i]} tmp=${cube[from]} cube[from]=${cube[i]} cube[i]=$tmp | |
else # figure out where 'piece' goes, swap, twist new piece correctly | |
for ((i = beg; i < beg + len; i++)); do | |
ori=$(same "$piece" "${solved[i]}") && break | |
done | |
cube[from]=$(twist "${cube[i]}" "$ori") cube[i]=${solved[i]} | |
fi | |
printf %s "${setups["$piece"]}" "$tperm" "$(invert "${setups["$piece"]}")" | |
done | |
} | |
solve 0 12 1 # starting at index 0, 12 edges, pieces move from 1-> 3 (UR ->UL ) in tperm | |
((n % 2)) && tmp=${cube[13]} cube[13]=${cube[12]} cube[12]=$tmp # odd number of tperms swap corners | |
solve 12 8 13 # starting at index 12, 8 corners, pieces move from 13->12 (URB->UFR) in tperm | |
echo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment