Valider les basculeurs de matrices aléatoires


33

Il y a presque six ans, steenslag, membre du PPCG, a lancé le défi suivant:

Dans un dé standard, les numéros sont disposés de telle sorte que les faces opposées totalisent sept. Ecrivez le programme le plus court possible dans votre langue préférée, qui génère un lancer aléatoire suivi de 9 basculements aléatoires. Un basculement est un quart de tour du dé, par exemple si le dé est tourné vers 5, tous les basculements possibles sont 1,3,4 et 6.

Exemple de sortie souhaitée:

1532131356

Donc, maintenant que tout le monde l'a complètement oublié et que la réponse gagnante a été acceptée depuis longtemps, nous allons écrire un programme pour valider les séquences de basculement générées générées par les solutions soumises. (Cela a du sens. Imaginez-le.)

Défi

Votre programme ou fonction reçoit une séquence telle que 1532131356. Valider que chaque chiffre consécutif est:

  • Pas égal au chiffre précédent
  • Pas égal à 7 moins le chiffre précédent

(Vous n'êtes pas obligé de valider le premier chiffre.)

Règles

  • Votre programme doit renvoyer une valeur de vérité si l'entrée est valide et une valeur de falsey sinon.
  • Vous pouvez supposer que la saisie ne comprend que les chiffres 1 à 6 et comporte au moins 1 caractère. Les séquences n'auront pas une longueur fixe comme dans le défi de steenslag.
  • Vous pouvez prendre l’entrée sous forme de chaîne ( "324324"), de tableau ou de structure de données de type tableau ( [1,3,5]) ou d’arguments multiples ( yourFunction(1,2,4)).

Les règles standard d' entrée / sortie et d' échappatoire s'appliquent.

Cas de test

Vérité

1353531414
3132124215
4142124136
46
4264626313135414154
6
2642156451212623232354621262412315654626212421451351563264123656353126413154124151545145146535351323
5414142

Falsey

  • Chiffre répété

    11
    3132124225
    6423126354214136312144245354241324231415135454535141512135141323542451231236354513265426114231536245
    553141454631
    14265411
    
  • Côté opposé du die

    16
    42123523545426464236231321
    61362462636351
    62362462636361
    

Réponses:


14

Python 2, 43 45 octets

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

43 octets (fortement inspirés par @Zgarb)

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

Cette fonction combine mon énoncé de réduction avec la logique de la réponse de @ Zgarb, qui consiste à utiliser une combinaison de bits plus courte, pour une combinaison plus courte que les deux.

Les deux réponses donnent les résultats suivants:

  • 0 si l'entrée n'est pas une séquence valide
  • Le dernier chiffre de la séquence s'il est valide

4
Bienvenue sur PPCG, C’est une très bonne première réponse.
Wheat Wizard

1
Cela ne fonctionne pas pour environ la moitié des faux cas. Par exemple, 3132124225revient 5.
Jake Cobb

Vous pouvez le réparer en utilisant n and p*(7-p!=n!=p).
Jake Cobb

@JakeCobb Cela devrait fonctionner avec tous les cas de test maintenant. Malheureusement, il est maintenant 2 octets plus long :(
notjagan

Quelle utilisation intelligente de réduire, en passant chaque valeur à l'étape suivante.
xnor

9

Python, 44 octets

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

Magie des bits! C'est une fonction anonyme qui prend une liste d'entiers et vérifie que le XOR de chaque élément consécutif est compris entre 1 et 6 inclus.

Pourquoi ça marche

Premièrement, le XOR est toujours compris entre 0 et 7 inclus, puisque 7 est 111en base 2 et que nos nombres ont au plus 3 chiffres binaires. Pour l'égalité, a^b == 0si et seulement si a == b. Aussi, nous avons 7-a == 7^aquand 0 ≤ a ≤ 7, et donc a^b == 7si et seulement si a == 7^b == 7-b.


7

05AB1E , 11 9 octets

-2 octets pour l’idée intelligente d’Oseable d’utiliser un produit.

¥¹D7-Á+«P

Essayez-le en ligne!

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

Troisième approche utilisant 05AB1E, qui n’utilise pas la commande pairwise:

  • 0 si elle viole les propriétés de tipy.
  • Not 0 si rien ne l'empêchait d'être ivre.

1
@ Emigna ne pensait pas que c'était important, mais corrigé!
Urne Magic Octopus

1
Je voulais poster une réponse avec les deltas, mais je n'y ai pas pensé Á. Agréable!
Osable

1
Vous pouvez économiser 2 octets en utilisant la définition des valeurs vérité / fausseté avec ¥¹D7-Á+«P. Cela donne 0 quand il y a un 0 dans le tableau ou toute autre valeur.
Osable

1
@Osable SMAART! Mega homme intelligent, bon travail.
Urne Magic Octopus

6

R, 39 37 32 31 octets

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

Essayez-le en ligne!

Prend les commentaires de stdin. Permet diffde voir si deux chiffres consécutifs sont identiques. compare ensuite chaque chiffre à 7 moins le chiffre précédent. Retours TRUEouFALSE .

5 octets sauvés grâce à Jarko Dubbeldam et un autre merci à JayCe.


Enregistrer les différences dans une variable q, puis tester 2*x+q-7au lieu de c(0,x)!=c(7-x,0)sauvegarder quelques octets. Si x1 + x2 = 7alors 2*x1 + diff(x1,x2) = 7. Vérifier 2*x+q - 7ensuite explicitement les tests !=0.
JAD

@JarkoDubbeldam Excellente observation, merci! J'ai mis à jour la solution.
rturnbull


@JayCe Merci, j'ai mis à jour la réponse maintenant.
rturnbull

5

05AB1E , 10 octets

$ü+7ʹüÊ*P

Utilise le codage CP-1252 . Essayez-le en ligne!


1
Argh !, pourquoi n'ai-je pas pensé à Ê: P Nice!
Emigna

Hmm, alors 1*[] = []mais product(1, []) = 1. C'est bon à savoir.
Emigna

@ Emigna En fait, c'est un bug. Le produit de []devrait être 1.
Adnan

Oui, j'ai souhaité que cela fonctionne comme ça plusieurs fois auparavant. L'ordre des opérations est également important ici. )1*, )1s*et )1Psont []tout ce qui )1sPest 1.
Emigna

1
@ Emigna Ahh, c'est parce que le produit de [] donne une erreur et est jeté. C'est pourquoi ça donne 1. J'essaierai de le réparer quand je rentrerai à la maison.
Adnan

5

R, 49 44 octets

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

Lit les entrées de stdin (séparées par un espace) et les sorties TRUE/FALSE. Donnera un avertissement si l'entrée est de longueur un mais fonctionne toujours.

Edit: sauvegardé quelques octets grâce à @rturnbull


Vous pouvez combiner all(x)&all(y)dans all(x,y)pour enregistrer des octets. Vous pouvez également basculer rle(x)$l==1vers rle(x)$l-1, qui renverra alors un ensemble de tous FALSEsi xest valide; puis passer le plus tard !=à un ==et allà !any. Cela permet d' !any(rle(x<-scan())$l-1,ts(x)==7-lag(ts(x)))économiser 5 octets au total. (PS, j'ai écrit une solution alternative qui pourrait vous intéresser.)
rturnbull


4

JavaScript (ES6), 43 40 octets

Retours 0/ true.

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

Cas de test


Malheureusement, le simple port de la réponse Retina n’est que de 38 octets.
Neil

@Neil Je pense que c'est 37 avectest()
Arnauld

Désolé, j'ai accidentellement collé une nouvelle ligne dans le compteur d'octets.
Neil

4

Perl 6 , 22 octets

En utilisant une regex:

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

Prend l'entrée sous forme de chaîne. Inspiré par la réponse de GB Ruby .
Comment ça marche:

  • / /: Une regex.
  • (.): Correspond à n'importe quel caractère et capture-le comme $0.
  • <{ }>: Générer dynamiquement une sous-expression rationnelle à faire correspondre à cette position.
  • "$0|" ~ (7 - $0): La sous-expression régulière que nous générons est celle qui correspond uniquement au chiffre précédent, ou 7 moins le chiffre précédent (par exemple 5|2).
    Ainsi, l'expression rationnelle globale correspondra si et seulement si elle trouve une paire de chiffres consécutifs non valide n'importe où.
  • {! }: Contraindre à un booléen (ce qui provoque la correspondance de l'expression rationnelle $_), l'annule et transforme le tout en lambda (avec un paramètre implicite $_).

Perl 6 , 38 octets

Utilisation du traitement de liste:

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

Prend l'entrée sous forme de tableau d'entiers.
Comment ça marche:

  • .[1..*] Z $_: Compressez la liste d'entrée avec une version d'elle-même décalée-par-un, afin de générer une liste de 2 tuples de chiffres consécutifs.
  • [!=] 7 - .[1], |$_: Pour chacun de ceux-ci, vérifiez si (7 - b) != a != b.
  • all ( ): Retourne une valeur de vérité ou de fausseté selon que toutes les itérations de boucle ont renvoyé la valeur True.

4

Python, 38 octets

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

Une fonction récursive qui prend des arguments tels que f(1,2,3).

Ceci utilise l'argument de décompression pour extraire le premier nombre het le reste dans le tuple t. Si test vide, la sortie est True. Sinon, utilisez l’ astuce de Zgarb pour vérifier que les deux premiers jets de dés ne sont pas incompatibles. Ensuite, vérifiez que le résultat est également valable pour l’appel récursif à la fin.


4

Ruby, 34 octets

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

2
vous pouvez supprimer deux octets en utilisant la #[]méthode de la chaîne :->s{!s[/[16]{2}|[25]{2}|[34]{2}/]}
Alexis Andersen

Je ne savais pas que tu pouvais l'utiliser avec regex, merci.
GB

4

JavaScript 61 43 octets

Des commentaires ont mentionné que je ne peux pas utiliser les fonctions linq de C # sans inclure l'instruction using, voici donc exactement la même chose en moins d'octets avec JS standard ...

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

C #, 99 67 65 octets

Prend l'entrée comme un tableau 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;}

Explication:

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

Je pense que cela doit être enveloppé dans une fonction, ou peut-être un lambda (C # en a-t-il?). Vous pouvez également économiser quelques octets en retournant 0ou à la 1place de falseoutrue
DJMcMayhem

oh, ok - premier post sur le code de golf. Je vais modifier ...
Erresen

Aucun problème. BTW, bienvenue sur le site! :)
DJMcMayhem

@DJMcMayhem Corrigez-moi si je me trompe, mais puisque l'exigence de sortie est vérité / falsey, les options de sortie dépendent de la langue. Dr 1/0 ne sont pas vérité / falsey en c #
JustinM - Rétablissez Monica

@Phaeze Vous avez raison de dire qu'ils ne sont pas véridiques / falsey, mais que les règles standard d'E / S meta.codegolf.stackexchange.com/questions/2447/ comptent que vous pouvez générer des codes de sortie à l'aide des codes de sortie et que les fonctions peuvent générer les mêmes résultats programmes. Je reviens aux booléens si nécessaire, mais cela me coûtera quelques bouchées
Erresen

3

> <> (Poisson) 47 octets

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

Assez simple;

Ligne 1: vérifiez si vous avez entré un nombre, s'il n'y a pas de numéro (EOF), alors nous avons la vérité pour imprimer d'autres chèques.

Ligne 2: résultat d'impression.

Ligne 3: transformer l'entrée en numéro (ASCII 0 - à partir de l'entrée), puis vérifier si elle est égale à l'entrée précédente.

Ligne 4: vérifiez si l'entrée est opposée au dé.


3

Brain-Flak 128 Octets

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

Sorties 0 pour falsey ou -7 pour la vérité.

Essayez-le en ligne! (Truthy)
Essayez-le en ligne! (Flasey)

Explication (t représente top et s correspond à la deuxième à partir du haut):

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

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

prend l'entrée comme liste d'arguments de commande; quitte avec 1(erreur) si l'entrée est invalide, 0(ok) si valide.

Courez avec -nr.

entrée en tant qu'argument de chaîne, 65 octets

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

3

PowerShell , 57 44 41 octets

( 44 barrées sont toujours régulières 44 )

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

Essayez-le en ligne!

(OP a précisé que prendre les entrées en tant qu'arguments séparés est correct - enregistrer 13 octets ... enregistrer 3 autres octets en éliminant $b)

Nous parcourons l'entrée $argsun chiffre à la fois. Chaque chiffre, on vérifie que le $lchiffre est ast -not equal au chiffre actuel $_, et qui 7-$_-$lest un nombre différent de zéro (qui est truthy). Ces résultats booléens sont encapsulés dans des parenthèses et introduits dans l'opérande droit de l' -notinopérateur, en vérifiant 0. En d'autres termes, s'il y a une Falsevaleur n'importe où dans la boucle, le-notin sera égalementFalse . Ce booléen est laissé sur le pipeline et la sortie est implicite.

Il est long en raison de la $nécessité de noms de variables et du fait que les commandes booléennes -ne -andsont détaillées dans PowerShell. Tant pis.


3

Traitement, 93 92 90 octets

Remplacé || par | : 1 octet enregistré grâce à @ClaytonRamsey

Commence à compter en arrière: 2 octets enregistrés grâce à @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;}

Prend l’entrée comme un tableau d’entiers, la sortie est 1vraie ou0 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;
}

Habituellement, Java permet | au lieu de || si vous voulez sauvegarder un octet.
Clayton Ramsey

@ClaytonRamsey Je ne sais pas pourquoi je n'y ai pas pensé, merci!
Kritixi Lithos

J'ai trouvé un autre. Vous pouvez réduire l'utilisation des retours avec l'opérateur tertiaire
Clayton Ramsey

@ClaytonRamsey Le return 0est dans la déclaration if alors que return 1n'est pas. Je ne vois pas comment cela serait possible à moins que vous n'ayez une autre idée.
Kritixi Lithos

2
Golfed it! Yipee! (nobody's going to read these summaries so why not have fun :)<- Je l'ai lu en comparant ce que vous avez avec ce que vous aviez.
Ismael Miguel

3

C 47 44 octets

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

prend une chaîne de chiffres (ou un tableau d'octets terminé par zéro)

Explication

F(char*s){

selon le type de intretour standard est implicite. (économiser 4 octets)

return retour inconditionnel parce que c'est une fonction récursive

en utilisant l'évaluation de raccourci:

!s[1]||si le second caractère est nul, retourne vrai

((*s^s[1])%7&& si les deux premiers caractères ne sont pas légaux, faux

F(s+1)) vérifier le reste de la chaîne de la même manière

cette expression déroutante

*sest le premier caractère s[1]est le second

*s^s[1] Si elles sont identiques, le résultat est 0 si elles ajoutent à 7, le résultat est 7 (si elles diffèrent et n'additionnent pas à 7, le résultat est compris entre 1 et 6 inclus)

donc (*s^s[1])%7est zéro pour les mauvaises entrées et non nul sinon, donc false si ces 2 caractères sont mauvais et true sinon

commentaire: comme cet appel de fonction utilise uniquement la fin de récursion (seule la dernière instruction est un appel récursif), un optimiseur pourrait traduire la récursion en boucle, ce qui est une bonne conicidence et ne vaut évidemment pas un score de golf, mais dans le vrai mot permet de traiter des chaînes de n'importe quelle longueur sans manquer de pile.


1
A propos de votre !((*s^s[1])%7)Je pense que vous ne voulez pas !. La valeur zéro pour une mauvaise entrée serait falsy, vous voulez donc renvoyer la falsy lorsqu'elle est mauvaise.
nmjcman101

2

Python, 71 octets

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

Utilise une approche récursive.

Explication:

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

Dites que l'entrée est une liste d'ints et que vous n'avez pas besoin de la distribution.
Jasen


2

MATL , 9 octets

dG2YCs7-h

L'entrée est un tableau de nombres représentant les chiffres.

La sortie est un tableau non vide, qui est truthy si toutes ses entrées ne sont pas nuls, et falsy autrement ( en savoir plus sur le critère de MATL pour truthy et falsy ici ).

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

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

Est-il possible / prévu d’ajouter de nouvelles fonctions MATLAB à MATL?
rahnema1

@ rahnema1 Oui, certains noms de fonctions sont actuellement inutilisés. Cependant, j’ai tendance à être sélectif et à n’ajouter que ceux qui, à mon avis, seront souvent utilisés. Si vous avez des propositions, nous pouvons en discuter dans la salle de discussion MATL :-)
Luis Mendo

@ rahnema1 Si vous songez à movsum, il y a déjà conv2(ce qui inclut conv); voir Y+etZ+
Luis Mendo

2

C # (avec Linq) 90 81 73 71 69 68 octets

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

Explication:

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 octets, 85 octets

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'entrée est un tableau d'entiers A de longueur L. Retourne 1 pour vrai et 0 pour faux. L'entrée est vérifiée de bout en bout en utilisant la longueur d'entrée L comme index du tableau.


int est facultatif au début, vous pouvez économiser 4 octets.
Jasen

int s=1;peut être déclaré en dehors de la fonction comme s=1;pour un autre 4.
nmjcman101

2

Haskell, 37 octets

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

Exemple d'utilisation: f [1,5,2]-> False.

Récursion simple. Cas de base: liste d'éléments uniques, qui retourne True. Cas récursif: laissez aet bsoyez les deux premiers éléments de la liste d’entrée et cle reste. Toutes les conditions suivantes doivent être: a+b/=7, a/=bet l'appel récursif a achuté.


2

JavaScript, 40 octets

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

Exploite la fonctionnalité JavaScript qui &&renvoie la dernière valeur analysée (soit le terme faux, soit le dernier terme). 0est transmis s'il ne remplit pas les conditions et si le terme précédent est transmis autrement. Le 9 s'assure qu'il commence par une valeur de vérité.



1

Python 2, 58 octets

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


1

Lot, 102 octets

@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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.