在不使用正则表达式的情况下检查UUID是否有效


44

给定字符串输入,编写一个程序,如果输入是有效的UUID,则在不使用正则表达式的情况下将真实值打印到STDOUT或等效项。

有效的UUID是

32个十六进制数字,分为5组,用连字符分隔,以8-4-4-4-12的形式表示,总共36个字符(32个字母数字字符和4个连字符)。

资源

测试用例

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)

规则

  • 不允许使用正则表达式
  • 不允许使用类似于正则表达式的文字模式匹配。例如,使用[0-9a-fA-F]或其他十六进制标识符(我们将其称为n),然后匹配nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnnn[8]-n[4]-n[4]-n[4]-n[12]不允许
  • 输入可以取自STDIN函数或可以作为函数的参数
  • 输入不区分大小写
  • 可以安全地假定输入将包含换行符或换行符。
  • 输入中可以包含任何可打印的ASCII字符(包括空格)
  • truthy值 必须印到STDOUT或等价的,如果该输入是一个有效的UUID
  • falsey值 必须印到STDOUT或等价的,如果输入是不是有效的UUID
  • 如果使用函数,而不是使用STDOUT,则输出可以是函数的返回值
  • 真假值不能打印到STDERR
  • 适用标准漏洞
  • 这是,因此以字节为单位的最短程序获胜。祝好运!

排行榜

这是一个堆栈片段,可按语言生成排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头

## Language Name, N bytes

N是提交内容的大小(以字节为单位)

如果要在标头中包含多个数字(例如,敲击旧分数或在字节数中包含标志),只需确保实际分数是标头中的最后一个数字

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


32
视网膜不良。D:
BrainSteel 2015年


8
仅供参考,我可以提出一个28字节的Retina解决方案。(因此,尽管目前处于领先地位,但与高尔夫语言相比并没有什么疯狂的优势。)
Martin Ender

5
允许Lua的模式吗?它们当然不是正则表达式。
manatwork

1
@JacobKrall我很确定这对您的所有问题都是“虚假”。我认为挑战很明显,只有格式\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\h十六进制数字)的字符串有效。
马丁·恩德

Answers:


15

CJam,31 30 29字节

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

在这里运行所有测试用例。

说明

与其直接对输入进行模式匹配,我们首先将其转换为更简单的形式,可以将其与单个模式字符串轻松进行比较。

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个字符

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

先前的55个字符的版本在组中的尾随空格有问题:

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

测试:

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

很棒(对我来说是凋零)+1
edc65

@ edc65,“枯萎”是什么意思?
Qwertiy 2015年

隐式转换+1的令人敬畏的滥用
Downgoat 2015年

4
轻蔑,轻蔑,严厉,严厉,刺痛,破坏性,羞辱,痛苦-(比较您对我的回答)
edc65

11

PowerShell,29 21 84 49 37字节

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

非常感谢在这个高尔夫球协助评论人跟上不断变化的规则- TessellatingHeckleriFreilicht雅各布·克劳,和乔伊。请查看编辑历史记录,以了解修订和较旧的版本。

此修订版将输入作为$g,然后创建一个@{}具有一个元素的新哈希表,索引36设置为$g-as[guid]。这使用内置的-as运算符尝试在两种.NET数据类型之间进行转换-从[string][guid]。如果转换成功,[guid]则返回一个对象,否则$null返回。这部分确保输入字符串是有效的.NET GUID。

下一步是使用索引到哈希表中[$g.length]。如果$g长度不完全是36个字符,则哈希表将返回$null,将作为假值输出。如果$g长度为36个字符,则将输出.NET调用的结果。如果$g不是有效的.NET GUID(以任何形式),则它将输出$null为falsey值。否则,它将输出.NET GUID对象作为真实值-可以输出的唯一方法是,如果它与挑战的请求格式匹配。

例子

在这里,我将脚本调用封装在parens中,并为清楚起见将其显式转换为布尔值。

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个字节。
TessellatingHeckler,2015年

2
您不能通过省略掉来保存4个字节!!()吗?由于这些值$NULL[guid]是互斥的,因此它们有资格代表真实价值和虚假价值,不是吗?无论如何,转换为布尔值的好方法,喜欢解决方案!
iFreilicht 2015年

@iFreilicht是重点;查看链接的“真实/虚假解释”帖子-我同意它看起来有效。
TessellatingHeckler 2015年

1
该解决方案错误地返回True0FCE98AC13264C798EBC94908DA8B034,它没有连字符
雅各布·克劳

1
@TessellatingHeckler Nope,太好了,难以置信。附加一个数字,例如0FCE98AC-1326-4C79-8EBC-94908DA8B034D(末尾加D)将返回falsey $TRUE,因为它只是将有问题的数字修剪掉并且前36个字符有效。
AdmBorkBork 2015年

9

Emacs Lisp,236字节

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

取消高尔夫:

(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

由于规则的更改,此答案不再具有竞争力:(

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

大多是相当自我解释。该%n格式说明给出的字节数读到目前为止,这应该是36. scanf()返回匹配的项目数,这应该是6.最后%c不应该匹配什么。如果是这样,则存在尾随文本,scanf()并将返回7。

编译-w以消除讨厌的警告(有多个)。


6

JavaScript ES6,70 83

注意 @Qwertiy,以查找错误(并建议一些改进和修复)

Thx @CᴏɴᴏʀO'Bʀɪᴇɴ已保存2个字节

其他9个字节保存simplifiying长度校验(复杂的方式在第一稿较短,但不是现在)

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

讲解

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
)

测试片段

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

与我以前的版本相同的问题:适用于00000000-0000-0000-000 -000000000000
Qwertiy 2015年

不。但是您添加了错误的测试。前导空格不是问题,但尾随空格是一个问题,因为转换为数字时会修剪字符串。参见我上面的评论进行测试。
Qwertiy 2015年

'00000000-0000-0000-000 -000000000000'现在我看到它@Qwertiy我错过了3个零而不是4个
edc65

1
@Stefnotch我不同意。every通话之外u是字符串,而不是数组
edc65

5

由于规则的更改,此答案不再具有竞争力:(

纯Bash(无外部实用程序),78

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

从命令行获取输入。

  • printf构建以下字符串- - - -
  • p=行将其转换为以下模式:[[: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:]]。注意,这看起来很像正则表达式。但是,不是在这种情况下。这是用于外壳模式匹配的模式。这在概念上与正则表达式相似,但是结构(和语法)不同。
  • 最后一行检查是否
    • 输入为非空
    • 如果将模式从输入字符串中拉出会产生一个空字符串

类似于外壳程序,返回码0表示成功/正确,返回码1表示失败/错误。echo $?运行脚本后,可以使用来检查返回码。


1
外壳模式匹配可能不遵循regex的语法,但是字符类肯定使用POSIX regex的定义和语法。无论如何,由OP决定是否可以接受。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 2015年

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳正则表达式可能包含Posix字符类,但我不认为这意味着任何使用Posix字符类的东西都是正则表达式。作为另一个示例,tr也使用Posix字符类,但不是正则表达式解析器。
Digital Trauma 2015年

您可以通过避免使用无用的双引号(例如采用printf格式)来去除一些字符。
詹斯(Jens)2015年

我已经更新了要澄清的挑战-禁止使用正则表达式是为了使其无法使用十六进制模式来匹配uuid
Jojodmo 2015年

4

Jolf,32个字节

在这里尝试

 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

由于我的代码中有错误,因此此时间比应有的长。:( [8,4,4,4,12] 应该与相同{8444*26},但}应该是一个函数:P的关闭


2
因此,它比必须的要长,因为您使用所创建的语言使用了模棱两可的命令?:P
Rɪᴋᴇʀ

@RikerW轻微的语义错误。现在已修复。
Conor O'Brien 2015年

4

MATL,55字节

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

我避免使用Yb函数(strsplit),因为它与有点相似regexp(..., 'split')。这仅使用索引和字符比较。

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

说明

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

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

在线尝试。如果为true,则输出原始字符串;如果为false,则输出空白字符串(允许使用)。

说明:

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*)<不会删除许多无效字符,例如空格+?...
Martin Ender 2015年

@MartinBüttner哦,开枪……我没有意识到,请过几分钟再解决。
GamrCorps,2015年

3

朱莉娅,86字节

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

这是一个匿名函数,它接受一个字符串并返回一个布尔值。要给它起个名字,例如f=s->...

取消高尔夫:

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

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

取消高尔夫:

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

T可以使用任何非空字符串来调用方法truefalse否则将返回有效的GUID 。这是一个持续时间验证。您只需花三个字符就可以提前退出方法(更改i < v.Lengthi < v.Length && r)。

稍后将尝试进一步减少字节数。

我显然已经省略了Guid.ParseExact路,因为那里的乐趣在哪里?在这里,没有太多尝试将其进一步压缩为86个字节

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

取消高尔夫:

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

2

Python 2中,99个 112字节

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

在有效输入上,它打印True。在无效的输入上,将打印False0,具体取决于无效的原因。False并且0在Python中都是假的。

该功能必须检查3件事:

  • 每个非连字符都是数字或以 ABCDEF
  • 共有4个连字符
  • 第一个连字符前有8个字符,最后一个连字符后有12个字符,其他两个字符之间有4个字符

以下是显示如何检查它们的细目。它有点过时了,但是我很饿,所以以后再更新。

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.

我想如果将两个实例替换为return,则可以节省2个字节print。(在这种情况下,您肯定要使用Python 2,因为print在Python 3中的工作方式有所不同。)
mathmandan 2015年

1
这在Python 3中不起作用,因为map现在返回的是“地图对象”,而不是列表。
蒂姆·佩德里克

这在python 2(可能也是3)中int不起作用,因为该函数允许使用空格- 0FCE98ac-1326-4c79-8EBC-94908da8B03尾随空格。如果可以,请在此处查看已删除的Pyth答案中的评论。
蓝色

2

Python 2,57字节

感谢天哪内置!-确保将字符串用引号引起来。

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

5
根据您链接到的文档,该文档将1作为input 打印12345678123456781234567812345678
丹尼斯2015年

如果这try:print uuid.UUID(input())行得通,您将可以通过执行此操作来节省字节,因为所需要做的就是打印一个真实的值
Undergroundmonorail

2
该程序接受许多UUID格式,但是问题只需要带连字符的36个字符的UUID格式。
雅各布·克劳

2
您可以通过检查输入字符串是否等于转换回字符串的uuid来解决此问题,以应对更新的规则。立即为您提供真实的价值。
agtoever


2

Perl 6的 83   67个字节

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

(计数不包括换行符或缩进,因为它们不需要)

用法:

# give it a name
my &code = {...}

say map &code, «
  D293DBB2-0801-4E60-9141-78EAB0E298FF
  0FCE98AC-1326-4C79-8EBC-94908DA8B034
  0fce98ac-1326-4c79-8ebc-94908da8b034
  0FCE98ac-1326-4c79-8EBC-94908da8B034
  00000000-1326-4c79-8EBC-94908da8B034
»;
# (True True True True True)

say map &code, «
  0GCE98AC-1326-4C79-8EBC-94908DA8B034
 '0FCE98AC 1326-4C79-8EBC-94908DA8B034'
  0FCE98AC-13264C79-8EBC-94908DA8B034
  0FCE98AC-13264-C79-8EBC-94908DA8B034
  0FCE98ACD-1326-4C79-8EBC-94908DA8B034
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-
  0FCE98AC-1326-4C79-8EBC-94908DA8B034-123
»;
# (False False False False False False False)

2

普通Lisp-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,则返回的值是作为数字的哈希值,这是有用的结果。

不打高尔夫球

(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是的,绝对可以!谢谢
coredump

2

F#44个字符

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

在F#中,out可以通过省略out参数来调用带有参数的函数。其返回值将与函数的真实返回值合并为一个元组。

在这里,将元组通过管道传递给该fst函数,该函数返回其第一个成员,在这种情况下,该成员是TryParseExact的布尔返回值,指示调用成功还是失败。

为了检查格式是否正确,我们true仅在字符串长度为36个字符时才返回。

在我看到RobIII的C#答案之前,我还没有想到要使用TryParseExact,所以我的答案是再长三个字符:

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

TryParse(string, Guid) 接受以下格式的输入:

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

其中,只有第二个是36个字符长。


2

Python 2,93 89 85字节

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

map()调用保证这些部分的长度正确,并all()测试每个字符是否为连字符或任意大小写的十六进制数字。生成器表达式通过遍历整个字符串来测试每个字符,因此,恐怕它不是性能最高的方法,但它应该满足测试用例:

>>> 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答案已被否决吗?没有足够的解释?
rsandwick3

Jojodmo –如果对此感到困惑,我不会拒绝您建议的更改–我已经进行了编辑,因为我错过了AF字符(我是从测试否定案例的窗口中复制的)和Community auto -拒绝了您的提议,甚至不知该提议是否提出。到我知道您提出的时候,@ nimi已经对标题进行了更正。我非常希望这与下降投票无关,因为那将对该社区造成非常不利的影响。无论如何,我认为这是另一回事,并添加更多说明。
rsandwick3 2015年

2
您可以f=在代码all块中删除和字符串周围的空格。
FryAmTheEggman 2015年

哦,太好了,很不错-编辑
rsandwick3

1
通过将您all(..)的设置转换为包含测试,您可以节省8(或6,您可能需要添加括号)字节set(u)<=set("-0123456789abcdefABCDEF")
409_Conflict 2015年

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;

实际上使用stdin和stdout-这种特定语言鲜为人知的功能之一。适用于到目前为止给出的示例,但可能并非在所有情况下都适用。可能可以改进。

更好的方法-一次一个字符:

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;

在中央表情上打了另外6个字符!

取消高尔夫:

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;

这会在日志中生成很多警告和注释,但不会将它们打印到stdout或stderr,因此我认为这是公平的游戏。


1

C,391字节

#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个字节

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个字节

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强制转换为以16为底的int。在0-9a-fA-F-以外的字符上,它失败,在这种情况下,我们返回0,这是虚假的。在该int上加1,我们得到保证的真实值-我们用str.split()除去了所有的连字符,所以我们不能得到值-1,而所有非0 int都是真实的。


1

C函数102

规则改变不允许我以前的C scanf()为基础的答案,所以这里的另一种C答案使用isxdigit(),我认为应该允许竞争

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

在线尝试。

  • 检查-相关位置的字符(ASCII 45)-如果是,则将它们替换为0s(ASCII 48(= 45 + 3))
  • 遍历字符串检查每个字符 isxdigit()
  • 如果字符串长度为36并且最后一个字符为NUL,则返回TRUE。

1

分批,148 139 + 2 = 150个 141字节

@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

添加了2个字节,因为您需要使用/v切换到CMD.EXE

成功时以ERRORLEVEL 0退出,失败时以1退出。

编辑:保存一些字节主要是因为:=不区分大小写,但也有其他调整。


1

Java,345字节

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

输入是第一个命令行参数。输出为错误代码(0表示有效的UUID,1表示无效)

取消评论:

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

编辑:没注意到STDOUT部分。糟糕,现在已修复。


真好!您可以if(b.length>36||b.length<36)简单地用代替if(b.length!=36)。此外,因为你可以打印truthy值,你可以简单地打印0,而不是1<0和,1而不是1>0
Jojodmo '17

@Jojodmo 对基于选票,一个truthy值的形式if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }所以在Java中的布尔是truthy价值,但1还是0没有。只有当挑战的OP发出类似这样的信息时:“ 您的输出可以为true / false,0/1,为空/非空;只要您指定要使用的内容即可。 ”然后,您的确可以使用01不是true/false如实/ falsey值。
凯文·克鲁伊森

1
至于曲奇的高尔夫技巧:@Jojodmo确实可以用替换它来代替if(b.length!=36)|||在多个地方,以及&&&; if(...!='-')可以if(...!=45); int i=-1; ... while(++i<b.length){可以替换为for(int i=-1;++i<b.length;){; 'F'可以是70'f'可以是102,但这没关系,因为它是相同的字节数)。我喜欢您如何使用java.io.PrintStream u=System.out;顺便说一句,我应该记住那个!那谢谢啦。
凯文·克鲁伊森

1

Swift 3,50个字节

传递字符串 s

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

1

PHP,109字节

打印1表示true,0表示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) 比这短5个字节 in_array($i,[8,13,18,23])

112字节

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

113字节

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

0

Java,172个字节 168个字节(感谢Wheat Wizard)

自从我使用java.util.UUID以来,它有点欺骗,但是这里有:

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

非高尔夫版本:

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

欢迎光临本站!我想你可以删除之间的空间try{
小麦巫师

@WheatWizard谢谢您:D还注意到我可以删除“ 0和1左右”
ryxn

2
你应该能够删除之间的空间String[]a。此外,你应该能够替换printlnprint
clismique

1
类名可以是1个字符。您可以使用java.util.UUID.fromString而不是导入。

0

AWK,98个字节

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

只需在每个字符处分割行,然后检查每个字符是否为十六进制数字,以及在适当的位置是否有连字符。 strtonum将无效字符转换为0。在0和之间m(以及任意选择的无效字符)进行比较需要其他步骤。幸运的01是一个有效的十六进制数字,但m1不是。

最初,我编写了两个for循环,但通过将它们压缩在一起节省了1个字节。:)

注意:GAWK可以将输入读取为十六进制数字,但这需要非常长的命令行选项。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.