Skip to content

Instantly share code, notes, and snippets.

@deepcube
Last active August 29, 2015 14:20
Show Gist options
  • Save deepcube/08d2931cd1a2835fcb9b to your computer and use it in GitHub Desktop.
Save deepcube/08d2931cd1a2835fcb9b to your computer and use it in GitHub Desktop.
#!/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