Skip to content

Instantly share code, notes, and snippets.

@hrjakobsen
Last active January 27, 2021 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrjakobsen/9b5d4798bfd463bf7ccc4bfc36688d8c to your computer and use it in GitHub Desktop.
Save hrjakobsen/9b5d4798bfd463bf7ccc4bfc36688d8c to your computer and use it in GitHub Desktop.
The function (find-algorithm moves from to) finds an algorithm from moving the edge piece in the from-position to the to-position using the specified moveset (subset of F, D, B, U, L, R). If no algorithm exists, it returns false. The algorithm must be performed with yellow on top, and blue in the front.
#lang racket
(define (-> move)
move)
(define (rotate-from-rotations rotations current-position face)
(let ((next-position (get-move rotations current-position face)))
(if (eq? next-position #f)
current-position
next-position)))
(define (get-move rotations current-position face)
(if (null? rotations)
#f
(let* ((first-element (car rotations))
(from (car first-element))
(move (cadr first-element))
(to (caddr first-element)))
(if (and (eq? from current-position) (eq? move face))
to
(get-move (cdr rotations) current-position face)))))
; All edge pieces with orientation. Green/Red edge
; is different from Red/Green. It is the same piece,
; but oriented differntly.
; YB, BY, YO, OY, YG, GY, YR, RY ; Top layer
; BR, RB, BO, OB, OG, GO, RG, GR ; Middle layer
; BW, WB, RW, WR, GW, WG, OW, WO ; Bottom layer
(define rotate
((curry rotate-from-rotations)
(list
(list 'YB (-> 'U) 'YO)
(list 'YB (-> 'F) 'RB)
(list 'BY (-> 'U) 'OY)
(list 'BY (-> 'F) 'BR)
(list 'YO (-> 'U) 'YG)
(list 'YO (-> 'L) 'BO)
(list 'OY (-> 'U) 'GY)
(list 'OY (-> 'L) 'OB)
(list 'YG (-> 'U) 'YR)
(list 'YG (-> 'B) 'OG)
(list 'GY (-> 'U) 'RY)
(list 'GY (-> 'B) 'GO)
(list 'YR (-> 'U) 'YB)
(list 'YR (-> 'R) 'GR)
(list 'RY (-> 'U) 'BY)
(list 'RY (-> 'R) 'RG)
(list 'BR (-> 'F) 'BW)
(list 'BR (-> 'R) 'YR)
(list 'RB (-> 'F) 'WB)
(list 'RB (-> 'R) 'RY)
(list 'BO (-> 'F) 'BY)
(list 'BO (-> 'L) 'WO)
(list 'OB (-> 'F) 'YB)
(list 'OB (-> 'L) 'OW)
(list 'OG (-> 'L) 'OY)
(list 'OG (-> 'B) 'WG)
(list 'GO (-> 'L) 'YO)
(list 'GO (-> 'B) 'GW)
(list 'RG (-> 'R) 'RW)
(list 'RG (-> 'B) 'YG)
(list 'GR (-> 'R) 'WR)
(list 'GR (-> 'B) 'GY)
(list 'BW (-> 'D) 'RW)
(list 'BW (-> 'F) 'BO)
(list 'WB (-> 'D) 'WR)
(list 'WB (-> 'F) 'OB)
(list 'RW (-> 'D) 'GW)
(list 'RW (-> 'R) 'RB)
(list 'WR (-> 'D) 'GW)
(list 'WR (-> 'R) 'BR)
(list 'GW (-> 'D) 'OW)
(list 'GW (-> 'B) 'GR)
(list 'WG (-> 'D) 'WO)
(list 'WG (-> 'B) 'RG)
(list 'OW (-> 'D) 'BW)
(list 'OW (-> 'L) 'OG)
(list 'WO (-> 'D) 'WB)
(list 'WO (-> 'L) 'GO)
)))
(define all-moves '(U F D B L R))
(define (find-algorithm moves from to)
(let ((alg (find-algorithm-1 moves moves (list from) '() from to)))
(if (list? alg)
(reverse alg)
alg)))
(define (find-algorithm-1 moves-full candidate-moves cache algorithm from to)
(if (eq? from to)
algorithm
(if (null? candidate-moves)
#f ; Ran out of available moves to progress further
(let* ((next-move (car candidate-moves))
(remaining-moves (cdr candidate-moves))
(next-position (rotate from next-move)))
(if (contains? cache next-position)
; Found a position we have already explored
(find-algorithm-1 moves-full remaining-moves cache algorithm from to)
(let ((possible-alg (find-algorithm-1 moves-full moves-full (cons next-position cache) (cons next-move algorithm) next-position to)))
(if (eq? #f possible-alg)
(find-algorithm-1 moves-full remaining-moves (cons next-position cache) algorithm from to)
possible-alg)))))))
(define (contains? lst item)
(if (null? lst)
#f
(or (equal? (car lst) item) (contains? (cdr lst) item))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment