Verifique se um UUID é válido sem usar expressões regulares

44

Dada uma entrada de sequência, escreva um programa que imprima um valor de verdade para STDOUT ou equivalente se a entrada for um UUID válido, sem usar expressões regulares.

Um UUID válido é

32 dígitos hexadecimais, exibidos em cinco grupos separados por hífens, no formato 8-4-4-4-12, para um total de 36 caracteres (32 caracteres alfanuméricos e quatro hífens).

Fonte

Casos de teste

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)

Regras

  • Expressões regulares não são permitidas
  • Correspondência de padrão literal que é como uma regex não é permitida. Por exemplo, usando [0-9a-fA-F]ou outros identificadores hexadecimais (nós chamaremos isso n) e, em seguida, correspondendo nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnou n[8]-n[4]-n[4]-n[4]-n[12]não é permitido
  • A entrada pode ser retirada de STDINou como argumento para uma função
  • A entrada não diferencia maiúsculas de minúsculas
  • É seguro assumir que a entrada não conterá feeds de linha ou novas linhas.
  • A entrada pode conter caracteres ASCII imprimíveis (espaços incluídos)
  • Um valor de verdade deve ser impresso STDOUTou equivalente se a entrada for um uuid válido
  • Um valor de falsey deve ser impresso STDOUTou equivalente se a entrada não for um uuid válido
  • Se estiver usando uma função, em vez de usar STDOUT, a saída pode ser o valor de retorno da função
  • O valor de verdade / falsey não pode ser impresso em STDERR.
  • Aplicam-se brechas padrão
  • Isso é , então o programa mais curto em bytes vence. Boa sorte!

Entre os melhores

Este é um snippet de pilha que gera um placar de líderes e uma visão geral dos vencedores por idioma.

Para garantir que sua resposta seja exibida, inicie sua resposta com um título, usando o seguinte modelo de remarcação

## Language Name, N bytes

Onde N é o tamanho, em bytes, do seu envio

Se você deseja incluir vários números no seu cabeçalho (por exemplo, localizar pontuações antigas ou incluir sinalizadores na contagem de bytes), verifique se a pontuação real é o último número no cabeçalho

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

Jojodmo
fonte
32
Pobre Retina . D:
BrainSteel
Relacionado
FryAmTheEggman
8
Apenas para referência, posso criar uma solução Retina de 28 bytes. (Portanto, não uma vantagem loucas sobre as línguas de golfe embora pudesse ser actualmente líder.)
Martin Ender
5
Os padrões de Lua são permitidos? Certamente não são expressões regulares.
manatwork
1
@JacobKrall Tenho certeza de que é "falso" para todas as suas perguntas. Eu acho que o desafio é bastante claro de que apenas as strings do formulário \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(onde \hé um dígito hexadecimal) são válidas.
Martin Ender

Respostas:

15

CJam, 31 30 29 bytes

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

Execute todos os casos de teste aqui.

Explicação

Em vez de o padrão corresponder diretamente à entrada, primeiro a transformamos em um formato mais simples, que pode ser facilmente comparado a uma única sequência de padrões.

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.
Martin Ender
fonte
23

JavaScript ES6, 73 55 56 caracteres

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

A versão anterior de 55 caracteres tem um problema com espaços à direita no grupo:

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

Teste:

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))
Qwertiy
fonte
Incrível (e minguante) +1
edc65
@ edc65, o que você quer dizer com "definhar"?
Qwertiy
Abuso impressionante de elenco implícito +1
Downgoat 14/12/15
4
desprezo, desdém, mordaz, ardor, devastando, humilhante, mortificando - (comparando a sua resposta para o meu)
edc65
11

PowerShell, 29 21 84 49 37 bytes

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

Muito obrigado às pessoas nos comentários que auxiliam neste golfe para acompanhar as novas regras - TessellatingHeckler , iFreilicht , Jacob Krall e Joey . Consulte o histórico de edições para obter revisões e versões mais antigas.

Esta revisão recebe entrada como $g, em seguida, cria uma nova tabela de hash @{}com um elemento, o índice 36é definido igual a $g-as[guid]. Isso usa o -asoperador interno para tentar a conversão entre dois tipos de dados .NET - de [string]para [guid]. Se a conversão for bem-sucedida, um [guid]objeto será retornado, e mais $nullserá retornado. Esta parte garante que a sequência de entrada seja um .NET GUID válido.

O próximo passo é indexar na tabela de hash com [$g.length]. Se $gnão tiver exatamente 36 caracteres, a tabela de hash retornará $null, que será exibida como um valor falsey. Se $gtiver 36 caracteres, o resultado da chamada do .NET será gerado. Se $gnão for um GUID .NET válido (de qualquer forma), será $nullexibido como um valor falsey. Caso contrário, ele produzirá um objeto GUID do .NET como um valor verdadeiro - a única maneira de gerar esse resultado é se ele corresponder ao formato solicitado do desafio.

Exemplos

Aqui estou encapsulando a chamada de script em parens e explicitamente lançando como um booleano para maior clareza.

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
AdmBorkBork
fonte
4
Vou jogar !!($args[0]-as[guid])com 21 bytes.
usar o seguinte
2
Você não poderia simplesmente salvar 4 bytes deixando de fora o !!()? Como os valores $NULLe [guid]são mutuamente exclusivos, eles se qualificam para representar valores verdadeiros e falsos, não é? Enfim, ótima maneira de converter para booleano, adore a solução!
IFreilicht
@iFreilicht esse é um ponto; olhando para o post "interpretação verdade / falsey" vinculado - eu concordo que parece válido.
usar o seguinte
1
Esta solução incorretamente retorna Truepara 0FCE98AC13264C798EBC94908DA8B034, que não tem hífens
Jacob Krall
1
@TessellatingHeckler Não, bom demais para ser verdade. Acrescentar um dígito, como 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(D extra no final), retorna falsey $TRUE, pois apenas apara o dígito ofensivo e os 36 primeiros caracteres são válidos.
AdmBorkBork
9

Emacs Lisp, 236 bytes

(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
Lord Yuuma
fonte
8

Devido a alterações nas regras , esta resposta não é mais 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 bastante auto-explicativo. O %nespecificador de formato fornece o número de bytes lidos até agora, que deve ser 36. scanf()retorna o número de itens correspondentes, que devem ser 6. A final %cnão deve corresponder a nada. Se isso acontecer, haverá um texto à direita e scanf()retornará 7.

Compile com -wpara suprimir os avisos traquinas (existem vários).

Trauma Digital
fonte
6

JavaScript ES6, 70 83

NOTA thx para @Qwertiy por encontrar um erro (e sugerir algumas melhorias e correções)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ 2 bytes salvos

Outros 9 bytes salvos simplificando a verificação de comprimento (a maneira complexa foi mais curta no primeiro rascunho, mas não agora)

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

Explicado

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
)

Snippet de teste

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>

edc65
fonte
-1-('0x'+h)=>1/('0x'+h)
Qwertiy
Mesmo problema que na minha versão anterior: verdadeiro para00000000-0000-0000-000 -000000000000
Qwertiy
Não. Mas você adicionou um teste errado. O espaço à esquerda não é um problema, mas o à direita é, pois uma string é aparada ao converter para número. Veja meu comentário acima com um teste.
Qwertiy
'00000000-0000-0000-000 -000000000000' agora vejo @ Qwertiy perdi os 3 zeros em vez de 4
edc65
1
@Stefnotch eu não concordo. Fora da everychamada uhá uma string, não uma matriz
edc65
5

Devido a alterações nas regras , esta resposta não é mais competitiva :(

Pure Bash (sem utilitários externos), 78

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

Recebe entrada da linha de comando.

  • O printfcria a seguinte seqüência de caracteres - - - -.
  • A p=linha transforma este com o seguinte padrão: [[: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:]]. Observe que isso se parece muito com uma expressão regular. No entanto, não é neste contexto. É um padrão para correspondência de padrões de shell . O conceito é semelhante a uma expressão regular, mas é uma construção (e sintaxe) diferente.
  • A última linha verifica se
    • a entrada não está vazia
    • se puxar o padrão para fora da sequência de entrada produz uma sequência vazia

Idiomatic to shell, um código de retorno 0 indica sucesso / VERDADEIRO e 1 indica falha / FALSO. O código de retorno pode ser inspecionado echo $?após a execução do script.

Trauma Digital
fonte
1
A correspondência do padrão de shell pode não seguir a sintaxe do regex, mas a classe de caracteres definitivamente usa a definição e a sintaxe do regex POSIX. De qualquer forma, cabe ao OP decidir se é aceitável.
N
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d expressions Expressões regulares podem incluir classes de caracteres Posix, mas não creio que isso implique que qualquer coisa que use uma classe de caracteres Posix seja uma expressão regular. Como outro exemplo, trtambém usa classes de caracteres Posix, mas não é um analisador de expressões regulares.
Digital Trauma
Você pode cortar alguns caracteres evitando aspas duplas inúteis, por exemplo, no formato printf.
Jens
Eu atualizei o desafio para esclarecer - a razão expressões regulares foram recusadas foi para torná-lo tão padrões hexagonais não poderia ser usado para UUIDs jogo
Jojodmo
4

Jolf, 32 bytes

Experimente aqui!

 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

Devido a um erro no meu código, isso é mais longo do que deveria. :( [8,4,4,4,12] deve ser o mesmo que {8444*26}, mas }também é o fechamento de uma função: P

Conor O'Brien
fonte
2
Portanto, é mais longo do que o necessário, porque você possui comandos ambíguos no idioma que criou? : P
Rɪᴋᴇʀ
@RikerW Menor erro semântico. Está consertado agora.
Conor O'Brien
4

MATL , 55 bytes

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

Abstive-me de usar a Ybfunção ( strsplit) porque é um pouco semelhante a regexp(..., 'split'). Isso usa apenas indexação e comparações de caracteres.

Exemplo

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

Explicação

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
Luis Mendo
fonte
3

CJam, 52 42 bytes

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

Experimente online . Emite a string original, se true, em branco, se false ( isso é permitido ).

Explicação:

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)
GamrCorps
fonte
A7*)<não removerá muitos caracteres inválidos, como espaços +, ?...
Martin Ender
@ MartinBüttner oh dispara ... Eu não percebi isso, vou consertar em alguns minutos.
GamrCorps
3

Julia, 86 bytes

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

Esta é uma função anônima que aceita uma string e retorna um booleano. Para chamá-lo, dê um nome, por exemplof=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
Alex A.
fonte
3

Bytes em C # 196

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

O método Tpode ser chamado com qualquer sequência não nula e retornará truepara GUIDs válidos, falsecaso contrário. Esta é uma validação em tempo constante; ao custo de três caracteres, você pode sair antecipadamente do método (alterari < v.Length parai < v.Length && r ).

Tentará diminuir o número de bytes mais tarde.

Obviamente, deixei de lado o Guid.ParseExactcaminho, porque é que está divertido nisso? Aqui está, sem muita tentativa de avançar ainda mais em 86 bytes :

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);
    }
}
RobIII
fonte
2

Python 2, 99 112 bytes

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

Em uma entrada válida, ele imprime True . Em uma entrada inválida, ela é impressa Falseou 0, dependendo do motivo da invalidez. Falsee0 são ambos falsey em Python.

A função tem que verificar 3 coisas:

  • Todo caractere que não seja hífen é um dígito ou está em ABCDEF
  • Existem exatamente 4 hífens
  • Existem 8 caracteres antes do primeiro hífen, 12 após o último e 4 entre outros dois

Aqui está um detalhamento para mostrar como ele os verifica. Está um pouco desatualizado, mas estou com fome, por isso vou atualizá-lo mais tarde.

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.
undergroundmonorail
fonte
Eu acho que você pode salvar 2 bytes se você substituir as duas instâncias de returncom print. (Caso em que você definitivamente vai querer estar em Python 2, porque printfunciona de maneira diferente em Python 3.)
mathmandan
1
Isso não funciona no Python 3, porque mapagora retorna um "objeto de mapa", não uma lista.
Tim Pederick
Isso não funciona no python 2 (provavelmente também 3) porque a intfunção permite espaços - 0FCE98ac-1326-4c79-8EBC-94908da8B03com um espaço à direita. Veja o comentário na resposta Pyth excluída aqui, se possível.
Azul
2

Python 2, 57 bytes

Graças a Deus por embutido! - inclua cadeias entre aspas.

import uuid
try:uuid.UUID(input());print 1
except:print 0
nimi
fonte
5
De acordo com os documentos aos quais você vinculou, isso seria impresso 1para entrada 12345678123456781234567812345678.
Dennis
se isso funcionou você seria capaz de salvar bytes fazendo try:print uuid.UUID(input())porque tudo o que é necessário é que você imprima um valor truthy
undergroundmonorail
2
Este programa aceita muitos formatos UUID, mas a questão deseja apenas o formato UUID de 36 caracteres, com hífens.
Jacob Krall
2
Você pode salvar isso, lidando com as regras atualizadas, verificando se a sequência de entrada é igual ao uuid convertido novamente em sequência. Dá a você um valor verdadeiro imediatamente.
agtoever
2

Pitão, 39 bytes

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

Experimente aqui .

Azul
fonte
O link "experimente aqui" não contém o \caractere K\-k, por isso ele não é executado como está.
Alex
Isso foi corrigido agora
Blue
2

Perl 6 ,  83   67 bytes

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

(as contagens não incluem novas linhas ou recuos, pois não são necessárias)

uso:

# 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)
Brad Gilbert b2gills
fonte
2

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

O valor retornado se true for o hash, como um número, que é um resultado útil a ter.

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))))
coredump
fonte
@Jojodmo Sim, definitivamente! Obrigado
coredump
2

F # 44 caracteres

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

Em F #, funções com out parâmetros podem ser chamadas omitindo o parâmetro out; seu valor no retorno será combinado com o verdadeiro valor de retorno da função em uma tupla.

Aqui, a tupla é canalizada para o fst função, que retorna seu primeiro membro, que nesse caso é o valor de retorno booleano de TryParseExact, indicando o sucesso ou falha da chamada.

Como verificação do formato correto, retornamos true apenas se a sequência tiver 36 caracteres.

Antes de ver a resposta em C # do RobIII, eu não tinha pensado em usar o TryParseExact, então minha resposta foi ter três caracteres a mais:

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

TryParse(string, Guid) aceita entrada nos seguintes formatos:

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

Destes, apenas o segundo tem 36 caracteres.

phoog
fonte
2

Python 2, 93 89 85 bytes

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

A map()chamada garante que as seções tenham o comprimento correto e all()testa cada caractere como sendo um hífen ou um dígito hexadecimal de caso arbitrário. A expressão do gerador está testando cada caractere iterando toda a cadeia, portanto, não é o método mais eficiente, receio, mas deve satisfazer os casos de teste:

>>> 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
>>> 
rsandwick3
fonte
Alguém tem alguma idéia de por que a resposta mais curta e correta do Python foi reduzida? Não há explicação suficiente?
rsandwick3
Jojodmo - caso houvesse confusão sobre isso, eu não rejeitei sua alteração proposta - eu já havia feito uma edição porque havia perdido os caracteres AF (copiei de uma janela onde estava testando casos negativos) e o Community auto - rejeitou sua proposta sem que eu soubesse que ela havia sido levantada. Quando soube que você tinha proposto, o @nimi já havia feito a correção no cabeçalho. Espero muito que isso não tenha nada a ver com o voto negativo, pois isso refletiria muito mal nesta comunidade. Enfim, eu vou assumir que é a outra coisa, e adicionar um pouco mais de explicação.
rsandwick3
2
Você pode remover os f=espaços ao redor da cadeia no allbloco.
FryAmTheEggman
oh impressionante, agradável catch - editados
rsandwick3
1
Você pode salvar 8 (ou 6, você pode precisar adicionar parêntese) bytes através da conversão de seu all(..)para definir testes inclusão: 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;

Na verdade, usa stdin e stdout - um dos recursos menos conhecidos desse idioma em particular. Trabalhos para os exemplos dados até agora, mas possivelmente não em todos os casos. Provavelmente pode ser melhorado.

Melhor abordagem - um personagem de cada vez:

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;

Golfou outros 6 caracteres fora da expressão central!

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;

Isso gera alguns avisos e notas no log, mas não os imprime em stdout ou stderr, então acho que este é um jogo justo.

user3490
fonte
1

C, 391 bytes

#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;}
user2064000
fonte
1

MATLAB, 126 bytes

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
costrom
fonte
1

Python 3, 134 bytes

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 converter k em uma base 16 int. Em um caractere diferente de 0-9a-fA-F-, ele falha; nesse caso, retornamos 0, o que é falso. Adicione 1 a esse int e obteremos um valor de verdade garantido - removemos todos os hífens com str.split () para que não possamos obter o valor -1 e todos os ints diferentes de 0 são verdadeiros.

Pjoelj
fonte
1

Função C, 102

Uma mudança de regra não permitiu minha scanf()resposta anterior baseada em c , então aqui está outra resposta c usando a isxdigit()qual acho que deveria poder competir :

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

Experimente online.

  • Verificar se há - caracteres (ASCII 45) nas posições relevantes - se houver, substitua-os por 0s (ASCII 48 (= 45 + 3))
  • Ande pela corda verificando cada caractere com isxdigit()
  • Retorne TRUE se o comprimento da string for 36 e o ​​caractere final for NUL.
Trauma Digital
fonte
1

Lote, 148 139 + 2 = 150 141 bytes

@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

Adicionado 2 bytes porque você precisa usar o /vswitch para CMD.EXE.

Sai com ERRORLEVEL 0 em caso de sucesso, 1 em caso de falha.

Editar: salvou alguns bytes principalmente porque não :=diferencia maiúsculas de minúsculas, mas também houve outros ajustes.

Neil
fonte
1

Java, 345 bytes

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

A entrada é o primeiro argumento da linha de comandos. Saída é código de erro (0 significa UUID válido, 1 significa inválido)

Ungolfed com comentários:

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ão percebeu a parte STDOUT. Opa, corrigido agora.

biscoito
fonte
Agradável! Você pode substituir if(b.length>36||b.length<36)com simplesmente if(b.length!=36). Além disso, como é possível imprimir valores reais , você pode simplesmente imprimir em 0vez de 1<0e em 1vez de 1>0.
Jojodmo
@Jojodmo Com base nos votos, um valor truthy é na forma de if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }Assim, em Java um booleano é um valor truthy, mas 1ou 0não é. Somente quando o OP de um desafio diz algo como: " Sua saída pode ser verdadeiro / falso, 0/1, vazia / não vazia; contanto que você especifique o que você usa. ", Então você pode realmente usar 0e 1, em vez de true/falsecomo truthy / valor de falsey.
Kevin Cruijssen
1
Quanto às dicas de golfe para o cookie: @Jojodmo está realmente certo em substituí-lo if(b.length!=36); ||pode estar |em vários lugares, bem como &&para &; if(...!='-')pode ser if(...!=45); int i=-1; ... while(++i<b.length){pode ser substituído por for(int i=-1;++i<b.length;){; 'F'pode ser 70( 'f'poderia ser 102, mas isso não importa, pois é a mesma contagem de bytes). Eu gosto de como você usou java.io.PrintStream u=System.out;btw, eu devo lembrar disso! Então obrigado.
Kevin Cruijssen
1

Swift 3, 50 bytes

Passar em uma string s

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

PHP, 109 bytes

imprime 1 para verdadeiro e 0 para 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) é 5 bytes mais curto que o in_array($i,[8,13,18,23])

112 bytes

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

113 bytes

echo array_diff(str_split(strtolower($argn)),array_map(dechex,range(0,15)))==[8=>"-",13=>"-",18=>"-",23=>"-"]?:0;
Jörg Hülsermann
fonte
0

Java, 172 bytes 168 bytes (Thanks Wheat Wizard)

Meio barato desde que eu usei java.util.UUID, mas aqui vai:

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

Versão não destruída:

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);}
    }
}
ryxn
fonte
Bem vindo ao site! Eu acho que você pode remover o espaço entre trye {.
Assistente de trigo
@WheatWizard obrigado: D também notou que posso remover o "em torno de 0 e 1
ryxn
2
Você deve poder remover o espaço entre String[]e a. Além disso, você poderá substituir printlnpor print.
Clismique
1
O nome da classe pode ter 1 caractere. Você pode usar em java.util.UUID.fromStringvez de importar.
Puxão
0

AWK, 98 bytes

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

Simplesmente divide a linha em cada caractere e verifica se cada caractere é um dígito hexadecimal e se há hífens nos locais apropriados. strtonumconverte caracteres inválidos em 0. Fazer a comparação entre 0e m(e caractere inválido escolhido arbitrariamente) requer etapas adicionais. Felizmente, 01é um número hexadecimal válido, masm1 não é.

Inicialmente, escrevi dois forloops, mas economizei 1 byte pressionando-os. :)

NOTA: GAWKpode ler a entrada como números hexadecimais, mas isso requer uma opção de linha de comando muito longa.

Robert Benson
fonte