Almost six years ago, fellow PPCG member steenslag posted the following challenge:

In a standard dice (die) the numbers are arranged so that opposite faces add to seven. Write the shortest possible program in your preferred language which outputs a random throw followed by 9 random tippings. A tipping is a quarter turn of the dice, e.g. if the dice is facing 5, all possible tippings are 1,3,4 and 6.

Example of desired output:


So, now that everybody has completely forgotten about it and the winning answer has long since been accepted, we'll be writing a program to validate the die tipping sequences generated by the submitted solutions. (This makes sense. Just pretend it does.)


Your program or function is given a sequence such as 1532131356. Validate that each consecutive digit is:

  • Not equal to the previous digit
  • Not equal to 7 minus the previous digit

(You don't have to validate the first digit.)


  • Your program must return a truthy value if the input is valid and a falsey value otherwise.
  • You can assume that the input consists of only the digits 1-6 and is at least 1 character long. Sequences won't have a fixed length like in steenslag's challenge.
  • You can take the input as a string ("324324"), an array or array-like datastructure ([1,3,5]) or as multiple arguments (yourFunction(1,2,4)).

Standard I/O and loophole rules apply.

Test cases




  • Repeated digit

  • Opposing side of die


38 Answers 38


Python 2, 43 45 bytes

lambda s:reduce(lambda p,n:n*(7-p!=n!=p>0),s)

43 bytes (inspired heavily by @Zgarb)

lambda s:reduce(lambda p,n:n*(p>0<n^p<7),s)

This function combines my reduce statement with the bit-flicking logic from @Zgarb's answer, for a combination that is shorter than both.

Both answers output the following:

  • 0 if the input is not a valid sequence
  • The last digit of the sequence if it is valid
  • 4
    \$\begingroup\$ Welcome to PPCG, This is a really nice first answer. \$\endgroup\$ – Sriotchilism O'Zaic Dec 21 '16 at 14:53
  • 1
    \$\begingroup\$ This doesn't work for about half of the false cases. E.g. 3132124225 returns 5. \$\endgroup\$ – Jake Cobb Dec 21 '16 at 15:37
  • \$\begingroup\$ You can fix it using n and p*(7-p!=n!=p). \$\endgroup\$ – Jake Cobb Dec 21 '16 at 15:45
  • \$\begingroup\$ @JakeCobb It should work with all the test cases now. Unfortunately it's now 2 bytes longer :( \$\endgroup\$ – notjagan Dec 21 '16 at 17:46
  • \$\begingroup\$ What a clever use of reduce, passing each value to the next step. \$\endgroup\$ – xnor Dec 22 '16 at 4:38

Python, 44 bytes

lambda x:all(0<a^b<7for a,b in zip(x,x[1:]))

Bitwise magic! This is an anonymous function that takes a list of integers, and checks that the XOR of every two consecutive elements is between 1 and 6 inclusive.

Why it works

First, the XOR is always between 0 and 7 inclusive, since 7 is 111 in base 2, and our numbers have at most 3 binary digits. For the equality, a^b == 0 if and only if a == b. Also, we have 7-a == 7^a when 0 ≤ a ≤ 7, and thus a^b == 7 if and only if a == 7^b == 7-b.


05AB1E, 11 9 bytes

-2 bytes for Osable's smart idea of using a product.


Try it online!

¥           # Push deltas.
 ¹D7-Á      # Push original array, and 7 - [Array] shifted right once.
      +     # Add original to the 7 - [Array] shifted right.
       «    # Concat both.
        P   # Product, if either contain a zero, results in 0, meaning false.

Third approach using 05AB1E, that doesn't use the pairwise command:

  • 0 if it violates the tipsy properties.
  • Not 0 if there was nothing preventing it from being tipsy.
  • 1
    \$\begingroup\$ @Emigna didn't think it mattered but fixed! \$\endgroup\$ – Magic Octopus Urn Dec 21 '16 at 16:40
  • 1
    \$\begingroup\$ I wanted to post an answer with deltas, but I did not think about Á. Nice! \$\endgroup\$ – Osable Dec 21 '16 at 18:05
  • 1
    \$\begingroup\$ You can save 2 bytes using the definition of truthy/falsy values with ¥¹D7-Á+«P . It yields 0 when there is a 0 in the array or any other value otherwise. \$\endgroup\$ – Osable Dec 21 '16 at 18:31
  • 1
    \$\begingroup\$ @Osable SMAART! Mega smart man, good job. \$\endgroup\$ – Magic Octopus Urn Dec 21 '16 at 20:03

R, 39 37 32 31 bytes


Try it online!

Takes input from stdin. Uses diff to see if any two consecutive digits are the same; then compares each digit to 7 minus the previous digit. Returns TRUE or FALSE.

Saved 5 bytes thanks to Jarko Dubbeldam, and another thanks to JayCe.

  • \$\begingroup\$ Saving the differences in some variable q and then testing 2*x+q-7 instead of c(0,x)!=c(7-x,0) saves a few bytes. If x1 + x2 = 7 then 2*x1 + diff(x1,x2) = 7. Checking 2*x+q - 7 then explicitly tests !=0. \$\endgroup\$ – JAD Dec 22 '16 at 11:25
  • \$\begingroup\$ @JarkoDubbeldam Great observation, thanks! I've updated the solution. \$\endgroup\$ – rturnbull Dec 22 '16 at 14:10
  • \$\begingroup\$ save 1 byte \$\endgroup\$ – JayCe Aug 8 '18 at 12:53
  • \$\begingroup\$ @JayCe Thanks, I've updated the answer now. \$\endgroup\$ – rturnbull Aug 9 '18 at 6:20

05AB1E, 10 bytes


Uses the CP-1252 encoding. Try it online!

  • 1
    \$\begingroup\$ Argh!, why didn't I think of Ê :P Nice! \$\endgroup\$ – Emigna Dec 21 '16 at 14:35
  • \$\begingroup\$ Hmm, so 1*[] = [] but product(1, []) = 1. That's good to know. \$\endgroup\$ – Emigna Dec 21 '16 at 14:38
  • \$\begingroup\$ @Emigna Actually, that is a bug. The product of [] should be 1. \$\endgroup\$ – Adnan Dec 21 '16 at 14:42
  • \$\begingroup\$ Yeah, I've wished that it worked like that several times before. Order of operations also matter here. )1*, )1s* and )1P are all [] while )1sP is 1. \$\endgroup\$ – Emigna Dec 21 '16 at 14:47
  • 1
    \$\begingroup\$ @Emigna Ahh, that's because the product of [] gives an error and is discarded. That's why it gives 1. I'll try to fix it when I get home. \$\endgroup\$ – Adnan Dec 21 '16 at 14:50

R, 49 44 bytes


Reads input from stdin (separated by space) and outputs TRUE/FALSE. Will give a warning if input is of length one but still works.

Edit: saved a couple of bytes thanks to @rturnbull

  • \$\begingroup\$ You can combine all(x)&all(y) into all(x,y) to save some bytes. You can also switch rle(x)$l==1 to rle(x)$l-1, which will then return a set of all FALSE if x is valid; then switch the later != to an == and the all to !any. This yields !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x))), saving 5 bytes in total. (PS, I've written an alternative solution you may be interested in.) \$\endgroup\$ – rturnbull Dec 22 '16 at 16:42

05AB1E, 15 bytes


Try it online! or as a Test suite


JavaScript (ES6), 43 40 bytes

Returns 0 / true.


Test cases


console.log('Testing truthy cases ...');

console.log('Testing falsy cases ...');

  • \$\begingroup\$ Sadly the simple port of the Retina answer is only 38 bytes. \$\endgroup\$ – Neil Dec 21 '16 at 20:23
  • \$\begingroup\$ @Neil I think it's actually 37 with test() \$\endgroup\$ – Arnauld Dec 21 '16 at 20:38
  • \$\begingroup\$ Sorry, I accidentally pasted a newline into the byte counter. \$\endgroup\$ – Neil Dec 21 '16 at 20:57

Perl 6, 22 bytes

Using a regex:


Takes the input as a string. Inspired by G B's Ruby answer.
How it works:

  • / /: A regex.
  • (.): Match any character, and capture it as $0.
  • <{ }>: Dynamically generate a sub-regex to be matched at that position.
  • "$0|" ~ (7 - $0): The sub-regex we generate is one that matches only the previous digit, or 7 minus the previous digit (e.g. 5|2).
    Thus the overall regex will match iff it finds an invalid consecutive pair of digits anywhere.
  • {! }: Coerce to a boolean (causing the regex to be matched against $_), negate it, and turn the whole thing into a lambda (with implicit parameter $_).

Perl 6, 38 bytes

Using list processing:

{all ([!=] 7-.[1],|$_ for .[1..*]Z$_)}

Takes the input as an array of integers.
How it works:

  • .[1..*] Z $_: Zip the input list with an offset-by-one version of itself, to generate a list of 2-tuples of consecutive digits.
  • [!=] 7 - .[1], |$_: For each of those, check if (7 - b) != a != b.
  • all ( ): Return a truthy or falsy value depending on whether all loop iterations returned True.

Python, 38 bytes

f=lambda h,*t:t==()or 7>h^t[0]>0<f(*t)

A recursive function that takes arguments like f(1,2,3).

This makes use of argument unpacking to extract the first number into h and the rest into the tuple t. If t is empty, output True. Otherwise, use Zgarb's bit trick to check that the first two die rolls are not incompatible. Then, check that the result also holds on the recursive call on the tail.


Ruby, 34 bytes

  • 2
    \$\begingroup\$ you could shave off two bytes by using the string #[] method instead: ->s{!s[/[16]{2}|[25]{2}|[34]{2}/]} \$\endgroup\$ – Alexis Andersen Dec 22 '16 at 20:38
  • \$\begingroup\$ I didn't know you can use it with regex, thanks. \$\endgroup\$ – G B Dec 22 '16 at 21:26

JavaScript 61 43 bytes

Comments have mentioned I can't use C# linq functions without including the using statement, so here's the exact same in less bytes using standard JS...


C#, 99 67 65 bytes

Takes input as an int array a

// new solution using linq
bool A(int[]a){return a.Aggregate((i,j)=>i>6|i==j|i+j==7?9:j)<7;}
// old solution using for loop
bool A(int[]a){for(int i=1;i<a.Length;)if(a[i]==a[i-1]|a[i-1]+a[i++]==7)return false;return true;}


// method that returns a boolean taking an integer array as a parameter
bool A(int[] a) 
    // aggregate loops over a collection, 
    // returning the output of the lambda 
    // as the first argument of the next iteration
    return a.Aggregate((i, j) => i > 6 // if the first arg (i) > than 6
    | i == j      // or i and j match
    | i + j == 7  // or i + j = 7
    ? 9   // return 9 as the output (and therefore the next i value)
    : j   // otherwise return j as the output (and therefore the next i value)
    // if the output is ever set to 9 then it will be carried through to the end
    < 7; // return the output is less than 7 (not 9)
  • \$\begingroup\$ I think this needs to be wrapped in a function, or maybe a lambda (does C# have those?) Also, you could save a few bytes by returning 0 or 1 instead of false or true \$\endgroup\$ – DJMcMayhem Dec 21 '16 at 18:21
  • \$\begingroup\$ oh, ok - first post on code golf. I'll edit... \$\endgroup\$ – Erresen Dec 21 '16 at 18:22
  • \$\begingroup\$ No problem. BTW, welcome to the site! :) \$\endgroup\$ – DJMcMayhem Dec 21 '16 at 18:23
  • \$\begingroup\$ @DJMcMayhem Correct me if I'm wrong but since the output requirement is truthy/falsey then the output options are language dependent tl;dr 1/0 are not truthy/falsey in c# \$\endgroup\$ – Phaeze Dec 21 '16 at 18:41
  • \$\begingroup\$ @Phaeze You're correct that they're not truthy/falsey, but the standard IO rules meta.codegolf.stackexchange.com/questions/2447/… reckon you can output using exit codes and that functions can output in the same way as programs. I'll change back to booleans if required, but it'll cost me a few bites \$\endgroup\$ – Erresen Dec 21 '16 at 18:51

><> (Fish) 47 bytes

   0n;n1< >
!? -{-$7:/^

Pretty simple;

Line 1: check to see if inputted a number, if no number (EOF) then we have a truthy to print else checks.

Line 2: print outcome.

Line 3: turn input into number (ASCII 0 - from input), then check if it's equal to previous input.

Line 4: check if input is opposite side of die.


Brain-Flak 128 Bytes


Outputs 0 for falsey, or -7 for truthy.

Try it Online! (Truthy)
Try it Online! (Flasey)

Explanation (t stands for top and s stands for second from the top):

(())                # push a 1 to get this loop started
{{}                 # loop through all pairs, or until 2 are equal
(({}<>)<>[({})])    # pop t, push t on the other stack, and t - s on this one
}{}                 # end loop and pop one more time
([])                # push the height of the stack
{                   # if the height isn't 0 (there were equal numbers)...
{{}}<>              # pop everything from this stack and switch
}                   # end if
{{}                 # for every pair on the stack: pop the height and...
({}({})<>)<>        # push t + s on the other stack leaving s on this one
([][()])            # push the height - 1
}                   # end loop when there is only 1 number left
{}(<{}>)<>          # pop t, pop s, push 0 and switch stacks
(([]))              # push the height twice
{                   # loop through every pair
{}{}                # pop the height and what was t - 7
({}[(()()()){}()])  # push t - 7
{<>}<>              # if t is not 0 switch stacks and come come back
                    # if t is 0 (ie, there was a pair that added to 7) just switch once
([][()])            # push height - 1
}                   # end loop
({}{})              # push t + s (either 0 + 0 or 0 + -7)

MATLAB, 30 bytes


PHP, 63 bytes


takes input as list of command arguments; exits with 1 (error) if input is invalid, 0 (ok) if valid.

Run with -nr.

input as string argument, 65 bytes


PowerShell, 57 44 41 bytes

(Crossed out 44 is still regular 44)


Try it online!

(OP has clarified that taking input as separate arguments is OK - saved 13 bytes ... saved another 3 bytes by eliminating $b)

We're looping through the input $args a digit at a time. Each digit, we verify that the $last digit is -notequal to the current digit $_, and that 7-$_-$l is some number other than zero (which is truthy). Those Boolean results are encapsulated in parens and fed into the right-hand operand of the -notin operator, checking against 0. In other words, if there is any False value anywhere in the loop, the -notin will also be False. That Boolean is left on the pipeline, and output is implicit.

Lengthy because of the $ requirement for variable names, and that Boolean commands -ne -and are verbose in PowerShell. Oh well.


Processing, 93 92 90 bytes

Changed || to | : 1 byte saved thanks to @ClaytonRamsey

Started counting backwards: 2 bytes saved thanks to @IsmaelMiguel

int b(int[]s){for(int i=s.length;--i>0;)if(s[i-1]==s[i]|s[i-1]==7-s[i])return 0;return 1;}

Takes input as an array of ints, output 1 for true or 0 for false.


int Q104044(int[]s){
      return 0;
  return 1;
  • \$\begingroup\$ Usually Java allows | instead of || if you want to save a byte. \$\endgroup\$ – Clayton Ramsey Dec 21 '16 at 16:59
  • \$\begingroup\$ @ClaytonRamsey I don't know why I didn't think of it, thanks! \$\endgroup\$ – Cows quack Dec 21 '16 at 17:01
  • \$\begingroup\$ I found another one. You could cut down on the use of returns with the tertiary operator \$\endgroup\$ – Clayton Ramsey Dec 21 '16 at 18:47
  • \$\begingroup\$ @ClaytonRamsey The return 0 is inside the if-statement while return 1 is not. I don't see how that is possible unless you have some other idea \$\endgroup\$ – Cows quack Dec 21 '16 at 18:56
  • 2
    \$\begingroup\$ Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :) <-- I read it, while comparing what you have with what you had. \$\endgroup\$ – Ismael Miguel Dec 22 '16 at 15:59

C 47 44 bytes


takes a string of digits (or a zero terminated array of bytes)



according to the standard int return type is implied. (saving 4 bytes)

return unconditional return because this is a recursive function

using shortcut evaluation:

!s[1]|| if the second character is nul return true

((*s^s[1])%7&& if the first two charcters aren't legal false

F(s+1)) check the rest of the string in the same way

that confusing expression

*s is the first character s[1] is the second

*s^s[1] exclusive-ors them together if they are the same the result is 0 if they add to 7 the result is 7 , (if they differ and don't add to 7 the result is between 1 and 6 inclusive)

so (*s^s[1])%7 is zero for bad input and non-zero otherwise, thus false if these 2 characters are bad, and true otherwise

comment: as this function call uses only end-recursion (only the last statement is a recursive call) an optimiser could translate the recursion into a loop, this is a happy conicidence and is obviously not worth any golf score, but in the real word makes it possible to process strings of any length without running out of stack.

  • 1
    \$\begingroup\$ About your !((*s^s[1])%7) I think you don't want the !. Zero values for bad input would be falsy, so you want to return the falsy when it's bad. \$\endgroup\$ – nmjcman101 Dec 22 '16 at 14:36

Python, 71 bytes

f=lambda s:len(s)<2or(s[0]!=s[1]and int(s[0])!=7-int(s[1]))and f(s[1:])

Uses a recursive approach.


f=lambda s:                                                              # Define a function which takes an argument, s
           len(s)<2 or                                                   # Return True if s is just one character
                      (s[0]!=s[1]                                        # If the first two characters matches or...
                                 and int(s[0])!=7-int(s[1])              # the first character is 7 - the next character, then return False
                                                           )and f(s[1:]) # Else, recurse with s without the first character
  • \$\begingroup\$ say that the input is a list of ints, and then you don't need the casts. \$\endgroup\$ – Jasen Dec 25 '16 at 2:24

Retina, 28 bytes


Try it online!



Try it online!


MATL, 9 bytes


The input is an array of numbers representing the digits.

The output is a non-empty array, which is truthy if all its entries are non-zero, and falsy otherwise (read more about MATL's criterion for truthy and falsy here).

Try it online! Or verify all test cases.


d     % Take input implicitly. Consecutive differences
G     % Push input again
2YC   % Overlapping blocks of length 2, arranged as columns of a matrix
s     % Sum of each column
7-    % Subtract 7, element-wise
h     % Concatenate horizontally. Implicitly display
  • \$\begingroup\$ Is it possible/intended to add some new MATLAB functions to MATL? \$\endgroup\$ – rahnema1 Dec 21 '16 at 16:11
  • \$\begingroup\$ @rahnema1 Yes, there are some function names currently unused. However, I tend to be selective and add only those that I think will be used often. If you have any proposals we can discuss them in the MATL chatroom :-) \$\endgroup\$ – Luis Mendo Dec 21 '16 at 17:34
  • \$\begingroup\$ @rahnema1 If you are thinking of movsum, there's already conv2 (which includes conv); see Y+ and Z+ \$\endgroup\$ – Luis Mendo Dec 21 '16 at 17:36

C# (with Linq) 90 81 73 71 69 68 Bytes

using System.Linq;n=>n.Aggregate((p,c)=>p<9|c==p|c==103-p?'\b':c)>9;


using System.Linq;           //Obligatory import
n=>n.Aggregate((p,c)=>       //p serves as both previous character in chain and error flag
    p<9                      //8 is the error flag, if true input is already invalid            
            |c==103-p        //103 comes from 55(7) + 48(0)
                ?'\b'       //'\b' because it has a single digit code (8)
                    :c)      //valid so set previous character, this catches the first digit case as well
                        >8;  //as long as the output char is not a backspace input is valid

C, 81 bytes, was 85 bytes

int F(int *A,int L){int s=1;while(--L)s&=A[L]!=A[L-1]&A[L]!=(7-A[L-1]);return s;}

Input is an array of integers A with length L. Returns 1 for true and 0 for false. The input is checked from the end to the start using the input length L as the array index.

  • \$\begingroup\$ int is optional at the start, you can save 4 bytes. \$\endgroup\$ – Jasen Dec 22 '16 at 10:05
  • \$\begingroup\$ int s=1; can be declared outside the function as s=1; for another 4. \$\endgroup\$ – nmjcman101 Dec 22 '16 at 14:18

Haskell, 37 bytes

f _=1<2

Usage example: f [1,5,2] -> False.

Simple recursion. Base case: single element list, which returns True. Recursive case: let a and b be the first two elements of the input list and c the rest. All of the following conditions must hold: a+b/=7, a/=b and the recursive call with a dropped.


JavaScript, 40 bytes


Takes advantage of the JavaScript feature that && will return the last value that is parsed (either the falsy term or the last term). 0 is passed along if it doesn't meet the conditions, and the previous term is passed along otherwise. The 9 makes sure that it starts with a truthy value.


Groovy, 61 bytes

{i=0;!(true in it.tail().collect{x->x in [7-it[i],it[i++]]})}

Python 2, 58 Bytes

lambda x:all(x[i]!=x[i+1]!=7-x[i]for i in range(len(x)-1))

><>, 39 bytes


Try it online!


Batch, 102 bytes

@set s=%1
@if %r%==0 exit/b
@if %n% gtr 6 %0 %s:~1%
@echo 1


@echo off
rem grab the input string
set s=%1
rem convert the first two digits as octal
set /a n = 0%s:~0,2%
rem check for divisibility by 9 (011...066)
set /a r = n %% 9
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem check for divisibility by 7 (016...061)
set /a r = n %% 7
rem exit with no (falsy) output if no remainder
if %r% == 0 exit/b
rem remove first digit
set s=%s:~1%
rem loop back if there were at least two digits
if %n% gtr 6 goto loop
rem truthy output
echo 1

Your Answer

