No Salesforce CRM , todo objeto tem um ID alfanumérico de 15 caracteres, que diferencia maiúsculas de minúsculas. Se alguém está curioso, na verdade é o número da base 62 . No entanto, as ferramentas usadas para migração e integração de dados podem ou não suportar a distinção entre maiúsculas e minúsculas. Para superar isso, os IDs podem ser convertidos com segurança em IDs alfanuméricos que não diferenciam maiúsculas de minúsculas de 18 caracteres. Nesse processo, a soma de verificação alfanumérica de 3 caracteres é anexada ao ID. O algoritmo de conversão é:
Exemplo :
a0RE000000IJmcN
Divida o ID em três blocos de 5 caracteres.
a0RE0 00000 IJmcN
Inverta cada pedaço.
0ER0a 00000 NcmJI
Substitua cada caractere em cada pedaço por
1
se estiver em maiúsculas ou por0
outro modo.01100 00000 10011
Para cada número binário de 5 dígitos
i
, obtenha o caractere na posiçãoi
em concatenação do alfabeto maiúsculo e os dígitos 0-5 (ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
).00000 -> A, 00001 -> B, 00010 -> C, ..., 11010 -> Z, 11011 -> 0, ..., 11111 -> 5`
Produzindo:
M A T
Anexe esses caracteres, a soma de verificação, ao ID original.
Saída :
a0RE000000IJmcNMAT
Escreva o programa ou a função que usa a sequência alfanumérica de 15 caracteres (ASCII) como entrada e retorna a identificação de 18 caracteres.
A validação de entrada está fora do escopo desta questão. Os programas podem retornar qualquer valor ou falha na entrada inválida.
Por favor, não use os recursos de idiomas apropriados do Salesforce que tornam esse desafio trivial (como fórmula CASESAFEID()
, conversão Id
para String
APEX etc.).
Casos de teste
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);}}
. Porém, funciona apenas com IDs válidos do Salesforce.Respostas:
Ruby, 97 bytes
Este tem alguns truques realmente legais.
Meu instinto original de dividir a string em grupos de 5 caracteres foi
each_slice
:Acontece que está muito longo em comparação com um simples regex (
x.chars.each_slice(5)
vs.x.scan(/.{5}/)
). Isso parece óbvio em retrospectiva, mas eu realmente nunca pensei nisso ... talvez eu possa otimizar algumas das minhas respostas antigas de Ruby aqui.O que mais me orgulha nesta resposta, porém, é este pedaço de código:
Tudo bem, então aqui estão alguns antecedentes para os não-rubiistas. O Ruby separa completamente os booleanos (
TrueClass
,FalseClass
) dos números inteiros / (Numeric
) - o que significa que não há conversão automática de verdadeiro para 1 e falso para 0 também. Isso é chato durante o golfe (mas uma coisa boa ... para todos os outros fins).A abordagem ingênua de verificar se um único caractere está em maiúsculas (e retornar 1 ou 0) é
Podemos aprofundar isso um pouco mais (novamente, com uma expressão regular):
Mas então eu realmente comecei a pensar. Hmm ...
=~
retorna o índice de uma correspondência (portanto, para o nosso único personagem, sempre0
se houver uma correspondência) ou,nil
na falta de correspondência, um valor falso (tudo o resto, excetoFalseClass
em Ruby, é verdade). O||
operador pega seu primeiro operando, se for verdade, e seu segundo operando, caso contrário. Portanto, podemos jogar isso atéTudo bem, vamos ver o que está acontecendo aqui. Se
y
for uma letra maiúscula, ela não corresponderá[^A-Z]
, portanto a parte regex retornaránil
.nil || 1
é1
, então as letras maiúsculas se tornam1
. Se nãoy
houver uma letra maiúscula, a parte regex retornará0
(porque há uma correspondência no índice0
) e, como0
é verdade,0 || 1
é0
.... e somente depois de escrever tudo isso eu percebo que esse é realmente o mesmo comprimento que
y=~/[A-Z]/?1:0
. Haha, tudo bem.fonte
Pitão,
2322 bytes1 byte salvo por FryAmTheEggman .
Experimente online. Suíte de teste.
Esta pode ser a primeira vez que usei as
p
instruções rint no golfe.Explicação
fonte
MATL , 24 bytes
Usa a versão atual (9.1.0) do idioma / compilador.
Exemplos
Explicação
fonte
JavaScript (ES6), 108
Teste
fonte
CJam, 27 bytes
Execute todos os casos de teste.
Uma implementação bastante direta das especificações. A parte mais interessante é a conversão em caracteres na soma de verificação. Adicionamos 17 ao resultado de cada bloco. Pegue esse módulo 43 e adicione o resultado disso ao personagem
'0
.fonte
Japonês, 46 bytes
Não estou muito feliz com o comprimento, mas não consigo encontrar uma maneira de jogar golfe. Experimente online!
fonte
JavaScript (ES6),
137132 bytes4 bytes salvos graças a @ ՊՓԼՃՐՊՃՈԲՍԼ !
Explicação
Este desafio não é adequado para JavaScript. Não há uma maneira curta de reverter uma string e parece que a maneira mais curta de converter o número em um caractere é codificar cada caractere possível.
Se os dígitos na soma de verificação tiverem letras minúsculas, isso poderá ser feito em 124 bytes como este:
Teste
Mostrar snippet de código
fonte
parseInt([...n].reverse().join``,2)
poderia ser alterado para+`0b${[...n].reverse().join``}`
..replace(/.{5}/g,n=>/*stuff*/)
.MATLAB,
10098 bytesUma sequência será solicitada como entrada e a saída será exibida na tela.
Explicação
Provavelmente estou usando a abordagem mais direta aqui:
Agora abaixo de 100 bytes, graças a Luis Mendo!
fonte
e=['A':'Z',48:53]
PHP,
186181 bytesUnglofed
Comecei pensando que poderia torná-lo muito mais curto do que isso, mas fiquei sem idéias para torná-lo mais curto.
fonte
Python 2, 97 bytes
fonte
PowerShell, 162 bytes
OK, muitas coisas legais acontecendo neste. Vou começar com a segunda linha.
Tomamos a entrada como uma string via
$args[0]
e configuramos$a
para uso posterior. Isso é encapsulado()
para que seja executado e o resultado retornado (ou seja$a
) , para que possamos concatená-lo imediatamente com os resultados de três chamadas de função(f ...)
. Cada chamada de função passa como argumento a string de entrada indexada em pedaços de ordem inversa como uma matriz de caracteres - o que significa, para a entrada de exemplo,$a[4..0]
será igual a@('0','E','R','0','a')
a cada entrada como um caractere, não uma string.Agora, para a função, onde está a verdadeira carne do programa. Tomamos a entrada como
$f
, mas ela só é usada no final, então vamos nos concentrar primeiro. Como é passado como um array de caracteres (graças à nossa indexação anterior), podemos inseri-lo imediatamente em um loop com$f|%{...}
. Dentro do loop, pegamos cada caractere e executamos uma correspondência de regex com distinção entre maiúsculas e minúsculas com a-cmatch
qual resultará em true / false se estiver em maiúsculas / caso contrário. Nós convertemos isso como um número inteiro com o encapsulamento+()
, então essa matriz de 1 e 0 é-join
ed para formar uma string. Isso é passado como o primeiro parâmetro na[convert]::ToInt32()
chamada do .NET para alterar o binário (base2
) em decimal. Usamos esse número decimal resultante para indexar em uma string (-join(...)[...]
) A string é formulada primeiro como um intervalo(65..90)
que é convertido como um array de caracteres, depois concatenado com o range(0..5)
(ou seja, a string é"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
). Tudo isso é retornar o caractere apropriado da string.fonte
Jolf, 30 bytes
Finalmente, um provavelmente ainda divertido! Experimente aqui!
fonte
Python 3,
201 174138 bytesMuito obrigado a Trang Oul por apontar uma declaração de função que não precisava mais existir. E operadores ternários do Python. E alguma saída incorreta. Apenas ... apenas dê a ele votos positivos.
fonte
z()
uma vez, pode substituir sua chamada e salvar 25 bytes. Além disso, seu código atribui incorretamente em[
vez de0
.if else
por essa construção e o segundo por operador ternário.J, 36 bytes
Uso:
Experimente online aqui.
fonte
C,
120118 bytesFunciona para qualquer entrada cujo comprimento seja múltiplo de 5 :)
Ungolfed
fonte
{}
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
expressão, portanto, substituir por 442 não é uma opção. Na medida em!!isupper
que essa função não retorna 1 como verdadeira no meu sistema, ela retorna 256.!!
É uma maneira curta de convertê-la em um valor de retorno 0/1, não importa o quê. YMMV.C #, 171 bytes
Eu não sou muito bem praticado no golfe C #, mas aqui está uma chance.
fonte
char.IsUpper(t)
pode ser substituído port>=65&t<=90
(&
no bool em C # é basicamente um golf mais&&
curto sem curto-circuito).447
é mais curto que26*17
. Você não precisa fazer um separadoSelect
: você pode incluir o ternário diretamente noSum
. Considere substituir todos esses usosSubstring
por um loop baseado emTake
vez disso, por exemplofor(int i=0;i<3;i++)s.Skip(i*5).Take(5)
. Para referência futura,u!=""
seria menor queu.Length>0
(mas isso não é mais necessário se você estiver usandoTake
).n/26*17
não é equivalente an/442
, mas fora isso, obrigado pelas sugestões. Como afirmado, eu não sou muito experiente no golfe em C #, então isso é uma coisa excelente para eu considerar no futuro.C # 334
Se solicitado, vou reverter meu código para legível e publicá-lo.
fonte
Python 3, 87 bytes
fonte