W Salesforce CRM każdy obiekt ma 15-znakowy alfanumeryczny identyfikator, w którym rozróżniana jest wielkość liter. Jeśli ktoś jest ciekawy, w rzeczywistości jest to liczba podstawowa-62 . Jednak narzędzia używane do migracji i integracji danych mogą, ale nie muszą obsługiwać rozróżniania wielkości liter. Aby temu zaradzić, identyfikatory można bezpiecznie przekonwertować na alfanumeryczne identyfikatory bez rozróżniania wielkości liter. W tym procesie do ID dołączana jest 3-znakowa alfanumeryczna suma kontrolna. Algorytm konwersji to:
Przykład :
a0RE000000IJmcN
Podziel identyfikator na trzy 5-znakowe części.
a0RE0 00000 IJmcN
Odwróć każdy fragment.
0ER0a 00000 NcmJI
Zastąp każdą postać w każdym fragmencie,
1
jeśli ma wielkie litery lub0
jeśli inaczej.01100 00000 10011
Dla każdej 5-cyfrowej liczby binarnej
i
uzyskaj znak w pozycjii
w połączeniu wielkich liter i cyfr 0-5 (ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
).00000 -> A, 00001 -> B, 00010 -> C, ..., 11010 -> Z, 11011 -> 0, ..., 11111 -> 5`
Wydajność:
M A T
Dołącz te znaki, sumę kontrolną, do oryginalnego identyfikatora.
Wyjście :
a0RE000000IJmcNMAT
Napisz program lub funkcję, która pobiera 15-znakowy ciąg alfanumeryczny (ASCII) jako dane wejściowe i zwraca 18-znakowy identyfikator.
Sprawdzanie poprawności danych wejściowych jest poza zakresem tego pytania. Programy mogą zwracać dowolną wartość lub ulegać awarii w przypadku nieprawidłowych danych wejściowych.
Proszę nie używać funkcji języków propretorialnych Salesforce, które sprawiają, że to wyzwanie jest trywialne (takie jak formuła CASESAFEID()
, konwersja Id
do String
APEX i c).
Przypadki testowe
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);}}
. Działa tylko z prawidłowymi identyfikatorami Salesforce.Odpowiedzi:
Ruby, 97 bajtów
Ten ma naprawdę fajne sztuczki.
Mój pierwotny instynkt dzielenia łańcucha na grupy po 5 znaków to
each_slice
:Okazuje się, że jest to zbyt długie w porównaniu do zwykłego wyrażenia regularnego (
x.chars.each_slice(5)
vs.x.scan(/.{5}/)
). Z perspektywy czasu wydaje się to oczywiste, ale tak naprawdę nigdy o tym nie myślałem ... być może uda mi się zoptymalizować niektóre z moich starych odpowiedzi Ruby.Najbardziej dumna z tej odpowiedzi jest jednak fragment kodu:
W porządku, oto kilka podstaw dla nie-Rubyistów. Ruby całkowicie oddziela wartości logiczne (
TrueClass
,FalseClass
) od liczb całkowitych / liczb (Numeric
) - co oznacza, że nie ma automatycznej konwersji z prawdy na 1 i fałszu na 0. Jest to denerwujące podczas gry w golfa (ale dobra rzecz ... do wszystkich innych celów).Naiwne podejście do sprawdzania, czy pojedynczy znak jest pisany wielkimi literami (i zwracanie 1 lub 0) to
Możemy to zrobić nieco dalej (ponownie, używając wyrażenia regularnego):
Ale potem naprawdę zacząłem myśleć. Hmm ...
=~
zwraca indeks dopasowania (więc dla naszego pojedynczego znaku, zawsze0
jeśli występuje dopasowanie) lubnil
w przypadku braku dopasowania, wartość fałszowania (wszystko inne opróczFalseClass
prawdy w Ruby).||
Operator wykonuje swój pierwszy argument, jeśli to truthy, a jej drugi argument inaczej. Dlatego możemy zagrać w golfa do tego stopniaDobra, spójrzmy na to, co się tutaj dzieje. Jeśli
y
jest wielką literą, nie będzie pasować[^A-Z]
, więc część wyrażenia regularnego powrócinil
.nil || 1
jest1
, więc stają się wielkie litery1
. Jeśliy
jest coś, ale wielką literą, regex część wróci0
(bo tam jest mecz w indeksie0
), a ponieważ0
jest truthy,0 || 1
jest0
.... i dopiero po spisaniu tego wszystkiego zdaję sobie sprawę, że jest to faktycznie taka sama długość jak
y=~/[A-Z]/?1:0
. Haha, no cóż.źródło
Pyth,
2322 bajtów1 bajt zapisany przez FryAmTheEggman .
Wypróbuj online. Zestaw testowy.
To może być pierwszy raz, kiedy użyłem
p
instrukcji rint podczas gry w golfa.Wyjaśnienie
źródło
MATL , 24 bajty
Korzysta z bieżącej wersji (9.1.0) języka / kompilatora.
Przykłady
Wyjaśnienie
źródło
JavaScript (ES6), 108
Test
źródło
CJam, 27 bajtów
Uruchom wszystkie przypadki testowe.
Dość prosta implementacja specyfikacji. Najbardziej interesującą częścią jest konwersja znaków na sumę kontrolną. Dodajemy 17 do wyniku każdej porcji. Weź ten modulo 43 i dodaj wynik tego do postaci
'0
.źródło
Japt, 46 bajtów
Nie jestem zbyt zadowolony z długości, ale nie mogę znaleźć sposobu na grę w golfa. Wypróbuj online!
źródło
JavaScript (ES6),
137132 bajtów4 bajty zapisane dzięki @ ՊՓԼՃՐՊՃՈԲՍԼ !
Wyjaśnienie
To wyzwanie nie jest w ogóle odpowiednie dla JavaScript. Nie ma krótkiego sposobu na odwrócenie łańcucha i wygląda na to, że najkrótszym sposobem na konwersję liczby na znak jest zakodowanie na stałe każdego możliwego znaku.
Gdyby cyfry w sumie kontrolnej były małe, można by to zrobić w 124 bajtach w następujący sposób:
Test
Pokaż fragment kodu
źródło
parseInt([...n].reverse().join``,2)
można zmienić na+`0b${[...n].reverse().join``}`
..replace(/.{5}/g,n=>/*stuff*/)
.MATLAB,
10098 bajtówJako dane wejściowe zostanie zażądany ciąg, a dane wyjściowe zostaną wyświetlone na ekranie.
Wyjaśnienie
Prawdopodobnie używam tutaj najbardziej bezpośredniego podejścia:
Teraz poniżej 100 bajtów dzięki Luisowi Mendo!
źródło
e=['A':'Z',48:53]
PHP,
186181 bajtówNieklofowany
Zacząłem myśleć, że mogę to zrobić o wiele krócej, ale zabrakło mi pomysłów, aby go skrócić.
źródło
Python 2, 97 bajtów
źródło
PowerShell, 162 bajty
OK, wiele fajnych rzeczy dzieje się w tym. Zacznę od drugiej linii.
Pobieramy dane wejściowe jako ciąg znaków
$args[0]
i ustawiamy je$a
na później. Jest on enkapsulowany,()
więc jest wykonywany, a wynik zwracany (tj.$a
), Dzięki czemu możemy natychmiast połączyć łańcuch z wynikami trzech wywołań funkcji(f ...)
. Każde wywołanie funkcji przekazuje jako argument łańcuch wejściowy indeksowany w kawałkach w odwrotnej kolejności jako tablica znaków - co oznacza, że na przykład dane wejściowe$a[4..0]
będą równe@('0','E','R','0','a')
każdemu wpisowi jako znak, a nie ciąg znaków.Przejdźmy teraz do funkcji, w której znajduje się prawdziwe mięso programu. Przyjmujemy dane wejściowe jako
$f
, ale jest to używane tylko do końca, więc skupmy się na tym, najpierw. Ponieważ jest przekazywany jako tablica znaków (dzięki naszemu wcześniejszemu indeksowaniu), możemy natychmiast potokować go w pętli za pomocą$f|%{...}
. Wewnątrz pętli bierzemy każdą postać i przeprowadzamy dopasowanie wyrażenia regularnego z rozróżnianiem wielkości liter, z-cmatch
którym wynikiem będzie prawda / fałsz, jeśli będzie to wielkie litery / inaczej. Rzucamy to jako liczbę całkowitą z enkapsulowaniem+()
, a następnie tablica 1 i 0 jest-join
edytowana w celu utworzenia łańcucha. Jest on następnie przekazywany jako pierwszy parametr w[convert]::ToInt32()
wywołaniu .NET w celu zmiany wartości binarnej (podstawowej2
) na dziesiętną. Używamy wynikowej liczby dziesiętnej do indeksowania w łańcuch (-join(...)[...]
). Łańcuch jest najpierw formułowany jako zakres(65..90)
rzutowany jako tablica znaków, a następnie łączony z zakresem(0..5)
(tzn. Łańcuch jest"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
). Wszystko po to, aby zwrócić odpowiedni znak z łańcucha.źródło
Jolf, 30 bajtów
Nareszcie, prawdopodobnie wciąż nie do przyjęcia! Wypróbuj tutaj!
źródło
Python 3,
201 174138 bajtówOgromne podziękowania dla Trang Oul za wskazanie deklaracji funkcji, która już nie musiała istnieć. I trójskładnikowe operatory Pythona. I niektóre nieprawidłowe dane wyjściowe. Po prostu ... po prostu daj mu głos.
źródło
z()
raz, możesz zastąpić jej wywołanie i zaoszczędzić 25 bajtów. Ponadto kod niepoprawnie przypisuje[
zamiast0
.if else
z tej konstrukcji , a drugi z potrójnego operatora.J, 36 bajtów
Stosowanie:
Wypróbuj online tutaj.
źródło
DO,
120118 bajtówDziała dla każdego wejścia, którego długość jest wielokrotnością 5 :)
Nie golfił
źródło
{}
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
wyrażenia, więc zamiana na 442 nie jest opcją. O ile!!isupper
funkcja ta nie zwraca 1 dla wartości true w moim systemie, zwraca 256.!!
Jest to krótki sposób na przekonwertowanie jej na wartość zwracaną 0/1 bez względu na wszystko. YMMV.C #, 171 bajtów
Nie jestem zbyt dobrze wyszkolony w golfie w C #, ale tutaj jest szansa.
źródło
char.IsUpper(t)
można go zastąpićt>=65&t<=90
(&
on bool w C # jest w zasadzie krótszym golfem&&
bez zwarcia).447
jest krótszy niż26*17
. Nie musisz robić osobnegoSelect
: możesz dołączyć trójkę bezpośrednio doSum
. Zastanów się nad zastąpieniem tych wszystkich zastosowańSubstring
pętlą opartą naTake
npfor(int i=0;i<3;i++)s.Skip(i*5).Take(5)
. W przyszłościu!=""
będzie krótszy niżu.Length>0
(ale nie jest to już konieczne, jeśli używaszTake
).n/26*17
nie jest równoważnen/442
, ale poza tym, dzięki za sugestie. Jak już wspomniano, nie mam zbyt dużego doświadczenia w grze w golfa w C #, więc to wszystko jest dla mnie świetne do rozważenia w przyszłości.C # 334
Na żądanie cofnę kod z powrotem do czytelnego i opublikuję.
źródło
Python 3, 87 bajtów
źródło