21
\$\begingroup\$

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)
\$\endgroup\$
  • \$\begingroup\$ Related. \$\endgroup\$ – FlipTack Dec 4 '17 at 20:30
  • \$\begingroup\$ It seems that the last two falsey cases are superfluous as any list longer than 3 will contain opposing values, no? \$\endgroup\$ – Weckar E. Dec 6 '17 at 12:22
  • \$\begingroup\$ @WeckarE yes, obviously - if you have a look at the answers they all exploit this. It was just an easier explanation to write. \$\endgroup\$ – FlipTack Dec 6 '17 at 15:09
  • \$\begingroup\$ @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. \$\endgroup\$ – Erik the Outgolfer Dec 7 '17 at 18:12
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ – Ferrybig Dec 14 '17 at 6:46

27 Answers 27

15
\$\begingroup\$

Python 2, 35 bytes

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

Try it online!

\$\endgroup\$
  • 5
    \$\begingroup\$ -1 byte in Python 3. \$\endgroup\$ – notjagan Dec 4 '17 at 22:53
14
\$\begingroup\$

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

\$\endgroup\$
8
\$\begingroup\$

Haskell, 24 bytes

-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
\$\endgroup\$
5
\$\begingroup\$

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?

\$\endgroup\$
5
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ I think you need some parens around (7-d), other wise d%in%d takes precedence. \$\endgroup\$ – Gregor - reinstate Monica Dec 5 '17 at 20:32
  • \$\begingroup\$ @Gregor you're absolutely right. \$\endgroup\$ – Giuseppe Dec 5 '17 at 20:35
4
\$\begingroup\$

Mathematica, 20 bytes

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

The is \[Function]

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

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Haskell, 26 bytes

f x=null[1|7<-(+)<$>x<*>x]

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Pyth, 5 bytes

!@-L7

Try it here.

\$\endgroup\$
  • \$\begingroup\$ I could swear I tried this two minutes ago and it didn’t work... Huh I wonder what went wrong \$\endgroup\$ – Mr. Xcoder Dec 4 '17 at 21:04
  • \$\begingroup\$ First thing I thought of? The Sandlot. \$\endgroup\$ – maxathousand Dec 4 '17 at 22:23
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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.
\$\endgroup\$
3
\$\begingroup\$

Retina, 21 20 bytes

O`.
M`1.*6|2.*5|34
0

Try it online! Link includes test cases. Edit: Saved 1 byte thanks to @MartinEnder. Explanation:

O`.

Sort the input.

M`1.*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.

\$\endgroup\$
2
\$\begingroup\$

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 
\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
2
\$\begingroup\$

Pyth, 5 bytes

-7sM*

Test suite.

isaacg saved a byte!

\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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!

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

Retina, 20 bytes

T`_654`d
M`(.).*\1
0

Try it online!

An alternative to Neil's approach.

Explanation

T`_654`d

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

\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 43 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

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

Similar to @MartinEnder’s Alice answer.

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

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.

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
0
\$\begingroup\$

J, 12 bytes

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

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

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)

enter image description here

\$\endgroup\$
0
\$\begingroup\$

Clean, 49 bytes

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

Try it online!

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

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
    })
}
\$\endgroup\$
0
\$\begingroup\$

Clojure, 89 80 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])))))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.