Verifique si un UUID es válido sin usar expresiones regulares


44

Dada una entrada de cadena, escriba un programa que imprima un valor verdadero en STDOUT o equivalente si la entrada es un UUID válido, sin usar expresiones regulares.

Un UUID válido es

32 dígitos hexadecimales, mostrados en cinco grupos separados por guiones, en la forma 8-4-4-4-12 para un total de 36 caracteres (32 caracteres alfanuméricos y cuatro guiones).

Fuente

Casos de prueba

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)

Reglas

  • No se permiten expresiones regulares.
  • La coincidencia de patrones literales que es como una expresión regular no está permitida. Por ejemplo, usar [0-9a-fA-F]u otros identificadores hexadecimales (lo llamaremos n) y luego hacer coincidir nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnno n[8]-n[4]-n[4]-n[4]-n[12]no está permitido
  • La entrada puede tomarse STDINo como argumento de una función
  • La entrada no distingue entre mayúsculas y minúsculas
  • Es seguro asumir que la entrada no contendrá saltos de línea o saltos de línea.
  • La entrada puede contener caracteres ASCII imprimibles (espacios incluidos)
  • Se debe imprimir un valor verdaderoSTDOUT o equivalente si la entrada es un uid válido
  • Se debe imprimir un valor de falseySTDOUT o equivalente si la entrada no es un uuid válido
  • Si usa una función, en lugar de usar STDOUT, la salida puede ser el valor de retorno de la función
  • No se puede imprimir el valor verdadero / falso STDERR.
  • Se aplican lagunas estándar
  • Este es el , por lo que gana el programa más corto en bytes. ¡Buena suerte!

Tabla de clasificación

Este es un fragmento de pila que genera una tabla de clasificación y una descripción general de los ganadores por idioma.

Para asegurarse de que su respuesta se muestre, comience con un título usando la siguiente plantilla de Markdown

## Language Name, N bytes

Donde N es el tamaño, en bytes, de su envío

Si desea incluir varios números en su encabezado (por ejemplo, tachar los puntajes antiguos o incluir marcas en el recuento de bytes), solo asegúrese de que el puntaje real sea el último número en su encabezado

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


32
Pobre retina . D:
BrainSteel


8
Solo como referencia, puedo encontrar una solución de Retina de 28 bytes. (Así que no es una gran ventaja sobre los idiomas de golf, aunque actualmente sería líder).
Martin Ender

55
¿Están permitidos los patrones de Lua ? Ciertamente no son expresiones regulares.
manatwork

1
@JacobKrall Estoy bastante seguro de que es "falso" para todas sus preguntas. Creo que el desafío es bastante claro: solo las cadenas de la forma \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(donde \hes un dígito hexadecimal) son válidas.
Martin Ender

Respuestas:


15

CJam, 31 30 29 bytes

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

Ejecute todos los casos de prueba aquí.

Explicación

En lugar de que el patrón coincida con la entrada directamente, primero lo estamos transformando en una forma más simple que se pueda comparar fácilmente con una sola cadena de patrón.

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 caracteres

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

La versión anterior de 55 caracteres tiene un problema con los espacios finales en el grupo:

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

Prueba:

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

Impresionante (y fulminante para mí) +1
edc65

@ edc65, ¿qué quieres decir con "marchitarse"?
Qwertiy

Abuso impresionante de casting implícito +1
Downgoat

44
desdeñoso, despectivo, mordaz, punzante, devastador, humillante, mortificante - (comparando su respuesta con la mía)
edc65

11

PowerShell, 29 21 84 49 37 Bytes

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

Muchas gracias a la gente en los comentarios que ayudaron con este golf para mantenerse al día con las reglas cambiantes: TessellatingHeckler , iFreilicht , Jacob Krall y Joey . Consulte el historial de edición para revisiones y versiones anteriores.

Esta revisión toma datos como $g, luego crea una nueva tabla hash @{}con un elemento, el índice 36se establece igual a $g-as[guid]. Esto utiliza el -asoperador incorporado para intentar la conversión entre dos tipos de datos .NET: de [string]a [guid]. Si la conversión es exitosa, [guid]se devuelve un objeto, de lo contrario $nullse devuelve. Esta parte garantiza que la cadena de entrada sea un GUID .NET válido.

El siguiente paso es indexar en la tabla hash con [$g.length]. Si $gno tiene exactamente 36 caracteres de longitud, se devolverá la tabla hash $null, que se mostrará como un valor falsey. Si $gtiene 36 caracteres de longitud, se generará el resultado de la llamada .NET. Si $gno es un GUID .NET válido (en cualquier forma), se generará $nullcomo un valor falsey. De lo contrario, generará un objeto GUID .NET como un valor verdadero; la única forma en que se puede generar es si coincide con el formato solicitado del desafío.

Ejemplos

Aquí estoy encapsulando la llamada del script en parens y explícitamente como Boolean para mayor claridad.

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

44
Voy a tirar !!($args[0]-as[guid])a los 21 bytes.
TessellatingHeckler

2
¿No podrías simplemente guardar 4 bytes dejando de lado el !!()? Como los valores $NULLy [guid]son mutuamente excluyentes, califican para representar los valores de verdad y falsey, ¿no? De todos modos, una excelente manera de convertir a booleano, ¡me encanta la solución!
iFreilicht

@iFreilicht que es un punto; mirando la publicación vinculada de "interpretación de la verdad / falsey", estoy de acuerdo en que parece válida.
TessellatingHeckler

1
Esta solución devuelve incorrectamente Truepara 0FCE98AC13264C798EBC94908DA8B034, que no tiene guiones
Jacob Krall

1
@TessellatingHeckler No, demasiado bueno para ser verdad. Agregar un dígito, como 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(D adicional al final) devuelve falsey $TRUE, ya que solo recorta el dígito ofensor y los primeros 36 caracteres son 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))))))

Sin golf:

(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

Debido a cambios en las reglas , esta respuesta ya no es 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);}

Mayormente bastante autoexplicativo. El %nespecificador de formato proporciona el número de bytes leídos hasta ahora, que debería ser 36. scanf()devuelve el número de elementos coincidentes, que debería ser 6. El final %cno debe coincidir con nada. Si lo hace, entonces hay texto final y scanf()devolverá 7.

Compile -wpara suprimir las molestas advertencias (hay varias).


6

JavaScript ES6, 70 83

NOTA gracias a @Qwertiy para encontrar un error (y sugerir algunas mejoras y correcciones)

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

Otros 9 bytes guardados simplificando la verificación de longitud (la forma compleja fue más corta en el primer borrador, pero no ahora)

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
)

Fragmento de prueba

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

Mismo problema que en mi versión anterior: cierto para00000000-0000-0000-000 -000000000000
Qwertiy

No. Pero agregaste una prueba incorrecta. El espacio inicial no es un problema, pero el final sí lo es, ya que se recorta una cadena cuando se convierte en número. Vea mi comentario arriba con una prueba.
Qwertiy

'00000000-0000-0000-000 -000000000000' ahora lo veo @Qwertiy Perdí los 3 ceros en lugar de 4
edc65

1
@ Stefnotch no estoy de acuerdo. Fuera de la everyllamada uhay una cadena, no una matriz
edc65

5

Debido a cambios en las reglas , esta respuesta ya no es competitiva :(

Pure Bash (sin utilidades externas), 78

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

Toma información de la línea de comando.

  • El printfconstruye la siguiente cadena - - - -.
  • La p=línea transforma esta a la siguiente distribución: [[: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:]]. Tenga en cuenta que esto se parece mucho a una expresión regular. Sin embargo, no es en este contexto. Es un patrón para la coincidencia de patrones de shell . Esto es similar en concepto a una expresión regular, pero es una construcción diferente (y sintaxis).
  • La última línea verifica si
    • la entrada no está vacía
    • si sacar el patrón de la cadena de entrada produce una cadena vacía

Idiomático para shell, un código de retorno de 0 indica éxito / VERDADERO y 1 indica falla / FALSO. Se puede inspeccionar el código de retorno echo $?después de ejecutar el script.


1
La coincidencia del patrón de shell puede no seguir la sintaxis de la expresión regular, pero la clase de caracteres definitivamente usa la definición y la sintaxis de la expresión regular POSIX. De todos modos, depende de OP decidir si es aceptable.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Las expresiones regulares pueden incluir clases de caracteres Posix, pero no creo que eso implique que cualquier cosa que use una clase de caracteres Posix es una expresión regular. Como otro ejemplo trtambién usa clases de caracteres Posix, pero no es un analizador de expresiones regulares.
Trauma digital

Puede eliminar algunos caracteres evitando las comillas dobles inútiles, por ejemplo, en el formato printf.
Jens

He actualizado el desafío para aclararlo: la razón por la que se rechazaron las expresiones regulares fue para que los patrones hexadecimales no se pudieran usar para que coincidan con los líquidos
Jojodmo

4

Jolf, 32 bytes

Pruébalo aquí!

 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

Debido a un error en mi código, esto es más largo de lo que debería ser. :( [8,4,4,4,12] debería ser igual que {8444*26}, pero }también es el cierre de una función: P


2
¿Entonces es más largo de lo que tiene que ser porque tiene comandos ambiguos en el idioma que creó? : P
Rɪᴋᴇʀ

@RikerW Error semántico menor. Ya está arreglado.
Conor O'Brien

4

MATL , 55 bytes

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

Me abstuve de usar la Ybfunción ( strsplit) porque es algo similar a regexp(..., 'split'). Esto solo usa indexación y comparaciones de caracteres.

Ejemplo

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

Explicación

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 bytes

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

Pruébalo en línea . Emite la cadena original si es verdadera, emite una cadena vacía si es falsa ( esto está permitido ).

Explicación:

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*)<no eliminará muchos caracteres no válidos, como espacios +, ?...
Martin Ender

@ MartinBüttner oh, dispara ... No me di cuenta de eso, lo arreglaré en unos 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 es una función anónima que acepta una cadena y devuelve un valor booleano. Para llamarlo, dale un nombre, por ejemplo f=s->....

Sin golf:

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 bytes

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

Sin golf:

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

El método Tse puede invocar con cualquier cadena no nula y true, de lo falsecontrario , devolverá los GUID válidos . Esta es una validación de tiempo constante; a costa de tres caracteres, puede salir anticipadamente del método (cambiar i < v.Lengtha i < v.Length && r).

Intentará bajar el bytecount más tarde.

Obviamente, he dejado de Guid.ParseExactlado porque ¿dónde está la diversión en eso? Aquí está, sin mucho intento de reducirlo aún más en 86 bytes :

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

Sin golf:

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

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

En una entrada válida, se imprime True. En una entrada no válida, se imprime Falseo 0, dependiendo de por qué no fue válida. Falsey 0ambos son falsey en Python.

La función tiene que verificar 3 cosas:

  • Cada carácter sin guión es un dígito o está en ABCDEF
  • Hay exactamente 4 guiones
  • Hay 8 caracteres antes del primer guión, 12 después del último y 4 entre cualquier otro dos

Aquí hay un desglose para mostrar cómo los verifica. Está un poco desactualizado pero tengo hambre, así que lo actualizaré más 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.

Supongo que puede guardar 2 bytes si reemplaza ambas instancias de returncon print. (En cuyo caso definitivamente querrás estar en Python 2, porque printfunciona de manera diferente en Python 3.)
Mathmandan

1
Esto no funciona en Python 3, porque mapahora devuelve un "objeto de mapa", no una lista.
Tim Pederick

Esto no funciona en python 2 (probablemente también en 3) porque la intfunción permite espacios, 0FCE98ac-1326-4c79-8EBC-94908da8B03con un espacio final. Vea el comentario en la respuesta eliminada de Pyth aquí si puede.
Azul

2

Python 2, 57 bytes

Gracias a Dios por incorporado! - asegúrese de incluir cadenas entre comillas.

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

55
Según los documentos a los que se vinculó, eso se imprimiría 1para la entrada 12345678123456781234567812345678.
Dennis

si esto funcionara, podría guardar bytes haciendo try:print uuid.UUID(input())porque todo lo que se requiere es imprimir un valor verdadero
undergroundmonorail

2
Este programa acepta muchos formatos UUID, pero la pregunta solo quiere el formato UUID de 36 caracteres, con guiones.
Jacob Krall

2
Puede salvar esto, haciendo frente a las reglas actualizadas, verificando si la cadena de entrada es igual al uuid convertido de nuevo a cadena. Le da un valor verdadero de inmediato.
agtoever

2

Pyth, 39 bytes

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

Pruébalo aquí .


Al enlace "Pruébelo aquí" le falta el \carácter K\-k, por lo que no puede ejecutarse tal cual.
Alex

Eso se ha solucionado ahora
Azul

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

(los recuentos no incluyen nuevas líneas o sangrías ya que no son necesarios)

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)

2

Lisp común - 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))))

El valor devuelto si es verdadero es el hash, como un número, que es un resultado útil para tener.

Sin golf

(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í, definitivamente! Gracias
coredump

2

F # 44 caracteres

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

En F #, outse pueden invocar funciones con parámetros omitiendo el parámetro out; su valor en el retorno se combinará con el verdadero valor de retorno de la función en una tupla.

Aquí, la tupla se canaliza a la fstfunción, que devuelve su primer miembro, que en este caso es el valor de retorno booleano de TryParseExact, que indica el éxito o el fracaso de la llamada.

Como comprobación del formato correcto, truesolo devolvemos si la cadena tiene 36 caracteres.

Antes de ver la respuesta C # de RobIII, no había pensado en usar TryParseExact, por lo que mi respuesta fue tener tres caracteres más:

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

TryParse(string, Guid) acepta entradas en los siguientes 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}}

De estos, solo el segundo tiene 36 caracteres de longitud.


2

Python 2, 93 89 85 bytes

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

La map()llamada garantiza que las secciones tienen las longitudes correctas y all()prueba que cada carácter sea un guión o un dígito hexadecimal de caso arbitrario. La expresión del generador está probando cada carácter iterando a través de toda la cadena, por lo que no es el método más eficaz, me temo, pero debería satisfacer los casos de prueba:

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

¿Alguien tiene alguna idea de por qué se ha rechazado la respuesta correcta más corta de Python? ¿No hay suficiente explicación?
rsandwick3

Jojodmo: en caso de que hubiera confusión sobre esto, no rechacé el cambio propuesto, ya había realizado una edición porque había perdido los caracteres AF (copié desde una ventana donde estaba probando casos negativos) y Community auto -rechazó su propuesta sin que yo supiera que incluso se había planteado. Cuando supe que lo había propuesto, @nimi ya había corregido el encabezado. Espero mucho que eso no tenga nada que ver con el voto negativo, ya que eso se reflejaría muy mal en esta comunidad. De todos modos, asumiré que es la otra cosa, y agregaré un poco más de explicación.
rsandwick3

2
Puede eliminar los f=espacios y alrededor de la cadena en el allbloque.
FryAmTheEggman

oh impresionante, buena captura - editado
rsandwick3

1
Puede guardar 8 (o 6, puede ser necesario añadir entre paréntesis) de bytes mediante la conversión de su all(..)para establecer las pruebas de inclusión: 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;

En realidad, usa stdin y stdout, una de las características menos conocidas de este lenguaje en particular. Funciona para los ejemplos dados hasta ahora, pero posiblemente no en todos los casos. Probablemente se puede mejorar.

Mejor enfoque: un personaje a la 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;

¡Golfó otros 6 caracteres de la expresión central!

Sin golf:

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;

Esto genera bastantes advertencias y notas en el registro, pero no las imprime en stdout o stderr, así que creo que este es un juego justo.


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

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

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) intenta convertir k en una base-16 int. En un carácter distinto de 0-9a-fA-F- falla, en cuyo caso devolvemos 0, que es falso. Agregue 1 a ese int y obtenemos un valor de verdad garantizado: hemos eliminado todos los guiones con str.split (), por lo que no podemos obtener el valor -1 y todas las entradas que no son 0 son verdaderas.


1

Función C, 102

Un cambio de regla rechazó mi scanf()respuesta anterior basada en c , así que aquí hay otra respuesta c con la isxdigit()que creo que debería permitirse 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];}

Pruébalo en línea.

  • Verifique los -caracteres (ASCII 45) en las posiciones relevantes; de ser así, reemplácelos con 0s (ASCII 48 (= 45 + 3))
  • Recorre la cuerda comprobando cada carácter con isxdigit()
  • Devuelve VERDADERO si la longitud de la cadena es 36 y el carácter final es NUL.

1

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

Se agregaron 2 bytes porque necesita usar el /vinterruptor para CMD.EXE.

Sale con ERRORLEVEL 0 en caso de éxito, 1 en caso de error.

Editar: guardé algunos bytes principalmente porque no :=distingue entre mayúsculas y minúsculas, pero también hubo otros ajustes.


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

La entrada es el primer argumento de línea de comando. La salida es un código de error (0 significa UUID válido, 1 significa no válido)

Ungolfed con comentarios:

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

EDITAR: No noté la parte STDOUT. Vaya, arreglado ahora.


¡Agradable! Se puede reemplazar if(b.length>36||b.length<36)con simplemente if(b.length!=36). Además, debido a que puede imprimir valores verdaderos , simplemente podría imprimir en 0lugar de 1<0y en 1lugar de 1>0.
Jojodmo

@Jojodmo base a los votos, un valor de verdad tiene la forma de if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }Entonces, en Java, un valor booleano es un valor de verdad, pero 1o 0no lo es. Solo cuando el OP de un desafío dice algo como: " Su resultado puede ser verdadero / falso, 0/1, vacío / no vacío; siempre y cuando especifique lo que usa ", entonces puede usarlo 0y 1no true/falseserlo como verdadero / valor de falsey.
Kevin Cruijssen

1
En cuanto a los consejos de golf para las cookies: @Jojodmo tiene razón al reemplazarlo por if(b.length!=36); ||puede estar |en múltiples lugares, así como &&a &; if(...!='-')puede ser if(...!=45); int i=-1; ... while(++i<b.length){puede ser reemplazado confor(int i=-1;++i<b.length;){ ; 'F'puede ser 70( 'f'podría ser 102, pero eso no importa ya que es el mismo número de bytes). Me gusta cómo has usado por java.io.PrintStream u=System.out;cierto, ¡debería recordar eso! Así que gracias.
Kevin Cruijssen

1

Swift 3, 50 bytes

Pase en una cuerda s

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

1

PHP, 109 bytes

imprime 1 para verdadero y 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) es 5 bytes más corto que 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;

0

Java, 172 bytes 168 bytes (Gracias Asistente de trigo)

Un poco engañoso ya que usé java.util.UUID, pero aquí va:

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

Versión sin golf:

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

Bienvenido al sitio! Creo que puedes eliminar el espacio entre tryy {.
Wheat Wizard

@WheatWizard gracias: D también notó que puedo eliminar el "alrededor de 0 y 1
ryxn

2
Debería poder eliminar el espacio entre String[]y a. Además, debe poder reemplazar printlncon print.
clismique

1
El nombre de la clase puede tener 1 carácter. Puede usar en java.util.UUID.fromStringlugar de importar.
Poke

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

Simplemente divide la línea en cada carácter y verifica si cada carácter es un dígito hexadecimal y si hay guiones en los lugares apropiados. strtonumconvierte caracteres inválidos a 0. Hacer la comparación entre 0y m(y caracteres inválidos elegidos arbitrariamente) requiere pasos adicionales. Afortunadamente 01es un número hexadecimal válido, perom1 no lo es.

Inicialmente escribí dos for bucles, pero ahorré 1 byte al juntarlos. :)

NOTA: GAWKpuede leer la entrada como números hexadecimales, pero esto requiere una opción de línea de comando muy larga.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.