Validar tombadores aleatórios


33

Há quase seis anos, steenslag, membro do PPCG, lançou o seguinte desafio:

Em um dado padrão (dado), os números são organizados de modo que faces opostas aumentem para sete. Escreva o programa mais curto possível no seu idioma preferido, que produz um lance aleatório seguido por 9 dicas aleatórias. Uma gorjeta é um quarto de volta dos dados, por exemplo, se os dados estão voltados para 5, todas as gorjetas possíveis são 1,3,4 e 6.

Exemplo de saída desejada:

1532131356

Portanto, agora que todo mundo se esqueceu completamente e a resposta vencedora já foi aceita há muito tempo, escreveremos um programa para validar as seqüências de derrubada de matriz geradas pelas soluções enviadas. (Isso faz sentido. Apenas finja que sim.)

Desafio

Seu programa ou função recebe uma sequência como 1532131356. Valide que cada dígito consecutivo é:

  • Diferente do dígito anterior
  • Diferente de 7 menos o dígito anterior

(Você não precisa validar o primeiro dígito.)

Regras

  • Seu programa deve retornar um valor verdadeiro se a entrada for válida e um valor falsey caso contrário.
  • Você pode assumir que a entrada consiste apenas nos dígitos 1 a 6 e tem pelo menos 1 caractere. As seqüências não terão um comprimento fixo, como no desafio de steenslag.
  • Você pode considerar a entrada como uma string ( "324324"), uma matriz ou uma estrutura de dados semelhante a uma matriz ( [1,3,5]) ou como vários argumentos ( yourFunction(1,2,4)).

Aplicam-se regras de E / S padrão e brecha .

Casos de teste

Truthy

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

  • Dígito repetido

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Lado oposto do dado

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    

Respostas:


14

Python 2, 43 45 bytes

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

43 bytes (inspirado fortemente em @Zgarb)

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

Essa função combina minha declaração de redução com a lógica de oscilação de bits da resposta do @ Zgarb, para uma combinação mais curta que ambas.

Ambas as respostas produzem o seguinte:

  • 0 se a entrada não for uma sequência válida
  • O último dígito da sequência, se for válido

4
Bem-vindo ao PPCG, esta é uma ótima primeira resposta.
Assistente de trigo

1
Isso não funciona para cerca da metade dos casos falsos. Por exemplo, 3132124225retornos 5.
Jake Cobb

Você pode corrigi-lo usando n and p*(7-p!=n!=p).
Jake Cobb

@JakeCobb Ele deve funcionar com todos os casos de teste agora. Infelizmente agora é 2 bytes mais longo :(
notjagan

Que uso inteligente de reduzir, passando cada valor para a próxima etapa.
Xnor

9

Python, 44 bytes

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

Magia bit a bit! Essa é uma função anônima que pega uma lista de números inteiros e verifica se o XOR de cada dois elementos consecutivos está entre 1 e 6, inclusive.

Por que funciona

Primeiro, o XOR está sempre entre 0 e 7, inclusive, já que 7 está 111na base 2 e nossos números têm no máximo 3 dígitos binários. Pela igualdade, a^b == 0se e somente se a == b. Além disso, temos 7-a == 7^aquando 0 ≤ a ≤ 7e, portanto, a^b == 7se e somente se a == 7^b == 7-b.


7

05AB1E , 11 9 bytes

-2 bytes para a idéia inteligente de Osable de usar um produto.

¥¹D7-Á+«P

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

Terceira abordagem usando 05AB1E, que não usa o comando pairwise:

  • 0 se violar as propriedades embriagadas.
  • Not 0 se não houvesse nada impedindo que fosse embriagado.

1
@Emigna não achou que isso importava, mas foi corrigido!
Magic Octopus Urn

1
Eu queria postar uma resposta com deltas, mas não pensei nisso Á. Agradável!
Osable

1
Você pode salvar 2 bytes usando a definição de valores de verdade / falsidade com ¥¹D7-Á+«P. Ele gera 0 quando há um 0 na matriz ou qualquer outro valor caso contrário.
Osable

1
@Osable SMAART! Mega homem esperto, bom trabalho.
Magic Octopus Urn

6

R, 39 37 32 31 bytes

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

Experimente online!

Recebe entrada de stdin. Usa diffpara verificar se dois dígitos consecutivos são iguais; então compara cada dígito a 7 menos o dígito anterior. Retorna TRUEou FALSE.

Economizou 5 bytes graças a Jarko Dubbeldam e outro graças a JayCe.


Salvar as diferenças em alguma variável qe depois testar em 2*x+q-7vez de c(0,x)!=c(7-x,0)salvar alguns bytes. Se x1 + x2 = 7então 2*x1 + diff(x1,x2) = 7. A verificação 2*x+q - 7então testa explicitamente !=0.
JD

@JarkoDubbeldam Ótima observação, obrigado! Eu atualizei a solução.
rturnbull


@ JayCe Obrigado, atualizei a resposta agora.
Rdb #

5

05AB1E , 10 bytes

$ü+7ʹüÊ*P

Usa a codificação CP-1252 . Experimente online!


1
Argh !, por que eu não pensei em Ê: P Legal!
Emigna

Hmm, 1*[] = []mas sim product(1, []) = 1. É bom saber disso.
Emigna

@ Emigna Na verdade, isso é um bug. O produto de []deve ser 1. #
Adnan

Sim, eu desejei que funcionasse assim várias vezes antes. A ordem das operações também é importante aqui. )1*, )1s*e )1Psão []enquanto )1sPé 1.
Emigna

1
@ Emigna Ahh, isso ocorre porque o produto da []dá um erro e é descartado. É por isso que dá 1. Vou tentar consertar quando chegar em casa.
`

5

R, 49 44 bytes

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

Lê entrada de stdin (separado por espaço) e saídas TRUE/FALSE. Emite um aviso se a entrada for do tamanho um, mas ainda funcionar.

Edit: salvou alguns bytes graças a @rturnbull


Você pode combinar all(x)&all(y)para all(x,y)salvar alguns bytes. Você também pode mudar rle(x)$l==1para rle(x)$l-1, que retornará um conjunto de todos FALSEse xfor válido; depois mude !=para mais tarde para ==e allpara !any. Isso gera !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x))), economizando 5 bytes no total. (PS, Eu escrevi uma solução alternativa você pode estar interessado em.)
rturnbull


4

JavaScript (ES6), 43 40 bytes

Retorna 0/ true.

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

Casos de teste


Infelizmente, a porta simples da resposta da Retina é de apenas 38 bytes.
21416 Neil

@Neil Eu acho que é realmente 37 comtest()
Arnauld

Desculpe, colei acidentalmente uma nova linha no contador de bytes.
21416 Neil

4

Perl 6 , 22 bytes

Usando uma regex:

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

Toma a entrada como uma sequência. Inspirado pela resposta Ruby da GB .
Como funciona:

  • / /: Um regex.
  • (.): Corresponde a qualquer caractere e capture-o como $0.
  • <{ }>: Gere dinamicamente um sub-regex a ser correspondido nessa posição.
  • "$0|" ~ (7 - $0): O sub-regex que geramos é aquele que corresponde apenas ao dígito anterior ou 7 menos o dígito anterior (por exemplo 5|2).
    Assim, a regex geral corresponderá se encontrar um par consecutivo inválido de dígitos em qualquer lugar.
  • {! }: Coerce com um booleano (fazendo com que o regex seja comparado $_), negue-o e transforme tudo em um lambda (com parâmetro implícito $_).

Perl 6 , 38 bytes

Usando o processamento de lista:

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

Toma a entrada como uma matriz de números inteiros.
Como funciona:

  • .[1..*] Z $_: Zip a lista de entrada com uma versão offset a uma, para gerar uma lista de 2 tuplas de dígitos consecutivos.
  • [!=] 7 - .[1], |$_: Para cada um deles, verifique se (7 - b) != a != b.
  • all ( ): Retorne um valor verdadeiro ou falso dependendo se todas as iterações de loop retornaram True.

4

Python, 38 bytes

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

Uma função recursiva que aceita argumentos como f(1,2,3).

Isso utiliza o argumento de descompactação para extrair o primeiro número he o restante na tupla t. Se testiver vazio, produza True. Caso contrário, use o truque de bit do Zgarb para verificar se os dois primeiros testes de dados são incompatíveis. Em seguida, verifique se o resultado também se aplica à chamada recursiva na cauda.


4

Ruby, 34 bytes

->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}

2
você pode cortar dois bytes usando o #[]método string :->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
Alexis Andersen

Eu não sabia que você pode usá-lo com regex, obrigado.
GB

4

JavaScript 61 43 bytes

Os comentários mencionaram que eu não posso usar funções C # linq sem incluir a instrução using, então aqui está exatamente o mesmo em menos bytes usando o JS padrão ...

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

C #, 99 67 65 bytes

Recebe entrada como uma 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;}

Explicação:

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

Eu acho que isso precisa ser envolvido em uma função, ou talvez um lambda (o C # possui esses?) Além disso, você pode salvar alguns bytes retornando 0ou em 1vez de falseoutrue
DJMcMayhem

ah, ok - primeiro post sobre código de golfe. Vou editar ...
Erresen

Sem problemas. BTW, bem-vindo ao site! :)
DJMcMayhem

@DJMcMayhem Me corrija se eu estiver errado, mas como o requisito de saída é verdade / falsey, as opções de saída dependem do idioma tl; dr 1/0 não é verdade / falsey em c #
JustinM - Reinstate Monica

@Phaeze Você está certo de que eles não são verdadeiros / falsos, mas as regras de IO padrão meta.codegolf.stackexchange.com/questions/2447/… consideram que você pode emitir usando códigos de saída e que as funções podem gerar da mesma maneira que programas. Vou voltar para booleanos, se necessário, mas isso me custará algumas mordidas
Erresen

3

> <> (Peixe) 47 bytes

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

Bem simples;

Linha 1: verifique se foi inserido um número, se nenhum número (EOF), então temos uma verdade para imprimir outros cheques.

Linha 2: resultado da impressão.

Linha 3: transforme a entrada em número (ASCII 0 - da entrada) e verifique se é igual à entrada anterior.

Linha 4: verifique se a entrada está do lado oposto da matriz.


3

Brain-Flak 128 Bytes

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

Saídas 0 para falsey ou -7 para verdade.

Experimente Online! (Verdade)
Experimente Online! (Flasey)

Explicação (t representa o topo e s representa o segundo do topo):

(())                # 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)


3

PHP, 63 bytes

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

recebe entrada como lista de argumentos de comando; sai com 1(erro) se a entrada for inválida, 0(ok) se válida.

Corra com -nr.

entrada como argumento de cadeia, 65 bytes

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

3

PowerShell , 57 44 41 bytes

( Riscado 44 ainda é regular 44 )

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

Experimente online!

(O OP esclareceu que aceitar entradas como argumentos separados é bom - salvou 13 bytes ... salvou outros 3 bytes ao eliminar $b)

Estamos percorrendo a entrada $argsum dígito de cada vez. Cada dígito, verificamos que o $ldígito ast é -not equalificado para o dígito atual $_, e esse 7-$_-$lé um número diferente de zero (o que é verdade). Esses resultados booleanos são encapsulados em parênteses e alimentados no operando do lado direito do -notinoperador, comparando 0. Em outras palavras, se houver algum Falsevalor em qualquer lugar do loop, -notintambém será False. Esse booleano é deixado no pipeline e a saída é implícita.

Longo devido ao $requisito para nomes de variáveis ​​e que os comandos booleanos -ne -andsão detalhados no PowerShell. Ah bem.


3

Processando, 93 92 90 bytes

Alterado || para | : 1 byte salvo graças a @ClaytonRamsey

Começou a contagem regressiva: 2 bytes salvos graças 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;}

Recebe entrada como uma matriz de entradas, saída 1para verdadeiro ou 0falso.

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

Geralmente Java permite | em vez de || se você deseja salvar um byte.
Clayton Ramsey

@ClaytonRamsey Não sei por que não pensei nisso, obrigado!
Kritixi Lithos

Eu encontrei outro. Você pode reduzir o uso de retornos com o operador terciário
Clayton Ramsey

@ClaytonRamsey O return 0está dentro da instrução if enquanto return 1não estiver. Não vejo como isso é possível, a menos que você tenha outra idéia
Kritixi Lithos

2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<- Eu li, enquanto comparava o que você tem com o que você tinha.
Ismael Miguel

3

C 47 44 bytes

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

usa uma sequência de dígitos (ou uma matriz de bytes terminada em zero)

Explicação

F(char*s){

de acordo com o inttipo de retorno padrão está implícito. (economizando 4 bytes)

return retorno incondicional, porque esta é uma função recursiva

usando avaliação de atalho:

!s[1]||se o segundo caractere for nul, retorne true

((*s^s[1])%7&& se os dois primeiros caracteres não são falsos legais

F(s+1)) verifique o restante da string da mesma maneira

essa expressão confusa

*sé o primeiro caractere s[1]é o segundo

*s^s[1] exclua-os juntos se forem iguais e o resultado for 0 se adicionarem a 7 o resultado for 7 (se forem diferentes e não adicionarem a 7 o resultado será entre 1 e 6, inclusive)

então (*s^s[1])%7é zero para entrada incorreta e diferente de zero, caso contrário, falso se esses 2 caracteres forem incorretos e verdadeiro caso contrário

comentário: como essa chamada de função usa apenas recursão final (apenas a última instrução é uma chamada recursiva), um otimizador pode converter a recursão em um loop, essa é uma conicidência feliz e obviamente não vale nenhuma pontuação de golfe, mas na palavra real torna possível processar seqüências de caracteres de qualquer tamanho sem ficar sem pilha.


1
Sobre o seu !((*s^s[1])%7)eu acho que você não quer o !. Valores zero para entrada incorreta seriam falsos, portanto, você deseja retornar a falsidade quando estiver incorreta.
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:])

Usa uma abordagem recursiva.

Explicação:

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

diga que a entrada é uma lista de entradas e, em seguida, você não precisa das transmissões.
Jasen


2

MATL , 9 bytes

dG2YCs7-h

A entrada é uma matriz de números representando os dígitos.

A saída é uma matriz não vazia, que é verdadeira se todas as suas entradas são diferentes de zero e, caso contrário, falsifica (leia mais sobre o critério do MATL para verdade e falsidade aqui ).

Experimente online! Ou verifique todos os casos de teste .

Explicação

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

É possível / pretendido adicionar algumas novas funções do MATLAB ao MATL?
usar o seguinte comando

@ rahnema1 Sim, existem alguns nomes de funções atualmente não utilizados. No entanto, costumo ser seletivo e adicionar apenas aqueles que acho que serão usados ​​com frequência. Se você tiver quaisquer propostas, podemos discuti-los na sala de chat MATL :-)
Luis Mendo

@ rahnema1 Se você está pensando movsum, já existe conv2(o que inclui conv); veja Y+eZ+
Luis Mendo

2

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

Explicação:

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

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

A entrada é uma matriz de números inteiros A com comprimento L. Retorna 1 para verdadeiro e 0 para falso. A entrada é verificada do fim ao início, usando o comprimento de entrada L como o índice da matriz.


int é opcional no início, você pode salvar 4 bytes.
Jasen

int s=1;pode ser declarado fora da função como s=1;para outro 4.
nmjcman101

2

Haskell, 37 bytes

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

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

Recursão simples. Caso base: lista de elemento único, que retorna True. Caso recursivo: deixe ae bseja o primeiro dos dois elementos da lista de entrada e co restante. Todas as seguintes condições devem conter: a+b/=7, a/=be a chamada recursiva com adescartado.


2

JavaScript, 40 bytes

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

Aproveita o recurso JavaScript que &&retornará o último valor analisado (o termo falso ou o último termo). 0é repassado se não atender às condições, e o termo anterior é repassado de outra forma. O 9 garante que ele comece com um valor verdadeiro.



1

Python 2, 58 bytes

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


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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.