Validar volquetes de matrices aleatorias

33

Hace casi seis años, el miembro miembro de PPCG steenslag publicó el siguiente desafío:

En un dado estándar (dado) los números están ordenados de modo que las caras opuestas sumen siete. Escriba el programa más corto posible en su idioma preferido que genere un lanzamiento aleatorio seguido de 9 propinas aleatorias. Una propina es un cuarto de vuelta del dado, por ejemplo, si el dado está orientado hacia 5, todas las posibles propinas son 1,3,4 y 6.

Ejemplo de salida deseada:

1532131356

Entonces, ahora que todos lo han olvidado por completo y la respuesta ganadora ha sido aceptada desde hace mucho tiempo, escribiremos un programa para validar las secuencias de troquelado generadas por las soluciones enviadas. (Esto tiene sentido. Solo finja que sí).

Reto

Su programa o función recibe una secuencia como 1532131356. Valide que cada dígito consecutivo sea:

  • No es igual al dígito anterior
  • No es igual a 7 menos el dígito anterior

(No tiene que validar el primer dígito).

Reglas

  • Su programa debe devolver un valor verdadero si la entrada es válida y un valor falso de lo contrario.
  • Puede suponer que la entrada consta solo de los dígitos 1-6 y tiene al menos 1 carácter de longitud. Las secuencias no tendrán una longitud fija como en el desafío de steenslag.
  • Puede tomar la entrada como una cadena ( "324324"), una matriz o una estructura de datos tipo matriz ( [1,3,5]) o como múltiples argumentos ( yourFunction(1,2,4)).

Se aplican las reglas estándar de E / S y lagunas .

Casos de prueba

Verdad

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

  • Dígito repetido

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Lado opuesto del dado

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    
usuario2428118
fuente

Respuestas:

14

Python 2, 43 45 bytes

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

43 bytes (inspirado en gran medida por @Zgarb)

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

Esta función combina mi declaración de reducción con la lógica de cambio de bits de la respuesta de @ Zgarb, para una combinación que es más corta que ambas.

Ambas respuestas generan lo siguiente:

  • 0 si la entrada no es una secuencia válida
  • El último dígito de la secuencia si es válido.
notjagan
fuente
44
Bienvenido a PPCG, esta es una muy buena primera respuesta.
Wheat Wizard
1
Esto no funciona para aproximadamente la mitad de los casos falsos. Por ejemplo, 3132124225vuelve 5.
Jake Cobb
Puedes arreglarlo usando n and p*(7-p!=n!=p).
Jake Cobb
@JakeCobb Debería funcionar con todos los casos de prueba ahora. Desafortunadamente ahora es 2 bytes más largo :(
notjagan
Qué inteligente uso de reducir, pasando cada valor al siguiente paso.
xnor
9

Python, 44 bytes

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

¡Magia bit a bit! Esta es una función anónima que toma una lista de enteros y verifica que el XOR de cada dos elementos consecutivos esté entre 1 y 6 inclusive.

Por que funciona

Primero, el XOR siempre está entre 0 y 7 inclusive, ya que 7 está 111en la base 2, y nuestros números tienen como máximo 3 dígitos binarios. Por la igualdad, a^b == 0si y solo si a == b. Además, tenemos 7-a == 7^acuándo 0 ≤ a ≤ 7y, por lo tanto, a^b == 7si y solo si a == 7^b == 7-b.

Zgarb
fuente
7

05AB1E , 11 9 bytes

-2 bytes para la idea inteligente de Osable de usar un producto.

¥¹D7-Á+«P

Pruébalo en línea!

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

Tercer enfoque usando 05AB1E, que no usa el comando pairwise:

  • 0 si viola las propiedades achispadas.
  • Not 0 si no había nada que le impidiera estar borracho.
Urna de pulpo mágico
fuente
1
¡@Emigna no creía que importara, pero lo arregló!
Urna de pulpo mágico
1
Quería publicar una respuesta con deltas, pero no lo pensé Á. ¡Agradable!
Osable
1
Puede guardar 2 bytes utilizando la definición de valores de verdad / falsedad con ¥¹D7-Á+«P. Produce 0 cuando hay un 0 en la matriz o cualquier otro valor.
Osable
1
@Osable SMAART! Mega hombre inteligente, buen trabajo.
Urna mágica del pulpo
6

R, 39 37 32 31 bytes

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

Pruébalo en línea!

Toma información de stdin. Utiliza diffpara ver si dos dígitos consecutivos son iguales; luego compara cada dígito con 7 menos el dígito anterior. Devoluciones TRUEo FALSE.

Ahorré 5 bytes gracias a Jarko Dubbeldam, y otro gracias a JayCe.

rturnbull
fuente
Guardar las diferencias en alguna variable qy luego probar en 2*x+q-7lugar de guardar c(0,x)!=c(7-x,0)algunos bytes. Si x1 + x2 = 7entonces 2*x1 + diff(x1,x2) = 7. Comprobación y 2*x+q - 7luego pruebas explícitas !=0.
JAD
@JarkoDubbeldam Gran observación, gracias! He actualizado la solución.
rturnbull
@ JayCe Gracias, he actualizado la respuesta ahora.
rturnbull
5

05AB1E , 10 bytes

$ü+7ʹüÊ*P

Utiliza la codificación CP-1252 . Pruébalo en línea!

Adnan
fuente
1
¡Argh !, ¿por qué no pensé en Ê: P Nice!
Emigna
Hmm, 1*[] = []pero pero product(1, []) = 1. Es bueno saberlo.
Emigna
@Emigna En realidad, eso es un error. El producto de []debería ser 1.
Adnan
Sí, he deseado que funcionara así varias veces antes. El orden de las operaciones también es importante aquí. )1*, )1s*y )1Pson todo []mientras )1sPes 1.
Emigna
1
@Emigna Ahh, eso es porque el producto de []da un error y se descarta. Es por eso que da 1. Intentaré arreglarlo cuando llegue a casa.
Adnan
5

R, 49 44 bytes

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

Lee entradas de stdin (separadas por espacio) y salidas TRUE/FALSE. Dará una advertencia si la entrada es de longitud uno pero aún funciona.

Editar: guardado un par de bytes gracias a @rturnbull

Billywob
fuente
Se pueden combinar all(x)&all(y)en all(x,y)salvar algunos bytes. También puede cambiar rle(x)$l==1a rle(x)$l-1, que luego devolverá un conjunto de todos FALSEsi xes válido; luego cambie el posterior !=a an ==y el alla !any. Esto produce !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x))), ahorrando 5 bytes en total. (PD, he escrito una solución alternativa que te puede interesar)
Rturnbull
4

JavaScript (ES6), 43 40 bytes

Devoluciones 0/ true.

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

Casos de prueba

Arnauld
fuente
Lamentablemente, el puerto simple de la respuesta Retina es de solo 38 bytes.
Neil
@Neil Creo que en realidad es 37 contest()
Arnauld
Lo siento, accidentalmente pegué una nueva línea en el contador de bytes.
Neil
4

Perl 6 , 22 bytes

Usando una expresión regular:

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

Toma la entrada como una cadena. Inspirado por la respuesta de GB Ruby .
Cómo funciona:

  • / /: Una expresión regular.
  • (.): Unir cualquier personaje y capturarlo como $0.
  • <{ }>: Generar dinámicamente una sub-expresión regular para que coincida en esa posición.
  • "$0|" ~ (7 - $0): El sub-regex que generamos es uno que coincide solo con el dígito anterior, o 7 menos el dígito anterior (por ejemplo 5|2).
    Por lo tanto, la expresión regular general coincidirá si encuentra un par de dígitos consecutivos no válidos en cualquier lugar.
  • {! }: Coaccionar a un booleano (haciendo que la expresión regular coincida $_), negarlo y convertir todo en una lambda (con parámetro implícito $_).

Perl 6 , 38 bytes

Usando el procesamiento de la lista:

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

Toma la entrada como una matriz de enteros.
Cómo funciona:

  • .[1..*] Z $_: Comprime la lista de entrada con una versión de sí mismo compensada para generar una lista de 2 tuplas de dígitos consecutivos.
  • [!=] 7 - .[1], |$_: Para cada uno de ellos, verifique si (7 - b) != a != b.
  • all ( ): Devuelve un valor verdadero o falso dependiendo de si todas las iteraciones de bucle devuelven Verdadero.
smls
fuente
4

Python, 38 bytes

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

Una función recursiva que toma argumentos como f(1,2,3) .

Esto utiliza el desempaquetado de argumentos para extraer el primer número hy el resto en la tupla t. Si testá vacío, salida Verdadero. De lo contrario, use el truco de Zgarb para comprobar que las dos primeras tiradas no son incompatibles. Luego, verifique que el resultado también se mantenga en la llamada recursiva en la cola.

xnor
fuente
4

Ruby, 34 bytes

->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
GB
fuente
2
podría reducir dos bytes utilizando el #[]método de cadena en su lugar:->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
Alexis Andersen
No sabía que puedes usarlo con expresiones regulares, gracias.
GB
4

JavaScript 61 43 bytes

Los comentarios han mencionado que no puedo usar las funciones C # linq sin incluir la declaración de uso, así que aquí está exactamente lo mismo en menos bytes usando JS estándar ...

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

C #, 99 67 65 bytes

Toma entrada como una matriz int 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;}

Explicación:

// 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)
}
Erresen
fuente
Creo que esto debe estar envuelto en una función, o tal vez una lambda (¿C # tiene esos?) Además, puede guardar algunos bytes devolviendo 0o en 1lugar de falseotrue
DJMcMayhem
oh, ok, primer post en code golf. Voy a editar ...
Erresen
No hay problema. Por cierto, bienvenido al sitio! :)
DJMcMayhem
@DJMcMayhem Corrígeme si me equivoco, pero dado que el requisito de salida es verdadero / falso, entonces las opciones de salida dependen del idioma tl; dr 1/0 no es verdadero / falso en c #
JustinM - Restablece Mónica
@Phaeze Tienes razón en que no son veraz / falsey, pero las reglas de E / S estándar meta.codegolf.stackexchange.com/questions/2447/… calculan que puedes emitir usando códigos de salida y que las funciones pueden emitirse de la misma manera que programas Si es necesario, volveré a cambiar a booleanos, pero me costará unos cuantos bocados
Erresen
3

> <> (Pescado) 47 bytes

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

Bastante simple;

Línea 1: verifique si ingresó un número, si no hay un número (EOF), entonces tenemos una verdad para imprimir otros cheques.

Línea 2: resultado impreso.

Línea 3: convierta la entrada en número (ASCII 0 - de la entrada), luego verifique si es igual a la entrada anterior.

Línea 4: verifique si la entrada está en el lado opuesto del dado.

Pelícano verde azulado
fuente
3

Brain-Flak 128 Bytes

(()){{}(({}<>)<>[({})])}{}([]){{{}}<>}{}([]){{}({}({})<>)<>([][()])}{}(<{}>)<>(([])){{}{}({}[(()()()){}()]){<>}<>([][()])}({}{})

Salidas 0 para falsey, o -7 para verdadero.

Pruébalo en línea! (Verdad) ¡
Pruébelo en línea! (Flasey)

Explicación (t representa la parte superior y s representa la segunda desde la parte superior):

(())                # 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)
Riley
fuente
3

MATLAB, 30 bytes

@(a)all(diff(a)&movsum(a,2)-7)
rahnema1
fuente
3

PHP, 63 bytes

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

toma entrada como lista de argumentos de comando; sale con 1(error) si la entrada no es válida,0 (ok) si es válida.

Corre con -nr.

entrada como argumento de cadena, 65 bytes

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

PowerShell , 57 44 41 bytes

( Tachado 44 sigue siendo regular 44 )

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

Pruébalo en línea!

(OP ha aclarado que tomar entradas como argumentos separados está bien: guardó 13 bytes ... guardó otros 3 bytes eliminando $b)

Estamos recorriendo la entrada $argsun dígito a la vez. Cada dígito, que verifique que el $ldígito ast es -not equal al dígito actual $_, y que 7-$_-$les un número distinto de cero (que es Truthy). Esos resultados booleanos se encapsulan en parens y se introducen en el operando de la derecha del -notinoperador, comprobando en contra 0. En otras palabras, si hay algunaFalse valor en parte del bucle, el-notin también lo será False. Ese booleano se deja en la tubería, y la salida es implícita.

Largo debido al $requisito de nombres de variables, y que los comandos booleanos -ne -andson detallados en PowerShell. Oh bien.

AdmBorkBork
fuente
3

Procesamiento, 93 92 90 bytes

Cambiado || a | : 1 byte guardado gracias a @ClaytonRamsey

Comenzó a contar hacia atrás: 2 bytes guardados gracias a @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;}

Toma la entrada como una matriz de entradas, salida 1para verdadero o 0falso.

Sin golf

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;
}
Kritixi Lithos
fuente
Por lo general, Java permite | en lugar de || si quieres guardar un byte.
Clayton Ramsey
@ClaytonRamsey No sé por qué no lo pensé, ¡gracias!
Kritixi Lithos
Encontré otro. Podría reducir el uso de devoluciones con el operador terciario
Clayton Ramsey
@ClaytonRamsey The return 0está dentro de la instrucción if mientras return 1que no lo está. No veo cómo eso es posible a menos que tengas alguna otra idea
Kritixi Lithos
2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<- Lo leí, mientras comparaba lo que tienes con lo que tenías.
Ismael Miguel
3

do 47 44 bytes

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

toma una cadena de dígitos (o una matriz de bytes terminada en cero)

Explicación

F(char*s){

de acuerdo con el inttipo de devolución estándar está implícito. (ahorro de 4 bytes)

return retorno incondicional porque esta es una función recursiva

utilizando la evaluación de acceso directo:

!s[1]||si el segundo caracter es nul devuelve verdadero

((*s^s[1])%7&& si los dos primeros personajes no son legales falsos

F(s+1)) verifique el resto de la cadena de la misma manera

esa expresión confusa

*ses el primer personaje s[1]es el segundo

*s^s[1] excluirlos juntos si son iguales, el resultado es 0 si suman 7, el resultado es 7 (si difieren y no suman 7, el resultado es entre 1 y 6 inclusive)

por (*s^s[1])%7lo tanto, es cero para una entrada incorrecta y, de lo contrario, no es cero, por lo tanto, es falso si estos 2 caracteres son incorrectos, y verdadero de lo contrario

comentario: como esta llamada a la función usa solo la recursión final (solo la última declaración es una llamada recursiva) un optimizador podría traducir la recursión en un bucle, esta es una feliz concordancia y obviamente no vale ningún puntaje de golf, pero en la palabra real permite procesar cadenas de cualquier longitud sin quedarse sin pila.

Jasen
fuente
1
Sobre tu !((*s^s[1])%7)creo que no quieres el !. Los valores cero para una entrada incorrecta serían falsos, por lo que desea devolverlos cuando sean incorrectos.
nmjcman101
2

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

Utiliza un enfoque recursivo.

Explicación:

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
Loovjo
fuente
digamos que la entrada es una lista de entradas, y luego no necesita los lanzamientos.
Jasen
2

MATL , 9 bytes

dG2YCs7-h

La entrada es una matriz de números que representan los dígitos.

La salida es una matriz no vacía, que es verdadera si todas sus entradas son distintas de cero, y falsa de lo contrario (lea más sobre el criterio de MATL para la verdad y la falsedad aquí ).

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

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
Luis Mendo
fuente
¿Es posible / pretendido agregar algunas nuevas funciones de MATLAB a MATL?
rahnema1
@ rahnema1 Sí, hay algunos nombres de funciones actualmente no utilizados. Sin embargo, tiendo a ser selectivo y agrego solo aquellos que creo que se usarán con frecuencia. Si tiene alguna propuesta, podemos discutirla en la sala de chat de MATL :-)
Luis Mendo
@ rahnema1 Si estás pensando movsum, ya hay conv2(que incluye conv); ver Y+yZ+
Luis Mendo
2

C # (con 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;

Explicación:

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
JustinM - Restablece a Monica
fuente
2

C, 81 bytes, era 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;}

La entrada es una matriz de enteros A con longitud L. Devuelve 1 para verdadero y 0 para falso. La entrada se verifica desde el final hasta el inicio utilizando la longitud de entrada L como índice de matriz.

usuario230118
fuente
int es opcional al inicio, puede guardar 4 bytes.
Jasen
int s=1;se puede declarar fuera de la función como s=1;para otros 4.
nmjcman101
2

Haskell, 37 bytes

f(a:b:c)=a+b/=7&&a/=b&&f(b:c)
f _=1<2

Ejemplo de uso: f [1,5,2] -> False.

Recurrencia simple Caso base: lista de un solo elemento, que devuelve True. Caso recursivo: dejar ay bser los dos primeros elementos de la lista de entrada y cel resto. Todas las siguientes condiciones deben contener: a+b/=7, a/=by la llamada recursiva con un acaído.

nimi
fuente
2

JavaScript, 40 bytes

f=i=>i.reduce((a,b)=>a&&a-b&&a+b-7&&b,9)

Aprovecha la función de JavaScript que &&devolverá el último valor analizado (ya sea el término falso o el último término). 0se pasa si no cumple con las condiciones, y el término anterior se pasa de lo contrario. El 9 se asegura de que comience con un valor verdadero.

JackW
fuente
1

Groovy, 61 bytes

{i=0;!(true in it.tail().collect{x->x in [7-it[i],it[i++]]})}
Urna de pulpo mágico
fuente
1

Python 2, 58 bytes

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

Lote, 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

Sin golf:

@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
Neil
fuente