Flexagonal flexagation

9

Being programmers, watching us flex aren't very interesting. Today we change that! In this challenge you will lex and flex hexaflexagons.

About

For a video introduction, watch viharts video(s) on flexagons

A flexagon is a shape that you can flex to reveal faces other than the top and bottom one; we are making a hexahexaflexagon, which has 6 faces. See the image below on how to fold a hexahexaflexagon out of a strip of paper.

hexahexaflexagon construction

A shows both sides of the strip. The two white triangles are glued together. This is how you would flex it:

flexing the flexagon

Below is a diagram of possible states and their relationships:

Diagram v6

The colored circles represent the 6 triangles with the same number from the first image. Each of the circes have two colors- the bottom most represent the back face (what you would see if you where to flip your flexagon around), which you don't have to consider in this challenge.

The gray circles in the background represent how you can flex your flexagon in any given state: there are 4 different ways to flex it, we call these Left, Right, Up and Down. You don't actually flex in these directions, the important bit is that some are opposite to each other.
If you are in the center you can use Left and Right to go to the other center ones. To get out of the center you use Up and Down. If you aren't in the center you cannot use Left or Right.

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

Challenge

Create a function or program that take as input what should be on the 18 front faces and the 18 back faces of a flexagon, a sequence of left, right, up and down flexes, and return the 8 visible faces after the flexes.

Elaborate example computation:

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"

Example implementation: http://jdoodle.com/a/18A

Input and expected output:

> hexaflexaperplexia flexagationdevices RRL
= efxeli

> loremipsumdolorsit hexaflexamexicania RUU
= riuort

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

> abcdefghijklmnopqr stuvwxyz1234567890 RRRRLLUDDUUUULDD
= uv1278

Rules

  • You may take input and return output in any reasonable way
  • If the input is impossible, you should indicate so in some way that is distinct from regular output
  • Standard loopholes apply
  • This is Codegolf. Shortest code in bytes win.

BlackCap

Posted 2016-09-14T23:45:02.340

Reputation: 3 576

Answers

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))

Usage:

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

[0,1,2,3] = [left,right,up,down]

Thanks to @Damien for a lot of bytes!

BlackCap

Posted 2016-09-14T23:45:02.340

Reputation: 3 576

1What's the use of |b/=0=[]!!1 ? You can save a few bytes rewriting some functions in pointfree style : \(a,_)(b,_)->a==b -> (.fst).(==).fst , (!)=(q.).zip.cycle – Damien – 2016-09-15T07:16:07.443

@Damien |b/=0=[]!!1 just throws an exception if you try to do a impossible flex – BlackCap – 2016-09-15T08:32:04.767

1OK, you could simplify it with o n(a,b)|n>1||b<1=(z$a+[-1,1,0,0]!!n,z$b+[0,0,-1,1]!!n) this will throw an Non-exhaustive patterns exception – Damien – 2016-09-15T09:32:21.137