Controlla se un UUID è valido senza usare regex


44

Dato un input di stringa, scrivere un programma che stampa un valore di verità su STDOUT o equivalente se l'input è un UUID valido, senza usare regex.

Un UUID valido è

32 cifre esadecimali, visualizzate in cinque gruppi separati da trattini, nella forma 8-4-4-4-12 per un totale di 36 caratteri (32 caratteri alfanumerici e quattro trattini).

fonte

Casi 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)

Regole

  • Le espressioni regolari non sono consentite
  • Non è consentita la corrispondenza di schemi letterali che è come una regex. Ad esempio, l'utilizzo [0-9a-fA-F]o altri identificatori esadecimali (chiameremo questo n) e quindi la corrispondenza nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnno n[8]-n[4]-n[4]-n[4]-n[12]non è consentita
  • L'input può essere preso da STDINo come argomento di una funzione
  • L'input non fa distinzione tra maiuscole e minuscole
  • È sicuro presumere che l'input non conterrà avanzamenti di riga o newline.
  • L'input può contenere qualsiasi carattere ASCII stampabile (spazi inclusi)
  • Un valore di verità deve essere stampato STDOUTo equivalente se l'input è un uuid valido
  • Un valore di falso deve essere stampato STDOUTo equivalente se l'input non è un uuid valido
  • Se si utilizza una funzione, anziché utilizzare STDOUT, l'output può essere il valore restituito della funzione
  • Non è possibile stampare il valore di verità / falsità STDERR.
  • Si applicano scappatoie standard
  • Questo è , quindi vince il programma più breve in byte. In bocca al lupo!

Classifica

Questo è un frammento di stack che genera sia una classifica che una panoramica dei vincitori per lingua.

Per assicurarti che la tua risposta venga visualizzata, inizia la tua risposta con un titolo usando il seguente modello Markdown

## Language Name, N bytes

Dove N è la dimensione, in byte, dell'invio

Se vuoi includere più numeri nella tua intestazione (ad esempio, colpendo i vecchi punteggi o includendo i flag nel conteggio dei byte), assicurati solo che il punteggio effettivo sia l' ultimo numero nella tua intestazione

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


32
Povera Retina . D:
BrainSteel,


8
Solo per riferimento, posso trovare una soluzione Retina da 28 byte. (Quindi non è un vantaggio folle rispetto alle lingue del golf, anche se attualmente sarebbe in testa.)
Martin Ender,

5
Gli schemi di Lua sono ammessi? Non sono certamente espressioni regolari.
arte

1
@JacobKrall Sono abbastanza sicuro che sia "falsa" per tutte le tue domande. Penso che la sfida sia abbastanza chiara che solo le stringhe del modulo \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(dove \hè una cifra esadecimale) sono valide.
Martin Ender,

Risposte:


15

CJam, 31 30 29 byte

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

Esegui tutti i casi di test qui.

Spiegazione

Invece di far corrispondere direttamente l'input al pattern, lo stiamo prima trasformando in una forma più semplice che può essere facilmente confrontata con una singola stringa di pattern.

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 caratteri

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

La precedente versione di 55 caratteri ha un problema con gli spazi finali nel gruppo:

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

Test:

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

Fantastico (e appassimento per me) +1
edc65

@ edc65, cosa intendi con "appassimento"?
Qwertiy,

Fantastico abuso del casting implicito +1
Downgoat

4
sprezzante, sprezzante, dispettoso, pungente, devastante, umiliante, mortificante - (paragonando la tua risposta alla mia)
edc65

11

PowerShell, 29 21 84 49 37 byte

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

Mille grazie alle persone nei commenti che hanno contribuito a questo golf per tenere il passo con le mutevoli regole: TessellatingHeckler , iFreilicht , Jacob Krall e Joey . Consulta la cronologia delle modifiche per le revisioni e le versioni precedenti.

Questa revisione accetta input come $g, quindi crea una nuova tabella hash @{}con un elemento, l'indice 36è impostato uguale $g-as[guid]. Questo utilizza l' -asoperatore integrato per tentare la conversione tra due tipi di dati .NET - da [string]a [guid]. Se la conversione ha esito positivo, [guid]viene restituito un oggetto, altrimenti $nullviene restituito. Questa parte garantisce che la stringa di input sia un GUID .NET valido.

Il prossimo passo è indicizzare nella tabella hash con [$g.length]. Se la $glunghezza non è esattamente di 36 caratteri, verrà restituita la tabella hash $null, che verrà emessa come valore di falso. Se la $glunghezza è di 36 caratteri, verrà emesso il risultato della chiamata .NET. Se $gnon è un GUID .NET valido (in qualsiasi forma), verrà $nullgenerato come valore false. Altrimenti genererà un oggetto GUID .NET come valore di verità: l'unico modo che può essere emesso è se corrisponde al formato richiesto della sfida.

Esempi

Qui sto incapsulando la sceneggiatura in parentesi e esplicitamente il cast come booleano per chiarezza.

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
Lancerò !!($args[0]-as[guid])a 21 byte.
Tessellating Heckler,

2
Non potresti semplicemente salvare 4 byte tralasciando !!()? Mentre i valori $NULLe [guid]si escludono a vicenda, si qualificano per rappresentare i valori truthey e Falsey, non è vero? Ad ogni modo, ottimo modo per convertirti in booleano, ama la soluzione!
iFreilicht,

@iFreilicht questo è un punto; guardando il post collegato "interpretazione di verità / falsità" - sono d'accordo che sembra valido.
TessellatingHeckler,

1
Questa soluzione restituisce erroneamente Trueper 0FCE98AC13264C798EBC94908DA8B034, che non ha trattini
Jacob Krall,

1
@TessellatingHeckler No, troppo bello per essere vero. L'aggiunta di una cifra, ad esempio 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(D extra alla fine) restituisce falsey $TRUE, poiché ritaglia semplicemente la cifra offensiva e i primi 36 caratteri sono validi.
AdmBorkBork,

9

Emacs Lisp, 236 byte

(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

A causa di modifiche alle regole , questa risposta non è più competitiva :(

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

Principalmente abbastanza autoesplicativo. L' %nidentificatore di formato fornisce il numero di byte letti finora, che dovrebbe essere 36. scanf()restituisce il numero di elementi corrispondenti, che dovrebbe essere 6. Il finale %cnon deve corrispondere a nulla. In tal caso, è presente un testo finale e scanf()verrà restituito 7.

Compilare con -wper sopprimere i fastidiosi avvisi (ce ne sono diversi).


6

JavaScript ES6, 70 83

NOTA grazie a @Qwertiy per trovare un bug (e suggerire alcuni miglioramenti e correzioni)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ 2 byte salvati

Altri 9 byte salvati semplificando il controllo della lunghezza (il modo complesso era più breve nella prima bozza, ma non ora)

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

spiegato

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
)

Test snippet

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,

Stesso problema della mia versione precedente: vero per00000000-0000-0000-000 -000000000000
Qwertiy

No. Ma hai aggiunto un test sbagliato. Lo spazio iniziale non è un problema, ma lo è uno di seguito, poiché una stringa viene tagliata durante la conversione in numero. Vedi il mio commento sopra con un test.
Qwertiy,

'00000000-0000-0000-000 -000000000000' ora lo vedo @Qwertiy Ho perso i 3 zeri anziché 4
edc65

1
@Stefnotch non sono d'accordo. Fuori dalla everychiamata uc'è una stringa, non un array
edc65

5

A causa di modifiche alle regole , questa risposta non è più competitiva :(

Pure Bash (senza utility esterne), 78

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

Riceve input dalla riga di comando.

  • Il printfcostruisce la seguente stringa - - - -.
  • La p=linea di questo trasforma il seguente schema: [[: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:]]. Nota che assomiglia moltissimo a un'espressione regolare. Tuttavia, non è in questo contesto. È un modello per la corrispondenza del modello di shell . Questo è simile nel concetto a un'espressione regolare, ma è un costrutto (e una sintassi) differente.
  • L'ultima riga controlla se
    • l'ingresso non è vuoto
    • se estraendo il pattern dalla stringa di input si produce una stringa vuota

Idiomatico per shell, un codice di ritorno di 0 indica successo / VERO e 1 indica fallimento / FALSO. Il codice di ritorno può essere controllato con echo $?dopo aver eseguito lo script.


1
La corrispondenza del modello di shell potrebbe non seguire la sintassi di regex, ma la classe di caratteri utilizza sicuramente la definizione e la sintassi di regex POSIX. Ad ogni modo, spetta all'OP decidere se è accettabile.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Le espressioni regolari possono includere classi di caratteri Posix, ma non penso che ciò implichi che tutto ciò che utilizza una classe di caratteri Posix sia una regex. Come altro esempio trusa anche le classi di caratteri Posix, ma non è un parser regex.
Digital Trauma,

Puoi radere alcuni caratteri evitando inutili doppie virgolette, ad esempio nel formato printf.
Jens,

Ho aggiornato la sfida per chiarire - il motivo per cui le regex sono state vietate è stato quello di renderlo in modo che gli schemi esadecimali non potessero essere usati per abbinare gli uuidi
Jojodmo,

4

Jolf, 32 byte

Provalo qui!

 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

A causa di un errore nel mio codice, questo è più lungo di quanto dovrebbe essere. :( [8,4,4,4,12] dovrebbe essere lo stesso di {8444*26}, ma }è anche la chiusura di una funzione: P


2
Quindi è più lungo di quanto deve essere perché hai comandi ambigui nella lingua che hai creato? : P
Rɪᴋᴇʀ

@RikerW Piccolo errore semantico. Ora è stato risolto.
Conor O'Brien,

4

MATL , 55 byte

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

Mi sono trattenuto dall'utilizzare la Ybfunzione ( strsplit) perché è in qualche modo simile a regexp(..., 'split'). Questo utilizza solo indicizzazioni e confronti di caratteri.

Esempio

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

Spiegazione

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 byte

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

Provalo online . Emette la stringa originale se vera, produce stringa vuota se falsa ( questo è permesso ).

Spiegazione:

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*)<non rimuoverà molti caratteri non validi, come spazi +, ?...
Martin Ender,

@ MartinBüttner oh spara ... Non me ne sono reso conto, lo aggiusterò in pochi minuti.
GamrCorps,

3

Julia, 86 byte

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

Questa è una funzione anonima che accetta una stringa e restituisce un valore booleano. Per chiamarlo, dagli un nome, ad es 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 byte

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

Il metodo Tpuò essere invocato con qualsiasi stringa non nulla e verrà restituito trueper GUID validi, falsealtrimenti. Questa è una validazione a tempo costante; al costo di tre caratteri è possibile uscire anticipatamente dal metodo (passare i < v.Lengtha i < v.Length && r).

Proverà a ridurre ulteriormente il numero di byte in seguito.

Ovviamente ho lasciato fuori Guid.ParseExactstrada perché dov'è il divertimento in questo? Eccolo qui, senza troppi tentativi di ridurlo ulteriormente in 86 byte :

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 byte

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

Su un input valido, stampa True. Su un input non valido viene stampato Falseo 0, a seconda del motivo per cui non è valido. Falsee 0sono entrambi falsi in Python.

La funzione deve controllare 3 cose:

  • Ogni carattere non trattino è una cifra o è in ABCDEF
  • Esistono esattamente 4 trattini
  • Vi sono 8 caratteri prima del primo trattino, 12 dopo l'ultimo e 4 tra gli altri due

Ecco una ripartizione per mostrare come li controlla. È leggermente obsoleto ma ho fame, quindi lo aggiornerò più tardi.

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.

Suppongo che puoi salvare 2 byte se sostituisci entrambe le istanze di returncon print. (Nel qual caso vorrai sicuramente essere in Python 2, perché printfunziona in modo diverso in Python 3.)
mathmandan,

1
Questo non funziona in Python 3, perché mapora restituisce un "oggetto mappa", non un elenco.
Tim Pederick,

Questo non funziona in Python 2 (probabilmente anche 3) perché la intfunzione consente spazi - 0FCE98ac-1326-4c79-8EBC-94908da8B03con uno spazio finale. Vedi il commento nella risposta Pyth eliminata qui se possibile.
Blu,

2

Python 2, 57 byte

Grazie al cielo per il built-in! - assicurati di racchiudere le stringhe tra virgolette.

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

5
Secondo i documenti a cui ti sei collegato, questo verrebbe stampato 1per l'input 12345678123456781234567812345678.
Dennis,

se funzionasse, saresti in grado di salvare i byte facendo try:print uuid.UUID(input())perché tutto ciò che serve è stampare un valore veritiero
undergroundmonorail

2
Questo programma accetta molti formati UUID, ma la domanda vuole solo il formato UUID a 36 caratteri, con trattini.
Jacob Krall,

2
Puoi recuperarlo, affrontando le regole aggiornate, controllando se la stringa di input è uguale all'uuido convertito nuovamente in stringa. Ti dà subito un valore sincero.
agtoever il

2

Pyth, 39 byte

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

Provalo qui .


Nel tuo link "provalo qui" manca il \personaggio K\-k, quindi non funziona così com'è.
Alex,

Questo problema è stato risolto ora
Blue

2

Perl 6 ,  83   67 byte

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

(i conteggi non includono newline o rientri in quanto non necessari)

utilizzo:

# 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

Lisp comune - 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))))

Il valore restituito se vero è l'hash, come numero, che è un risultato utile da avere.

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 Sì, sicuramente! Grazie
coredump il

2

Caratteri F # 44

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

In F #, le funzioni con outparametri possono essere richiamate omettendo il parametro out; il suo valore al ritorno sarà combinato con il vero valore di ritorno della funzione in una tupla.

Qui, la tupla viene reindirizzata alla fstfunzione, che restituisce il suo primo membro, che in questo caso è il valore di ritorno booleano di TryParseExact, che indica l'esito positivo o negativo della chiamata.

Come controllo per il formato corretto, restituiamo truesolo se la stringa è lunga 36 caratteri.

Prima di vedere la risposta C # di RobIII, non avevo pensato di usare TryParseExact, quindi la mia risposta sarebbe stata di tre caratteri in più:

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

TryParse(string, Guid) accetta input nei seguenti formati:

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

Di questi, solo il secondo è lungo 36 caratteri.


2

Python 2, 93 89 85 byte

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

La map()chiamata garantisce che le sezioni abbiano le giuste lunghezze e all()verifica che ogni carattere sia un trattino o una cifra esadecimale di un caso arbitrario. L'espressione del generatore sta testando ogni carattere ripetendo l'intera stringa, quindi non è il metodo più performante, temo, ma dovrebbe soddisfare i casi di 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
>>> 

Qualcuno ha idea del perché la risposta Python corretta più breve è stata sottoposta a downgrade? Non abbastanza spiegazione?
rsandwick3,

Jojodmo - in caso di confusione a riguardo, non ho rifiutato la tua proposta di modifica - Avevo già fatto una modifica perché avevo perso i caratteri AF (ho copiato da una finestra in cui stavo testando casi negativi) e Auto comunitaria - respinse la tua proposta senza che io sapessi che era stata persino sollevata. Quando sapevo che l'avresti proposto, @nimi aveva già apportato la correzione alla rubrica. Spero vivamente che non abbia nulla a che fare con il downvote, poiché ciò si rifletterebbe molto male su questa comunità. Ad ogni modo, suppongo sia l'altra cosa e aggiungerò un po 'più di spiegazione.
rsandwick3,

2
È possibile rimuovere gli f=spazi attorno alla stringa nel allblocco.
FryAmTheEggman,

oh fantastico, bella cattura - a cura di
rsandwick3 il

1
È possibile salvare 8 (o 6, potrebbe essere necessario aggiungere parentesi) byte convertendo il tuo all(..)per impostare il test di inclusione: set(u)<=set("-0123456789abcdefABCDEF").
409_Conflitto

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;

In realtà utilizza stdin e stdout, una delle caratteristiche meno conosciute di questo particolare linguaggio. Funziona con gli esempi forniti finora, ma forse non in tutti i casi. Probabilmente può essere migliorato.

Approccio migliore - un personaggio alla volta:

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;

Giocato a golf altri 6 caratteri dall'espressione 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;

Questo genera parecchi avvertimenti e note nel registro, ma non li stampa su stdout o stderr, quindi penso che questo sia un gioco corretto.


1

C, 391 byte

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

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 byte

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) tenta di lanciare k su una base-16 int. Su un personaggio diverso da 0-9a-fA-F- fallisce, nel qual caso restituiamo 0, che è falso. Aggiungi 1 a quell'int e otteniamo un valore di verità garantito - abbiamo eliminato tutti i trattini con str.split () in modo da non poter ottenere il valore -1 e tutti gli in non-0 sono veritieri.


1

Funzione C, 102

Una modifica alla regola non ha consentito la mia precedente scanf()risposta basata su c , quindi ecco un'altra risposta c che uso a isxdigit()cui penso dovrebbe essere permesso di competere :

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

Provalo online.

  • Controlla i -caratteri (ASCII 45) nelle posizioni pertinenti - in tal caso, sostituiscili con 0s (ASCII 48 (= 45 + 3))
  • Cammina la stringa controllando ogni carattere con isxdigit()
  • Restituisce VERO se la lunghezza della stringa è 36 e il carattere finale è NUL.

1

Lotto, 148 139 + 2 = 150 141 byte

@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

Aggiunti 2 byte perché è necessario utilizzare l' /vopzione per CMD.EXE.

Esce con ERRORLEVEL 0 in caso di successo, 1 in caso di errore.

Modifica: salvato alcuni byte principalmente perché non :=fa distinzione tra maiuscole e minuscole, ma c'erano anche altre modifiche.


1

Java, 345 byte

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'input è il primo argomento della riga di comando. L'output è un codice di errore (0 significa UUID valido, 1 significa non valido)

Ungolfed con commenti:

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: non ho notato la parte STDOUT. Oops, risolto ora.


Bello! Puoi sostituirlo if(b.length>36||b.length<36)con semplicemente if(b.length!=36). Inoltre, poiché è possibile stampare valori veritieri , è possibile semplicemente stampare 0anziché 1<0e 1invece di 1>0.
Jojodmo,

@Jojodmo Sulla base dei voti, un valore truthy è sotto forma di if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }Così in Java un valore booleano è un valore truthy, ma 1o 0non lo è. Solo quando l'OP di una sfida dice qualcosa del tipo: " Il tuo output può essere vero / falso, 0/1, vuoto / non vuoto; purché specifichi ciò che usi. " Allora puoi effettivamente usare 0e 1invece che true/falsecome verità / valore false.
Kevin Cruijssen,

1
Per quanto riguarda i suggerimenti sul golf per i cookie: @Jojodmo ha davvero ragione a sostituirlo con if(b.length!=36); ||può trovarsi |in più punti, oltre &&a &; if(...!='-')può essere if(...!=45); int i=-1; ... while(++i<b.length){può essere sostituito con for(int i=-1;++i<b.length;){; 'F'può essere 70( 'f'potrebbe essere 102, ma non importa poiché ha lo stesso numero di byte). Mi piace come hai usato java.io.PrintStream u=System.out;BTW, dovrei ricordare quello! Quindi grazie.
Kevin Cruijssen,

1

Swift 3, 50 byte

Passa una stringa s

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

1

PHP, 109 byte

stampa 1 per vero e 0 per falso

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) è quindi 5 byte più breve in_array($i,[8,13,18,23])

112 byte

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

113 byte

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

0

Java, 172 byte 168 byte (Thanks Wheat Wizard)

Un po 'economico da quando ho usato java.util.UUID, ma ecco qui:

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

Versione non golfata:

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

Benvenuti nel sito! Penso che puoi rimuovere lo spazio tra trye {.
Wheat Wizard

@WheatWizard grazie: D ha anche notato che posso rimuovere il "circa 0 e 1
ryxn

2
Dovresti essere in grado di rimuovere lo spazio tra String[]e a. Inoltre, dovresti essere in grado di sostituire printlncon print.
clismique,

1
Il nome della classe può avere 1 carattere. È possibile utilizzare java.util.UUID.fromStringinvece di importare.
Colpo

0

AWK, 98 byte

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

Basta dividere la linea in corrispondenza di ogni personaggio e verificare se ogni personaggio è una cifra esadecimale e che ci sono trattini nei punti appropriati. strtonumconverte i caratteri non validi in 0. Effettuare il confronto tra 0e m(e il carattere non valido scelto arbitrariamente) richiede passaggi aggiuntivi. Fortunatamente 01è un numero esadecimale valido, ma m1non lo è.

Inizialmente ho scritto due forloop, ma ho salvato 1 byte stringendoli insieme. :)

NOTA: GAWKpuò leggere l'input come numeri esadecimali, ma ciò richiede un'opzione della riga di comando molto lunga.

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.