Visible Dice Faces

21

2

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)

FlipTack

Posted 2017-12-04T20:29:37.827

Reputation: 13 242

Related. – FlipTack – 2017-12-04T20:30:53.640

It seems that the last two falsey cases are superfluous as any list longer than 3 will contain opposing values, no? – Weckar E. – 2017-12-06T12:22:38.657

@WeckarE yes, obviously - if you have a look at the answers they all exploit this. It was just an easier explanation to write. – FlipTack – 2017-12-06T15:09:52.510

@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. – Erik the Outgolfer – 2017-12-07T18:12:54.640

@EriktheOutgolfer Yes, that's exactly the point I was making - of course I realised that when making the challenge, but it doesn't make my explanations for those test cases invalid. – FlipTack – 2017-12-07T18:37:17.073

1You can still see up to 5 faces from a single point if you bent the light waves with something heavy like a black hole – Ferrybig – 2017-12-14T06:46:23.190

Answers

15

Python 2, 35 bytes

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

Try it online!

Chas Brown

Posted 2017-12-04T20:29:37.827

Reputation: 8 959

5-1 byte in Python 3. – notjagan – 2017-12-04T22:53:39.193

14

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

Arnauld

Posted 2017-12-04T20:29:37.827

Reputation: 111 334

8

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

totallyhuman

Posted 2017-12-04T20:29:37.827

Reputation: 15 378

5

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?

Uriel

Posted 2017-12-04T20:29:37.827

Reputation: 11 708

5

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.

Giuseppe

Posted 2017-12-04T20:29:37.827

Reputation: 21 077

I think you need some parens around (7-d), other wise d%in%d takes precedence. – Gregor Thomas – 2017-12-05T20:32:08.993

@Gregor you're absolutely right. – Giuseppe – 2017-12-05T20:35:36.280

4

Mathematica, 20 bytes

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

The is \[Function]

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

Try it online!

J42161217

Posted 2017-12-04T20:29:37.827

Reputation: 15 931

3

Haskell, 26 bytes

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

Try it online!

H.PWiz

Posted 2017-12-04T20:29:37.827

Reputation: 10 962

3

Pyth, 5 bytes

!@-L7

Try it here.

Erik the Outgolfer

Posted 2017-12-04T20:29:37.827

Reputation: 38 134

I could swear I tried this two minutes ago and it didn’t work... Huh I wonder what went wrong – Mr. Xcoder – 2017-12-04T21:04:46.777

First thing I thought of? The Sandlot.

– maxathousand – 2017-12-04T22:23:19.303

3

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

Mego

Posted 2017-12-04T20:29:37.827

Reputation: 32 998

3

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.

Neil

Posted 2017-12-04T20:29:37.827

Reputation: 95 035

3

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.

Martin Ender

Posted 2017-12-04T20:29:37.827

Reputation: 184 808

2

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 

Erik the Outgolfer

Posted 2017-12-04T20:29:37.827

Reputation: 38 134

2

Pyth, 5 bytes

-7sM*

Test suite.

isaacg saved a byte!

Mr. Xcoder

Posted 2017-12-04T20:29:37.827

Reputation: 39 774

2

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.

G B

Posted 2017-12-04T20:29:37.827

Reputation: 11 099

2

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.

Martin Ender

Posted 2017-12-04T20:29:37.827

Reputation: 184 808

1

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

Emigna

Posted 2017-12-04T20:29:37.827

Reputation: 50 798

1

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!

Xcali

Posted 2017-12-04T20:29:37.827

Reputation: 7 671

3 1 4 gives true, what about say 1>grep{$x=$_;grep$_+$x==7,@F}@F – Nahuel Fouilleul – 2017-12-05T16:14:47.370

25 + 1 (-p) inspired from sed solution – Nahuel Fouilleul – 2017-12-05T16:51:31.647

1

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

Jordan

Posted 2017-12-04T20:29:37.827

Reputation: 5 001

It doesn't exactly print the input for truthy, it prints the input with 1-3 replaced by 6-4. – Andrew – 2017-12-05T19:05:57.287

1

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

Martin Ender

Posted 2017-12-04T20:29:37.827

Reputation: 184 808

1

Java (OpenJDK 8), 43 bytes

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

Try it online!

Olivier Grégoire

Posted 2017-12-04T20:29:37.827

Reputation: 10 647

1

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.

Sean

Posted 2017-12-04T20:29:37.827

Reputation: 4 136

0

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

Draconis

Posted 2017-12-04T20:29:37.827

Reputation: 561

0

Clean, 49 bytes

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

Try it online!

Οurous

Posted 2017-12-04T20:29:37.827

Reputation: 7 916

1@StephenLeppik I don't think this answer is necessarily using the file name to store information. – Steadybox – 2017-12-05T01:02:23.303

@StephenLeppik Oh fair point there, the import is required but the function doesn't need to be declared in a specific module. Thanks. – Οurous – 2017-12-05T03:27:41.530

0

J, 12 bytes

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

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

Try it online!

Galen Ivanov

Posted 2017-12-04T20:29:37.827

Reputation: 13 815

0

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

ElPedro

Posted 2017-12-04T20:29:37.827

Reputation: 5 301

0

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

Herman L

Posted 2017-12-04T20:29:37.827

Reputation: 3 611

0

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

Carcigenicate

Posted 2017-12-04T20:29:37.827

Reputation: 3 295