# Visible Dice Faces

A traditional Western die is a cube, on which the integers 1 to 6 are marked on the faces. Pairs that add to 7 are placed on opposite faces.

As it is cube, we can only see between 1 and 3 faces (inclusive)1 at any given time. Opposite faces can never be seen at the same time.

Your task is to write a program or function which, given a list of integers representing sides on a die, determines if it is possible to see these faces at the same time.

1Okay, maybe you can see 4 or 5 faces with a pair of eyes, but for the purpose of this challenge we observing the die from a single point.

# Rules:

• Your submission may assume the input list:
• Is non-empty.
• Only contains values which satisfy 1 ≤ n ≤ 6.
• Contains no duplicate elements.
• You may not assume that the input is sorted.
• Your submission should output a truthy / falsy value: truthy is the faces can be seen at the same time, falsy otherwise.
• This is , so the shortest answer (in bytes) wins!
• Standard loopholes are forbidden by default.

## Test Cases

Truthy:

[6]                 (One face)
[6, 2]              (Share a side)
[1, 3]              (Share a side)
[2, 1, 3]           (Share a vertex)
[3, 2, 6]           (Share a vertex)

Falsy:

[1, 6]              (1 and 6 are opposite)
[5, 4, 2]           (2 and 5 are opposite)
[3, 1, 4]           (3 and 4 are opposite)
[5, 4, 6, 2]        (Cannot see 4 faces)
[1, 2, 3, 4, 5, 6]  (Cannot see 6 faces)
• Dec 4 '17 at 20:30
• It seems that the last two falsey cases are superfluous as any list longer than 3 will contain opposing values, no? Dec 6 '17 at 12:22
• @WeckarE yes, obviously - if you have a look at the answers they all exploit this. It was just an easier explanation to write. Dec 6 '17 at 15:09
• @FlipTack Actually you don't have to check the length at all, every list longer than 3 elements has at least one pair of opposite sides. Dec 7 '17 at 18:12
• You can still see up to 5 faces from a single point if you bent the light waves with something heavy like a black hole Dec 14 '17 at 6:46

# Python 2, 35 bytes

lambda a:any(7-i in a for i in a)<1

Try it online!

• -1 byte in Python 3. Dec 4 '17 at 22:53

# JavaScript (ES6),  38 34 30 29  28 bytes

Takes input as any number of separate parameters. Returns 0 or 1.

(a,b,c,d)=>!(d|(a^b^c)%7)^!c

### Test cases

let f =

(a,b,c,d)=>!(d|(a^b^c)%7)^!c

console.log('[Truthy]')
console.log(f(6      ))
console.log(f(6, 2   ))
console.log(f(1, 3   ))
console.log(f(2, 1, 3))
console.log(f(3, 2, 6))

console.log('[Falsy]')
console.log(f(1, 6            ))
console.log(f(5, 4, 2         ))
console.log(f(3, 1, 4         ))
console.log(f(5, 4, 6, 2      ))
console.log(f(1, 2, 3, 4, 5, 6))

### How?

Below are simplified versions of the main expression according to the number of parameters provided, undefined variables being coerced to either 0 or false:

# of param. | simplified expression        | comment
------------+------------------------------+---------------------------------------------
1      | !(a % 7) ^ 1                 | always true
2      | !((a ^ b) % 7) ^ 1           | false for (1,6), (2,5) and (3,4)
3      | !((a ^ b ^ c) % 7)           | see the table below
4+     | !(d | (a ^ b ^ c) % 7)       | always false

NB: The order of (a,b,c) doesn't matter because they're always XOR'd together.

The trickiest case is the 3rd one. Here is a table showing all possible combinations:

a | b | c | a^b^c | %7 | =0? | faces that sum to 7
--+---+---+-------+----+-----+--------------------
1 | 2 | 3 |   0   |  0 | Yes | none
1 | 2 | 4 |   7   |  0 | Yes | none
1 | 2 | 5 |   6   |  6 | No  | 2 + 5
1 | 2 | 6 |   5   |  5 | No  | 1 + 6
1 | 3 | 4 |   6   |  6 | No  | 3 + 4
1 | 3 | 5 |   7   |  0 | Yes | none
1 | 3 | 6 |   4   |  4 | No  | 1 + 6
1 | 4 | 5 |   0   |  0 | Yes | none
1 | 4 | 6 |   3   |  3 | No  | 1 + 6
1 | 5 | 6 |   2   |  2 | No  | 1 + 6
2 | 3 | 4 |   5   |  5 | No  | 3 + 4
2 | 3 | 5 |   4   |  4 | No  | 2 + 5
2 | 3 | 6 |   7   |  0 | Yes | none
2 | 4 | 5 |   3   |  3 | No  | 2 + 5
2 | 4 | 6 |   0   |  0 | Yes | none
2 | 5 | 6 |   1   |  1 | No  | 2 + 5
3 | 4 | 5 |   2   |  2 | No  | 3 + 4
3 | 4 | 6 |   1   |  1 | No  | 3 + 4
3 | 5 | 6 |   0   |  0 | Yes | none
4 | 5 | 6 |   7   |  0 | Yes | none

# Alt. version #1, 32 bytes

Takes input as an array. Returns a boolean.

a=>a.every(x=>a.every(y=>x+y-7))

### Test cases

let f =

a=>a.every(x=>a.every(y=>x+y-7))

console.log('[Truthy]')
console.log(f([6]      ))
console.log(f([6, 2]   ))
console.log(f([1, 3]   ))
console.log(f([2, 1, 3]))
console.log(f([3, 2, 6]))

console.log('[Falsy]')
console.log(f([1, 6]            ))
console.log(f([5, 4, 2]         ))
console.log(f([3, 1, 4]         ))
console.log(f([5, 4, 6, 2]      ))
console.log(f([1, 2, 3, 4, 5, 6]))

# Alt. version #2, Chrome/Firefox, 34 bytes

This one abuses the sort methods of Chrome and Firefox. It doesn't work with Edge.

Takes input as an array. Returns 0 or 1.

a=>a.sort((a,b)=>k&=a+b!=7,k=1)&&k

### Test cases

let f =

a=>a.sort((a,b)=>k&=a+b!=7,k=1)&&k

console.log('[Truthy]')
console.log(f([6]      ))
console.log(f([6, 2]   ))
console.log(f([1, 3]   ))
console.log(f([2, 1, 3]))
console.log(f([3, 2, 6]))

console.log('[Falsy]')
console.log(f([1, 6]            ))
console.log(f([5, 4, 2]         ))
console.log(f([3, 1, 4]         ))
console.log(f([5, 4, 6, 2]      ))
console.log(f([1, 2, 3, 4, 5, 6]))

-3 bytes thanks to H.PWiz.

f l=all(/=7)$(+)<$>l<*>l

Try it online!

## Explanation

f l=all(/=7)$(+)<$>l<*>l

f l=                      -- make a function f that takes a single argument l
(+)<$>l<*>l -- take the sum of each pair in the cartesian product... all(/=7)$             -- ...and check if they're all inequal to 7

# APL (Dyalog), 7 bytes

~7∊∘.+⍨

Try it online!

∘.+⍨ - addition table (every element with every element)

7∊ - 7 exists?

~ - negate

# APL (Dyalog), 7 bytes

⍬≡⊢∩7-⊢

Try it online!

7-⊢ - subtract each element from 7

⊢∩ - intersect with the original array

⍬≡ - empty?

# R, 27 bytes

thanks to Gregor for fixing a bug

function(d)!any((7-d)%in%d)

Try it online!

Port of Chas Brown's answer. Having vectorized operations helps make this much shorter in R.

• I think you need some parens around (7-d), other wise d%in%d takes precedence. Dec 5 '17 at 20:32
• @Gregor you're absolutely right. Dec 5 '17 at 20:35

# Mathematica, 20 bytes

xFreeQ[#+x&/@x,7]

The is \[Function]

-12 bytes from Martin Ender
-7 bytes from Misha Lavrov

Try it online!

f x=null[1|7<-(+)<$>x<*>x] Try it online! # Pyth, 5 bytes !@-L7 Try it here. • I could swear I tried this two minutes ago and it didn’t work... Huh I wonder what went wrong Dec 4 '17 at 21:04 • First thing I thought of? The Sandlot. Dec 4 '17 at 22:23 # Actually, 8 bytes ;∙♂Σ7@cY Try it online! (runs all the test cases) Explanation: ;∙♂Σ7@cY ;∙ Cartesian product with self ♂Σ sum all pairs 7@c count 7s Y logical negate ## Husk, 5 bytes Ëo≠7+ Try it online! ### Explanation Ëo Check that the following function gives a truthy value for all pairs from the input. + Their sum... ≠7 ...is not equal to 7. # Retina, 21 20 bytes O. M1.*6|2.*5|34 0 Try it online! Link includes test cases. Edit: Saved 1 byte thanks to @MartinEnder. Explanation: O. Sort the input. M1.*6|2.*5|34 Check for a pair of opposite sides (3 and 4 sort next to each other). This returns 1 for an invalid die or 0 for a valid one. 0 Logically negate the result. # Jelly, 5 bytes 7_f⁸Ṇ Try it online! Port of Chas Brown's answer. ### Explanation 7_f⁸Ṇ 7_ Subtract each element from 7 f⁸ Filter with the original list Ṇ Check if empty ## Alice, 18 bytes /..y1nr@ \iReA6o/ Try it online! Prints Jabberwocky for valid inputs and nothing otherwise. ### Explanation Unfolding the zigzag control flow, the program is really just: i.e16r.RyAno i. Read all input and duplicate it. e16 Push "16". r Range expansion to get "123456". .R Duplicate and reverse. y Transliterate, replaces each face with its opposite. A Intersection with input. n Logical NOT, turns empty strings into "Jabberwocky" and everything else into an empty string. # Pyth, 5 bytes -7sM* Test suite. isaacg saved a byte! # Ruby, 36 31 24 23 bytes ->l{l-l.map{|x|7-x}==l} Try it online! It was so simple, I was looking for the solution to the wrong problem all the time. # 05AB1E, 5 bytes 7αå_P Try it online! Explanation 7α # absolute difference between 7 an each in input list å # check each element if it exist in input _ # logical negate P # product of list One of several ways to do this in 5 bytes in 05AB1E # Perl 5, 51 + 1 (-a) = 52 bytes say$F[0]+($t=$F[1])-7&&$F[0]+$t-7&&$t+$F[2]-7&&@F<4

Try it online!

• 3 1 4 gives true, what about say 1>grep{$x=$_;grep$_+$x==7,@F}@F Dec 5 '17 at 16:14
• 25 + 1 (-p) inspired from sed solution Dec 5 '17 at 16:51

## Retina, 20 bytes

T_654d
M(.).*\1
0

Try it online!

An alternative to Neil's approach.

### Explanation

T_654d

Turn 6,5, 4 into 1, 2, 3, respectively.

M(.).*\1

Try to find repeated characters and count the number of matches.

0

Make sure the result was zero (effectively a logical negation).

# Java (OpenJDK 8), 43 bytes

l->l.stream().noneMatch(x->l.contains(7-x))

Try it online!

# GNU sed, 37 22 + 1 = 23 bytes

+1 byte for -r flag. Takes input as digits; prints the input for truthy and 0 for falsy.

-10 bytes thanks to @MartinEnder.

y/123/654/
/(.).*\1/c0

Try it online!

## Explanation

y/123/654/   # Transliterate 1-3 to 6-4
/(.).*\1/c0  # If a digit appears twice, replace the pattern space with 0
• It doesn't exactly print the input for truthy, it prints the input with 1-3 replaced by 6-4. Dec 5 '17 at 19:05

# Perl 6, 18 bytes

!(1&6|2&5|3&4∈*)

Try it online!

1 & 6 | 2 & 5 | 3 & 4 is a junction consisting of the numbers 1 and 6, OR the numbers 2 and 5, OR the numbers 3 and 4. This junction is an element of () the input list * if it contains 1 and 6, or 2 and 5, or 3 and 4. That result is then negated (!) to get the required boolean value.

## Haskell, 46 41 37 bytes

f z=all ((/=7).sum) [[x,y]|x<-z,y<-z]

Takes the Cartesian product of the list with itself, then checks if all of the resulting lists do not sum to 7. (If any of them summed to 7, opposite faces would be visible, and "all do not" is shorter than "not any do".)

# J, 12 bytes

7-.@e.[:,+/~

This is pretty much the same as the first APL solution by Uriel

Try it online!

# IBM/Lotus Notes Formula, 7 bytes

!7-i*=i

Takes input from a multi-value number field i.

Recursively subtracts each value of i from 7 and checks to see if it is in the original list. ! changes the 1 if it is to a 0 (faces cannot all be seen).

Test Cases (no TIO available for Notes Formula)

# Clean, 49 bytes

import StdEnv
f l=and[(a+b)<>7\\(a,b)<-diag2 l l]

Try it online!

• @StephenLeppik I don't think this answer is necessarily using the file name to store information. Dec 5 '17 at 1:02
• @StephenLeppik Oh fair point there, the import is required but the function doesn't need to be declared in a specific module. Thanks. Dec 5 '17 at 3:27

# Swift, 46 bytes

f(a:Int)->[Int]{!a.contains{a.contains(7-\$0)}}

Takes input as [Int] (integer array) and returns a Bool (boolean).

## Short Explanation (ungolfed)

f(a:Int)->[Int]{
!a.contains (where: {n in    // The input doesn't have an element where
a.contains(7 - n)        //    the opposite side is in the input
})
}

# Clojure, 8980 72 bytes

-9 bytes because I realized use of reduced is unnecessary

-8 bytes by changing from using reduce to using some

#(if(< 0(count %)4)(not(some(fn[[a b]](=(+ a b)7))(for[a % b %][a b]))))

I tried writing this without looking at any of the tricks other answers use. I may be able to improve on this later.

Returns true for true cases, false if any sides sum to 7, and nil if the number of sides is illegal.

(defn can-see? [dice-sides]
; Ensure its a valid length
(if (< 0 (count dice-sides) 4)

; Then check if any of the permutations sum to 7
(not (some (fn [[a b]]
(= (+ a b) 7))

; Generate all permutations
(for [a dice-sides, b dice-sides] [a b])))))