# Output a Face on a Numbered Cube

Assign the numbers 0 through 7 to the 8 vertices of a cube in any way you want. Exactly one number must be assigned to each vertex.

For example, your vertices might be assigned like this:

  3-----1
/|    /|
4-----2 |
| |   | |
| 5---|-0
|/    |/
6-----7


Write a program that takes in an integer from 0 to 5. Each of these 6 numbers is associated with exactly one face of your cube in any way you like. When one of these numbers is input, the 4 vertex numbers of the associated face must be printed to stdout in a 2×2 square of digits. The face is to be viewed straight on from outside the cube. All 4 face rotations are valid.

For example, if 0 is associated with the front face of the example cube above, then this would be a valid output for input 0:

42
67


The face may be viewed at any 90° rotation, so these are also valid:

27
46
76
24
64
72

This output (and its rotations) are not valid, as they are viewed from the wrong side of the face:

24
76


The same idea applies to all other faces. e.g. if 1 is associated with the back face, then input 1 might produce output 13[newline]05 (and 31[newline]50 would be invalid).

So the real challenge is choosing your vertex numbers and rotations such that translating the input into its 4 vertex numbers is easy and short.

The shortest code in bytes wins. Tiebreaker is earlier post. (Handy byte counter.)

### Notes

• You may write a function instead of a program. It should take an integer from 0 to 5 and print or return the 2×2 digit grid string.
• Take input from stdin, command line, or function arg. You may assume input is valid.
• The output may optionally have a trailing newline.
• Be sure to tell us the vertex and face numbers you chose.

# CJam, 23 16 bytes

There's probably an elegant mathematical solution to this problem. But I have no clue how to find one, so super compressed hard coding it is!

I found one! Well, it's not a classically elegant mathematical solution as it uses bitwise operations, but it is entirely formulaic.

li_o1^_p_6|o3+6%


Try it online.

### Cube layout

  4-----7          4-----7          3-----2
/|    /|         /  0  /|         /  3  /|
1-----0 |        1-----0 |        6-----5 |
| |   | |        |     |2|        |     |4|
| 5---|-2        |  1  | 2        |  5  | 7
|/    |/         |     |/         |     |/
6-----3          6-----3          1-----4


### Explanation

My old answer already laid out the cube such that each face can be described with its first (top-left) vertex number equal to the face number. But I wanted to be able to calculate more vertex numbers using the face number. At some point, I came up with the idea that got my foot in the door, to calculate the second (top-left) vertex number as the face number XOR 1. And after a while of trial and error, I managed to come up with the layout shown above and the formulas below that allow me to to calculate every vertex number for a face n quite succinctly:

• Top-left: n
• Top-right: n^1
• Bottom-left: (n^1)|6
• Bottom-right: ((n^1)+3)%6

For reference, I'll reproduce the output for each face in the desired layout here:

Face:      0     1     2     3     4     5

Vertices:  01    10    23    32    45    54
74    63    70    65    72    61


So the whole program just comes down to reading the input face number and producing these values in order, albeit with slightly different printing logic for different vertices. Note that, because every vertex after the first starts with a base of n^1, I only need to calculate that once, which compacts the logic even further.

For posterity's sake, and because I think it was still a pretty good approach, here's my old answer.

# CJam, 23 bytes

There's probably an elegant mathematical solution to this problem. But I have no clue how to find one, so super compressed hard coding it is!

"pÜ×ñè¨"487b8b3/ri_o=~p


Try it online.

### Cube layout

  0-----7          0-----7          3-----6
/|    /|         /  0  /|         /  3  /|
1-----2 |        1-----2 |        4-----5 |
| |   | |        |     |2|        |     |5|
| 5---|-6        |  1  | 6        |  4  | 7
|/    |/         |     |/         |     |/
4-----3          4-----3          1-----0


### Explanation

The basic approach employed is to hard code the vertices for each face in as little space as possible. Similarly to Optimizer's base conversion solution, this treats the vertex list as an octal number packed as ASCII character data. But that's about where the similarities end to make way for further optimizations!

Here are the three key optimizations I made to the "naive" solution:

• Lay out the cube such that each face can be described with its face number as the first vertex number. Looking at my cube layout as presented above, one can see that the top-left vertex number of each face is equal to the face number. This allows me to encode six fewer vertices at the cost of having to print the input back, which turns out to save a byte.
• Pack the vertex data into a string for which each "character" has a maximum larger than 256. As this maximum increases past 256, the length of the string slowly decreases, but it becomes increasingly likely that any one "character" exceeds 256 and is thus no longer part of the 1-byte ASCII character set. So I wrote a program that tries encoding the vertex data in every base from 256 to 1000, with which I found about 10 bases that save one byte of character data compared to base 256. I chose 487, as that also has the nice property that the resulting string consists entirely of printable ASCII.
• Mixed with the first optimization, produce the output asymetrically. The usual approach in CJam would be to format the vertex data as a 2-element list of 2-element lists, insert a newline in the middle, and let the output be implicitly printed. But I instead print the first vertex (equal to the input face number) with an operator that doesn't add a newline, retrieve the 3-element list of the other vertices, grab the next vertex and print it with an operator that does add a newline, and let the other two vertices be implicitly printed. This saves a byte.
• I tried permutations as an elegant mathematical approach and it's more verbose than hard-coding without your optimisations. – Peter Taylor Apr 14 '15 at 17:56
• Your latest answer is brilliant. I think you should have posted it as a separate answer as it's a completely different approach and worthy of another upvote. Basically you have the same cube as my C answer but with the first three even corners shifted one place. I can't believe I missed 6+n%2 --> 6|n (i've already incorporated that into my Ruby answer.) Note that by performing the transform n --> n^1 on the faces you could simplify your formulas, though I'm guessing that as you discard n and carry on with n^1 it won't help your score. – Level River St Apr 15 '15 at 17:16
• @steveverrill Thanks for the praise! I asked in chat if I should post this as an entirely new answer, but there wasn't a consensus so I didn't. I was definitely pleased with myself when I realized that carefully ordering the n and n^1 pairs around the cube would allow me to calculate another vertex with just |6. And I didn't see that n --> n^1 transform, which definitely makes sense. But you correctly surmised that it wouldn't actually affect my score, so I'll probably just leave it as-is. – Runer112 Apr 15 '15 at 17:32
• I've gone ahead and incorporated your XOR idea into my Ruby answer. It gives a saving of 10 (in addition to the 2 for 6+n%2 --> 6|n) I hope you don't mind. I did use the n --> n^1 transform on the faces, so my latest revision gives the same outputs as yours, but with different inputs. BTW, I don't think bit operations are inelegant, it all depends how you use them! – Level River St Apr 15 '15 at 18:04
• 1 char shorter in GolfScript: ~.1^..n@6|@3+6% – Peter Taylor Apr 15 '15 at 18:56

# C,69

f(c){int d=c++%2*2-1;printf("%d%d\n%d%d",(c-d)%6,c%6,c%2+6,(c+d)%6);}


Ungolfed in test program

f(c){
int d=c++%2*2-1;
printf("%d%d\n%d%d",(c-d)%6,c%6,c%2+6,(c+d)%6);
}

int n;
main(){
scanf("%d",&n);
f(n);
}


Explanation

My cube numbering, when unfolded, looks like this:

0---7
|   |
| 0 |
|   |
1---2---7
|   |   |
| 1 | 2 |
|   |   |
6---3---4---7
|   |   |
| 3 | 4 |
|   |   |
6---5---0
|   |
| 5 |
|   |
6---1


The top left corner has the same number as the face.

The bottom right corner has number (n+2)%6

For odd n the top right corner is (n+1)%6 and the bottom left is 6

For even n the top right corner is 7 and the bottom left is (n+1)%6

The program displays the odd numbers as shown and the even numbers rotated 180 degrees. This means that the top right corner is always (n+1)%6 and the bottom left is always (n+1)%2+6. Inverting n and n+2 is easier (it is done by setting c=n+1 and using d to add or subtract 1 or -1 as necessary.)

Output

$./a 0 21 70$ ./a
1
12
63

$./a 2 43 72$ ./a
3
34
65

$./a 4 05 74$ ./a
5
50
61

• +1 This is the kind of elegant mathematical solution I was imagining. Unfortunately, it's implemented in C... – Runer112 Apr 14 '15 at 16:50
• @Runer112 Thanks. Unfortunately, C is the language I know best. I'm learning Ruby but I'm still a beginner. Ruby should be able to smash this score but probably not compete with Cjam. Maybe I will post in Ruby later, or just find some minor improvements to my C answer (for example by changing c%6 to c%=6 and rotating the face so it comes first, it should be possible to eliminate some modulus calculations.) Another thing to experiment with is shifting the face labelling by one place, so I get n-1,n,n+1 instead of n,n+1,n+2. – Level River St Apr 14 '15 at 17:02
• @steveverrill you are already declaring n global, so you could save a few bytes by declaring it higher, change the signature to f()? Or are we only looking at the f function here? – dwcanillas Apr 15 '15 at 15:24
• @dwcanillas "You may write a function instead of a program" so I'm only counting the function. In any case, this was just a proof of concept in the language I'm most familiar with. I'm more interested in shortening my Ruby answer, which from the start was already much shorter than this. – Level River St Apr 15 '15 at 15:59

# Element, 18

_4:2%6+2+6%-5+


Unlike many more advanced golfing languages, Element does not have a compression operator, so the brevity of the solution is tied rather closely to the exact numbering scheme used. After some experimentation, I have created a new numbering scheme which allows the vertices to be computed using only simple arithmetic operations.

  1-----0          1-----0          2-----5
/|    /|         /  4  /|         /  3  /|
4-----6 |        4-----6 |        3-----7 |
| |   | |        |     |0|        |     |5|
| 7---|-5        |  2  | 5        |  1  | 0
|/    |/         |     |/         |     |/
3-----2          3-----2          4-----1


The top-left corner is 6 if even and 7 if odd. The top-right corner is the face number itself. The bottom-left is the face number, plus 2, mod 6. The bottom-right is 5 minus the face number.

Here is an explanation of the code.

_4:2%6+2+6%-5+
_4:                    take input and make several copies of it
2%6+               take face #, mod 2, add 6, and output
output input, which already has the newline attached
2+6%         take face #, add 2, mod 6, and output
-5+     negate face #, add 5, and output


Here are the outputs for each of the faces:

0
60
25

1
71
34

2
62
43

3
73
52

4
64
01

5
75
10

• +1: Although I find your code indecipherable, it's nice to see how this scores in a golfing language. Looks like you're currently in joint 3rd place, behind 2 CJam answers: Peter Taylor and Runer 112. – Level River St Apr 15 '15 at 9:21
• Now it's in a solid second place, but I don't foresee it beating CJam. – PhiNotPi Apr 15 '15 at 13:52

# Octave, 10810068 50 bytes

Of course ther is a way of doing it way more elegant than my previous approaches, plain hardcoding. I am amazed how Octave is way more suitable for codegolf than Matlab=)

f=@(n)['040201375767';'261345154623'](:,2*n+(1:2))


## Layout:

(Sorry, I forgot to add this.)

### Cube layout

  1-----5          1-----5          6-----7
/|    /|         /  2  /|         /  5  /|
0-----4 |        0-----4 |        2-----3 |
| |   | |        |     |4|        |     |3|
| 3---|-7        |  0  | 7        |  1  | 5
|/    |/         |     |/         |     |/
2-----6          2-----6          0-----1


## Old Versions:

f=@(n)[0 4 0 2 0 1 3 7 5 7 6 7;2 6 1 3 4 5 1 5 4 6 2 3](:,2*n+(1:2))


Even older Versions:

This is really gonna make a 2x2x2 array and then choosing a 'slice'. We do a 3d matrix permutation and each time choose the top or bottom slice. (This one does not work in matlab because of the indexing of an expression rather than a matrix) I am sure there would be more direct ways of doing it that would be shorter.

f=@(n)squeeze(permute(reshape(0:7,2,2,2),circshift((1:3)',n))(n=fix(n/3)+1,circshift((1:2)',n-1),:))

f=@(n)squeeze(permute(reshape(0:7,2,2,2),circshift((1:3)',n))(floor(n/3)+1,circshift((1:2)',floor(n/3)),:))


# CJam, 31 28 (or 26) bytes

8,2/W%_1m<]z[D75K46]2/+ri=N*


which can also be compressed using base conversion into a 26 bytes version.

Assumes the cube to be like:

  7-----1
/|    /|
5-----3 |
| |   | |
| 6---|-0
|/    |/
4-----2


with faces like

  7-----1      .-----.      .-----.      .-----.
/  4  /|     /  4  /|     /  4  /|     /  0  /|
5-----3 |    .-----. |    .-----. |    .-----. |
|     |2|    |     |1|    |     |0|    |     |5|
|  1  | 0    |  0  | .    |  3  | .    |  3  | .
|     |/     |     |/     |     |/     |     |/
4-----2      .-----.      .-----.      .-----.


Try it online here

## CJam (25 bytes)

"ñRXµ  roM~"(ib65b2/q~=N*


This contains a non-printable character and a tab (which will be mangled by the StackExchange software), so in xxd format:

0000000: 22f1 5258 1fb5 0972 6f4d 7e22 2869 6236  ".RX...roM~"(ib6
0000010: 3562 322f 717e 3d4e 2a                   5b2/q~=N*


Online demo

Cube:

  1-----0        Faces:
/|    /|        10 46
4-----6 |        14 37
| |   | |        20 31
| 3---|-2        23 57
|/    |/         56 20
7-----5          57 64


This is pure hard-coding, with the cube vertices selected to maximise base compressibility. I decode to 2-digit numbers, so none of them can begin with 0. I don't want any to begin with 7 either, since that pushes the second base too high. Therefore 0 and 7 must be on a long diagonal. I want a 10 edge to go first to reduce the value I'm encoding. Other than that, there's a fair amount of flexibility without changing the byte count.

I'm slightly disappointed that having popped the first character from the magic string, it's necessary to cast it to an int before using it as a base for base conversion. Hopefully future versions of CJam will save that byte, although it will be too late to exploit that here.

# JavaScript (ES6), 53 62

Edit Save 8 bytes using template strings, thx @NinjaBearMonkey. Beware, the newlines inside quotes are significant and cannot be collapsed.

Can't be clever in Javascript, it's too verbose.

f=n=>01
23
45
67
01
31
5702
64.substr(n-4?n*3:20,5)


Output for(i=0;i<6;i++)console.log(f(i),i)

01
23
0

23
45
1

45
67
2

67
01
3

02
64
4

31
57
5

See the snippet to veify the number associations (that was fun)

function P3D(x,y,z) {
this.x = x;this.y = y;this.z = z;
this.rotateX = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad),sina = Math.sin(rad),
y = this.y * cosa - this.z * sina,
z = this.y * sina + this.z * cosa
return new P3D(this.x, y, z)
}
this.rotateY = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad), sina = Math.sin(rad),
z = this.z * cosa - this.x * sina,
x = this.z * sina + this.x * cosa
return new P3D(x,this.y, z)
}
this.rotateZ = angle => {
var rad = angle * Math.PI / 180,
cosa = Math.cos(rad), sina = Math.sin(rad),
x = this.x * cosa - this.y * sina,
y = this.x * sina + this.y * cosa
return new P3D(x, y, this.z)
}
this.project = (viewWidth, viewHeight, fov, viewDistance) => {
var factor = fov / (viewDistance + this.z),
x = this.x * factor + viewWidth / 2,
y = this.y * factor + viewHeight / 2
return new P3D(x, y, this.z)
}
}

var vx = [
new P3D(-1,1,-1),
new P3D(1,1,-1),
new P3D(-1,-1,-1),
new P3D(1,-1,-1),
new P3D(-1,-1,1),
new P3D(1,-1,1),
new P3D(-1,1,1),
new P3D(1,1,1),
];
// Define the vx that compose each of the 6 faces. These numbers are
// indices to the vertex list defined above.

var faces = [[0,1,3,2],[2,3,5,4],[4,5,7,6],[6,7,1,0],[0,2,4,6],[1,3,5,7]]

faces.map((f,i)=>{
var mx=vx[f[0]].x+vx[f[1]].x+vx[f[2]].x+vx[f[3]].x,
my=vx[f[0]].y+vx[f[1]].y+vx[f[2]].y+vx[f[3]].y,
mz=vx[f[0]].z+vx[f[1]].z+vx[f[2]].z+vx[f[3]].z
vx[i+10]=new P3D(mx/4, my/4, mz/4)
f[4]=i
f[5]=i+10
})

var angle = 0;

var ctx = CV.getContext("2d");

setInterval(loop,33)

function loop() {
ctx.fillStyle = "#fff"
ctx.fillRect(0,0,400,200);
ctx.font = "20px Arial"
angle += 2

var t = vx.map(v=>
v
.rotateX(angle).rotateY(-angle).rotateZ(-angle)
.project(400,200,128,3)
)

ctx.strokeStyle = "#f00"
t.forEach((v,i)=>i<8?ctx.strokeText(i,v.x,v.y):0)

ctx.strokeStyle = "#428"
ctx.beginPath()
faces.forEach(f=>(
ctx.moveTo(t[f[0]].x,t[f[0]].y),
ctx.lineTo(t[f[1]].x,t[f[1]].y),
ctx.lineTo(t[f[2]].x,t[f[2]].y),
ctx.lineTo(t[f[3]].x,t[f[3]].y),
ctx.lineTo(t[f[0]].x,t[f[0]].y),
ctx.strokeText(f[4],t[f[5]].x,t[f[5]].y)
))
ctx.closePath(),
ctx.stroke()
}
<canvas id=CV width=400 height=200></canvas>

• If you use ES6 template strings, you can use actial newline characters instead of \n, which should save 8 bytes. – NinjaBearMonkey Apr 14 '15 at 21:58
• You have to use tick marks  instead of quote marks for template strings. – NinjaBearMonkey Apr 14 '15 at 22:28
• Right, that's how I tested it in fact. – edc65 Apr 14 '15 at 22:30

# Ruby Rev 1, 40 36

->(c){print(c^1,c,"\n",6|c,(c+3)%6)}

Thanks to @rcrmn for suggesting using a lambda to save 4 bytes. I wasn't sure about leaving it anonymous but it seems to have been discussed on meta here and decided this was OK.

Here it is as a 40-byte function, for comparison with my Rev 0 Ruby answer, also below (Original C answer is in a separate post.)

def f(c)print(c^1,c,"\n",6|c,(c+3)%6)end


Further inspiration from Runer112: This relies on a modification of the numbering scheme used in his latest (16 byte!) answer. A direct port of PhiNotPi's scheme would give the same score.

By shifting the numbering from Rev 0 round one step, and taking everything XOR 1, we get the following cube:

4---7
|   |
| 1 |
|   |
1---0---7
|   |   |
| 0 | 3 |
|   |   |
6---3---2---7
|   |   |
| 2 | 5 |
|   |   |
6---5---4
|   |
| 4 |
|   |
6---1


Output

0
10
63

1
01
74

2
32
65

3
23
70

4
54
61

5
45
72


# Ruby Rev 0, 56 52 50

Saved 4 bytes by removing unnecesary ()%6from c-d and another 2 (inspired by runer112) by 6+c%2 --> 6|c .

Score is for the function, which is just the first line. I'm new to Ruby and I'm surprised I can't find a shorter way than 12 characters (11 plus newline) to get a user input number into n. As a result, doing a function instead of a program saves 1 byte.

def f(c)d=c%2*2-1;print((c+d)%6,c,"\n",c|6,c-d)end

n=gets.to_i
f(n)


This is a port of my C answer. In C, the % operator returns a negative value with a negative number. In Ruby it always returns a positive value, so there is no need to add 1 to c. As a result, it is advantageous to shift the numbering of the faces by 1 as below:

0---7
|   |
| 1 |
|   |
1---2---7
|   |   |
| 2 | 3 |
|   |   |
6---3---4---7
|   |   |
| 4 | 5 |
|   |   |
6---5---0
|   |
| 0 |
|   |
6---1


With the new face numbering, the program prints the evens as shown above and the odds rotated through 180 degrees:

1
21
70

2
12
63

3
43
72

4
34
65

5
05
74

0
50
61

• I believe you can shorten the function by using lambdas: ->(x){...code...} which leaves your function definition 4 characters shorter. You then have to assign it to a variable to use it, and call it with #call – rorlork Apr 15 '15 at 8:02
• @rcrmn thanks, you're right, f=->(c){print(c^1,c,"\n",6|c,(c+3)%6)} does run and is 2 characters shorter (4 characters shorter if I omit the f=). Not sure if its fair to omit f= but the question doesn't say the function can't be anonymous. What I find odd is that this syntax is totally different from the syntax shown to beginners, that has the passed parameter inside the braces: f=lambda{|c|print(c^1,c,"\n",6|c,(c+3)%6)} – Level River St Apr 15 '15 at 23:18
• This is what's called a lambda literal. And indeed I always find it difficult to find a reference when I need to remember the syntax... – rorlork Apr 16 '15 at 7:32

# Pyth, 30

Thanks @Jakube for 2 bytes.

Jc2jkfx>Q2!.&T^2%Q3U8jb?_J%Q2J


Try it here.

Golfing advice from pyth experts will be graciously accepted. In particular I think the output section might have some improvements.

Port of the following python:...

# Python, 109

Q=input()
s=''.join(map(str,filter(lambda v:(Q<3)^(v&(1<<Q%3)>0),range(8))))
print s[1-Q%2::2],'\n',s[Q%2::2]


...which is a port of

# Pure Bash, 130

For the purposes of explanation:

for v in {0..7};{
if(($1/3));then((v&(1<<$1%3)))&&a+=$v else((v&(1<<$1%3)))||a+=$v fi } i=$[$1%2*2] echo "${a:i:2+i}
\${a:2-i:4-i}"


The cube vertices are numbered thus:

  4-----5
/|    /|
0-----1 |
| |   | |
| 6---|-7
|/    |/
2-----3


And the faces are numbered thus:

Face  Vertices  Swap
0  0,2,4,6
1  0,1,4,5   x
2  0,1,2,3
3  1,3,5,7   x
4  2,3,6,7
5  4,5,6,7   x


The Swap column indicates the order of the vertices should be switched in the output.

The algorithm starts out with all vertices {0..7}. Vertices are eliminated according to bits set in the vertex numbers:

• For faces 0,1 and 2, vertices with bits 1,2 or 3 cleared respectively are kept
• For faces 3,4 and 5, vertices with bits 1,2 or 3 set respectively are kept

The "kept" vertices are appended to a string. The string is output chars 0,1 then 2,3 or vice versa, depending on whether the swap flag (face number mod 2) is set.

# J - 26 bytes

Function taking face number as argument and returning the grid of digits.

0{.@":"0@{0&(|:|.)&(i.3#2)


We are using the following cube:

  4-----5    Face numbers:
/|    /|     0 - front
0-----1 |     1 - top
| |   | |     2 - left
| 6---|-7     3 - back
|/    |/      4 - bottom
2-----3       5 - right


Example (try it yourself at tryj.tk):

   0{.@":"0@{0&(|:|.)&(i.3#2) 3         NB. inline
76
54
f =: 0{.@":"0@{0&(|:|.)&(i.3#2)      NB. named
f each 0 1 2 3 4 5                   NB. all results
+--+--+--+--+--+--+
|01|40|64|76|37|13|
|23|51|20|54|26|57|
+--+--+--+--+--+--+


The bread and butter is 0&(|:|.). This is a verb that reverses and rotates the cube in such as way as to visit every face when iteratively applied, which is what we do using the input argument. The vertices of the cube are generated by i.3#2, so we use that as the starting point, and take the front face 0...{ when we're done.

Printing the digits as a string costs 8 chars: {.@":"0@ If we were allowed to simply return an array, that's a saving of 8 whole characters. [commences fist-shaking and indiscernible griping]

• Results for 1, 4 and 5 appear to be reversed – Digital Trauma Apr 15 '15 at 15:03

# ><> (Fish), 38 bytes

'/ =/2= 28"H5'a@i-!
noan~\;
~>:?!^1-@~


Every output is stored as two 2-digit rows. The rows are stored as charcodes in the string '/ =/2= 28"H' (except the row 10 which is appended after the string as a). The first character (/ = 47) is used to redirect the program flow on the second interaction.

The top 2*(53-n) elements are discarded (where n is the charcode of the input number) and the next two codes are printed with a newline between.

Layout:

  3-----2
/|    /|
4-----7 |
| |   | |
| 5---|-0
|/    |/
6-----1      0 1 2 3 4 5 sides are top front bottom back left right respectively.
`