Convalida i ribaltatori di dadi casuali


33

Quasi sei anni fa, Steenslag, membro del PPCG, ha pubblicato la seguente sfida:

In un dado standard (dado) i numeri sono disposti in modo tale che le facce opposte si sommino a sette. Scrivi il programma più breve possibile nella tua lingua preferita che genera un lancio casuale seguito da 9 suggerimenti casuali. Una mancia è un quarto di giro del dado, ad esempio se il dado è rivolto verso 5, tutti i possibili ribaltamenti sono 1,3,4 e 6.

Esempio di output desiderato:

1532131356

Quindi, ora che tutti se ne sono completamente dimenticati e la risposta vincente è stata accettata da tempo, scriveremo un programma per convalidare le sequenze di ribaltamento generate dalle soluzioni presentate. (Questo ha senso. Fingi di sì.)

Sfida

Al programma o alla funzione viene assegnata una sequenza come 1532131356. Convalida che ogni cifra consecutiva è:

  • Non uguale alla cifra precedente
  • Non uguale a 7 meno la cifra precedente

(Non è necessario convalidare la prima cifra.)

Regole

  • Il programma deve restituire un valore di verità se l'input è valido e un valore di falsa in caso contrario.
  • Si può presumere che l'input sia composto solo dalle cifre 1-6 e sia lungo almeno 1 carattere. Le sequenze non avranno una lunghezza fissa come nella sfida di steenslag.
  • Puoi prendere l'input come stringa ( "324324"), una matrice o una struttura di dati simile a matrice ( [1,3,5]) o come argomenti multipli ( yourFunction(1,2,4)).

Si applicano le regole I / O standard e scappatoia .

Casi test

Truthy

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

  • Cifra ripetuta

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Lato opposto del dado

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    

Risposte:


14

Python 2, 43 45 byte

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

43 byte (fortemente ispirato a @Zgarb)

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

Questa funzione combina la mia dichiarazione di riduzione con la logica del bit-flicking dalla risposta di @ Zgarb, per una combinazione più breve di entrambe.

Entrambe le risposte generano quanto segue:

  • 0 se l'ingresso non è una sequenza valida
  • L'ultima cifra della sequenza se è valida

4
Benvenuti in PPCG, questa è davvero una bella prima risposta.
Mago del grano,

1
Questo non funziona per circa la metà dei casi falsi. Ad esempio, 3132124225ritorna 5.
Jake Cobb,

Puoi ripararlo usando n and p*(7-p!=n!=p).
Jake Cobb,

@JakeCobb Ora dovrebbe funzionare con tutti i casi di test. Purtroppo ora è più lungo di 2 byte :(
notjagan il

Che uso intelligente di ridurre, passando ogni valore al passaggio successivo.
xnor

9

Python, 44 byte

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

Magia bit a bit! Questa è una funzione anonima che accetta un elenco di numeri interi e verifica che l'XOR di ogni due elementi consecutivi sia compreso tra 1 e 6 inclusi.

Perché funziona

Innanzitutto, XOR è sempre compreso tra 0 e 7, poiché 7 è 111nella base 2 e i nostri numeri hanno al massimo 3 cifre binarie. Per l'uguaglianza, a^b == 0se e solo se a == b. Inoltre, abbiamo 7-a == 7^aquando 0 ≤ a ≤ 7, e quindi a^b == 7se e solo se a == 7^b == 7-b.


7

05AB1E , 11 9 byte

-2 byte per l'idea intelligente di Osable di utilizzare un prodotto.

¥¹D7-Á+«P

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

Terzo approccio usando 05AB1E, che non usa il comando pairwise:

  • 0 se viola le proprietà alticcio.
  • Not 0 se non c'era nulla che gli impedisse di essere alticcio.

1
@Emigna non pensava che importasse ma riparato!
Magic Octopus Urn il

1
Volevo pubblicare una risposta con delta, ma non ci ho pensato Á. Bello!
Osable,

1
È possibile salvare 2 byte usando la definizione di valori di verità / falsa con ¥¹D7-Á+«P. Produce 0 quando c'è uno 0 nell'array o qualsiasi altro valore in altro modo.
Osable,

1
@Osable SMAART! Mega uomo intelligente, buon lavoro.
Magic Octopus Urn il

6

R, 39 37 32 31 byte

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

Provalo online!

Riceve input dallo stdin. Usa diffper vedere se due cifre consecutive sono uguali; quindi confronta ogni cifra a 7 meno la cifra precedente. Restituisce TRUEo FALSE.

Risparmiato 5 byte grazie a Jarko Dubbeldam e un altro grazie a JayCe.


Salvare le differenze in alcune variabili qe quindi testare 2*x+q-7invece di c(0,x)!=c(7-x,0)risparmiare qualche byte. Se x1 + x2 = 7allora 2*x1 + diff(x1,x2) = 7. Il controllo 2*x+q - 7quindi verifica esplicitamente !=0.
JAD,

@JarkoDubbeldam Ottima osservazione, grazie! Ho aggiornato la soluzione.
rturnbull,


@JayCe Grazie, ho aggiornato la risposta ora.
rturnbull,

5

05AB1E , 10 byte

$ü+7ʹüÊ*P

Utilizza la codifica CP-1252 . Provalo online!


1
Argh !, perché non ho pensato a Ê: P Nice!
Emigna,

Hmm, quindi 1*[] = []ma product(1, []) = 1. Buono a sapersi.
Emigna,

@Emigna In realtà, questo è un bug. Il prodotto di []dovrebbe essere 1.
Adnan,

Sì, ho desiderato che funzionasse così diverse volte prima. Anche l'ordine delle operazioni è importante qui. )1*, )1s*e )1Psono tutti []mentre )1sPè 1.
Emigna,

1
@Emigna Ahh, è perché il prodotto di []dà un errore e viene scartato. Ecco perché dà 1. Proverò a ripararlo quando torno a casa.
Adnan,

5

R, 49 44 byte

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

Legge l'input dallo stdin (separato dallo spazio) e gli output TRUE/FALSE. Fornirà un avviso se l'ingresso è di lunghezza uno ma funziona ancora.

Modifica: salvato un paio di byte grazie a @rturnbull


È possibile combinare all(x)&all(y)in all(x,y)per salvare alcuni byte. Puoi anche passare rle(x)$l==1a rle(x)$l-1, che restituirà quindi un set di tutti FALSEse xè valido; quindi passa !=a un successivo ==e alla !any. Questo produce !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x))), risparmiando 5 byte in totale. (PS, ho scritto una soluzione alternativa che potrebbe interessarti.)
rturnbull


4

JavaScript (ES6), 43 40 byte

Restituisce 0/ true.

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

Casi test


Purtroppo la semplice porta della risposta Retina è di soli 38 byte.
Neil,

@Neil Penso che in realtà sia 37 contest()
Arnauld il

Spiacente, ho accidentalmente incollato una nuova riga nel contatore byte.
Neil,

4

Perl 6 , 22 byte

Usando un regex:

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

Prende l'input come stringa. Ispirato dalla risposta di Ruby di GB .
Come funziona:

  • / /: Una regex.
  • (.): Abbina qualsiasi personaggio e catturalo come $0.
  • <{ }>: Genera dinamicamente un sotto-regex da abbinare in quella posizione.
  • "$0|" ~ (7 - $0): Il sotto-regex che generiamo è uno che corrisponde solo alla cifra precedente, o 7 meno la cifra precedente (ad es 5|2.).
    Quindi la regex complessiva corrisponderà se trova ovunque una coppia di cifre consecutive non valida.
  • {! }: Costringilo a un booleano (facendo corrispondere il regex $_), negalo e trasforma il tutto in un lambda (con parametro implicito $_).

Perl 6 , 38 byte

Utilizzando l'elaborazione dell'elenco:

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

Prende l'input come una matrice di numeri interi.
Come funziona:

  • .[1..*] Z $_: Comprime l'elenco di input con una versione offset di uno di se stesso, per generare un elenco di 2 tuple di cifre consecutive.
  • [!=] 7 - .[1], |$_: Per ognuno di questi, controlla se (7 - b) != a != b.
  • all ( ): Restituisce un valore di verità o falsa a seconda che tutte le iterazioni di loop abbiano restituito True.

4

Python, 38 byte

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

Una funzione ricorsiva che accetta argomenti come f(1,2,3).

Questo fa uso dell'argomento unpacking per estrarre il primo numero he il resto nella tupla t. Se tè vuoto, genera True. Altrimenti, usa il piccolo trucco di Zgarb per verificare che i primi due tiri di dado non siano incompatibili. Quindi, controlla che il risultato valga anche per la chiamata ricorsiva sulla coda.


4

Rubino, 34 byte

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

2
è possibile radere due byte utilizzando #[]invece il metodo stringa :->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
Alexis Andersen il

Non sapevo che puoi usarlo con regex, grazie.
GB

4

JavaScript 61 43 byte

I commenti hanno menzionato che non posso usare le funzioni C # linq senza includere l'istruzione using, quindi ecco lo stesso in meno byte usando JS standard ...

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

C #, 99 67 65 byte

Accetta input come array 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;}

Spiegazione:

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

Penso che questo debba essere racchiuso in una funzione, o forse in una lambda (ce ne sono in C #?) Inoltre, potresti salvare qualche byte restituendo 0o 1invece di falseotrue
DJMcMayhem

oh, ok - primo post sul codice golf.
Modificherò

Nessun problema. A proposito, benvenuto nel sito! :)
DJMcMayhem

@DJMcMayhem Correggimi se sbaglio, ma poiché il requisito di output è verità / falsità, le opzioni di output dipendono dalla lingua tl; dr 1/0 non sono verità / falsità in c #
JustinM - Ripristina Monica

@Phaeze Hai ragione nel dire che non sono verità / falsità, ma le regole IO standard meta.codegolf.stackexchange.com/questions/2447/… calcolano che puoi generare usando i codici di uscita e che le funzioni possono essere emesse allo stesso modo di programmi. Tornerò ai booleani, se necessario, ma mi costerà qualche
boccone

3

> <> (Pesce) 47 byte

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

Abbastanza semplice;

Riga 1: controlla se è stato immesso un numero, se non c'è un numero (EOF), allora abbiamo una verità per stampare altri controlli.

Riga 2: risultato di stampa.

Riga 3: trasforma l'ingresso in numero (ASCII 0 - dall'ingresso), quindi controlla se è uguale all'input precedente.

Linea 4: verificare se l'ingresso è sul lato opposto della matrice.


3

Brain-Flak 128 byte

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

Emette 0 per falsey o -7 per verità.

Provalo online! (Sinceramente)
Provalo online! (Flasey)

Spiegazione (t sta per cima e s sta per seconda dalla cima):

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

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

accetta input come elenco di argomenti di comando; esce con 1(errore) se l'input non è valido, 0(ok) se valido.

Corri con -nr.

input come argomento stringa, 65 byte

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

3

PowerShell , 57 44 41 byte

( Barrato 44 è ancora regolare 44 )

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

Provalo online!

(OP ha chiarito che accettare input come argomenti separati è OK - salvato 13 byte ... salvato altri 3 byte eliminando $b)

Effettuiamo il ciclo dell'input $argsuna cifra alla volta. Ad ogni cifra, verifichiamo che la $lcifra ast sia -not equala alla cifra corrente $_e che 7-$_-$lsia un numero diverso da zero (che è vero). Questi risultati booleani sono incapsulati in parentesi e immessi nell'operando di destra -notindell'operatore, verificando il contrario 0. In altre parole, se c'è qualche Falsevalore in qualsiasi punto del loop, lo -notinsarà anche False. Quel booleano è rimasto sulla pipeline e l'output è implicito.

Lungo a causa del $requisito per i nomi delle variabili e che i comandi booleani -ne -andsono dettagliati in PowerShell. Oh bene.


3

Elaborazione, 93 92 90 byte

Modificato || in | : 1 byte salvato grazie a @ClaytonRamsey

Iniziato il conteggio all'indietro: 2 byte salvati grazie 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;}

Accetta l'input come una matrice di ints, l'output 1per true o 0per 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;
}

Di solito Java consente | anziché || se vuoi salvare un byte.
Clayton Ramsey,

@ClaytonRamsey Non so perché non ci abbia pensato, grazie!
Kritixi Lithos,

Ne ho trovato un altro. Potresti ridurre l'uso dei ritorni con l'operatore terziario
Clayton Ramsey il

@ClaytonRamsey Il return 0è all'interno dell'istruzione if mentre return 1non lo è. Non vedo come sia possibile a meno che tu non abbia qualche altra idea
Kritixi Lithos il

2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<- L'ho letto, confrontando quello che hai con quello che hai avuto.
Ismael Miguel,

3

C 47 44 byte

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

accetta una stringa di cifre (o una matrice di byte con terminazione zero)

Spiegazione

F(char*s){

secondo il inttipo di ritorno standard è implicito. (salvataggio di 4 byte)

return ritorno incondizionato perché questa è una funzione ricorsiva

usando la valutazione scorciatoia:

!s[1]||se il secondo carattere è nullo, restituisce vero

((*s^s[1])%7&& se i primi due caratteri non sono falsi legali

F(s+1)) controlla il resto della stringa allo stesso modo

quell'espressione confusa

*sè il primo personaggio s[1]è il secondo

*s^s[1] li ordina in modo esclusivo se sono uguali il risultato è 0 se si sommano a 7 il risultato è 7, (se differiscono e non si aggiungono a 7 il risultato è compreso tra 1 e 6 inclusi)

così (*s^s[1])%7è zero per input errato e diverso da zero altrimenti, quindi falso se questi 2 caratteri sono errati e vero altrimenti

commento: poiché questa chiamata di funzione utilizza solo la ricorsione finale (solo l'ultima affermazione è una chiamata ricorsiva) un ottimizzatore potrebbe tradurre la ricorsione in un ciclo, questa è una felice coincidenza e ovviamente non vale alcun punteggio di golf, ma nella parola reale rende possibile elaborare stringhe di qualsiasi lunghezza senza esaurire lo stack.


1
A proposito del tuo !((*s^s[1])%7)credo che tu non voglia il !. I valori zero per un input errato sarebbero falsi, quindi si desidera restituire il falso quando è errato.
nmjcman101,

2

Python, 71 byte

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

Utilizza un approccio ricorsivo.

Spiegazione:

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

dire che l'input è un elenco di ints e quindi non è necessario il cast.
Jasen,


2

MATL , 9 byte

dG2YCs7-h

L'input è una matrice di numeri che rappresentano le cifre.

L'output è un array non vuoto, che è vero se tutte le sue voci sono diverse da zero, e falsa altrimenti (leggi di più sul criterio MATL per verità e falsità qui ).

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

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

È possibile / inteso aggiungere alcune nuove funzioni MATLAB a MATL?
rahnema1,

@ rahnema1 Sì, ci sono alcuni nomi di funzioni attualmente inutilizzati. Tuttavia, tendo ad essere selettivo e aggiungere solo quelli che penso saranno usati spesso. Se hai qualche proposta, possiamo parlarne nella chat di MATL :-)
Luis Mendo,

@ rahnema1 Se stai pensando movsum, c'è già conv2(che include conv); vedi Y+eZ+
Luis Mendo il

2

C # (con Linq) 90 81 73 71 69 68 byte

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

Spiegazione:

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 byte, era 85 byte

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

L'input è un array di numeri interi A con lunghezza L. Restituisce 1 per true e 0 per false. L'input viene verificato dall'inizio alla fine utilizzando la lunghezza di input L come indice dell'array.


int è facoltativo all'inizio, è possibile salvare 4 byte.
Jasen,

int s=1;può essere dichiarato esterno alla funzione come s=1;per un altro 4.
nmjcman101

2

Haskell, 37 byte

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

Esempio di utilizzo: f [1,5,2]-> False.

Ricorsione semplice. Caso di base: elenco di elementi singoli, che restituisce True. Caso ricorsivo: lascia ache bsiano i primi due elementi dell'elenco di input e cil resto. Tutte le seguenti condizioni devono contenere: a+b/=7, a/=be la chiamata ricorsiva con acaduto.


2

JavaScript, 40 byte

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

Sfrutta la funzionalità JavaScript che && restituirà l'ultimo valore analizzato (il termine falsy o l'ultimo termine). 0viene passato se non soddisfa le condizioni e il termine precedente viene passato diversamente. Il 9 si assicura che inizi con un valore veritiero.



1

Python 2, 58 byte

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


1

Lotto, 102 byte

@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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.