Vérifier si un UUID est valide sans utiliser de regex


44

Avec une entrée de chaîne, écrivez un programme qui affiche une valeur de vérité dans STDOUT ou son équivalent si l’entrée est un UUID valide, sans utiliser de regex.

Un UUID valide est

32 chiffres hexadécimaux, affichés en cinq groupes séparés par des traits d'union, sous la forme 8-4-4-4-12 pour un total de 36 caractères (32 caractères alphanumériques et quatre traits d'union).

La source

Cas de test

0FCE98AC-1326-4C79-8EBC-94908DA8B034
    => true
00000000-0000-0000-0000-000000000000
    => true
0fce98ac-1326-4c79-8ebc-94908da8b034
    => true
0FCE98ac-1326-4c79-8EBC-94908da8B034
    => true

{0FCE98AC-1326-4C79-8EBC-94908DA8B034}
    => false (the input is wrapped in brackets)
0GCE98AC-1326-4C79-8EBC-94908DA8B034
    => false (there is a G in the input)
0FCE98AC 1326-4C79-8EBC-94908DA8B034
    => false (there is a space in the input)
0FCE98AC-13264C79-8EBC-94908DA8B034
    => false (the input is missing a hyphen)
0FCE98AC-13264-C79-8EBC-94908DA8B034
    => false (the input has a hyphen in the wrong place)
0FCE98ACD-1326-4C79-8EBC-94908DA8B034
    => false (one of the groups is too long)
0FCE98AC-1326-4C79-8EBC-94908DA8B034-
    => false (has a trailing hyphen)
0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
    => false (too many groups)
0FCE98AC13264C798EBC94908DA8B034
    => false (there is no grouping)

Règles

  • Les expressions régulières ne sont pas autorisées
  • La correspondance de motif littéral qui ressemble à une expression régulière n'est pas autorisée. Par exemple, en utilisant [0-9a-fA-F]ou d'autres identifiants hexadécimaux (nous appellerons cela n), puis en correspondance nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnou n[8]-n[4]-n[4]-n[4]-n[12]non.
  • L'entrée peut être prise à partir de STDINou comme argument d'une fonction
  • L'entrée est insensible à la casse
  • Il est prudent de supposer que l'entrée ne contiendra pas de sauts de ligne ou de saut de ligne.
  • L'entrée peut contenir des caractères ASCII imprimables (espaces compris).
  • Une valeur de vérité doit être imprimée STDOUTou équivalente si la saisie est un uuid valide
  • Une valeur de falsey doit être imprimée STDOUTou équivalente si la saisie n’est pas un uuid valide
  • Si vous utilisez une fonction, au lieu d’utiliser STDOUT, la sortie peut être la valeur de retour de la fonction
  • La valeur vérité / falsey ne peut pas être imprimée STDERR.
  • Les failles standard s'appliquent
  • C'est le , donc le programme le plus court en octets gagne. Bonne chance!

Classement

Il s'agit d'un extrait de pile qui génère un classement et un aperçu des gagnants par langue.

Pour que votre réponse apparaisse, commencez votre réponse par un titre utilisant le modèle Markdown suivant.

## Language Name, N bytes

Où N est la taille, en octets, de votre soumission

Si vous souhaitez inclure plusieurs numéros dans votre en-tête (par exemple, en supprimant d'anciens scores ou en incluant des indicateurs dans le nombre d'octets), assurez-vous que le score réel est le dernier numéro de votre en-tête.

## Language Name, <s>K</s> X + 2 = N bytes


32
Pauvre rétine . D:
BrainSteel


8
Juste pour référence, je peux trouver une solution de rétine de 28 octets. (Donc, pas un avantage fou sur les langues de golf bien qu'il soit actuellement en tête.)
Martin Ender

5
Les modèles de Lua sont-ils autorisés? Ce ne sont certainement pas des expressions régulières.
manatwork

1
@JacobKrall Je suis à peu près sûr que c'est «faux» à toutes vos questions. Je pense que le défi est assez clair: seules les chaînes du formulaire \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(où \hest un chiffre hexadécimal) sont valides.
Martin Ender

Réponses:


15

CJam, 31 30 29 octets

8 4__C]Nf*'-*qA,s'G,_el^+Ner=

Exécutez tous les cas de test ici.

Explication

Au lieu de mettre en correspondance directe le motif avec l'entrée, nous le transformons d'abord en un formulaire plus simple qui peut être facilement comparé à une chaîne de motif unique.

8 4__C] e# Push the array of segment lengths, [8 4 4 4 12].
Nf*     e# Turn that into strings of linefeeds of the given length.
'-*     e# Join them by hyphens, giving "NNNNNNNN-NNNN-NNNN-NNNN-NNNNNNNNNNNN".
q       e# Read the input.
A,s     e# Push the string "0123456789".
'G,_el^ e# Push the string "ABCDEFabcdef".
+       e# Concatenate the two strings.
N       e# Push a linefeed.
er      e# Replace all hexadecimal digits with linefeeds.
=       e# Check for equality with the pattern string.

23

JavaScript ES6, 73 55 56 caractères

s=>s.split`-`.map(x=>x.length+`0x${x}0`*0)=="8,4,4,4,12"

La version précédente à 55 caractères a un problème avec les espaces de fin dans le groupe:

s=>s.split`-`.map(x=>x.length+("0x"+x)*0)=="8,4,4,4,12"
// "00000000-0000-0000-000 -000000000000" true

Tester:

f=s=>s.split`-`.map(x=>x.length+`0x${x}0`*0)=="8,4,4,4,12"
;`0FCE98AC-1326-4C79-8EBC-94908DA8B034
0fce98ac-1326-4c79-8ebc-94908da8b034
0FCE98ac-1326-4c79-8EBC-94908da8B034
0GCE98AC-1326-4C79-8EBC-94908DA8B034
0FCE98AC-13264C79-8EBC-94908DA8B034
0FCE98AC-13264-C79-8EBC-94908DA8B034
0FCE98ACD-1326-4C79-8EBC-94908DA8B034
0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
00000000-0000-0000-0000-000000000000
D293DBB2-0801-4E60-9141-78EAB0E298FF
0FCE98AC-1326-4C79-8EBC-94908DA8B034-
00000000-0000-0000-000 -000000000000`.split(/\n/g).every(s=>f(s)==/^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i.test(s))

Génial (et dépérissant pour moi) +1
edc65

@ edc65, qu'entendez-vous par "flétrir"?
Qwertiy

Abus impressionnant de casting implicite +1
Downgoat

4
méprisant, méprisant, cinglant, cinglant, dévastateur, humiliant, mortifiant - (comparant votre réponse à la mienne)
edc65

11

PowerShell, 29 21 84 49 37 octets

param($g)@{36=$g-as[guid]}[$g.length]

Un grand merci aux personnes dans les commentaires qui ont aidé à la pratique du golf pour suivre l'évolution des règles - TessellatingHeckler , iFreilicht , Jacob Krall et Joey . Veuillez consulter l'historique des modifications pour les révisions et les versions antérieures.

Cette révision prend les entrées comme $g, puis crée une nouvelle table de hachage @{}avec un élément, index 36étant défini sur égal $g-as[guid]. Ceci utilise l' -asopérateur intégré pour tenter la conversion entre deux types de données .NET - de [string]à [guid]. Si la conversion aboutit, un [guid]objet est renvoyé, sinon $nullest renvoyé. Cette partie garantit que la chaîne d'entrée est un GUID .NET valide.

L'étape suivante consiste à indexer dans la table de hachage [$g.length]. Si la $glongueur n'est pas exactement de 36 caractères, la table de hachage retournera $null, qui sera sortie en tant que valeur de falsey. Si $gest composé de 36 caractères, le résultat de l'appel .NET sera généré. Si $gn'est pas un GUID .NET valide (sous quelque forme que ce soit), il sera $nullalors affiché sous forme de valeur falsey. Sinon, un objet GUID .NET sera généré en tant que valeur de vérité. Le seul moyen de générer une sortie est celui-ci s'il correspond au format demandé pour le défi.

Exemples

Ici, j'encapsule l'appel de script entre parenthèses et le transforme explicitement en booléen pour plus de clarté.

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC-1326-4C79-8EBC-94908DA8B034')
True

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC-1326-4C79-8EBC-94908DA8B034D')
False

PS C:\Tools\Scripts\golfing> [bool](.\check-if-a-uuid-is-valid.ps1 '0FCE98AC13264C798EBC94908DA8B034')
False

4
Je vais jeter !!($args[0]-as[guid])à 21 octets.
TessellatingHeckler

2
Ne pourriez-vous pas simplement économiser 4 octets en omettant le !!()? Comme les valeurs $NULLet [guid]sont mutuellement exclusifs, ils se qualifient pour représenter les valeurs de truthey et Falsey, non? Quoi qu'il en soit, excellent moyen de convertir en booléen, aimez la solution!
iFreilicht

@ iFreilicht c'est un point; en regardant le message "interprétation vérité / falsey" posté - je conviens que cela semble valable.
TessellatingHeckler

1
Cette solution retourne à tort Truepour 0FCE98AC13264C798EBC94908DA8B034, qui n'a pas de trait d'union
Jacob Krall

1
@TessellatingHeckler Nope, trop beau pour être vrai. Ajouter un chiffre, tel que 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(D supplémentaire à la fin) renvoie falsey $TRUE, car cela élimine simplement le chiffre incriminé et les 36 premiers caractères sont valides.
AdmBorkBork

9

Emacs Lisp, 236 octets

(lambda(s)(and(eq(string-bytes s)36)(let((l(string-to-list s))(i 0)(h '(8 13 18 23))(v t))(dolist(c l v)(set'v(and v(if(member i h)(and v(eq c 45))(or(and(> c 47)(< c 58))(and(> c 64)(< c 91))(and(> c 96)(< c 123))))))(set'i(+ i 1))))))

Ungolfed:

(lambda (s)
  (and (eq (string-bytes s) 36) ; check length
       (let ((l (string-to-list s))
             (i 0)
             ; location of hyphens
             (h '(8 13 18 23))
             (v t))
         (dolist (c l v)
           (set 'v (and v (if (member i h)      ; check if at hyphen position
                              (and v (eq c 45)) ; check if hyphen
                            (or (and (> c 47) (< c 58))      ; check if number
                                (and (> c 64) (< c 91))      ; check if upper case letter
                                (and (> c 96) (< c 123)))))) ; check if lower case letter
           (set 'i (+ i 1)))))) ; increment

8

En raison de changements dans les règles , cette réponse n’est plus compétitive :(

C, 98

main(a,n){printf("%d",scanf("%8x-%4hx-%4hx-%4hx-%4hx%8x%n%c",&a,&a,&a,&a,&a,&a,&n,&a)==6&&n==36);}

Surtout assez explicite. Le %nspécificateur de format indique le nombre d'octets lus jusqu'à présent, qui devrait être 36. scanf()renvoie le nombre d'éléments correspondants, qui devrait être 6. La finale %cne doit correspondre à rien. Si c'est le cas, il y a un texte de fin, et le résultat scanf()est 7.

Compilez avec -wpour supprimer les avertissements embêtants (il y en a plusieurs).


6

JavaScript ES6, 70 83

NOTE: merci à @Qwertiy pour avoir trouvé un bogue (et suggéré quelques améliorations et corrections)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ 2 octets enregistrés

Autres 9 octets enregistrés simplifiant la vérification de la longueur (la manière complexe était plus courte dans le premier brouillon, mais pas maintenant)

u=>u.split`-`.every((h,l,u)=>u[4]&&-`0x${h}1`&&h.length-'40008'[l]==4)

A expliqué

u=>u.split`-` // make an array splitting at '-'
.every( // for every element the following must be true
 (h,l,u)=> // h is the element, l is the index, u is the whole array
 u[4] // element 4 must be present (at least 5 element in array)
 && -`0x${h}1` // element must be a valid hex string with no extraneous blanks (else NaN that is falsy)
 // get requested length from index (8,4,4,4,12 sub 4 to put in 1 char)
 // a 6th elements will be rejected as undefined != 4
 && h.length-'40008'[l]==4// then check element length
)

Extrait de test

f=u=>u.split`-`.every((h,l,u)=>u[4]&&-`0x${h}1`&&h.length-'40008'[l]==4)

console.log=x=>O.innerHTML+=x+'\n'

;[
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034',true],
  ['0fce98ac-1326-4c79-8ebc-94908da8b034',true],
  ['0FCE98ac-1326-4c79-8EBC-94908da8B034',true],
  ['00000000-0000-0000-0000-000000000000', true],
  ['ffffffff-ffff-ffff-ffff-ffffffffffff', true],
  ['0GCE98AC-1326-4C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-13264C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-13264-C79-8EBC-94908DA8B034',false],
  ['0FCE98ACD-1326-4C79-8EBC-94908DA8B034',false],
  ['0FCE98AC-1326-4C79-8EBC',false],
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034-',false],
  ['00000000-0000-0000-000 -000000000000', false],
  ['0FCE98AC-1326-4C79-8EBC-94908DA8B034-123',false],
].forEach(x=>{
  var t=x[0], r=f(t), k=x[1]
  console.log('Test '+t+' result '+r+(r==k?' ok':' fail'))
})
<pre id=O></pre>


-1-('0x'+h)=>1/('0x'+h)
Qwertiy

Même problème que dans ma version précédente: true for00000000-0000-0000-000 -000000000000
Qwertiy

Non, mais vous avez ajouté un mauvais test. L'espacement principal n'est pas un problème, mais un problème final, car une chaîne est coupée lors de la conversion en nombre. Voir mon commentaire ci-dessus avec un test.
Qwertiy

'00000000-0000-0000-000 -000000000000' maintenant je le vois @Qwertiy j'ai raté les 3 zéros au lieu de 4
edc65

1
@Stefnotch je ne suis pas d'accord. En dehors de l' everyappel uest une chaîne, pas un tableau
edc65

5

En raison de changements dans les règles , cette réponse n’est plus compétitive :(

Pure Bash (aucun utilitaire externe), 78

printf -vv %8s-%4s-%4s-%4s-%12s
p=${v// /[[:xdigit:]]}
[ "$1" -a ! "${1/$p}" ]

Prend une entrée à partir de la ligne de commande.

  • Le printfconstruit la chaîne suivante - - - -.
  • La p=ligne transforme ce le schéma suivant: [[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]-[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]. Notez que cela ressemble beaucoup à une expression régulière. Cependant, ce n'est pas dans ce contexte. C'est un modèle de correspondance de modèle de shell . Ce concept est similaire à une expression régulière, mais constitue une construction (et une syntaxe) différente.
  • La dernière ligne vérifie si
    • l'entrée est non vide
    • si extraire le motif de la chaîne en entrée produit une chaîne vide

Idiomatique pour shell, un code de retour de 0 indique succès / VRAI et 1 indique un échec / FAUX. Le code de retour peut être inspecté echo $?après l'exécution du script.


1
La correspondance de modèle de shell ne suit peut-être pas la syntaxe de regex, mais la classe de caractères utilise définitivement la définition et la syntaxe de regex POSIX. De toute façon, c'est à OP de décider si c'est acceptable.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Les expressions régulières peuvent inclure des classes de caractères Posix, mais je ne pense pas que cela implique que tout ce qui utilise une classe de caractères Posix est une regex. Comme autre exemple, trutilise également les classes de caractères Posix, mais n’est pas un analyseur de regex.
Digital Trauma

Vous pouvez éliminer quelques caractères en évitant les guillemets inutiles, par exemple au format printf.
Jens

J'ai mis à jour le défi pour clarifier - la raison pour laquelle les regexes ont été refusées était pour que les motifs hexadécimaux ne puissent pas être utilisés pour correspondre aux uuids
Jojodmo

4

Jolf, 32 octets

Essayez-le ici!

 eGi'-DN&bH*28=lH.[8,4,4,4,12]S}
 e                               Property "e"very of next object
  Gi'-                           Split i at hyphen
      DN                       } every comparison function
        &                        logical conjugation of next two arguments
         bH*28                   base 16 of H (first arg); is NaN (falsey) if invalid
              =                  equality of next two items
               lH                the length of H (first arg)
                 .            S  the Sth (index) member of the object inbetween
                  [8,4,4,4,12]   array of lengths

À cause d'une erreur dans mon code, c'est plus long que cela ne devrait être. :( [8,4,4,4,12] devrait être identique à {8444*26}, mais }est aussi la fermeture d'une fonction: P


2
Donc, il est plus long que cela doit être parce que vous avez des commandes ambiguës dans le langage que vous avez créé? : P
Rɪᴋᴇʀ

@RikerW Erreur sémantique mineure. C'est corrigé maintenant.
Conor O'Brien

4

MATL , 55 octets

jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$

Je me suis abstenu d'utiliser la Ybfonction ( strsplit) parce que c'est un peu similaire à regexp(..., 'split'). Cela utilise uniquement l'indexation et les comparaisons de caractères.

Exemple

>> matl
 > jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$
 > 
> This is a test
0

>> matl
 > jttn36=?[9,5,5,5]XsXK)45=?36:Km~)4Y2'A':'F'hm?}F]]]N~1$
 > 
> D293DBB2-0801-4E60-9141-78EAB0E298FF
1

Explication

jt                     % input string, duplicate
tn36=?                 % if length is 36
  [9,5,5,5]XsXK        % build and copy indices of required '-' positions
  )45=?                % if those entries are indeed '-'
    36:Km~)            % logical index of remaining positions
    4Y2'A':'F'h        % allowed chars in those positions
    m?                 % if all those entries are legal: do nothing
    }                  % else
      F                % false value
    ]                  % end
  ]                    % end
]                      % end
N~                     % true if stack is empty
1$                     % display last result only

3

CJam, 52 42 octets

qeu__{A7*)<},\'-/83 3b{)4*}%.{\,=}[1]5*=*=

Essayez-le en ligne . Affiche la chaîne d'origine si vrai et la chaîne vide si faux ( ceci est autorisé ).

Explication:

qeu__                                      e# Take input, make 2 copies
     {A7*)<},\                             e# Remove invalid characters from first copy
              '-/                          e# Split top of stack on '-
                 83 3b{)4*}%               e# Array of group lengths: [8 4 4 4 12]
                            .{\,=}[1]5*=   e# Compare two arrays, return true if group lengths are correct
                                        *= e# Multiply this value by original string (0 = empty string, 1 = same string)

A7*)<ne supprimera pas beaucoup de caractères non valides, tels que les espaces +, ?...
Martin Ender

@ MartinBüttner oh shoot ... Je ne savais pas que, je vais le réparer en quelques minutes.
GamrCorps

3

Julia, 86 octets

s->(t=split(s,"-");map(length,t)==[8,4,4,4,12]&&all(i->!isnull(tryparse(Int,i,16)),t))

C'est une fonction anonyme qui accepte une chaîne et retourne un booléen. Pour l'appeler, donnez-lui un nom, par exemple f=s->....

Ungolfed:

function f(s::AbstractString)
    # Split the input into an array on dashes
    t = split(s, "-")

    # Ensure the lengths are appropriate
    ok1 = map(length, t) == [8, 4, 4, 4, 12]

    # Ensure each element is a valid hexadecimal number
    ok2 = all(i -> !isnull(tryparse(Int, i, 16)), t)

    return ok1 && ok2
end

3

C # 196 octets

using System.Linq;class P{bool T(string v){var r=v.Length==36;for(var i=0;i<v.Length;i++)r&=new[]{8,13,18,23}.Any(t=>t==i)?v[i]=='-':v[i]>47&&v[i]<58|v[i]>64&&v[i]<71|v[i]>96&&v[i]<103;return r;}}

Ungolfed:

using System.Linq;
class P
{
    public bool T(string v)
    {
        var r = v.Length == 36;
        for (var i = 0; i < v.Length; i++)
            r &= new[] { 8, 13, 18, 23 }.Any(t => t == i) 
                ? v[i] == '-' 
                : v[i] > 47 && v[i] < 58 | v[i] > 64 && v[i] < 71 | v[i] > 96 && v[i] < 103;
        return r;
    }
}

La méthode Tpeut être appelée avec n'importe quelle chaîne non NULL et retournera trueles GUID valides, falsesinon. Ceci est une validation à temps constant; au prix de trois caractères que vous pouvez sortir en début de la méthode (changement i < v.Lengthde i < v.Length && r).

Je vais essayer d'obtenir le décompte plus tard.

J'ai évidemment laissé de côté le Guid.ParseExactchemin, car où est le plaisir? La voici, sans trop d’efforts, pour la jouer encore plus loin dans 86 octets :

using System;class P{bool T(string v){Guid x;return Guid.TryParseExact(v,"D",out x);}}

Ungolfed:

using System;
class P
{
    bool T(string v)
    {
        Guid x;
        return Guid.TryParseExact(v, "D", out x);
    }
}

2

Python 2, 99 112 octets

def f(u):
 try:u=u.split()[0];int(u.replace('-',''),16);print[8,4,4,4,12]==map(len,u.split('-'))
 except:print 0

Sur une entrée valide, il imprime True. Sur une entrée non valide, il est imprimé Falseou 0, en fonction de la raison, invalide. Falseet 0sont tous les deux falsey en python.

La fonction doit vérifier 3 choses:

  • Chaque caractère non-tiret est un chiffre ou est en ABCDEF
  • Il y a exactement 4 traits d'union
  • Il y a 8 caractères avant le premier tiret, 12 après le dernier et 4 entre deux autres caractères.

Voici une ventilation pour montrer comment il vérifie pour eux. Il est légèrement obsolète mais j'ai faim alors je le mettrai à jour plus tard.

def f(u):
    try:
        int(u.replace('-',''),16) # Remove all hyphens from the string and parse what's
                                  # left as a base 16 number. Don't do anything with this
                                  # number, but throw an exception if it can't be done.

        return[8,4,4,4,12]==map(len,u.split('-')) # Split the string at each hyphen and
                                                  # get the length of each resulting
                                                  # string. If the lengths == [8,4,4,4,12],
                                                  # there are the right number of groups
                                                  # with the right lengths, so the string
                                                  # is valid.
    except:
        return 0 # The only way to get here is if the string (minus hyphens) couldn't be
                 # parsed as a base 16 int, so there are non-digit, non-ABCDEF characters
                 # and the string is invalid.

Je suppose que vous pouvez économiser 2 octets si vous remplacez les deux instances de returnavec print. (Dans ce cas, vous voudrez certainement être en Python 2, car cela printfonctionne différemment en Python 3.)
mathmandan

1
Cela ne fonctionne pas dans Python 3, car maprenvoie maintenant un "objet map", pas une liste.
Tim Pederick

Cela ne fonctionne pas dans Python 2 (probablement 3 aussi) car la intfonction autorise les espaces - 0FCE98ac-1326-4c79-8EBC-94908da8B03avec un espace de fin. Voir le commentaire dans la réponse Pyth supprimée ici si possible.
Bleu

2

Python 2, 57 octets

Dieu merci pour construit! - assurez-vous de mettre les chaînes entre guillemets.

import uuid
try:uuid.UUID(input());print 1
except:print 0

5
Selon les documents que vous avez liés, cela imprimerait 1pour l'entrée 12345678123456781234567812345678.
Dennis

si cela fonctionnait, vous pourriez économiser des octets, try:print uuid.UUID(input())car tout ce dont vous avez besoin est d’imprimer une valeur de vérité
undergroundmonorail

2
Ce programme accepte de nombreux formats UUID, mais la question ne demande que le format UUID à 36 caractères, avec des traits d'union.
Jacob Krall

2
Vous pouvez le récupérer, en gérant les règles mises à jour, en vérifiant si la chaîne d'entrée est égale à l'uuid reconverti en chaîne. Vous donne tout de suite une valeur de vérité.
agtoever

2

Pyth, 39 octets

&&!+1xzd.xi:zK\-k16ZqxKc+zK1mid36"8dinz

Essayez ici .


Il manque le \caractère dans votre lien "essayez-le ici" K\-k, il ne s'exécute donc pas tel quel.
Alex

Cela a été corrigé
Bleu

2

Perl 6 ,  83   67 octets

# 83 bytes
{
  (
    my@a=.uc.split('-')
  ).map(*.comb)⊆('0'..'9','A'..'F')
&&
  @a».chars~~(8,4,4,4,12)
}

# 67 bytes
{
  (
    $/=.split('-')
  ).map({:16($_)//|()})==5
&&
  $/».chars~~(8,4,4,4,12)
}

(les chiffres n'incluent pas les nouvelles lignes ni les retraits car ils ne sont pas nécessaires)

usage:

# give it a name
my &code = {...}

say map &code, «
  D293DBB2-0801-4E60-9141-78EAB0E298FF
  0FCE98AC-1326-4C79-8EBC-94908DA8B034
  0fce98ac-1326-4c79-8ebc-94908da8b034
  0FCE98ac-1326-4c79-8EBC-94908da8B034
  00000000-1326-4c79-8EBC-94908da8B034
»;
# (True True True True True)

say map &code, «
  0GCE98AC-1326-4C79-8EBC-94908DA8B034
 '0FCE98AC 1326-4C79-8EBC-94908DA8B034'
  0FCE98AC-13264C79-8EBC-94908DA8B034
  0FCE98AC-13264-C79-8EBC-94908DA8B034
  0FCE98ACD-1326-4C79-8EBC-94908DA8B034
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
»;
# (False False False False False False False)

2

Common Lisp - 161

(lambda(s &aux(u(remove #\- s)))(and(=(length s)36)(=(length u)32)(every(lambda(p)(char=(char s p)#\-))'(8 13 18 23))(ignore-errors(parse-integer u :radix 16))))

La valeur renvoyée si true est le hachage, en tant que nombre, ce qui est un résultat utile à obtenir.

Ungolfed

(defun uuid-p (string &aux (undashed (remove #\- string)))
  (and
   ;; length of input string must be 36
   (= (length string) 36)

   ;; there are exactly 4 dashes
   (= (length undashed) 32)

   ;; We check that we find dashes where expected
   (every (lambda (position)
            (char= (char string position) #\-))
          '(8 13 18 23))

   ;; Finally, we decode the undashed string as a number in base 16,
   ;; but do not throw an exception if this is not possible.
   (ignore-errors
    (parse-integer undashed :radix 16))))

@Jojodmo Oui, certainement! Merci
Coredump

2

F # 44 caractères

fun s->System.Guid.TryParseExact(s,"D")|>fst

En F #, les fonctions avec des outparamètres peuvent être appelées en omettant le paramètre out; sa valeur au retour sera combinée avec la valeur de retour vraie de la fonction dans un tuple.

Ici, le tuple est dirigé vers la fstfonction, qui retourne son premier membre, qui est dans ce cas la valeur de retour booléenne de TryParseExact, indiquant le succès ou l'échec de l'appel.

Pour vérifier le format correct, nous truene renvoyons que si la chaîne comporte 36 caractères.

Avant de voir la réponse C # de RobIII, je n'avais pas pensé à utiliser TryParseExact; ma réponse était donc d'avoir été trois caractères plus longs:

fun s->System.Guid.TryParse s|>fst&&s.Length=36

TryParse(string, Guid) accepte les entrées dans les formats suivants:

00000000000000000000000000000000 
00000000-0000-0000-0000-000000000000 
{00000000-0000-0000-0000-000000000000} 
(00000000-0000-0000-0000-000000000000)
{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}

Parmi ceux-ci, seul le second comporte 36 caractères.


2

Python 2, 93 89 85 octets

lambda u:(set(u)<=set("-0123456789abcdefABCDEF"))*map(len,u.split("-"))==[8,4,4,4,12]

L' map()appel garantit que les sections ont la bonne longueur et all()teste chaque caractère en tant que trait d'union ou chiffre hexadécimal à casse quelconque. L'expression du générateur teste chaque caractère en effectuant une itération sur l'ensemble de la chaîne. Ce n'est donc pas la méthode la plus performante, mais elle devrait satisfaire les cas de test:

>>> f=lambda u:(set(u)<=set("-0123456789abcdefABCDEF"))*map(len,u.split("-"))==[8,4,4,4,12]
>>> testcases = """\
... D293DBB2-0801-4E60-9141-78EAB0E298FF
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034
... 0fce98ac-1326-4c79-8ebc-94908da8b034
... 0FCE98ac-1326-4c79-8EBC-94908da8B034
... 00000000-0000-0000-0000-000000000000""".splitlines()
>>> failcases = """\
... 0GCE98AC-1326-4C79-8EBC-94908DA8B034
... 0FCE98AC 1326-4C79-8EBC-94908DA8B034
... 0FCE98AC-13264C79-8EBC-94908DA8B034
... 0FCE98AC-13264-C79-8EBC-94908DA8B034
... 0FCE98ACD-1326-4C79-8EBC-94908DA8B034
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034-
... 0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
... 00000000-0000-0000-000 -000000000000
... 00000000-0000-0000- 000-000000000000""".splitlines()
>>> all(f(u) for u in testcases)
True
>>> any(f(u) for u in failcases)
False
>>> 

Quelqu'un sait-il pourquoi la réponse la plus courte et correcte de Python a été refusée? Pas assez d'explication?
rsandwick3

Jojodmo - en cas de confusion à ce sujet, je n'ai pas rejeté votre proposition de modification - j'avais déjà effectué une modification car j'avais oublié les caractères AF (je les ai copiés à partir d'une fenêtre dans laquelle je testais des cas négatifs), et Community auto -réjeté votre proposition sans que je sache qu'elle avait même été soulevée. Au moment où je savais que vous l'aviez proposé, @nimi avait déjà corrigé l'en-tête. J'espère sincèrement que cela n'a rien à voir avec le vote négatif, car cela nuirait beaucoup à cette communauté. Quoi qu'il en soit, je vais supposer que c'est l'autre chose et ajouter un peu plus d'explications.
rsandwick3

2
Vous pouvez supprimer le f=et les espaces autour de la chaîne dans le allbloc.
FryAmTheEggman

oh génial, belle prise - édité
rsandwick3

1
Vous pouvez enregistrer 8 (ou 6, vous pourriez avoir besoin d'ajouter entre parenthèses) octets en convertissant votre all(..)pour définir les tests d'inclusion: set(u)<=set("-0123456789abcdefABCDEF").
409_Conflict

1

SAS, 171 144 141

data;infile stdin;file stdout;input a$9b$14c$19d$24;e=(a!!b!!c!!d='----')*length(_infile_)=36*(1-missing(put(input(compress(_infile_,,'adk'),$hex32.),$hex32.)));put e;run;

Utilise en fait stdin et stdout - l’une des fonctionnalités les moins connues de ce langage particulier. Fonctionne pour les exemples donnés jusqu'à présent, mais peut-être pas dans tous les cas. Peut probablement être amélioré.

Meilleure approche - un personnage à la fois:

data;infile stdin;file stdout;do i=1 to 37;input@i c$1.@;a+ifn(i in(9,14,19,24),c='-',n(input(c,hex.))-36*(i>36&c^=''));end;b=a=36;put b;run;

Golfé 6 autres caractères de l'expression centrale!

Ungolfed:

data;
infile stdin;
file stdout;
do i=1 to 37;
input@i c$1.@;
a+ifn(i in(9,14,19,24),c='-',n(input(c,hex.))-36*(i>36&c^=''));
end;
b=a=36;
put b;
run;

Cela génère pas mal d'avertissements et de notes dans le journal, mais cela ne les imprime pas sur stdout ou stderr, je pense donc que c'est un jeu juste.


1

C, 391 octets

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define F printf("0")
#define T printf("1")
#define E return 0
main(){char s[99],*t;int k=1,l,i;scanf("%99[^\n]",s);if(s[strlen(s)-1]=='-'){F;E;}t=strtok(s,"-");while(t!=NULL){for(i=0,l=0;t[i]!=0;i++,l++){if(!isxdigit(t[i])){F;E;}}if((k==1&&l!=8)||((k>1&&k<5)&&l!=4)||(k==5&&l!=12)){F;E;}k++;t=strtok(NULL,"-");}if(k==6){T;E;};F;}

1

MATLAB, 126 octets

function f(a)
b='-';if length(a)==36&&a(9)==b&&a(13)==b&&a(17)==b&&a(21)==b;a(a==b)=[];if any(isnan(hex2dec(a)));0;end;1;end;0

1

Python 3, 134 octets

def a(i):
 try:l=[1+int(k,16)and(len(k)==c)for k,c in zip(i.split("-"),[8,4,4,4,12])];return(len(l)==5)&(0 not in l)
 except:return 0

int (k, 16) essaye de convertir k en base 16 int. Sur un caractère autre que 0-9a-fA-F-, il échoue, auquel cas nous renvoyons 0, ce qui est faux. Ajoutez 1 à cet int et vous obtenez une valeur de vérité garantie - nous avons supprimé tous les tirets avec str.split () afin que nous ne puissions pas obtenir la valeur -1 et que tous les éléments non-0 sont vrais.


1

Fonction C, 102

Un changement de règle a annulé ma scanf()réponse précédente basée sur le c , alors voici une autre réponse c à l' aide de isxdigit()laquelle je pense qu'il devrait être autorisé à concurrencer :

i;f(char *s){for(i=8;i<24;i+=5)s[i]=s[i]-45?1:s[i]+3;for(i=0;isxdigit(s[i]);i++);return i==36&&!s[i];}

Essayez-le en ligne.

  • Recherchez les -caractères (ASCII 45) aux positions appropriées - le cas échéant, remplacez-les par 0s (ASCII 48 (= 45 + 3))
  • Parcourez la chaîne en vérifiant chaque personnage avec isxdigit()
  • Renvoie VRAI si la longueur de la chaîne est 36 et si le dernier caractère est NUL.

1

Lot, 148 139 + 2 = 150 141 octets

@set/pu=
@for %%d in (1 2 3 4 5 6 7 8 9 A B C D E F)do @set u=!u:%%d=0!
@if -!u!==-00000000-0000-0000-0000-000000000000 exit/b0
@exit/b1

Ajout de 2 octets car vous devez utiliser le /vcommutateur pour CMD.EXE.

Quitte avec ERRORLEVEL 0 en cas de succès, 1 en cas d'échec.

Edit: Sauvegardé des octets principalement parce qu’il :=est insensible à la casse, mais il y avait aussi d’autres réglages.


1

Java, 345 octets

interface q{static void main(String[]a){int i=-1;char[]b=a[0].toCharArray();java.io.PrintStream u=System.out;if(b.length>36||b.length<36)u.print(1<0);if(b[8]!='-'||b[13]!='-'||b[18]!='-'||b[23]!='-')u.print(1<0);while(++i<b.length){if(i!=8&&i!=13&&i!=18&&i!=23){if(!((b[i]>='0'&&b[i]<='F')||(b[i]>='a'&&b[i]<='f')))u.print(1<0);}}u.print(1>0);}}

L'entrée est le premier argument de la ligne de commande. La sortie est un code d'erreur (0 signifie UUID valide, 1 signifie non valide)

Ungolfed avec des commentaires:

interface q {
    static void main(String[] a) {
        int i = -1;                                                             // Index
        char[] b = a[0].toCharArray();                                          // Characters from input
        java.io.PrintStream u = System.out;                                     // STDOUT
        if (b.length > 36||b.length < 36)                                       // If input length is not 36
            u.print(1<0);                                                       // Invalid
        if (b[8]!='-'||b[13]!='-'||b[18]!='-'||b[23]!='-')                      // If hasn't got separators at correct positions
            u.print(1<0);                                                       // Invalid
        while (++i<b.length) {                                                  // Iterate over all characters
            if (i!=8 && i!=13 & i!=18 && i!=23) {                               // If not at separator indexes
                if ( !( (b[i]>='0'&&b[i]<='F') || (b[i]>='a'&&b[i]<='f') ))     // If incorrect hexadecimal number
                    u.print(1<0);                                               // Invalid
            }
        }
        u.print(1>0);                                                           // Valid
    }
}

EDIT: N'a pas remarqué la partie STDOUT. Oups, corrigé maintenant.


Agréable! Vous pouvez remplacer if(b.length>36||b.length<36)par simplement if(b.length!=36). De plus, comme vous pouvez imprimer des valeurs conformes à la vérité , vous pouvez simplement imprimer 0au lieu de 1<0, et 1au lieu de 1>0.
Jojodmo

@Jojodmo Sur la base des votes, une valeur de truthy est sous forme de if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }So en Java un booléen est une valeur truthy, mais 1ou 0est pas. Seulement lorsque l'OP d'un défi dit quelque chose comme: « Votre sortie peut être vrai / faux, 0/1, vide / non vide, tant que vous indiquez ce que vous utilisez. » En effet , vous pouvez alors utiliser 0et au 1lieu de true/falsecomme truthy / valeur falsey.
Kevin Cruijssen

1
En ce qui concerne les conseils de golf pour cookie: @Jojodmo a effectivement raison de le remplacer par if(b.length!=36); ||peut être |sur plusieurs endroits, ainsi que &&pour &; if(...!='-')peut être if(...!=45); int i=-1; ... while(++i<b.length){peut être remplacé par for(int i=-1;++i<b.length;){; 'F'peut être 70( 'f'pourrait être 102, mais cela n'a pas d'importance puisqu'il s'agit du même nombre d'octets). J'aime la façon dont vous avez utilisé java.io.PrintStream u=System.out;, je devrais m'en rappeler! Donc merci.
Kevin Cruijssen

1

Swift 3, 50 octets

Passer dans une ficelle s

import Foundation
print(UUID(uuidString:s) != nil)

1

PHP, 109 octets

affiche 1 pour vrai et 0 pour faux

for($t=($l=strlen($a=$argn))==36;$i<$l;$i++)$t*=$i>7&$i<24&!($i%5-3)?$a[$i]=="-":ctype_xdigit($a[$i]);echo$t;

$i>7&$i<24&!($i%5-3) est 5 octets plus court alors in_array($i,[8,13,18,23])

112 octets

echo array_filter(str_split($argn),function($i){return!ctype_xdigit($i);})==[8=>"-",13=>"-",18=>"-",23=>"-"]?:0;

113 octets

echo array_diff(str_split(strtolower($argn)),array_map(dechex,range(0,15)))==[8=>"-",13=>"-",18=>"-",23=>"-"]?:0;

0

Java, 172 octets 168 octets (Assistant Merci Wheat)

Un peu cheaty depuis que java.util.UUID est utilisé, mais voici:

import java.util.UUID;class ValidUUID{public static void main(String[] a){try{UUID.fromString(a[0]);System.out.println(1);}catch(Exception e){System.out.println(0);}}}

Version non-golfée:

import java.util.UUID;

class ValidUUID {

    public static void main(String[] a) {
        try {
            UUID.fromString(a[0]);
            System.out.println(1);
        } catch(Exception e) {System.out.println(0);}
    }
}

Bienvenue sur le site! Je pense que vous pouvez supprimer l'espace entre tryet {.
Wheat Wizard

@ WheatWizard merci: D aussi remarqué que je peux enlever le "autour de 0 et 1
ryxn

2
Vous devriez pouvoir supprimer l’espace entre String[]et a. En outre, vous devriez pouvoir remplacer printlnpar print.
Clismique

1
Le nom de la classe peut avoir 1 caractère. Vous pouvez utiliser java.util.UUID.fromStringau lieu d'importer.
Poke

0

AWK, 98 octets

BEGIN{FS=""}{for(j=4;k<NF;){h+=(j+=5)<25?$j=="-":0
s+=strtonum("0x"$++k 1)>0}$0=h+s==36&&NF==36}1

Fractionne simplement la ligne à chaque caractère et vérifie si chaque caractère est un chiffre hexadécimal et s'il y a des traits d'union aux endroits appropriés. strtonumconvertit les caractères non valides en 0. Faire la comparaison entre 0et m(et un caractère invalide choisi arbitrairement) nécessite des étapes supplémentaires. Heureusement, 01c'est un nombre hexadécimal valide, mais ce m1n'est pas le cas.

Au départ, j’ai écrit deux forboucles, mais j’ai économisé 1 octet en les comprimant ensemble. :)

REMARQUE: GAWKpeut lire les entrées sous forme de nombres hexadécimaux, mais cela nécessite une très longue option en ligne de commande.

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.