Sprawdź, czy identyfikator UUID jest prawidłowy bez użycia wyrażeń regularnych

44

Biorąc pod uwagę ciąg wejściowy, napisz program, który wypisuje prawdziwą wartość do STDOUT lub równoważnego, jeśli dane wejściowe są poprawnym UUID, bez użycia wyrażeń regularnych .

Prawidłowy identyfikator UUID to

32 cyfry szesnastkowe, wyświetlane w pięciu grupach oddzielonych łącznikami, w postaci 8-4-4-4-12 dla łącznie 36 znaków (32 znaki alfanumeryczne i cztery łączniki).

Źródło

Przypadki testowe

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)

Zasady

  • Wyrażenia regularne są niedozwolone
  • Dosłowne dopasowanie wzorca, które jest jak wyrażenie regularne, jest niedozwolone. Na przykład używanie [0-9a-fA-F]lub inne identyfikatory szesnastkowe (nazywamy to n), a następnie dopasowanie nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnlub n[8]-n[4]-n[4]-n[4]-n[12]niedozwolone
  • Dane wejściowe mogą być pobierane z funkcji STDINlub jako argument funkcji
  • Dane wejściowe nie uwzględniają wielkości liter
  • Można bezpiecznie założyć, że dane wejściowe nie będą zawierały linii ani nowych linii.
  • Dane wejściowe mogą zawierać dowolne znaki ASCII do wydruku (ze spacjami)
  • Wartość truthy muszą być wydrukowane na STDOUTlub równoważne, jeśli wejście jest prawidłowy UUID
  • Wartość falsey muszą być wydrukowane na STDOUTlub równoważne, jeśli wejście jest nie poprawny UUID
  • Jeśli używasz funkcji, zamiast używać STDOUT, wyjściem może być zwracana wartość funkcji
  • Nie można wydrukować wartości true / falsey STDERR.
  • Standardowe luki zastosowanie
  • To jest , więc wygrywa najkrótszy program w bajtach. Powodzenia!

Tabela liderów

To jest fragment kodu, który generuje zarówno tabelę wyników, jak i przegląd zwycięzców według języka.

Aby mieć pewność, że Twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown

## Language Name, N bytes

Gdzie N jest rozmiarem twojego przesłania w bajtach

Jeśli chcesz dołączyć wiele liczb do nagłówka (na przykład przekreślając stare wyniki lub włączając flagi w liczbie bajtów), po prostu upewnij się, że rzeczywisty wynik jest ostatnią liczbą w nagłówku

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

Jojodmo
źródło
32
Biedna siatkówka . D:
BrainSteel,
Powiązane
FryAmTheEggman
8
Dla porównania mogę wymyślić 28-bajtowe rozwiązanie Retina. (Tak więc nie jest to szalona przewaga nad językami golfowymi, chociaż obecnie byłaby wiodąca.)
Martin Ender
5
Czy wzory Lui są dozwolone? Z pewnością nie są to wyrażenia regularne.
manatwork
1
@JacobKrall Jestem pewien, że to „fałsz” na wszystkie pytania. Myślę, że wyzwanie jest dość jasne, że poprawne są tylko łańcuchy formy \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(gdzie \hjest cyfrą szesnastkową).
Martin Ender

Odpowiedzi:

15

CJam, 31 30 29 bajtów

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

Tutaj uruchom wszystkie przypadki testowe.

Wyjaśnienie

Zamiast wzorca dopasowującego bezpośrednio dane wejściowe, najpierw przekształcamy go w prostszą formę, którą można łatwo porównać z pojedynczym ciągiem wzorca.

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
źródło
23

JavaScript ES6, 73 55 56 znaków

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

Poprzednia wersja 55 znaków miała problem z końcowymi spacjami w grupie:

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))
Qwertiy
źródło
Niesamowite (i miażdżące dla mnie) +1
edc65
@ edc65, co rozumiesz przez „więdnięcie”?
Qwertiy,
Niesamowite nadużywanie niejawnego rzucania +1
Downgoat
4
pogardliwy, pogardliwy, zjadliwy, kłujący, druzgocący, poniżający, upokarzający - (porównując twoją odpowiedź do mojej)
edc65
11

PowerShell, 29 21 84 49 37 bajtów

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

Ogromne podziękowania dla ludzi w komentarzach pomagających w grze w golfa, aby nadążyć za zmieniającymi się zasadami - TessellatingHeckler , iFreilicht , Jacob Krall i Joey . Zobacz historię edycji poprawek i starszych wersji.

Ta wersja pobiera dane wejściowe jako $g, a następnie tworzy nową tabelę skrótów @{}z jednym elementem, indeks 36jest ustawiony na wartość równą $g-as[guid]. To używa wbudowanego -asoperatora do próby konwersji między dwoma typami danych .NET - od [string]do [guid]. Jeśli konwersja zakończy się powodzeniem, [guid]obiekt jest zwracany, w przeciwnym razie $nullzwracany. Ta część zapewnia, że ​​ciąg wejściowy jest prawidłowym identyfikatorem GUID .NET.

Następnym krokiem jest zindeksowanie do tabeli skrótów za pomocą [$g.length]. Jeśli $gdługość nie jest dokładnie 36 znaków, zostanie zwrócona tabela skrótów $null, która zostanie wyprowadzona jako wartość falsey. Jeśli $gma 36 znaków, wynik połączenia .NET zostanie wyprowadzony. Jeśli $gnie jest prawidłowym identyfikatorem GUID .NET (w dowolnej formie), zostanie $nullwygenerowany jako wartość falsey. W przeciwnym razie wygeneruje obiekt .NET GUID jako prawdziwą wartość - jedynym sposobem, który można wygenerować, jest dopasowanie go do żądanego formatu wyzwania.

Przykłady

Tutaj podsumowuję wywołanie skryptu w parens i jawnie rzucam jako logiczny dla jasności.

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
źródło
4
Wrzucę !!($args[0]-as[guid])przy 21 bajtach.
TessellatingHeckler
2
Czy nie możesz po prostu zapisać 4 bajtów, pomijając !!()? Ponieważ wartości $NULLi [guid]wzajemnie się wykluczają, kwalifikują się do reprezentowania wartości prawdy i falseya, prawda? W każdym razie świetny sposób na konwersję na wartość logiczną, pokochaj to rozwiązanie!
iFreilicht,
@ iFreilicht to jest punkt; patrząc na powiązany link „interpretacja prawdy / falseya” - zgadzam się, że wygląda na prawidłowy.
TessellatingHeckler,
1
To rozwiązanie niepoprawnie zwraca wartość, Truedla 0FCE98AC13264C798EBC94908DA8B034której nie ma łączników
Jacob Krall,
1
@TessellatingHeckler Nie, zbyt piękne, aby mogło być prawdziwe. Dodanie cyfry, takiej jak 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(dodatkowe D na końcu), zwraca falsey $TRUE, ponieważ po prostu usuwa obcą cyfrę, a pierwsze 36 znaków jest poprawnych.
AdmBorkBork,
9

Emacs Lisp, 236 bajtów

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

Nie golfowany:

(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
źródło
8

Ze względu na zmiany zasad ta odpowiedź nie jest już konkurencyjna :(

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

W większości dość oczywiste. Specyfikator %nformatu podaje do tej pory liczbę odczytanych bajtów, która powinna wynosić 36. scanf()zwraca liczbę dopasowanych elementów, która powinna wynosić 6. Ostateczna wartość %cnie powinna być zgodna. Jeśli tak, to pojawia się tekst końcowy i scanf()zwraca 7.

Skompiluj z, -waby ukryć nieznośne ostrzeżenia (jest ich kilka).

Cyfrowa trauma
źródło
6

JavaScript ES6, 70 83

UWAGA, dziękuję @Qwertiy za znalezienie błędu (i sugerowanie ulepszeń i poprawek)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ Zapisano 2 bajty

Pozostałe 9 bajtów zaoszczędzonych upraszczając kontrolę długości (skomplikowany sposób był krótszy w pierwszym szkicu, ale nie teraz)

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

Wyjaśniono

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
)

Testowy fragment kodu

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
źródło
-1-('0x'+h)=>1/('0x'+h)
Qwertiy,
Ten sam problem, co w mojej poprzedniej wersji: prawda dla00000000-0000-0000-000 -000000000000
Qwertiy
Nie. Ale dodałeś zły test. Wiodąca spacja nie stanowi problemu, ale jedna z nich jest końcowa, ponieważ łańcuch jest przycinany podczas konwersji na liczbę. Zobacz mój komentarz powyżej z testem.
Qwertiy,
„00000000-0000-0000-000 -000000000000” teraz widzę to @Qwertiy Brakowało mi 3 zer zamiast 4
edc65
1
@Stefnotch Nie zgadzam się. Poza everywywołaniem ujest ciąg znaków, a nie tablica
edc65
5

Ze względu na zmiany zasad ta odpowiedź nie jest już konkurencyjna :(

Pure Bash (bez narzędzi zewnętrznych), 78

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

Pobiera dane z wiersza poleceń.

  • printfBuduje następujący ciąg - - - -.
  • p=Linia przemienia ten z następującym wzorem: [[: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:]]. Zauważ, że to wygląda okropnie podobnie jak wyrażenie regularne. Nie ma to jednak miejsca w tym kontekście. Jest to wzorzec do dopasowywania wzorca powłoki . Jest to podobne pojęcie do wyrażenia regularnego, ale jest inną konstrukcją (i składnią).
  • Ostatnia linia sprawdza, czy
    • dane wejściowe nie są puste
    • jeśli wyciągnięcie wzoru z ciągu wejściowego spowoduje powstanie pustego ciągu

Idiomatyczny dla powłoki, kod powrotu 0 oznacza sukces / PRAWDA, a 1 oznacza błąd / FAŁSZ. Kod powrotu można sprawdzić echo $?po uruchomieniu skryptu.

Cyfrowa trauma
źródło
1
Dopasowanie wzorca powłoki może nie być zgodne ze składnią wyrażenia regularnego, ale klasa znaków zdecydowanie używa definicji i składni wyrażenia regularnego POSIX. W każdym razie to OP musi zdecydować, czy jest to dopuszczalne.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳ Wyrażenia regularne mogą zawierać klasy znaków Posix, ale nie sądzę, aby sugerowało to, że wszystko, co korzysta z klasy znaków Posix, jest wyrażeniem regularnym. Jako inny przykład trwykorzystuje także klasy znaków Posix, ale nie jest parserem wyrażeń regularnych.
Cyfrowy uraz
Możesz ogolić kilka znaków, unikając bezużytecznych podwójnych cudzysłowów, np. W formacie printf.
Jens,
Zaktualizowałem wyzwanie, aby wyjaśnić - powodem, dla którego wyrażenia
regularne
4

Jolf, 32 bajty

Wypróbuj tutaj!

 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

Z powodu błędu w moim kodzie jest on dłuższy niż powinien. :( [8,4,4,4,12] powinno być takie samo jak {8444*26}, ale }jest także zamknięciem funkcji: P

Conor O'Brien
źródło
2
Czyli jest to dłuższe niż trzeba, ponieważ masz niejednoznaczne polecenia w utworzonym języku? : P
Rɪᴋᴇʀ
@RikerW Drobny błąd semantyczny. Zostało to naprawione teraz.
Conor O'Brien
4

MATL , 55 bajtów

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

Powstrzymałem się od używania Ybfunkcji ( strsplit), ponieważ jest ona nieco podobna do regexp(..., 'split'). Używa tylko indeksowania i porównań znaków.

Przykład

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

Wyjaśnienie

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
źródło
3

CJam, 52 42 bajty

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

Wypróbuj online . Wysyła oryginalny ciąg, jeśli ma wartość true, zwraca pusty ciąg, jeśli ma wartość false ( jest to dozwolone ).

Wyjaśnienie:

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
źródło
A7*)<nie usunie wielu nieprawidłowych znaków, takich jak spacje +, ?...
Martin Ender
@ MartinBüttner oh strzelać ... Nie zdawałem sobie z tego sprawy, naprawię to w ciągu kilku minut.
GamrCorps,
3

Julia, 86 bajtów

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

Jest to anonimowa funkcja, która przyjmuje ciąg znaków i zwraca wartość logiczną. Aby to nazwać, nadaj mu nazwę, np f=s->....

Nie golfowany:

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.
źródło
3

C # 196 bajtów

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

Nie golfowany:

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

Metodę Tmożna wywołać za pomocą dowolnego niepustego łańcucha i truew falseprzeciwnym razie zwróci prawidłowe identyfikatory GUID . Jest to walidacja w czasie stałym; kosztem trzech znaków możesz wcześniej wyjść z metody (zmienić i < v.Lengthna i < v.Length && r).

Spróbuję później obniżyć liczbę bajtów.

Oczywiście pominąłem Guid.ParseExactdrogę, bo gdzie jest w tym zabawa? Oto, bez większych prób gry w golfa dalej w 86 bajtów :

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

Nie golfowany:

using System;
class P
{
    bool T(string v)
    {
        Guid x;
        return Guid.TryParseExact(v, "D", out x);
    }
}
RobIII
źródło
2

Python 2, 99 112 bajtów

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

Po prawidłowym wejściu zostanie wydrukowane True. W przypadku nieprawidłowego wejścia drukowane jest Falselub 0, w zależności od tego, dlaczego było nieprawidłowe. Falsei 0oba są falsey w Pythonie.

Funkcja musi sprawdzić 3 rzeczy:

  • Każdy znak niebędący łącznikiem jest cyfrą lub jest w nim ABCDEF
  • Są dokładnie 4 łączniki
  • Przed pierwszym łącznikiem jest 8 znaków, 12 po ostatnim i 4 między dowolnymi dwoma innymi

Oto podział pokazujący, jak je sprawdza. Jest trochę nieaktualny, ale jestem głodny, więc zaktualizuję go później.

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.
podziemny monorail
źródło
Myślę, że można zaoszczędzić 2 bajty, jeśli zastąpić oba wystąpienia returnz print. (W takim przypadku na pewno będziesz chciał być w Pythonie 2, ponieważ printdziała inaczej w Pythonie 3)
mathmandan
1
To nie działa w Pythonie 3, ponieważ mapteraz zwraca „obiekt mapy”, a nie listę.
Tim Pederick,
To nie działa w Pythonie 2 (prawdopodobnie również 3), ponieważ intfunkcja dopuszcza spacje - 0FCE98ac-1326-4c79-8EBC-94908da8B03z końcową spacją. Zobacz komentarz w usuniętej odpowiedzi Pyth tutaj, jeśli to możliwe.
Blue
2

Python 2, 57 bajtów

Dzięki Bogu za wbudowane! - pamiętaj, aby zawrzeć ciągi w cudzysłowie.

import uuid
try:uuid.UUID(input());print 1
except:print 0
nimi
źródło
5
Zgodnie z dokumentami, z którymi się połączyłeś, zostaną wydrukowane w 1celu wprowadzenia 12345678123456781234567812345678.
Dennis
jeśli to zadziała, będziesz w stanie zaoszczędzić bajty, try:print uuid.UUID(input())ponieważ wystarczy, że wydrukujesz prawdziwą wartość
undergroundmonorail
2
Ten program akceptuje wiele formatów UUID, ale pytanie wymaga tylko 36-znakowego formatu UUID z łącznikami.
Jacob Krall,
2
Możesz to uratować, radząc sobie ze zaktualizowanymi regułami, sprawdzając, czy wejściowy ciąg znaków jest równy identyfikatorowi UUID konwertowanemu z powrotem na ciąg. Od razu daje prawdziwą wartość.
agtoever
2

Pyth, 39 bajtów

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

Wypróbuj tutaj .

niebieski
źródło
W linku „wypróbuj tutaj” brakuje \znaku K\-k, więc nie działa tak, jak jest.
Alex,
To zostało już naprawione
Blue
2

Perl 6 ,  83   67 bajtów

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

(liczby nie uwzględniają nowego wiersza ani wcięcia, ponieważ nie są potrzebne)

stosowanie:

# 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
źródło
2

Common Lisp - 161

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

Zwrócona wartość, jeśli true, to liczba mieszająca, która jest przydatnym wynikiem.

Nie golfił

(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))))
rdzeń rdzeniowy
źródło
@Jojodmo Tak, zdecydowanie! Dzięki
coredump,
2

F # 44 znaków

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

W języku F # funkcje z outparametrami można wywoływać, pomijając parametr out; jego wartość po powrocie zostanie połączona z rzeczywistą wartością zwracaną przez funkcję w krotkę.

W tym przypadku krotka jest przekazywana do fstfunkcji, która zwraca swój pierwszy element członkowski, który w tym przypadku jest logiczną wartością zwracaną TryParseExact, wskazującą powodzenie lub niepowodzenie wywołania.

W celu sprawdzenia poprawności formatu zwracamy truetylko wtedy, gdy łańcuch ma 36 znaków.

Zanim zobaczyłem odpowiedź C # RobIII, nie myślałem o użyciu TryParseExact, więc moja odpowiedź miała być o trzy znaki dłuższa:

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

TryParse(string, Guid) akceptuje dane wejściowe w następujących formatach:

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

Spośród nich tylko drugi ma 36 znaków.

phoog
źródło
2

Python 2, 93 89 85 bajtów

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

Te map()gwarancje połączeń, które odcinki są z odpowiednich długościach, a all()testy na każdy znak jest albo myślnik lub cyfra hex arbitralne-case. Wyrażenie generatora testuje każdy znak przez iterację całego łańcucha, więc obawiam się, że nie jest to najbardziej wydajna metoda, ale powinna spełniać przypadki testowe:

>>> 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
źródło
Czy ktoś ma pojęcie, dlaczego najkrótsza poprawna odpowiedź w języku Python została odrzucona? Za mało wyjaśnień?
rsandwick3
Jojodmo - w przypadku wątpliwości co do tego, nie odrzuciłem proponowanej przez ciebie zmiany - już dokonałem edycji, ponieważ brakowało mi znaków AF (skopiowałem z okna, w którym testowałem przypadki negatywne), a auto Community -odrzuciła twoją propozycję bez mojej wiedzy, że została podniesiona. Kiedy wiedziałem, że to zaproponowałeś, @nimi już poprawił nagłówek. Mam wielką nadzieję, że nie ma to nic wspólnego z przegłosowaniem, ponieważ bardzo źle odbije się to na tej społeczności. W każdym razie założę, że to druga rzecz i dodam trochę więcej wyjaśnień.
rsandwick3
2
Możesz usunąć f=i spacje wokół ciągu w allbloku.
FryAmTheEggman
och, super, fajny haczyk - edytowany
rsandwick3
1
Można zapisać 8 (lub 6, może trzeba dodać nawias) bajtów przez konwertowania all(..)ustawić testowanie integracji: set(u)<=set("-0123456789abcdefABCDEF").
409_Konflikt
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;

Właściwie używa stdin i stdout - jednej z mniej znanych cech tego konkretnego języka. Działa z podanymi przykładami, ale prawdopodobnie nie we wszystkich przypadkach. Prawdopodobnie można to poprawić.

Lepsze podejście - jedna postać na raz:

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;

Grał w golfa o kolejne 6 znaków poza głównym wyrażeniem!

Nie golfowany:

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;

Generuje to całkiem sporo ostrzeżeń i notatek w dzienniku, ale nie drukuje ich na standardowe lub standardowe, więc myślę, że to uczciwa gra.

użytkownik3490
źródło
1

C, 391 bajtów

#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
źródło
1

MATLAB, 126 bajtów

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
źródło
1

Python 3, 134 bajty

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) próbuje rzutować k na int-16 base. W przypadku znaku innego niż 0-9a-fA-F- kończy się niepowodzeniem, w którym to przypadku zwracamy 0, co jest fałszem. Dodaj 1 do tej wartości int, a otrzymamy gwarantowaną prawdziwą wartość - usunęliśmy wszystkie łączniki za pomocą str.split (), więc nie możemy uzyskać wartości -1, a wszystkie wartości nie będące 0 są prawdziwe.

Pjoelj
źródło
1

Funkcja C, 102

Zmiana reguły uniemożliwiła moją poprzednią scanf()odpowiedź opartą na c , więc oto kolejna odpowiedź c, za pomocą isxdigit()której moim zdaniem powinno się konkurować :

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

Wypróbuj online.

  • Sprawdź -znaki (ASCII 45) w odpowiednich pozycjach - jeśli tak, zamień je na 0s (ASCII 48 (= 45 + 3))
  • Przejdź sznurkiem, sprawdzając każdy znak za pomocą isxdigit()
  • Zwraca PRAWDA, jeśli długość łańcucha wynosi 36, a końcowy znak to NUL.
Cyfrowa trauma
źródło
1

Partia, 148 139 + 2 = 150 141 bajtów

@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

Dodano 2 bajty, ponieważ musisz użyć /vprzełącznika do CMD.EXE.

Wyjście z ERRORLEVEL 0 w przypadku powodzenia, 1 w przypadku niepowodzenia.

Edycja: Zapisano niektóre bajty głównie dlatego, że :=nie uwzględnia wielkości liter, ale były też inne poprawki.

Neil
źródło
1

Java, 345 bajtów

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

Dane wejściowe to argument pierwszego wiersza poleceń. Dane wyjściowe to kod błędu (0 oznacza prawidłowy UUID, 1 oznacza nieprawidłowy)

Niegolfowany z komentarzami:

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

EDYCJA: Nie zauważyłem części STDOUT. Ups, naprawione teraz.

ciastko
źródło
Miły! Możesz if(b.length>36||b.length<36)po prostu zastąpić if(b.length!=36). Ponadto, ponieważ możesz drukować prawdziwe wartości , możesz po prostu drukować 0zamiast 1<0, a 1zamiast 1>0.
Jojodmo
@Jojodmo podstawie głosów wartość truthy jest w formie if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }to w Javie boolean ma wartość truthy, ale 1czy 0nie jest. Dopiero gdy OP wyzwaniem mówi coś takiego: „ Twoje wyjście może być prawda / fałsz, 0/1, pusty / niepusty, tak długo, jak określić to, czego używasz. ”, A następnie można rzeczywiście wykorzystać 0i 1zamiast true/falsejak truthy / wartość falsey.
Kevin Cruijssen
1
Jeśli chodzi o wskazówki dotyczące plików cookie dotyczące gry w golfa: @Jojodmo rzeczywiście ma rację, zastępując je if(b.length!=36); ||może być |w wielu miejscach, a także &&w celu &; if(...!='-')może być if(...!=45); int i=-1; ... while(++i<b.length){można zastąpić for(int i=-1;++i<b.length;){; 'F'może być 70( 'f'może wynosić 102, ale to nie ma znaczenia, ponieważ jest to ta sama liczba bajtów). Podoba mi się to, jak wykorzystałeś java.io.PrintStream u=System.out;btw, powinienem pamiętać o tym! Więc dziękuję.
Kevin Cruijssen
1

Swift 3, 50 bajtów

Podaj ciąg s

import Foundation
print(UUID(uuidString:s) != nil)
Matt
źródło
1

PHP, 109 bajtów

wypisuje 1 dla true i 0 dla false

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) jest o 5 bajtów krótszy niż in_array($i,[8,13,18,23])

112 bajtów

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

113 bajtów

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

Java, 172 bajty 168 bajtów (Thanks Wheat Wizard)

Trochę oszustwo, odkąd użyłem java.util.UUID, ale oto:

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

Wersja bez golfa:

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
źródło
Witamy na stronie! Myślę, że możesz usunąć przestrzeń pomiędzy tryi {.
Wheat Wizard
@WheatWizard dziękuję: D również zauważyłem, że mogę usunąć „około 0 i 1
ryxn
2
Powinieneś być w stanie usunąć odstęp między String[]i a. Ponadto, należy być w stanie wymienić printlnz print.
clismique
1
Nazwa klasy może zawierać 1 znak. Możesz użyć java.util.UUID.fromStringzamiast importować.
Poke
0

AWK, 98 bajtów

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

Po prostu dzieli linię na każdy znak i sprawdza, czy każdy znak jest cyfrą szesnastkową i czy w odpowiednich miejscach są łączniki. strtonumkonwertuje nieprawidłowe znaki na 0. Dokonanie porównania między 0i m(i dowolnie wybrany nieprawidłowy znak) wymagać dodatkowych czynności. Na szczęście 01jest to poprawny numer szesnastkowy, ale m1nie jest.

Początkowo napisałem dwie forpętle, ale zaoszczędziłem 1 bajt, ściskając je razem. :)

UWAGA: GAWKmożna odczytać dane wejściowe jako liczby szesnastkowe, ale wymaga to bardzo długiej opcji wiersza poleceń.

Robert Benson
źródło