В Salesforce CRM каждый объект имеет 15-символьный буквенно-цифровой идентификатор, который учитывает регистр. Если кому-то интересно, на самом деле это номер базы 62 . Однако инструменты, используемые для переноса и интеграции данных, могут поддерживать или не поддерживать чувствительность к регистру. Чтобы преодолеть это, идентификаторы могут быть безопасно преобразованы в 18-символьные, без учета регистра буквенно-цифровые идентификаторы. В этом процессе трехзначная буквенно-цифровая контрольная сумма добавляется к идентификатору. Алгоритм преобразования:
Пример :
a0RE000000IJmcN
Разделите ID на три 5-символьных блока.
a0RE0 00000 IJmcN
Переверните каждый кусок.
0ER0a 00000 NcmJI
Замените каждый символ в каждом чанке,
1
если он в верхнем регистре или0
если в противном случае.01100 00000 10011
Для каждого 5-значного двоичного числа
i
, получить символ в положенииi
в сочетании прописных букв и цифр 0-5 (ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
).00000 -> A, 00001 -> B, 00010 -> C, ..., 11010 -> Z, 11011 -> 0, ..., 11111 -> 5`
Уступая:
M A T
Добавьте эти символы, контрольную сумму, к исходному идентификатору.
Выход :
a0RE000000IJmcNMAT
Напишите программу или функцию, которая принимает 15-символьную буквенно-цифровую (ASCII) строку в качестве ввода и возвращает 18-значный идентификатор.
Проверка входных данных выходит за рамки этого вопроса. Программы могут возвращать любое значение или сбой при неверном вводе.
Пожалуйста, не используйте функцию Salesforce propretiary Языки , которые делают эту задачу тривиальной (например, формулы CASESAFEID()
, преобразовывая Id
к String
в APEX & с).
Тестовые случаи
a01M00000062mPg -> a01M00000062mPgIAI
001M000000qfPyS -> 001M000000qfPySIAU
a0FE000000D6r3F -> a0FE000000D6r3FMAR
0F9E000000092w2 -> 0F9E000000092w2KAA
aaaaaaaaaaaaaaa -> aaaaaaaaaaaaaaaAAA
AbCdEfGhIjKlMnO -> AbCdEfGhIjKlMnOVKV
aBcDEfgHIJKLMNO -> aBcDEfgHIJKLMNO025
public class X{public X(Id i){System.debug((String)i);}}
. Работает только с действительными идентификаторами Salesforce.Ответы:
Рубин, 97 байт
У этого есть некоторые действительно аккуратные уловки.
Мой оригинальный инстинкт для разделения строки на группы из 5 символов был
each_slice
:Оказывается, это слишком долго по сравнению с простым регулярным выражением (
x.chars.each_slice(5)
противx.scan(/.{5}/)
). Оглядываясь назад, это кажется очевидным, но я никогда не задумывался об этом ... возможно, я могу оптимизировать некоторые из моих старых ответов Ruby здесь.Однако в этом ответе я больше всего горжусь этим фрагментом кода:
Хорошо, так что вот немного предыстории для нерубистов. Ruby полностью отделяет логические значения (
TrueClass
,FalseClass
) от целых чисел / (Numeric
) - это означает, что нет автоматического преобразования из true в 1 и из false в 0. Это раздражает во время игры в гольф (но это хорошо ... для всех других целей).Наивный подход к проверке, является ли единственный символ заглавными (и возвращает 1 или 0),
Мы можем получить это немного дальше (опять же, с помощью регулярного выражения):
Но потом я действительно начал думать. Хм ...
=~
возвращает индекс совпадения (то есть для нашего отдельного символа, всегда,0
если совпадение есть) или,nil
если совпадение не найдено, ложное значение (все остальное, кромеFalseClass
правдоподобного в Ruby).||
Оператор берет свой первый операнд , если это truthy, а его второй операнд в противном случае. Поэтому мы можем сыграть в гольф доХорошо, давайте посмотрим на то, что здесь происходит. Если
y
это заглавная буква, она не будет соответствовать[^A-Z]
, поэтому часть регулярного выражения вернетсяnil
.nil || 1
есть1
, поэтому заглавные буквы становятся1
. Еслиy
это что-то, кроме заглавной буквы, часть регулярного выражения вернется0
(потому что в индексе есть совпадение0
), и, поскольку0
это правда,0 || 1
есть0
.... и только после записи всего этого я понимаю, что это на самом деле такая же длина, как
y=~/[A-Z]/?1:0
. Хаха, да ладно.источник
Pyth,
2322 байта1 байт сохранен FryAmTheEggman .
Попробуйте онлайн. Тестирование.
Это может быть первый раз, когда я использовал
p
инструкцию по игре в гольф.объяснение
источник
MATL , 24 байта
Использует текущую версию (9.1.0) языка / компилятора.
Примеры
объяснение
источник
JavaScript (ES6), 108
Тестовое задание
источник
CJam, 27 байт
Запустите все тестовые случаи.
Довольно простая реализация спецификации. Самая интересная часть - это преобразование символов в контрольную сумму. Мы добавляем 17 к результату каждого куска. Возьми это по модулю 43 и добавь результат этого к персонажу
'0
.источник
Japt, 46 байт
Не слишком доволен длиной, но я не могу найти способ поиграть в нее. Попробуйте онлайн!
источник
JavaScript (ES6),
137132 байта4 байта сохранены благодаря @ ՊՓԼՃՐՊՃՈԲՍԼ !
объяснение
Эта задача совсем не подходит для JavaScript. Нет короткого способа перевернуть строку, и похоже, что самый короткий способ преобразовать число в символ - это жестко закодировать каждый возможный символ.
Если бы цифры в контрольной сумме были разрешены в нижнем регистре, это могло бы быть сделано в 124 байтах следующим образом:
Тестовое задание
Показать фрагмент кода
источник
parseInt([...n].reverse().join``,2)
можно изменить на+`0b${[...n].reverse().join``}`
..replace(/.{5}/g,n=>/*stuff*/)
.MATLAB,
10098 байтВ качестве входных данных будет запрошена строка, а выходные данные будут отображены на экране.
объяснение
Я, наверное, использую самый простой подход здесь:
Теперь ниже 100 байтов благодаря Луису Мендо!
источник
e=['A':'Z',48:53]
PHP,
186181 байтUnglofed
Я начал с того, что думал, что смогу сделать его намного короче, но у меня не осталось идей сделать его короче.
источник
Python 2, 97 байт
источник
PowerShell, 162 байта
ОК, в этом много чего интересного. Я начну со второй строки.
Мы принимаем ввод как строку через
$args[0]
и устанавливаем его$a
для использования позже. Он инкапсулирован()
так, что он выполняется и возвращается результат (т. Е.$a
), Поэтому мы можем сразу же объединить его с результатами трех вызовов функций(f ...)
. Каждый вызов функции передает в качестве аргумента входную строку, индексированную в чанках в обратном порядке, как массив символов - значение для входного примера$a[4..0]
будет равно@('0','E','R','0','a')
каждой записи как символ, а не строка.Теперь о функции, где настоящее мясо программы. Мы воспринимаем ввод как
$f
, но он используется только ближе к концу, поэтому давайте сначала сосредоточимся на этом. Поскольку он передается как массив символов (благодаря нашей предыдущей индексации), мы можем немедленно передать его в цикл с помощью$f|%{...}
. Внутри цикла мы берем каждый символ и выполняем регистрозависимое совпадение с учетом регистра,-cmatch
которое приводит к значению true / false, если оно прописное / в противном случае. Мы приводим это как целое число к инкапсуляции+()
, затем этот массив из 1 и 0-join
редактируется для формирования строки. Это затем передается в качестве первого параметра в .NET который приводится как массив символов, а затем объединяется с диапазоном[convert]::ToInt32()
вызова , чтобы изменить двоичный (базовый2
) в десятичной системе . Мы используем это результирующее десятичное число для индексации в строку (-join(...)[...]
). Строка сначала формулируется как диапазон(65..90)
(0..5)
(то есть строка"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
). Все это - вернуть соответствующий символ из строки.источник
Джольф, 30 байт
Наконец-то, вероятно, все еще в шутку! Попробуй это здесь!
источник
Python 3,
201 174138 байтБольшое спасибо Trang Oul за указание на объявление функции, которая больше не нужна. И Python троичные операторы. И какой-то неверный вывод. Просто ... просто отдай ему голоса.
источник
z()
один раз, вы можете заменить ее вызов и сохранить 25 байтов. Кроме того, ваш код неправильно назначает[
вместо0
.if else
на эту конструкцию, а второй на троичный оператор.J, 36 байт
Использование:
Попробуйте это онлайн здесь.
источник
C,
120118 байтРаботает для любого входа, длина которого кратна 5 :)
Ungolfed
источник
{}
j;main(n,v,s)char**v,*s;{for(printf(s=v[1]);*s;s+=5,putchar(n+65-n/442))for(n=0,j=5;j--;n=n*2+isupper(s[j]));}
n/26*17
выражения, поэтому замена на 442 не вариант. Поскольку!!isupper
эта функция не возвращает 1 для true в моей системе, она возвращает 256. Это!!
короткий способ преобразовать его в возвращаемое значение 0/1, несмотря ни на что. YMMV.C #, 171 байт
Я не очень хорошо практиковался в игре в гольф на C #, но здесь есть шанс.
источник
char.IsUpper(t)
могут быть заменены наt>=65&t<=90
(&
на bool в C # это в основном гольф-короче&&
без короткого замыкания).447
короче чем26*17
. Вам не нужно делать отдельноеSelect
: вы можете включить троичный непосредственно вSum
. Попробуйте заменить все эти использованияSubstring
цикла на основеTake
, например, напримерfor(int i=0;i<3;i++)s.Skip(i*5).Take(5)
. Для дальнейшего использованияu!=""
будет корочеu.Length>0
(но это больше не нужно, если вы используетеTake
).n/26*17
не эквивалентноn/442
, но кроме этого, спасибо за предложения. Как уже говорилось, я не очень разбираюсь в гольфе в C #, так что это все, что я должен рассмотреть в будущем.C # 334
Если потребуется, я верну свой код обратно для чтения и опубликую его.
источник
Python 3, 87 байт
источник