{- Copyright 2011 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} module Twisty.Cycles where import Twisty.Group import Twisty.Lists import Twisty.Wreath import Data.List (elemIndex) import Data.Maybe (fromJust) -- | Creates a cycle from a face, a list of pieces, and a function that maps a -- piece to its constituent faces. Calculates the twist for each piece as the -- difference in location of the face within each pair of pieces' faces. asCycle :: forall f a. (Eq f, WreathPermutable a, Num (WreathTwist a)) => f -> [a] -> (a -> [f]) -> [WreathEntry a] asCycle f as toFs = zipWith toEntry as twists where toEntry a t = Entry (a, t) indices = map indexIn as indexIn a = toInteger $ fromJust $ f `elemIndex` toFs a twists = zipWith toTwist indices $ rotate 1 indices toTwist i j = fromInteger (i - j) -- | A variant of asCycle for when the list of pieces is more readily accessible -- as a function of the face. asCycle' :: forall f a. (Eq f, WreathPermutable a, Num (WreathTwist a)) => f -> (f -> [a]) -> (a -> [f]) -> [WreathEntry a] asCycle' f toAs = asCycle f (toAs f) -- | Creates a cycle from a list of pieces, for situations where no twisting is -- possible. asSimpleCycle :: forall a. (WreathPermutable a) => [a] -> [WreathEntry a] asSimpleCycle as = map toEntry as where toEntry a = Entry (a, one)