Tengo un tipo llamado cubo, que representa un cubo físico. He escrito un código que toma un cubo y genera una lista de todas las orientaciones posibles del cubo.¿Existe alguna manera más agradable de calcular todas las orientaciones posibles de un cubo en F #?
He utilizado la siguiente terminología, suponiendo que el cubo está sentado frente a mí a la altura de los ojos.
Para caras del cubo:
- La parte superior se enfrenta al techo.
- La parte inferior está frente a la mesa.
- El frente está lejos de mí.
- La parte trasera está hacia mí.
- La izquierda se enfrenta a la pared a la izquierda de mí.
- La derecha se enfrenta a la pared a la derecha de mí.
para los ejes del cubo se puede girar alrededor de:
- Los tramos eje normal de la tabla en el techo.
- El eje longitudinal se extiende desde mí hacia la pared frente a mí.
- El eje lateral se extendía desde la pared izquierda hasta la pared derecha.
Mientras que cada una de las 6 caras permanece hacia abajo, el cubo se puede girar alrededor de su eje normal de 4 formas diferentes (0, 90, 180 y 270 grados). Esto resulta en 24 orientaciones posibles.
he comenzado con el tipo de cubo (disculpen S/coloreado de sintaxis de O):
type 'a cube(top:'a, bottom:'a, left:'a, right:'a, front:'a, back:'a) =
member this.Top = top
member this.Bottom = bottom
member this.Left = left
member this.Right = right
member this.Front = front
member this.Back = back
override this.ToString() =
sprintf "Top: %O, Bottom: %O, Left: %O, Right: %O Front: %O, Back: %O" top bottom left right front back
Entonces fui a escribir un módulo Cubo que proporcionó los getOrientations de función.
module Cube =
let rotateNormalRight (c:'a cube) =
cube(c.Top, c.Bottom, c.Back, c.Front, c.Left, c.Right)
let rotateLongitudinalRight (c:'a cube) =
cube(c.Left, c.Right, c.Bottom, c.Top, c.Front, c.Back)
let rotateLongitudinalLeft (c:'a cube) =
cube(c.Right, c.Left, c.Top, c.Bottom, c.Front, c.Back)
let private operations =
[ rotateNormalRight; rotateNormalRight; rotateNormalRight; rotateLongitudinalRight
rotateNormalRight; rotateNormalRight; rotateNormalRight; rotateLongitudinalRight
rotateNormalRight; rotateNormalRight; rotateNormalRight; rotateLongitudinalLeft
rotateNormalRight; rotateNormalRight; rotateNormalRight; rotateLongitudinalLeft
rotateNormalRight; rotateNormalRight; rotateNormalRight; rotateLongitudinalRight
rotateNormalRight; rotateNormalRight; rotateNormalRight ]
let getOrientations startCube =
let rec getCubeInner (ops:('a cube -> 'a cube) list) (cl:'a cube list) =
match ops with
| [] -> cl
| op :: rest -> getCubeInner rest ((cl |> List.hd |> op) :: cl)
getCubeInner operations [startCube]
Este módulo simplemente proporciona tres posibles rotaciones de 90 grados, una lista de las rotaciones que se llevan a un cubo a través de cada orientación posible, y una función que produce todas las orientaciones dadas un solo cubo.
Si hago:
cube(1, 2, 3, 4, 5, 6)
|> Cube.getOrientations
|> List.iter (printfn "%O")
me sale:
Top: 3, Bottom: 4, Left: 1, Right: 2 Front: 6, Back: 5
Top: 3, Bottom: 4, Left: 6, Right: 5 Front: 2, Back: 1
Top: 3, Bottom: 4, Left: 2, Right: 1 Front: 5, Back: 6
Top: 3, Bottom: 4, Left: 5, Right: 6 Front: 1, Back: 2
Top: 6, Bottom: 5, Left: 3, Right: 4 Front: 1, Back: 2
Top: 6, Bottom: 5, Left: 1, Right: 2 Front: 4, Back: 3
Top: 6, Bottom: 5, Left: 4, Right: 3 Front: 2, Back: 1
Top: 6, Bottom: 5, Left: 2, Right: 1 Front: 3, Back: 4
Top: 2, Bottom: 1, Left: 5, Right: 6 Front: 3, Back: 4
Top: 2, Bottom: 1, Left: 3, Right: 4 Front: 6, Back: 5
Top: 2, Bottom: 1, Left: 6, Right: 5 Front: 4, Back: 3
Top: 2, Bottom: 1, Left: 4, Right: 3 Front: 5, Back: 6
Top: 4, Bottom: 3, Left: 1, Right: 2 Front: 5, Back: 6
Top: 4, Bottom: 3, Left: 5, Right: 6 Front: 2, Back: 1
Top: 4, Bottom: 3, Left: 2, Right: 1 Front: 6, Back: 5
Top: 4, Bottom: 3, Left: 6, Right: 5 Front: 1, Back: 2
Top: 5, Bottom: 6, Left: 4, Right: 3 Front: 1, Back: 2
Top: 5, Bottom: 6, Left: 1, Right: 2 Front: 3, Back: 4
Top: 5, Bottom: 6, Left: 3, Right: 4 Front: 2, Back: 1
Top: 5, Bottom: 6, Left: 2, Right: 1 Front: 4, Back: 3
Top: 1, Bottom: 2, Left: 5, Right: 6 Front: 4, Back: 3
Top: 1, Bottom: 2, Left: 4, Right: 3 Front: 6, Back: 5
Top: 1, Bottom: 2, Left: 6, Right: 5 Front: 3, Back: 4
Top: 1, Bottom: 2, Left: 3, Right: 4 Front: 5, Back: 6
Esto hace lo que yo quiero. Pero el módulo Cube está ocupado por esa enorme lista de operaciones.
¿Hay una mejor manera de hacerlo con menos operaciones o con un enfoque completamente diferente?
Como referencia, los dados en estos días tienen una propiedad en particular: cada lado y su lado opuesto suman hasta 7. – cHao
@cHao: De hecho, es por eso que usé el término cubo, supongo que hubiera sido mejor usar caracteres sueltos para la pregunta en lugar de enteros. –
Y no usa "Dados" en nombre de una de sus funciones. :) – cHao