Flexagração flexagonal

9

Sendo programadores, nos assistir flexionar não é muito interessante. Hoje nós mudamos isso! Neste desafio, você lex e flexionará hexaflexágonos.

Sobre

Para uma introdução em vídeo, assista ao (s) vídeo (s) do viharts nos flexágonos

Um flexágono é uma forma que você pode flexionar para revelar faces diferentes da superior e inferior; estamos fazendo um hexahexaflexagon, que tem 6 faces. Veja a imagem abaixo sobre como dobrar um hexa-hexaflexágono de uma tira de papel.

construção hexahexaflexagon

Amostra os dois lados da tira. Os dois triângulos brancos são colados. É assim que você flexionaria:

flexionando o flexágono

Abaixo está um diagrama de possíveis estados e seus relacionamentos:

Diagrama v6

Os círculos coloridos representam os 6 triângulos com o mesmo número da primeira imagem. Cada um dos circuitos tem duas cores - a parte inferior mais representa a face traseira (o que você veria se girasse seu flexágono), o que você não precisa considerar neste desafio.

Os círculos cinzentos no fundo representam como você pode flex seu flexagon em qualquer estado: existem 4 maneiras diferentes de flexionar-lo, chamamos estes Left, Right, Upe Down. Na verdade, você não se flexiona nessas direções, o importante é que algumas são opostas uma à outra.
Se você estiver no centro, poderá usar Lefte Rightir para os outros centros. Para sair do centro, você usa Upe Down. Se você não estiver no centro, não poderá usarLeftou Right.

Left/Down = clockwise
Right/Up  = anti-clockwise

Desafio

Crie uma função ou programa que tenha como entrada o que deve estar nas 18 faces frontais e 18 de um flexágono, uma sequência de flexões esquerda, direita, para cima e para baixo e retorne as 8 faces visíveis após as flexões.

Exemplo de cálculo elaborado:

flex "hexaflexaperplexia" 
     "flexagationdevices" 
     [Right, Right, Left]

Divide a strip of paper into 18 triangles:
1/2\3/1\2/3\1/2\3/1\2/3\1/2\3/1\2/3   Front
4/4\5/5\6/6\4/4\5/5\6/6\4/4\5/5\6/6   Back

Write "hexaflexaperplexia" on the front of the paper strip:
1/2\3/1\2/3\1/2\3/1\2/3\1/2\3/1\2/3

hexaflexaperplexia
123123123123123123
h  a  e  p  p  x     Face 1, Initially the front face
 e  f  x  e  l  i    Face 2, Initially the back face
  x  l  a  r  e  a   Face 3, Initially hidden


Write "flexagationdevices" on the back of the paperstrip:
4/4\5/5\6/6\4/4\5/5\6/6\4/4\5/5\6/6

flexagationdevices
445566445566445566
fl    at    ev       Face 4, up from 3
  ex    io    ic     Face 5, up from 2
    ag    nd    es   Face 6, up from 1


Flex it [Right, Right, Left]
  The initial visible face is 1: "haeppx"
  flexing Right ..
  The current visible face is 2: "efxeli"
  flexing Right ..
  The current visible face is 3: "xlarea"
  flexing Left ..
  The current visible face is 2: "efxeli"
  flexed [Right, Right, Left]!

outputting "efxeli"

Exemplo de implementação: http://jdoodle.com/a/18A

Entrada e saída esperada:

> hexaflexaperplexia flexagationdevices RRL
= efxeli

> loremipsumdolorsit hexaflexamexicania RUU
= riuort

> abcdefghijklmnopqr stuvwxyz1234567890 UL
= I can't flex that way :(

> abcdefghijklmnopqr stuvwxyz1234567890 RRRRLLUDDUUUULDD
= uv1278

Regras

  • Você pode receber e devolver a saída de qualquer maneira razoável
  • Se a entrada for impossível, você deve indicá-lo de alguma maneira distinta da saída regular
  • Aplicam-se brechas padrão
  • Isto é Codegolf. O código mais curto em bytes vence.
BlackCap
fonte

Respostas:

2

Haskell (Lambdabot), 270 234 bytes

(!)=((map(snd<$>).groupBy((.fst).(==).fst).sortOn fst).).zip.cycle
o n(a,b)|n>1||b<1=(mod(a+[-1,1,0,0]!!n)3,mod(b+[0,0,-1,1]!!n)3)
(x&y)d|(g,h)<-foldl(flip(.))id(o<$>d)(0,0)=([0,1,2]!x++[3,3,4,4,5,5]!y)!!([0,5,1,1,4,2,2,3,0]!!(3*g+h))

Uso:

> (&) "hexaflexaperplexia" "flexagationdevices" [1,3]
"exioic"

[0,1,2,3] = [esquerda, direita, cima, baixo]

Obrigado a @Damien por muitos bytes!

BlackCap
fonte
11
Para que serve |b/=0=[]!!1? Você pode salvar alguns bytes reescrevendo algumas funções no estilo pointfree: \(a,_)(b,_)->a==b-> (.fst).(==).fst,(!)=(q.).zip.cycle
Damien
@Damien |b/=0=[]!!1apenas lança uma exceção se você tentar fazer uma flexão impossível
Cabeção
11
OK, você pode simplificá-lo com o n(a,b)|n>1||b<1=(z$a+[-1,1,0,0]!!n,z$b+[0,0,-1,1]!!n)este irá lançar uma padrões de exceção não exaustiva
Damien