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:

1532131356

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

Challenge

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

Rules

  • 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

Truthy

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

  • Repeated digit

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Opposing side of die

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    
share|improve this question

36 Answers 36

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
share|improve this answer
4  
Welcome to PPCG, This is a really nice first answer. – Wheat Wizard Dec 21 at 14:53
1  
This doesn't work for about half of the false cases. E.g. 3132124225 returns 5. – Jake Cobb Dec 21 at 15:37
    
You can fix it using n and p*(7-p!=n!=p). – Jake Cobb Dec 21 at 15:45
    
@JakeCobb It should work with all the test cases now. Unfortunately it's now 2 bytes longer :( – notjagan 2 days ago
    
What a clever use of reduce, passing each value to the next step. – xnor 2 days ago

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.

share|improve this answer

05AB1E, 11 9 bytes

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

¥¹D7-Á+«P

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.
share|improve this answer
1  
@Emigna didn't think it mattered but fixed! – carusocomputing Dec 21 at 16:40
1  
I wanted to post an answer with deltas, but I did not think about Á. Nice! – Osable 2 days ago
1  
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. – Osable 2 days ago
1  
@Osable SMAART! Mega smart man, good job. – carusocomputing 2 days ago

05AB1E, 10 bytes

$ü+7ʹüÊ*P

Uses the CP-1252 encoding. Try it online!

share|improve this answer
1  
Argh!, why didn't I think of Ê :P Nice! – Emigna Dec 21 at 14:35
    
Hmm, so 1*[] = [] but product(1, []) = 1. That's good to know. – Emigna Dec 21 at 14:38
    
@Emigna Actually, that is a bug. The product of [] should be 1. – Adnan Dec 21 at 14:42
    
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. – Emigna Dec 21 at 14:47
1  
@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. – Adnan Dec 21 at 14:50

R, 39 37 32 bytes

q=diff(x<-scan())
all(q,2*x+q-7)

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.

share|improve this answer
    
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. – Jarko Dubbeldam 2 days ago
    
@JarkoDubbeldam Great observation, thanks! I've updated the solution. – rturnbull 2 days ago

05AB1E, 15 bytes

ü+7å¹ü-0å¹g_~~_

Try it online! or as a Test suite

share|improve this answer

JavaScript (ES6), 43 40 bytes

Returns 0 / true.

f=([k,...a],n=0)=>!k||k-n&&7-k-n&&f(a,k)

Test cases

f=([k,...a],n=0)=>!k||k-n&&7-k-n&&f(a,k)

console.log('Testing truthy cases ...');
console.log(f('1353531414'));
console.log(f('3132124215'));
console.log(f('4142124136'));
console.log(f('46'));
console.log(f('4264626313135414154'));
console.log(f('6'));
console.log(f('2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323'));
console.log(f('5414142'));

console.log('Testing falsy cases ...');
console.log(f('11'));
console.log(f('3132124225'));
console.log(f('6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245'));
console.log(f('553141454631'));
console.log(f('14265411'));
console.log(f('16'));
console.log(f('42123523545426464236231321'));
console.log(f('61362462636351'));
console.log(f('62362462636361'));

share|improve this answer
    
Sadly the simple port of the Retina answer is only 38 bytes. – Neil 2 days ago
    
@Neil I think it's actually 37 with test() – Arnauld 2 days ago
    
Sorry, I accidentally pasted a newline into the byte counter. – Neil 2 days ago

Perl 6, 22 bytes

Using a regex:

{!/(.)<{"$0|"~7-$0}>/}

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.
share|improve this answer

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

f=a=>a.reduce((i,j)=>i>6|i==j|i+j==7?9:j)<7

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

Explanation:

// 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)
}
share|improve this answer
    
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 – DJMcMayhem 2 days ago
    
oh, ok - first post on code golf. I'll edit... – Erresen 2 days ago
    
No problem. BTW, welcome to the site! :) – DJMcMayhem 2 days ago
    
@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# – Phaeze 2 days ago
    
@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 – Erresen 2 days ago

R, 49 44 bytes

!any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))

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

share|improve this answer
    
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.) – rturnbull 2 days ago

Ruby, 34 bytes

->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
share|improve this answer
1  
you could shave off two bytes by using the string #[] method instead: ->s{!s[/[16]{2}|[25]{2}|[34]{2}/]} – Alexis Andersen yesterday
    
I didn't know you can use it with regex, thanks. – G B yesterday

><> (Fish) 47 bytes

0:i:1+?!v\!
   0n;n1< >
!?-{:-"0"/^
!? -{-$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.

share|improve this answer

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)
share|improve this answer

MATLAB, 30 bytes

@(a)all(diff(a)&movsum(a,2)-7)
share|improve this answer

PowerShell, 57 44 41 bytes

(Crossed out 44 is still regular 44)

0-notin($args|%{7-$_-$l-and$l-ne($l=$_)})

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.

share|improve this answer

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.

share|improve this answer

C 47 bytes

F(char*s){return!s[1]||!((*s^s[1])%7)&&F(s+1);}

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

Explanation

F(char*s){

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 ,

so (*s^s[1])%7 is zero for bad input and non-zero otherwise

thus !((*s^s[1])%7) is false if these 2 characters are bad

share|improve this answer
    
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. – nmjcman101 2 days ago

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.

Ungolfed

int Q104044(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;
}
share|improve this answer
    
Usually Java allows | instead of || if you want to save a byte. – Clayton Ramsey Dec 21 at 16:59
    
@ClaytonRamsey I don't know why I didn't think of it, thanks! – Kritixi Lithos Dec 21 at 17:01
    
I found another one. You could cut down on the use of returns with the tertiary operator – Clayton Ramsey 2 days ago
    
@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 – Kritixi Lithos 2 days ago
1  
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. – Ismael Miguel 2 days ago

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.

Explanation:

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
share|improve this answer

Retina, 28 bytes

M`(.)\1|16|25|34|43|52|61
^0

Try it online!

Alternatively:

M`[16]{2}|[25]{2}|[34]{2}
^0

Try it online!

share|improve this answer

MATL, 9 bytes

dG2YCs7-h

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.

Explanation

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
share|improve this answer
    
Is it possible/intended to add some new MATLAB functions to MATL? – rahnema1 Dec 21 at 16:11
    
@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 :-) – Luis Mendo 2 days ago
    
@rahnema1 If you are thinking of movsum, there's already conv2 (which includes conv); see Y+ and Z+ – Luis Mendo 2 days ago

PHP, 63 bytes

for($d=$argv[$i=1];$c=$argv[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);

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

for($d=($s=$argv[1])[0];$c=$s[++$i];$d=$c)$d-$c&&$d+$c-7?:die(1);
share|improve this answer

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;

Explanation:

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==p            
            |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
share|improve this answer

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.

share|improve this answer
    
int is optional at the start, you can save 4 bytes. – Jasen 2 days ago
    
int s=1; can be declared outside the function as s=1; for another 4. – nmjcman101 2 days ago

Groovy, 61 bytes

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

Python 2, 58 Bytes

lambda x:all(x[i]!=x[i+1]!=7-x[i]for i in range(len(x)-1))
share|improve this answer

><>, 39 bytes

0>i'0'-::&0)?v1n;>&!
?=0+=7+@=}:{:<;n0^

Try it online!

share|improve this answer

Batch, 102 bytes

@set s=%1
@set/an=0%s:~0,2%,r=n%%9*(n%%7)
@if %r%==0 exit/b
@if %n% gtr 6 %0 %s:~1%
@echo 1

Ungolfed:

@echo off
rem grab the input string
set s=%1
:loop
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
share|improve this answer

Clojure, 55 49 46 bytes

edit 1: using (mapcat ...) instead of (flatten(map ...))

edit 2: using (juxt - +) instead of (juxt = +), checking for values 0 or 7

#(not(some #{0 7}(mapcat(juxt - +)(rest %)%)))

Consecutive values are not allowed to be equal (difference = 0) or sum up to 7. Got to use juxt again :)

share|improve this answer

JavaScript (ES6), 46 Bytes

a=>r=1&&a.reduce((c,p)=>r=c==p||c==7-p?0:1)&&r

f=a=>r=1&&a.reduce((c,p)=>r=c==p||c==7-p?0:1)&&r;

console.log(f([4,6]));
console.log(f([1,6]));

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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