Periksa apakah UUID valid tanpa menggunakan regex

44

Diberikan input string, tulis sebuah program yang mencetak nilai kebenaran ke STDOUT atau setara jika inputnya adalah UUID yang valid, tanpa menggunakan regex.

UUID yang valid adalah

32 digit heksadesimal, ditampilkan dalam lima kelompok yang dipisahkan oleh tanda hubung, dalam bentuk 8-4-4-4-12 untuk total 36 karakter (32 karakter alfanumerik dan empat tanda hubung).

Sumber

Uji Kasus

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)

Aturan

  • Ekspresi Reguler tidak diizinkan
  • Pencocokan pola literal yang seperti regex tidak diizinkan. Misalnya, menggunakan [0-9a-fA-F]atau pengidentifikasi heksadesimal lainnya (kami akan menyebutnya n) dan kemudian cocok nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnatau n[8]-n[4]-n[4]-n[4]-n[12]tidak diizinkan
  • Input dapat diambil dari STDINatau sebagai argumen ke suatu fungsi
  • Input tidak sensitif huruf
  • Aman untuk berasumsi bahwa input tidak akan mengandung umpan baris atau baris baru.
  • Input dapat berisi karakter ASCII yang dapat dicetak (termasuk spasi)
  • Nilai kebenaran harus dicetak ke STDOUTatau setara jika inputnya adalah uuid yang valid
  • Nilai kepalsuan harus dicetak STDOUTatau setara jika inputnya bukan uuid yang valid
  • Jika menggunakan fungsi, alih-alih menggunakan STDOUT, output bisa menjadi nilai balik dari fungsi
  • Nilai truthy / falsey tidak bisa dicetak STDERR.
  • Celah standar berlaku
  • Ini adalah , jadi program terpendek dalam byte menang. Semoga berhasil!

Papan peringkat

Ini adalah Stack Snippet yang menghasilkan leaderboard dan ikhtisar pemenang berdasarkan bahasa.

Untuk memastikan jawaban Anda muncul, silakan mulai jawaban Anda dengan tajuk utama menggunakan templat Penurunan harga berikut

## Language Name, N bytes

Di mana N adalah ukuran, dalam byte, dari kiriman Anda

Jika Anda ingin memasukkan beberapa angka dalam tajuk Anda (misalnya, mencoret skor lama, atau menyertakan bendera dalam jumlah byte), pastikan saja skor sebenarnya adalah angka terakhir di tajuk Anda

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

Jojodmo
sumber
32
Retina yang buruk . D:
BrainSteel
Terkait
FryAmTheEggman
8
Hanya untuk referensi, saya dapat datang dengan solusi Retina 28-byte. (Jadi bukan keuntungan gila dari bahasa golf meskipun saat ini akan memimpin.)
Martin Ender
5
Apakah pola Lua diperbolehkan? Mereka tentu bukan ekspresi reguler.
manatwork
1
@ JacobKall, saya cukup yakin itu "salah" untuk semua pertanyaan Anda. Saya pikir tantangannya cukup jelas bahwa hanya string bentuk \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(di mana \hdigit heksadesimal) yang valid.
Martin Ender

Jawaban:

15

CJam, 31 30 29 byte

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

Jalankan semua test case di sini.

Penjelasan

Alih-alih pola yang cocok dengan input secara langsung, kami pertama-tama mengubahnya menjadi bentuk yang lebih sederhana yang dapat dengan mudah dibandingkan dengan string pola tunggal.

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

JavaScript ES6, 73 55 56 karakter

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

Versi 55 karakter sebelumnya memiliki masalah dengan spasi tambahan dalam grup:

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

Uji:

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
sumber
Luar biasa (dan layu untuk saya) +1
edc65
@ edc65, apa yang Anda maksud dengan "layu"?
Qwertiy
Penyalahgunaan mengagumkan dari casting implisit +1
Downgoat
4
menghina, menghina, pedas, menyengat, menghancurkan, mempermalukan, memalukan - (membandingkan jawaban Anda dengan saya)
edc65
11

PowerShell, 29 21 84 49 37 Bytes

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

Terima kasih banyak kepada orang-orang di komentar yang membantu bermain golf ini untuk mengikuti aturan yang berubah - TessellatingHeckler , iFreilicht , Jacob Krall , dan Joey . Silakan lihat riwayat edit untuk revisi dan versi yang lebih lama.

Revisi ini mengambil input sebagai $g, kemudian membuat tabel hash baru @{}dengan satu elemen, indeks 36diset sama dengan $g-as[guid]. Ini menggunakan -asoperator bawaan untuk mencoba konversi antara dua tipe data .NET - dari [string]hingga [guid]. Jika konversi berhasil, [guid]objek dikembalikan, yang lain $nulldikembalikan. Bagian ini memastikan bahwa string input adalah .NET GUID yang valid.

Langkah selanjutnya adalah mengindeks ke tabel hash dengan [$g.length]. Jika $gpanjangnya tidak tepat 36 karakter, tabel hash akan kembali $null, yang akan ditampilkan sebagai nilai falsey. Jika $gpanjangnya 36 karakter, maka hasil dari panggilan .NET akan ditampilkan. Jika $gbukan .NET GUID yang valid (dalam bentuk apa pun), maka akan ditampilkan $nullsebagai nilai falsey. Jika tidak maka akan menampilkan objek .NET GUID sebagai nilai kebenaran - satu-satunya cara yang bisa dihasilkan adalah jika cocok dengan format tantangan yang diminta.

Contohnya

Di sini saya merangkum panggilan skrip dalam parens dan secara eksplisit casting sebagai Boolean untuk kejelasan.

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
sumber
4
Saya akan melempar !!($args[0]-as[guid])21 byte.
TessellatingHeckler
2
Tidak bisakah Anda hanya menyimpan 4 byte dengan meninggalkan !!()? Sebagai nilai-nilai $NULLdan [guid]saling eksklusif, mereka memenuhi syarat untuk mewakili nilai-nilai yang sebenarnya dan palsu, bukan? Bagaimanapun, cara yang bagus untuk mengonversi ke boolean, cinta solusinya!
iFreilicht
@ iFreilicht itu intinya; melihat posting "interpretasi kebenaran / falsey" yang ditautkan - Saya setuju itu terlihat valid.
TessellatingHeckler
1
Solusi ini tidak benar kembali Trueuntuk 0FCE98AC13264C798EBC94908DA8B034, yang tidak memiliki tanda hubung
Jacob Krall
1
@ TessellatingHeckler Tidak, terlalu bagus untuk menjadi kenyataan. Menambahkan digit, seperti 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(tambahan D di akhir) mengembalikan falsey $TRUE, karena hanya memotong digit yang menyinggung dan 36 karakter pertama valid.
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))))))

Tidak Disatukan:

(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
Tuan Yuuma
sumber
8

Karena perubahan pada aturan , jawaban ini tidak lagi kompetitif :(

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

Sebagian besar cukup jelas. The %nFormat specifier memberikan jumlah byte yang dibaca sejauh ini, yang harus 36. scanf()pengembalian jumlah item yang cocok, yang harus 6. akhir %charus tidak cocok apa-apa. Jika ya, maka ada teks tambahan, dan scanf()akan mengembalikan 7.

Kompilasi dengan -wuntuk menekan peringatan sial (ada beberapa).

Trauma Digital
sumber
6

JavaScript ES6, 70 83

CATATAN thx to @Qwertiy untuk menemukan bug (dan menyarankan beberapa perbaikan dan perbaikan)

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

9 byte lainnya disimpan simplifiying cek panjang (jalan kompleks itu lebih pendek dalam draft pertama, tapi tidak sekarang)

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

Dijelaskan

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
)

Cuplikan tes

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
sumber
-1-('0x'+h)=>1/('0x'+h)
Qwertiy
Masalah yang sama seperti dalam versi saya sebelumnya: true for00000000-0000-0000-000 -000000000000
Qwertiy
Tidak. Tapi kamu menambahkan tes yang salah. Leading space bukan masalah, tetapi tertinggal satu, karena string dipangkas saat mengonversi ke angka. Lihat komentar saya di atas dengan tes.
Qwertiy
'00000000-0000-0000-000 -000000000000' 'sekarang saya melihatnya @Qwertiy Saya melewatkan 3 nol alih-alih 4
edc65
1
@Stefnotch saya tidak setuju. Di luar everypanggilan uadalah string, bukan array
edc65
5

Karena perubahan pada aturan , jawaban ini tidak lagi kompetitif :(

Bash Murni (tanpa utilitas eksternal), 78

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

Mengambil input dari baris perintah.

  • The printfmembangun string berikut - - - -.
  • The p=baris mengubah ini untuk pola berikut: [[: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:]]. Perhatikan ini terlihat sangat mirip dengan ekspresi reguler. Namun, tidak dalam konteks ini. Ini adalah pola untuk pencocokan pola shell . Ini mirip dalam konsep dengan ekspresi reguler, tetapi merupakan konstruk yang berbeda (dan sintaksis).
  • Baris terakhir memeriksa apakah
    • input tidak kosong
    • jika menarik pola keluar dari string input menghasilkan string kosong

Idiomatik ke shell, kode pengembalian 0 menunjukkan keberhasilan / BENAR dan 1 menunjukkan kegagalan / SALAH. Kode kembali dapat diperiksa echo $?setelah menjalankan skrip.

Trauma Digital
sumber
1
Pencocokan pola shell mungkin tidak mengikuti sintaks regex, tetapi kelas karakter pasti menggunakan definisi dan sintaksis dari POSIX regex. Bagaimanapun, terserah OP untuk memutuskan apakah itu dapat diterima.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Ekspresi reguler dapat menyertakan kelas karakter Posix, tapi saya tidak berpikir itu menyiratkan bahwa apa pun yang menggunakan kelas karakter Posix adalah regex. Sebagai contoh lain trjuga menggunakan kelas karakter Posix, tetapi bukan pengurai regex.
Digital Trauma
Anda dapat memangkas beberapa karakter dengan menghindari tanda kutip ganda yang tidak berguna, misalnya dalam format printf.
Jens
Saya telah memperbarui tantangan untuk mengklarifikasi - alasan mengapa regex tidak diizinkan adalah untuk membuatnya sehingga pola hex tidak dapat digunakan untuk mencocokkan uuids
Jojodmo
4

Jolf, 32 byte

Coba di sini!

 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

Karena kesalahan dalam kode saya, ini lebih lama dari yang seharusnya. :( [8,4,4,4,12] harus sama dengan {8444*26}, tetapi }juga merupakan penutupan fungsi: P

Conor O'Brien
sumber
2
Jadi itu lebih lama dari seharusnya karena Anda memiliki perintah ambigu dalam bahasa yang Anda buat? : P
Rɪᴋᴇʀ
@RikerW Kesalahan semantik kecil. Sudah diperbaiki sekarang.
Conor O'Brien
4

MATL , 55 byte

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

Saya menahan diri untuk tidak menggunakan Ybfunction ( strsplit) karena agak mirip regexp(..., 'split'). Ini hanya menggunakan pengindeksan dan perbandingan karakter.

Contoh

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

Penjelasan

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

CJam, 52 42 byte

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

Cobalah online . Keluarkan string asli jika benar, menghasilkan string kosong jika salah ( ini diizinkan ).

Penjelasan:

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
sumber
A7*)<tidak akan menghapus banyak karakter yang tidak valid, seperti spasi +,, ?...
Martin Ender
@ MartinBüttner oh tembak ... Saya tidak menyadari itu, saya akan memperbaikinya dalam beberapa menit.
GamrCorps
3

Julia, 86 byte

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

Ini adalah fungsi anonim yang menerima string dan mengembalikan boolean. Untuk menyebutnya, berikan nama, mis f=s->....

Tidak Disatukan:

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.
sumber
3

C # 196 byte

using System.Linq;class P{bool T(string v){var r=v.Length==36;for(var i=0;i<v.Length;i++)r&=new[]{8,13,18,23}.Any(t=>t==i)?v[i]=='-':v[i]>47&&v[i]<58|v[i]>64&&v[i]<71|v[i]>96&&v[i]<103;return r;}}

Tidak Disatukan:

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

Metode Tdapat dipanggil dengan string non-null dan akan kembali trueuntuk GUID yang valid, falsejika tidak. Ini adalah validasi waktu-konstan; dengan biaya tiga karakter Anda dapat keluar dari metode lebih awal (ubah i < v.Lengthke i < v.Length && r).

Akan mencoba untuk mendapatkan bytecount lebih jauh nanti.

Saya jelas telah meninggalkan Guid.ParseExactjalan karena di mana kesenangan dalam itu? Ini dia, tanpa banyak usaha untuk menurunkannya lebih jauh dalam 86 byte :

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

Tidak Disatukan:

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

Python 2, 99 112 byte

def f(u):
 try:u=u.split()[0];int(u.replace('-',''),16);print[8,4,4,4,12]==map(len,u.split('-'))
 except:print 0

Pada input yang valid, ia mencetak True. Pada input yang tidak valid ia mencetak Falseatau 0, tergantung pada mengapa itu tidak valid. Falsedan 0keduanya falsey dalam Python.

Fungsi harus memeriksa 3 hal:

  • Setiap karakter bukan tanda hubung adalah digit atau dalam ABCDEF
  • Tepatnya ada 4 tanda hubung
  • Ada 8 karakter sebelum tanda hubung pertama, 12 setelah yang terakhir, dan 4 di antara dua lainnya

Berikut ini rincian untuk menunjukkan bagaimana memeriksa mereka. Agak ketinggalan zaman tapi saya lapar jadi saya akan memperbaruinya nanti.

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.
monmon bawah tanah
sumber
Saya kira Anda dapat menyimpan 2 byte jika Anda mengganti kedua contoh returndengan print. (Dalam hal ini Anda pasti ingin berada di Python 2, karena printbekerja secara berbeda dalam Python 3.)
mathmandan
1
Ini tidak berfungsi di Python 3, karena mapsekarang mengembalikan "objek peta", bukan daftar.
Tim Pederick
Ini tidak berfungsi di python 2 (mungkin 3 juga) karena intfungsinya memungkinkan spasi - 0FCE98ac-1326-4c79-8EBC-94908da8B03dengan spasi tambahan. Lihat komentar dalam jawaban Pyth yang dihapus di sini jika bisa.
Biru
2

Python 2, 57 byte

Syukurlah untuk built-in! - pastikan untuk menyertakan string dalam tanda kutip.

import uuid
try:uuid.UUID(input());print 1
except:print 0
nimi
sumber
5
Menurut dokumen yang Anda tautkan, itu akan mencetak 1untuk input 12345678123456781234567812345678.
Dennis
jika ini berhasil, Anda dapat menyimpan byte dengan melakukan try:print uuid.UUID(input())karena yang diperlukan hanyalah Anda mencetak nilai yang sebenarnya
undergroundmonorail
2
Program ini menerima banyak format UUID, tetapi pertanyaannya hanya menginginkan format UUID 36 karakter, dengan tanda hubung.
Jacob Krall
2
Anda bisa menyelamatkan ini, mengatasi aturan yang diperbarui, dengan memeriksa apakah string input sama dengan uuid yang dikonversi kembali ke string. Memberi Anda nilai kebenaran segera.
agtoever
2

Pyth, 39 byte

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

Coba di sini .

Biru
sumber
Tautan "coba di sini" Anda tidak memiliki \karakter K\-k, jadi gagal berjalan seperti apa adanya.
Alex
Itu sudah diperbaiki sekarang
Biru
2

Perl 6 ,  83   67 byte

# 83 bytes
{
  (
    my@a=.uc.split('-')
  ).map(*.comb)⊆('0'..'9','A'..'F')
&&
  @a».chars~~(8,4,4,4,12)
}

# 67 bytes
{
  (
    $/=.split('-')
  ).map({:16($_)//|()})==5
&&
  $/».chars~~(8,4,4,4,12)
}

(Hitungan tidak termasuk baris baru atau indentasi karena mereka tidak diperlukan)

pemakaian:

# 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
sumber
2

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

Nilai yang dikembalikan jika true adalah hash, sebagai angka, yang merupakan hasil yang berguna untuk dimiliki.

Tidak disatukan

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

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

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

   ;; Finally, we decode the undashed string as a number in base 16,
   ;; but do not throw an exception if this is not possible.
   (ignore-errors
    (parse-integer undashed :radix 16))))
coredump
sumber
@Jojodmo Ya, tentu saja! Terima kasih
coredump
2

F # 44 karakter

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

Dalam F #, fungsi dengan outparameter dapat dipanggil dengan menghilangkan parameter keluar; nilainya pada pengembalian akan dikombinasikan dengan nilai pengembalian sejati fungsi menjadi tupel.

Di sini, tuple disalurkan ke fstfungsi, yang mengembalikan anggota pertamanya, yang dalam hal ini adalah nilai pengembalian Boolean dari TryParseExact, yang menunjukkan keberhasilan atau kegagalan panggilan.

Sebagai tanda centang untuk format yang benar, kami kembali truehanya jika string sepanjang 36 karakter.

Sebelum saya melihat jawaban C # RobIII, saya tidak pernah berpikir untuk menggunakan TryParseExact, jadi jawaban saya adalah tiga karakter lebih lama:

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

TryParse(string, Guid) menerima input dalam format berikut:

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

Dari jumlah tersebut, hanya yang kedua adalah 36 karakter.

phoog
sumber
2

Python 2, 93 89 85 byte

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

The map()jaminan panggilan itu bagian adalah dari panjang yang tepat, dan all()tes masing-masing karakter untuk menjadi baik tanda hubung atau sewenang-wenang-kasus hex digit. Ekspresi generator sedang menguji masing-masing karakter dengan mengulangi seluruh string itu, jadi itu bukan metode yang paling performan, saya rasa, tapi itu harus memenuhi kasus uji:

>>> 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
sumber
Adakah yang tahu mengapa jawaban Python terpendek yang benar telah diturunkan? Tidak cukup penjelasan?
rsandwick3
Jojodmo - jika ada kebingungan tentang hal ini, saya tidak menolak perubahan yang Anda usulkan - Saya sudah melakukan pengeditan karena saya telah melewatkan karakter AF (saya menyalin dari jendela tempat saya menguji kasus negatif), dan Komunitas otomatis -menolak proposal Anda tanpa saya sadari bahkan telah diajukan. Pada saat saya tahu Anda akan mengusulkannya, @nimi sudah melakukan koreksi ke pos. Saya sangat berharap bahwa tidak ada hubungannya dengan downvote, karena itu akan berdampak sangat buruk pada komunitas ini. Pokoknya, saya akan menganggap itu hal lain, dan menambahkan sedikit penjelasan.
rsandwick3
2
Anda dapat menghapus f=dan spasi di sekitar string di allblok.
FryAmTheEggman
oh luar biasa, tangkapan yang bagus - diedit
rsandwick3
1
Anda dapat menyimpan 8 (atau 6, Anda mungkin perlu menambahkan kurung) byte dengan mengkonversi Anda all(..)untuk mengatur pengujian inklusi: set(u)<=set("-0123456789abcdefABCDEF").
409_Konflik
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;

Sebenarnya menggunakan stdin dan stdout - salah satu fitur yang kurang dikenal dari bahasa khusus ini. Bekerja untuk contoh-contoh yang diberikan sejauh ini, tetapi mungkin tidak dalam semua kasus. Mungkin bisa diperbaiki.

Pendekatan yang lebih baik - satu karakter pada satu waktu:

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;

Dipotong 6 karakter lain dari ekspresi sentral!

Tidak Disatukan:

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;

Ini menghasilkan beberapa peringatan dan catatan di log, tetapi tidak mencetaknya ke stdout atau stderr, jadi saya pikir ini adalah permainan yang adil.

pengguna3490
sumber
1

C, 391 byte

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#define F printf("0")
#define T printf("1")
#define E return 0
main(){char s[99],*t;int k=1,l,i;scanf("%99[^\n]",s);if(s[strlen(s)-1]=='-'){F;E;}t=strtok(s,"-");while(t!=NULL){for(i=0,l=0;t[i]!=0;i++,l++){if(!isxdigit(t[i])){F;E;}}if((k==1&&l!=8)||((k>1&&k<5)&&l!=4)||(k==5&&l!=12)){F;E;}k++;t=strtok(NULL,"-");}if(k==6){T;E;};F;}
pengguna2064000
sumber
1

MATLAB, 126 byte

function f(a)
b='-';if length(a)==36&&a(9)==b&&a(13)==b&&a(17)==b&&a(21)==b;a(a==b)=[];if any(isnan(hex2dec(a)));0;end;1;end;0
costrom
sumber
1

Python 3, 134 byte

def a(i):
 try:l=[1+int(k,16)and(len(k)==c)for k,c in zip(i.split("-"),[8,4,4,4,12])];return(len(l)==5)&(0 not in l)
 except:return 0

int (k, 16) mencoba untuk melemparkan k ke basis-16 int. Pada karakter selain 0-9a-fA-F- gagal, dalam hal ini kita mengembalikan 0, yang salah. Tambahkan 1 ke int itu dan kami mendapatkan nilai kebenaran yang dijamin - kami telah menghapus semua tanda hubung dengan str.split () sehingga kami tidak bisa mendapatkan nilai -1 dan semua int non-0 benar.

Pjoelj
sumber
1

Fungsi C, 102

Perubahan aturan dianulir c saya sebelumnya scanf()jawabannya berbasis , jadi di sini lain jawaban c menggunakan isxdigit()yang saya pikir harus diizinkan untuk bersaing :

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

Cobalah online.

  • Periksa -karakter (ASCII 45) di posisi yang relevan - jika demikian, ganti dengan 0s (ASCII 48 (= 45 + 3))
  • Berjalan tali memeriksa setiap char dengan isxdigit()
  • Kembalikan BENAR jika panjang string adalah 36 dan karakter akhir adalah NUL.
Trauma Digital
sumber
1

Batch, 148 139 + 2 = 150 141 byte

@set/pu=
@for %%d in (1 2 3 4 5 6 7 8 9 A B C D E F)do @set u=!u:%%d=0!
@if -!u!==-00000000-0000-0000-0000-000000000000 exit/b0
@exit/b1

Menambahkan 2 byte karena Anda perlu menggunakan /vperalihan ke CMD.EXE.

Keluar dengan ERRORLEVEL 0 pada kesuksesan, 1 pada kegagalan.

Sunting: Disimpan beberapa byte terutama karena :=case-sensitive tetapi ada tweak lain juga.

Neil
sumber
1

Java, 345 byte

interface q{static void main(String[]a){int i=-1;char[]b=a[0].toCharArray();java.io.PrintStream u=System.out;if(b.length>36||b.length<36)u.print(1<0);if(b[8]!='-'||b[13]!='-'||b[18]!='-'||b[23]!='-')u.print(1<0);while(++i<b.length){if(i!=8&&i!=13&&i!=18&&i!=23){if(!((b[i]>='0'&&b[i]<='F')||(b[i]>='a'&&b[i]<='f')))u.print(1<0);}}u.print(1>0);}}

Input adalah argumen baris perintah pertama. Output adalah kode kesalahan (0 berarti UUID valid, 1 berarti tidak valid)

Tidak dikoleksi dengan komentar:

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: Tidak melihat bagian STDOUT. Ups, perbaiki sekarang.

Kue kering
sumber
Bagus! Anda dapat menggantinya if(b.length>36||b.length<36)dengan sederhana if(b.length!=36). Juga, karena Anda bisa mencetak nilai-nilai yang sebenarnya , Anda bisa mencetak 0bukan 1<0, dan 1bukannya 1>0.
Jojodmo
@Jojodmo Berdasarkan suara, nilai kebenaran adalah dalam bentuk if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }Jadi di Jawa, boolean adalah nilai kebenaran, tetapi ada 1atau 0tidak. Hanya ketika OP dari suatu tantangan mengatakan sesuatu seperti: " Output Anda bisa benar / salah, 0/1, kosong / tidak kosong; selama Anda menentukan apa yang Anda gunakan. " Maka Anda memang dapat menggunakan 0dan 1bukannya true/falsesebagai kebenaran / nilai falsey.
Kevin Cruijssen
1
Adapun tips golf untuk cookie: @Jojodmo memang tepat untuk menggantikannya if(b.length!=36); ||bisa |di banyak tempat, juga &&untuk &; if(...!='-')bisa if(...!=45); int i=-1; ... while(++i<b.length){dapat diganti dengan for(int i=-1;++i<b.length;){; 'F'bisa 70( 'f'bisa 102, tapi itu tidak masalah karena itu adalah byte-count yang sama). Saya suka bagaimana Anda menggunakan java.io.PrintStream u=System.out;btw, saya harus ingat itu! Jadi terima kasih.
Kevin Cruijssen
1

Swift 3, 50 byte

Lewati sebuah string s

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

PHP, 109 Bytes

mencetak 1 untuk true dan 0 untuk 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) lebih pendek 5 Bytes in_array($i,[8,13,18,23])

112 Bytes

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

113 Bytes

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

Java, 172 byte 168 byte (Terima kasih Wheat Wizard)

Agak curang sejak saya menggunakan java.util.UUID, tapi begini:

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 tidak disatukan:

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
sumber
Selamat datang di situs ini! Saya pikir Anda dapat menghapus ruang antara trydan {.
Wheat Wizard
@WheatWizard terima kasih: D juga memperhatikan saya dapat menghapus "sekitar 0 dan 1
ryxn
2
Anda harus dapat menghapus ruang antara String[]dan a. Anda juga harus bisa menggantinya printlndengan print.
clismique
1
Nama kelas bisa 1 karakter. Anda dapat menggunakan java.util.UUID.fromStringalih-alih mengimpor.
Poke
0

AWK, 98 byte

BEGIN{FS=""}{for(j=4;k<NF;){h+=(j+=5)<25?$j=="-":0
s+=strtonum("0x"$++k 1)>0}$0=h+s==36&&NF==36}1

Cukup pisahkan garis pada setiap karakter dan periksa apakah setiap karakter adalah angka heks dan ada tanda hubung di tempat yang sesuai. strtonummengkonversi karakter yang tidak valid ke 0. Membuat perbandingan antara 0dan m(dan karakter tidak sah yang dipilih secara sewenang-wenang) memerlukan langkah-langkah tambahan. Untungnya 01adalah nomor hex yang valid, tetapi m1tidak.

Awalnya saya menulis dua forloop, tetapi saya menghemat 1 byte dengan meremasnya. :)

CATATAN: GAWKdapat membaca input sebagai angka hex, tetapi ini membutuhkan opsi baris perintah yang sangat panjang.

Robert Benson
sumber