Regex kullanmadan bir UUID'nin geçerli olup olmadığını kontrol edin


44

Bir dize girişi verildiğinde , giriş geçerli bir UUID ise, regex kullanmadan, STDOUT ya da eşdeğerinde bir gerçek değeri basan bir program yazın .

Geçerli bir UUID

Toplam 36 karakter için (32 alfanümerik karakter ve dört tire) 8-4-4-4-12 şeklinde, tire ile ayrılmış beş grupta görüntülenen 32 onaltılık basamak.

Kaynak

Test Kılıfları

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)

kurallar

  • Normal İfadelere izin verilmiyor
  • Bir regex'e benzeyen değişmez örüntü eşleşmesine izin verilmez. Örneğin, kullanmak için [0-9a-fA-F]ya da diğer onaltılık tanımlayıcılar (biz bu arayacağım n) ve daha sonra eşleştirme nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnveya n[8]-n[4]-n[4]-n[4]-n[12]izin verilmez
  • Girdi, STDINişlevden veya bir işlevin argümanı olarak alınabilir.
  • Giriş büyük / küçük harf duyarsız
  • Giriş varsaymak güvenlidir değil linefeeds veya yeni satırlar içeriyor.
  • Girdi, yazdırılabilir ASCII karakterleri içerebilir (boşluklar dahil)
  • Girdi geçerli bir kullanıcı birimiyse, bir gerçeğe uygun değer yazdırılmalıdır.STDOUT
  • Bir Falsey değeri için basılı olmalıdır STDOUTgirişi veya dengi olup , geçerli Uuid
  • Bir işlev kullanılıyorsa STDOUT, kullanmak yerine çıktı, işlevin dönüş değeri olabilir.
  • Gerçek / falsey değeri yazdırılamaz STDERR.
  • Standart boşluklar uygulanır
  • Bu , yani bayt cinsinden en kısa program kazanır. İyi şanslar!

Liderler Sıralaması

Bu, hem lider tablosunu hem de kazananların dile göre genel bir bakışını oluşturan bir Stack Snippet'tir.

Cevabınızın göründüğünden emin olmak için, lütfen aşağıdaki Markdown şablonunu kullanarak cevabınızı bir başlık ile başlatın

## Language Name, N bytes

N, gönderinizin bayt olarak büyüklüğüdür.

Başlığınıza birden çok numara eklemek istiyorsanız (örneğin, eski puanlara dikkat çekmek veya bayt sayımındaki bayraklar dahil), gerçek puanın başlığınızdaki son sayı olduğundan emin olun.

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


32
Zavallı Retina . D:
BrainSteel,


8
Sadece referans olarak, 28 baytlık bir Retina çözümü bulabilirim. (Yani şu anda lider olmasına rağmen golf dillerine göre çılgın bir avantaj değil.)
Martin Ender

5
Lua'nın kalıplarına izin veriliyor mu? Kesinlikle normal ifadeler değiller.
Manat çalışması

1
@JacobKrall Tüm sorularınızın "sahte" olduğundan eminim. Bence zorluk sadece biçim dizgilerinin \h{8}-\h{4}-\h{4}-\h{4}-\h{12}( \honaltılık bir rakam olan) geçerli olduğu oldukça açık .
Martin Ender

Yanıtlar:


15

CJam, 31 30 29 bayt

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

Tüm test durumlarını burada çalıştırın.

açıklama

Girdiyi doğrudan eşleşen desen yerine, önce onu tek bir desen dizisine kolayca karşılaştırılabilecek daha basit bir forma dönüştürüyoruz.

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 karakter

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

Önceki 55 karakter sürümünün gruptaki arkadaki boşluklarla ilgili bir sorunu var:

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

Ölçek:

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

Müthiş (ve benim için solduran) +1
edc65

@ edc65, "solmak" derken ne demek istiyorsun?
Qwertiy,

Örtülü yayın
yapmanın aşırı

4
utangaç, tefekkür, saçma, acı, yıkıcı, küçük düşürücü, ipotek - (cevabını benimkiyle karşılaştırarak)
edc65

11

PowerShell, 29 21 84 49 37 Bayt

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

- Bu golf ile yardımcı yorumlarda millet için çok teşekkürler değişen kurallara ayak uydurmak için TessellatingHeckler , iFreilicht , Jacob Krall ve Joey . Lütfen revizyonlar ve daha eski sürümler için düzenleme geçmişine bakın.

Bu revizyon girdi olarak alır $g, daha sonra @{}bir elemanlı yeni bir karma tablosu yaratır , indeks 36eşit olarak ayarlanır $g-as[guid]. Bu kullanır yerleşik -asoperatörün iki .NET veri türleri arasında dönüştürme girişimi - dan [string]için [guid]. Dönüşüm başarılı olursa, bir [guid]nesne döndürülür, başka bir $nullşey döndürülür. Bu kısım, giriş dizesinin geçerli bir .NET GUID olmasını sağlar.

Bir sonraki adım, ile karma tabloya indekslemektir [$g.length]. Eğer $guzunluk tam olarak 36 karakter değil, karma tablo döner $nullbir Falsey değeri olarak çıkış olacak. Eğer $guzunluğu 36 karakterden sonra .NET çağrının sonucu çıkış olacaktır. Eğer $g(herhangi bir biçimde) geçerli .NET GUID değil, o zaman çıktısı verecektir $nullbir Falsey değeri olarak. Aksi takdirde, bir .NET GUID nesnesini bir truthy değeri olarak çıkarır - çıktının tek yolu, istenen meydan okuma biçimiyle eşleşiyorsa olur.

Örnekler

Burada script çağrısı parens içinde kapsama ve açıkça netlik için bir Boole olarak döküm.

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

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

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

4
!!($args[0]-as[guid])21 bayta atacağım .
TessellatingHeckler

2
4 bayt'ı dışarıda bırakarak kaydedemez miydin !!()? Değerler $NULLve [guid]karşılıklı olarak dışlayıcı olduklarından, doğruluk ve yanlışlık değerlerini temsil etmeye hak kazanıyorlar, öyle değil mi? Her neyse, boole dönüştürmek için harika bir yol, çözümü seviyorum!
iFreilicht

@ iFreilicht bu bir nokta; bağlantılı "truthy / falsey yorumlama" yazısına bakıldığında - geçerli göründüğünü kabul ediyorum.
TessellatingHeckler

1
Yanlış döndürür Bu çözüm Trueiçin 0FCE98AC13264C798EBC94908DA8B034hiçbir tire vardır
Jacob Krall

1
@TessellatingHeckler Hayır, gerçek olamayacak kadar iyi. 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(Sonunda ekstra D) gibi bir rakam eklemek $TRUE, falsey değerini döndürür , çünkü sadece rahatsız edici rakamı keser ve ilk 36 karakter geçerlidir.
AdmBorkBork,

9

Emacs Lisp, 236 Bayt

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

Ungolfed:

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

8

Kurallardaki değişiklikler nedeniyle , bu cevap artık rekabetçi değildir :(

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

Çoğunlukla oldukça açıklayıcı. %nBiçim belirteci 36. olması gereken okuma şimdiye kadar bayt sayısını verir scanf()döner 6. nihai olmalıdır eşleşti öğelerin sayısı, %chiçbir şey aynı olmamalıdır. Eğer öyleyse, o zaman takip eden metin var ve scanf()7 döndürür.

Sinir -wbozucu uyarıları bastırmak için derleyin (birkaç tane var).


6

JavaScript ES6, 70 83

NOT: Hata bulmak için @Qwertiy 'e teşekkürler (ve bazı iyileştirmeler ve düzeltmeler önerin)

Thx @ CᴏɴᴏʀO'Bʀɪᴇɴ 2 bayt kaydedildi

Diğer 9 bayt, uzunluk kontrolünü basitleştirerek kaydetti ( ilk taslakta karmaşık yol daha kısaydı, ancak şimdi değil)

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

Açıklaması

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

Test pasajı

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

Aynı benim önceki sürümde olduğu gibi sorun: true için00000000-0000-0000-000 -000000000000
Qwertiy

Hayır. Ancak yanlış bir test eklediniz. Önde gelen boşluk bir sorun değildir, ancak sonuncusu, sayıya dönüştürülürken bir dize kesildiğindendir. Bir test ile yukarıdaki yorumumu bakın.
Qwertiy,

'00000000-0000-0000-000 -000000000000' şimdi görüyorum @ Qwertiy 4 yerine 3 sıfır özledim
edc65

1
@Stefnotch Katılmıyorum. everyArama dışında ubir dizedir, bir dizi değildir
edc65

5

Kurallardaki değişiklikler nedeniyle , bu cevap artık rekabetçi değildir :(

Saf Bash (harici yardımcı program yoktur), 78

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

Komut satırından girdi alır.

  • printfAşağıdaki dizeyi oluşturur - - - -.
  • p=Çizgi desene bu dönüşümleri: [[: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:]]. Bunun normal bir ifade gibi çok fazla göründüğüne dikkat edin. Ancak bu bağlamda değildir. Kabuk deseni eşleşmesi için bir kalıptır . Bu kavram olarak normal ifadeye benzer , ancak farklı bir yapı (ve sözdizimi).
  • Son satır kontrol eder
    • giriş boş değil
    • Desenin giriş dizgisinden çekilmesi boş bir dize üretiyorsa

Kabuğa deyimsel, 0 dönüş kodu başarı / DOĞRU ve 1 başarısızlık / YANLIŞ gösterir. Dönüş kodu echo $?senaryoyu çalıştırdıktan sonra kontrol edilebilir .


1
Kabuk deseni eşleşmesi regex'in sözdizimini takip etmeyebilir, ancak karakter sınıfı kesinlikle POSIX regex'in tanımını ve sözdizimini kullanır. Her neyse, kabul edilip edilemeyeceğine karar vermek OP'ye bağlı.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Normal ifadeler Posix karakter sınıflarını içerebilir, ancak Posix karakter sınıfını kullanan hiçbir şeyin bir regex olduğunu ima etmiyorum. Başka bir örnek olarak trda Posix karakter sınıflarını kullanır, ancak bir regex ayrıştırıcısı değildir.
Dijital Travma

Örneğin printf biçiminde gereksiz çift tırnak işaretlerinden kaçınarak birkaç karakteri tıraş edebilirsiniz.
Jens

Açıklığa kavuşturma zorluğunu güncelledim
regex'lerin izinsiz

4

Jolf, 32 bayt

Burada dene !

 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

Kodumdaki bir hata nedeniyle, bu olması gerekenden daha uzun. :( ile aynı [8,4,4,4,12] olmalı{8444*26} , ancak }bir işlevin kapanması da aynı: P


2
Öyleyse, olması gerekenden daha uzun, çünkü yarattığınız dilde belirsiz komutlar var? : P
Rɪᴋᴇʀ

@RikerW Küçük anlamsal hata. Şimdi düzeltildi.
Conor O'Brien,

4

MATL , 55 bayt

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

Yb( strsplit) İşlevini kullanmaktan kaçındım çünkü buna biraz benziyordu regexp(..., 'split'). Bu sadece indeksleme ve karakter karşılaştırmalarını kullanır.

Örnek

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

açıklama

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 bayt

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

Çevrimiçi deneyin . True olursa orijinal dizeyi, false ise boş dizge çıktılar ( buna izin verilir ).

Açıklama:

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*)<boşluklar gibi birçok geçersiz karakterler kaldırmaz, +, ?...
Martin Ender

@ MartinBüttner oh ateş ... Ben fark etmedim, Ben birkaç dakika içinde düzeltmek.
GamrCorps,

3

Julia, 86 bayt

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

Bu bir dizgeyi kabul eden ve bir boolean döndüren adsız bir işlevdir. Aramak için bir isim verin, örneğin f=s->....

Ungolfed:

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

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

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

    return ok1 && ok2
end

3

C # 196 bayt

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

Yöntem T, boş olmayan herhangi bir dize ile çağrılabilir ve aksi takdirde truegeçerli bir GUID için falsedöndürür. Bu sabit zamanlı bir doğrulamadır; Üç karakter pahasına size yöntemi (değişim erken çıkabilirsiniz i < v.Lengthiçin i < v.Length && r).

Bayt sayısını daha sonra almaya çalışacağım.

Belli ki dışarıda bıraktım Guid.ParseExactçünkü eğlence nerde? İşte, 86 baytta daha fazla golf atmaya çalışmaksızın :

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

Ungolfed:

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

2

Python 2, 99 112 bayt

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

Geçerli bir girişte yazdırılır True. Geçersiz bir girişte Falseya da 0neden geçersiz olduğuna bağlı olarak yazdırılır . Falseve 0her ikisi de Python'da falsey.

İşlev 3 şeyi kontrol etmek zorundadır:

  • Her kısa çizgi olmayan karakter bir rakamdır veya ABCDEF
  • Tam olarak 4 tire var
  • İlk kısa çizgiden önce 8, sondan sonra 12 ve diğer ikisi arasında 4 karakter vardır.

İşte onlar için nasıl kontrol ettiğini göstermek için bir döküm. Biraz güncel değil ama açım o yüzden daha sonra güncelleyeceğim.

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.

Sana her iki örneklerini değiştirmek eğer 2 bayt kaydedebilirsiniz tahmin returnile print. (Bu durumda kesinlikle Python 2'de olmak isteyeceksiniz, çünkü printPython 3'te farklı şekilde çalışıyor.)
mathmandan

1
Bu Python 3'te çalışmaz, çünkü mapşimdi bir liste değil "harita nesnesi" döndürür.
Tim Pederick

Bu intişlev python 2'de (muhtemelen 3 de) çalışmaz, çünkü işlev boşluklar sağlar - 0FCE98ac-1326-4c79-8EBC-94908da8B03izleyen bir boşlukla. Mümkünse, burada silinen Pyth cevabındaki yoruma bakın .
Mavi

2

Python 2, 57 bayt

Yerleşik için çok şükür! - dizeleri tırnak içine aldığınızdan emin olun.

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

5
Bağlandığınız belgelere göre, bu 1girdi için yazdırır 12345678123456781234567812345678.
Dennis,

eğer bu işe yaradıysa, baytları tasarruf ederek yapabileceksiniz try:print uuid.UUID(input())çünkü gereken tek şey bir gerçeğe uygun değer basmaktır
undergroundmonorail

2
Bu program birçok UUID formatını kabul ediyor, ancak soru sadece 36 karakterli UUID formatını tire ile istiyor.
Jacob Krall

2
Güncellenen kurallarla başa çıkarak, girdi dizgisinin dizgiye geri dönüştürülen uuid'e eşit olup olmadığını kontrol ederek bunu kurtarabilirsiniz. Size hemen bir acayip değer verir.
agtoever

2

Pyth, 39 bayt

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

Burada dene .


"Burada dene" bağlantınız \karakterin içinde K\-kbulunmuyor, bu nedenle olduğu gibi çalıştırılamıyor.
Alex,

Bu şimdi düzeltildi
Blue

2

Perl 6 ,  83   67 bayt

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

(sayılar gerekli olmadıkça yeni satırlar veya girintiler içermez)

kullanımı:

# 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

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

True olursa döndürülen değer, sayı olarak elde edilen yararlı sonuç olan karmadır.

Ungolfed

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

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

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

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

@Jojodmo Evet, kesinlikle! Teşekkürler
coredump

2

F # 44 karakter

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

F # 'da, outparametreli fonksiyonlar , out parametresini atlayarak çağırılabilir; dönüşündeki değeri, fonksiyonun gerçek dönüş değeri ile bir tuple halinde birleştirilecektir.

Burada, tuple, fstilk üyesini döndüren işleve iletilir ; bu durumda, çağrının başarılı veya başarısız olduğunu gösteren TryParseExact'in Boole dönüş değeridir.

Doğru formatın kontrolü için, trueyalnızca karakter 36 karakter uzunluğundaysa döneriz.

RobIII'in C # cevabını görmeden önce, TryParseExact'i kullanmayı düşünmemiştim, bu yüzden cevabım üç karakter daha olacaktı:

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

TryParse(string, Guid) aşağıdaki formatlarda girişi kabul eder:

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

Bunlardan sadece ikincisi 36 karakter uzunluğunda.


2

Python 2, 93 89 85 bayt

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

map()Çağrı garanti bölümler sağ uzunlukta olduğu ve bu all()testler bir tire veya keyfi bir durum altıgen basamaklı ya olduğun için her karakter. Jeneratör ifadesi, her bir karakteri tüm dizgiyi yineleyerek test ediyor, bu yüzden en performanslı yöntem değil, korkarım ama test durumlarını yerine getirmesi gerekiyor:

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

Python'un en kısa doğru cevabının neden reddedildiğine dair bir fikri olan var mı? Yeterli açıklama yok mu?
rsandwick3

Jojodmo - bu konuda bir karışıklık olması durumunda önerilen değişikliğinizi reddetmedim - AF karakterlerini (negatif vakaları test ettiğim bir pencereden kopyaladım) ve Topluluk otomasyonunu kaçırdığım için zaten bir düzenleme yaptım - teklifini bile yükseltildiğini bile bilmeden reddetti. Bunu teklif edeceğini bildiğim zaman, @ nimi zaten başlığın düzeltmesini yapmıştı. Umarım, bu topluluğa çok kötü yansıtacağı için, aşağı oyla ilgisi yoktur. Her neyse, başka bir şey olduğunu kabul edeceğim ve biraz daha açıklama ekleyeceğim.
rsandwick3

2
f=Ve allbloktaki dize etrafındaki boşlukları kaldırabilirsiniz .
FryAmTheEggman

oh harika, güzel yakalamak - düzenlenmiş
rsandwick3

1
Sen 8 senin dönüştürerek bayt (veya 6, sen parantez eklemeniz gerekebilir) kaydedebilir all(..)içerme testi ayarlamak için: 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;

Aslında, bu dilin daha az bilinen özelliklerinden biri olan stdin ve stdout'u kullanır. Şimdiye kadar verilen örnekler için çalışır, ancak muhtemelen her durumda değil. Muhtemelen geliştirilebilir.

Daha iyi yaklaşım - her seferinde bir karakter:

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;

Merkezi ifadenin dışında 6 karakter daha golf oynadı!

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;

Bu, günlükte epeyce uyarı ve not oluşturur, ancak bunları stdout veya stderr'e yazdırmaz, bu yüzden bu adil bir oyun olduğunu düşünüyorum.


1

C, 391 bayt

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

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 bayt

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), k'yı bir 16 tabanına atmaya çalışır. 0-9a-fA-F dışında bir karakterde başarısız olur, bu durumda 0 döndürürsek, sahte olur. Bu int'e 1 ekleyin ve garantili bir truthy değeri elde ettik - str.split () ile tüm heceleri çıkardık, -1 değerini alamayız ve 0 olmayan tüm öğeler truthy olur.


1

C işlevi, 102

Bir kural değişikliği önceki c izin verilmeyen scanf()tabanlı cevabı , işte başka bir c cevabı kullanarak isxdigit()ı rekabet ettiğini izin verilmesi gerektiğini düşünüyorum :

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

Çevrimiçi deneyin.

  • Olup olmadığını kontrol edin -, ilgili pozisyonlarda karakterleri (ASCII 45) - eğer öyleyse, bunların yerine 0lar (ASCII 48 (= 45 + 3))
  • Her bir karakteri kontrol ederek dizeyi yürü isxdigit()
  • Dize uzunluğu 36 ve son karakter NUL ise TRUE döndürür.

1

Toplu, 148 139 + 2 = 150 141 bayt

@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

/vAnahtarı kullanmanız gerektiğinden 2 bayt eklendi CMD.EXE.

ERRORLEVEL 0 ile başarılı, 1 başarısız ile çıkar.

Düzenleme: Bazı baytlar kaydedildi :=, çünkü büyük / küçük harfe duyarsız, ancak başka tweaks de vardı.


1

Java, 345 bayt

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

Giriş, ilk komut satırı argümanıdır. Çıktı hata kodudur (0 geçerli UUID demektir, 1 geçerli değil demektir)

Yorumsuz Ungolfed:

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: STDOUT kısmını fark etmedi. Hata! Şimdi düzeltildi.


Güzel! Sen değiştirebilirsiniz if(b.length>36||b.length<36)basitçe ile if(b.length!=36). Ayrıca, truthy değerlerini yazdırabileceğinizden, 0yerine 1<0ve 1yerine yazdırabilirsiniz 1>0.
Jojodmo

@Jojodmo oylarına dayanarak, bir truthy değerdir şeklinde if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }bir boolean bir truthy değerdir Java So ancak 1ya 0değildir. Bir meydan okuma OP gibi bir şey diyor Yalnızca: " Çıktınız doğru / yanlış, 0/1, boş olabilir / boş olmayan; ne kullanmak belirtmek sürece. " O zaman gerçekten kullanabilirsiniz 0ve 1yerine true/falsetruthy olarak / falsey değeri.
Kevin Cruijssen

1
Çerez için golf ipuçlarına gelince: @Jojodmo gerçekten bunun yerine if(b.length!=36); ||olabilir |birden fazla yerde üzerinde, hem de &&hiç &; if(...!='-')olabilir if(...!=45); int i=-1; ... while(++i<b.length){ile değiştirilebilir for(int i=-1;++i<b.length;){; 'F'olabilir 70( 'f'102 olabilir, fakat aynı bayt sayısından beri önemli değil). java.io.PrintStream u=System.out;BTW'yi nasıl kullandığın hoşuma gitti, bunu hatırlamalıyım! Çok teşekkürler.
Kevin Cruijssen

1

Swift 3, 50 bayt

Bir dizede geçmek s

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

1

PHP, 109 Bayt

doğru için 1, yanlış için 0 yazdırır

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 Bayt daha kısa in_array($i,[8,13,18,23])

112 Bayt

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

113 Bayt

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

0

Java, 172 bayt 168 bayt (Teşekkürler Buğday Sihirbazı)

Java.util.UUID kullandığımdan beri biraz hile, ama işte:

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

Ungolfed versiyonu:

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

Siteye Hoşgeldiniz! Bence tryve arasındaki boşluğu kaldırabilirsin {.
Buğday Sihirbazı

@WheatWizard teşekkür ederim: D ayrıca "yaklaşık 0 ve 1
ryxn

2
String[]Ve arasındaki boşluğu kaldırabilmelisiniz a. Ayrıca, değiştirmek gerekir printlnile print.
clismique

1
Sınıf ismi 1 karakter olabilir. java.util.UUID.fromStringİçe aktarmak yerine kullanabilirsiniz .
Poke

0

AWK, 98 bayt

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

Satırı her karakterde böler ve her karakterin onaltılık bir rakam olup olmadığını ve uygun yerlerde tire olup olmadığını kontrol eder. strtonumgeçersiz karakterleri dönüştürür 0. 0Ve m(ve keyfi olarak seçilen geçersiz karakter) karşılaştırması yapmak, ek adımlar gerektirir. Neyse ki 01geçerli bir onaltılık sayı, ama m1değil.

Başlangıçta iki fordöngü yazdım , ancak 1 byte'ı birlikte sıkarak kurtardım. :)

NOT: GAWKgirişi onaltılık sayılar olarak okuyabilir, ancak bu çok uzun bir komut satırı seçeneği gerektirir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.