Проверьте, допустим ли UUID без использования регулярных выражений


44

Для заданного строкового ввода напишите программу, которая печатает истинное значение в STDOUT или эквивалентное, если вход является допустимым UUID, без использования регулярных выражений.

Действительный UUID

32 шестнадцатеричные цифры, отображаемые в пяти группах, разделенных дефисами, в форме 8-4-4-4-12, всего 36 символов (32 буквенно-цифровых символа и четыре дефиса).

Источник

Тестовые случаи

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-nnnnnnnnnnnnили n[8]-n[4]-n[4]-n[4]-n[12]недопустимо
  • Входные данные могут быть взяты из функции STDINили в качестве аргумента функции
  • Ввод нечувствителен к регистру
  • Можно с уверенностью предположить, что ввод не будет содержать перевод строки или перевод строки.
  • Входные данные могут содержать любые печатные символы ASCII (включая пробелы)
  • Значение truthy должно быть напечатано на STDOUTили эквивалент , если вход является действительным UUID
  • Значение Falsey должно быть напечатано STDOUTили эквивалентно, если ввод не является допустимым UUID
  • Если вместо функции используется функция, STDOUTто результатом может быть возвращаемое значение функции
  • Значение truey / falsey не может быть напечатано STDERR.
  • Применяются стандартные лазейки
  • Это , поэтому выигрывает самая короткая программа в байтах. Удачи!

Leaderboard

Это фрагмент стека, который генерирует как таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ появляется, пожалуйста, начните свой ответ с заголовка, используя следующий шаблон уценки

## Language Name, N bytes

Где N - размер вашего сообщения в байтах

Если вы хотите включить в заголовок несколько чисел (например, пролистать старые оценки или включить флаги в счетчик байтов), просто убедитесь, что фактическая оценка является последней цифрой в заголовке.

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


32
Бедная сетчатка . D:
BrainSteel


8
Просто для справки, я могу предложить 28-байтовое решение Retina. (Так что не сумасшедшее преимущество над языками игр в гольфе , хотя бы в настоящее время быть ведущим.)
Мартин Эндер

5
Разрешены ли образцы Луа ? Они, конечно, не регулярные выражения.
Манатворк

1
@JacobKrall Я почти уверен, что это "ложь" на все твои вопросы. Я думаю, что задача достаточно ясна, что допустимы только строки вида \h{8}-\h{4}-\h{4}-\h{4}-\h{12}(где \hшестнадцатеричная цифра).
Мартин Эндер

Ответы:


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

Удивительное злоупотребление неявным кастингом +1
Downgoat

4
презрительный, презрительный, резкий, жгучий, разрушительный, унижающий, унижающий достоинство - (сравнивая ваш ответ с моим)
edc65

11

PowerShell, 29 21 84 49 37 байт

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

Большое спасибо тем людям в комментариях, которые помогали в этом гольфе не отставать от меняющихся правил - TessellatingHeckler , iFreilicht , Jacob Krall и Joey . Пожалуйста, смотрите историю изменений для ревизий и более старых версий.

Эта ревизия принимает входные данные как $g, а затем создает новую хеш-таблицу @{}с одним элементом, индекс 36устанавливается равным $g-as[guid]. При этом используется встроенный -asоператор для попытки преобразования между двумя типами данных .NET - из [string]в [guid]. Если преобразование прошло успешно, [guid]объект возвращается, в противном случае $nullвозвращается. Эта часть гарантирует, что входная строка является допустимым .NET GUID.

Следующим шагом является индексирование в хеш-таблицу с помощью [$g.length]. Если $gдлина не совсем 36 символов, вернется хеш-таблица $null, которая будет выведена в виде значения фальси. Если $gдлина составляет 36 символов, то результат вызова .NET будет выведен. Если $gнедопустимый GUID .NET (в любой форме), он будет $nullвыведен в виде фальшивого значения. В противном случае он выведет объект .NET GUID в качестве истинного значения - единственный способ вывести его, если он соответствует запрошенному формату запроса.

Примеры

Здесь я инкапсулирую вызов скрипта в скобках и явно приведу его к логическому значению для ясности.

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

2
Не могли бы вы просто сохранить 4 байта, пропустив !!()? Поскольку ценности $NULLи [guid]являются взаимоисключающими, они могут представлять ценности truthey и falsey, не так ли? Во всяком случае, отличный способ преобразовать в логическое значение, любите решение!
iFreilicht

@iFreilicht это точка; глядя на связанный пост «истина / ложная интерпретация» - я согласен, что это выглядит правдоподобно.
TessellatingHeckler

1
Это решение неправильно возвращает Trueдля 0FCE98AC13264C798EBC94908DA8B034, у которого нет дефисов
Джейкоб Кралл

1
@TessellatingHeckler Нет, слишком хорошо, чтобы быть правдой. Добавление цифры, например, 0FCE98AC-1326-4C79-8EBC-94908DA8B034D(дополнительная буква D в конце), возвращает значение «ложь» $TRUE, поскольку оно просто удаляет оскорбительную цифру, и первые 36 символов действительны.
AdmBorkBork

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

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

Из-за изменений в правилах этот ответ больше не является конкурентным :(

С, 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 байтов сэкономили, упрощая проверку длины (сложный способ был короче в первом наброске, но не сейчас)

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

Та же проблема, что и в моей предыдущей версии: верно для00000000-0000-0000-000 -000000000000
Qwertiy

Нет, но вы добавили неправильный тест. Начальный пробел не является проблемой, но его следует оставить позади, поскольку строка преобразуется при преобразовании в число. Смотрите мой комментарий выше с тестом.
Qwertiy

'00000000-0000-0000-000 -000000000000' теперь я вижу это @Qwertiy Я пропустил 3 нуля вместо 4
edc65

1
@ Стефнотч, я не согласен. Вне everyвызова uэто строка, а не массив
edc65

5

Из-за изменений в правилах этот ответ больше не является конкурентным :(

Pure 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 указывает на успех / TRUE, а 1 указывает на сбой / FALSE. Код возврата может быть проверен echo $?после запуска скрипта.


1
Сопоставление с шаблоном оболочки может не соответствовать синтаксису регулярных выражений, но класс символов определенно использует определение и синтаксис из регулярных выражений POSIX. Во всяком случае, это зависит от OP, чтобы решить, является ли это приемлемым.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Регулярные выражения могут включать классы символов Posix, но я не думаю, что это подразумевает, что все, что использует класс символов Posix, является регулярным выражением. В качестве другого примера trтакже используются классы символов Posix, но это не синтаксический анализатор регулярных выражений.
Цифровая травма

Вы можете сбрить несколько символов, избегая ненужных двойных кавычек, например, в формате printf.
Йенс

Я обновил задачу, чтобы уточнить - причина, по которой регулярные выражения были запрещены, состояла в том, чтобы сделать так, чтобы шестнадцатеричные шаблоны не могли использоваться для соответствия uuids
Jojodmo

4

Джольф, 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 Незначительная семантическая ошибка. Это исправлено сейчас.
Конор О'Брайен

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

Попробуйте онлайн . Выводит исходную строку, если истина, выводит пустую строку, если ложь ( это разрешено ).

Объяснение:

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

@ MartinBüttner, блин ... Я не осознавал этого, я исправлю это через несколько минут.
GamrCorps

3

Юлия, 86 байт

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

Это анонимная функция, которая принимает строку и возвращает логическое значение. Чтобы назвать его, дайте ему имя, например 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 байт

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

Метод Tможет быть вызван с любой ненулевой строкой, и trueв falseпротивном случае будет возвращен действительный идентификатор GUID . Это проверка в постоянном времени; по стоимости трех символов вы можете досрочно выйти из метода (сменить i < v.Lengthна i < v.Length && r).

Попробую отключить бай-счет позже.

Я, очевидно, оставил Guid.ParseExactпуть, потому что где в этом веселье? Вот оно, без особых попыток упростить его до 86 байтов :

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 байт

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. На неверном вводе он печатает Falseили 0, в зависимости от того, почему он был неверным. 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.

Я думаю , вы можете сохранить 2 байта , если заменить оба экземпляра returnс print. (В этом случае вы определенно захотите быть в Python 2, потому что printв Python 3 работает иначе).
mathmandan

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для ввода 12345678123456781234567812345678.
Деннис

если это try:print uuid.UUID(input())сработает, вы сможете сэкономить байты, потому что все, что вам нужно, это напечатать истинное значение
подземный

2
Эта программа принимает множество форматов UUID, но вопрос требует только 36-символьный формат UUID с дефисами.
Джейкоб Кралл

2
Вы можете спасти это, справившись с обновленными правилами, проверив, совпадает ли входная строка с uuid, преобразованным обратно в строку. Дает вам истинную ценность сразу.
agtoever

2

Pyth, 39 байт

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

Попробуй это здесь .


В вашей ссылке "попробуйте здесь" отсутствует \символ K\-k, поэтому он не может работать как есть.
Алекс

Это было исправлено сейчас
Blue

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

Common Lisp - 161

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

Возвращаемое значение, если true - это хеш, как число, которое является полезным результатом.

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 Да, безусловно! Спасибо
coredump

2

Символы F # 44

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

В F # функции с outпараметрами можно вызывать, опуская параметр out; его значение при возврате будет объединено с истинным возвращаемым значением функции в кортеж.

Здесь кортеж передается в fstфункцию, которая возвращает свой первый член, который в данном случае является логическим возвращаемым значением TryParseExact, указывающим на успех или неудачу вызова.

В качестве проверки правильности формата мы возвращаем trueтолько если строка длиной 36 символов.

До того, как я увидел ответ RobIII's 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

2
Вы можете удалить f=и пробелы вокруг строки в allблоке.
FryAmTheEggman

о,
круто

1
Вы можете сохранить 8 (или 6, то , возможно , необходимо добавить круглые скобки) байт путем преобразования all(..)установить тестирование включения: set(u)<=set("-0123456789abcdefABCDEF").
409_Конфликт

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 символов от центрального выражения!

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;

Это генерирует довольно много предупреждений и заметок в журнале, но не выводит их на 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, что ложно. Добавьте 1 к этому int, и мы получим гарантированное истинное значение - мы удалили все дефисы с помощью str.split (), поэтому мы не можем получить значение -1, и все не-0 целые числа являются правдивыми.


1

Функция С, 102

Изменение правила отклонило мой предыдущекло scanf()-ответ , так вот еще с ответом , используя 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()
  • Вернуть TRUE, если длина строки равна 36, а последний символ равен NUL.

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). Кроме того, поскольку вы можете печатать истинные значения , вы можете просто напечатать 0вместо 1<0и 1вместо 1>0.
Jojodmo

@Jojodmo Исходя из голосов, истинное значение имеет вид if(truthy_value){ doSomethingOnYes(); } else{ doSomethingOnFalse(); }Так что в Java логическое значение является истинным значением, но оно 1или 0нет. Только когда ОП задачи говорит что-то вроде: « Ваш вывод может быть истинным / ложным, 0/1, пустым / непустым; до тех пор, пока вы указываете, что вы используете. », Тогда вы действительно можете использовать, 0а 1не true/falseкак правдивый / значение фальси.
Кевин Круйссен

1
Что касается советов по гольфу для cookie: @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 для истинного и 0 для ложного

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и {.
Wheat Wizard

@WheatWizard спасибо: D также заметил, что я могу удалить "около 0 и 1
ryxn

2
Вы должны быть в состоянии удалить пространство между String[]и a. Кроме того, вы должны быть в состоянии заменить printlnна print.
clismique

1
Имя класса может быть 1 символом. Вы можете использовать java.util.UUID.fromStringвместо импорта.
Poke

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может читать ввод как шестнадцатеричные числа, но это требует очень длинной опции командной строки.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.