En Salesforce CRM , cada objeto tiene una ID alfanumérica de 15 caracteres, que distingue entre mayúsculas y minúsculas. Si alguien tiene curiosidad, en realidad es el número base 62 . Sin embargo, las herramientas utilizadas para la migración e integración de datos pueden o no admitir mayúsculas y minúsculas. Para superar eso, las ID se pueden convertir de manera segura en ID alfanuméricas que no distinguen entre mayúsculas y minúsculas de 18 caracteres. En ese proceso, se agrega suma de verificación alfanumérica de 3 caracteres a la ID. El algoritmo de conversión es:
Ejemplo :
a0RE000000IJmcN
Divide la identificación en tres fragmentos de 5 caracteres.
a0RE0 00000 IJmcN
Invierta cada trozo.
0ER0a 00000 NcmJI
Reemplace cada personaje en cada fragmento por
1
si está en mayúscula o por0
lo contrario.01100 00000 10011
Para cada número binario de 5 dígitos
i
, obtenga el carácter en la posicióni
en concatenación del alfabeto en mayúscula y los dígitos 0-5 (ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
).00000 -> A, 00001 -> B, 00010 -> C, ..., 11010 -> Z, 11011 -> 0, ..., 11111 -> 5`
Flexible:
M A T
Agregue estos caracteres, la suma de verificación, a la ID original.
Salida :
a0RE000000IJmcNMAT
Escriba un programa o función que tome una cadena alfanumérica de 15 caracteres (ASCII) como entrada y devuelva una ID de 18 caracteres.
La validación de entrada está fuera del alcance de esta pregunta. Los programas pueden devolver cualquier valor o bloquearse en una entrada no válida.
Por favor, no use las características de los lenguajes propios de Salesforce que hacen que este desafío sea trivial (como la fórmula CASESAFEID()
, la conversión Id
a String
APEX & c).
Casos de prueba
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);}}
. Sin embargo, solo funciona con ID de Salesforce válidas.Respuestas:
Ruby, 97 bytes
Este tiene algunos trucos muy buenos.
Mi instinto original para dividir la cadena en grupos de 5 caracteres fue
each_slice
:Resulta que eso es muuuuucho tiempo en comparación con una simple expresión regular (
x.chars.each_slice(5)
vs.x.scan(/.{5}/)
). Esto parece obvio en retrospectiva, pero nunca lo pensé realmente ... tal vez pueda optimizar algunas de mis viejas respuestas de Ruby aquí.Sin embargo, lo que más me enorgullece en esta respuesta es este código:
Muy bien, así que aquí hay algunos antecedentes para los no rubíes. Ruby separa completamente los booleanos (
TrueClass
,FalseClass
) de los enteros / números (Numeric
), lo que significa que tampoco hay conversión automática de verdadero a 1 y falso a 0. Esto es molesto durante el golf (pero algo bueno ... para todos los demás fines).El enfoque ingenuo para verificar si un solo carácter es mayúscula (y devolver 1 o 0) es
Podemos bajar esto un poco más (de nuevo, con una expresión regular):
Pero entonces realmente empecé a pensar. Hmm ...
=~
devuelve el índice de una coincidencia (por lo tanto, para nuestro único personaje, siempre0
si hay una coincidencia) o,nil
en caso de no coincidir, un valor falso (todo lo demás exceptoFalseClass
es verdad en Ruby). El||
operador toma su primer operando si es verdadero, y su segundo operando de lo contrario. Por lo tanto, podemos jugar golf hastaMuy bien, veamos qué está pasando aquí. Si
y
es una letra mayúscula, no coincidirá[^A-Z]
, por lo que la parte regex volveránil
.nil || 1
es decir1
, las letras mayúsculas se vuelven1
. Siy
es cualquier cosa menos una letra mayúscula, la parte regex regresará0
(porque hay una coincidencia en el índice0
), y como0
es verdad, lo0 || 1
es0
.... y solo después de escribir todo esto me doy cuenta de que en realidad tiene la misma longitud que
y=~/[A-Z]/?1:0
. Jaja, oh bueno.fuente
Pyth,
2322 bytes1 byte guardado por FryAmTheEggman .
Pruébalo en línea. Banco de pruebas.
Esta podría ser la primera vez que utilizo la
p
instrucción rint en golf.Explicación
fuente
MATL , 24 bytes
Utiliza la versión actual (9.1.0) del lenguaje / compilador.
Ejemplos
Explicación
fuente
JavaScript (ES6), 108
Prueba
fuente
CJam, 27 bytes
Ejecute todos los casos de prueba.
Una implementación bastante sencilla de la especificación. La parte más interesante es la conversión a caracteres en la suma de verificación. Agregamos 17 al resultado de cada fragmento. Tome ese módulo 43 y agregue el resultado de eso al personaje
'0
.fuente
Japt, 46 bytes
No estoy muy contento con la longitud, pero no puedo encontrar una manera de jugar golf. Pruébalo en línea!
fuente
JavaScript (ES6),
137132 bytes¡4 bytes guardados gracias a @ ՊՓԼՃՐՊՃՈԲՍԼ !
Explicación
Este desafío no es adecuado para JavaScript en absoluto. No hay una forma corta de revertir una cadena y parece que la forma más corta de convertir el número en un carácter es codificar cada carácter posible.
Si se permitiera que los dígitos en la suma de verificación fueran minúsculas, se podría hacer en 124 bytes de esta manera:
Prueba
Mostrar fragmento de código
fuente
parseInt([...n].reverse().join``,2)
podría cambiarse a+`0b${[...n].reverse().join``}`
..replace(/.{5}/g,n=>/*stuff*/)
.MATLAB,
10098 bytesSe solicitará una cadena como entrada y la salida se mostrará en la pantalla.
Explicación
Probablemente estoy usando el enfoque más directo aquí:
¡Ahora por debajo de 100 bytes gracias a Luis Mendo!
fuente
e=['A':'Z',48:53]
PHP,
186181bytesSin pelar
Empecé pensando que podría hacerlo mucho más corto que esto, pero se me acabaron las ideas para hacerlo más corto.
fuente
Python 2, 97 bytes
fuente
PowerShell, 162 bytes
OK, muchas cosas interesantes están sucediendo en este caso. Comenzaré con la segunda línea.
Tomamos la entrada como una cadena a través
$args[0]
y la configuramos$a
para su uso posterior. Esto se encapsula()
para que se ejecute y se devuelva el resultado (es decir,$a
) para que podamos concatenarlo inmediatamente con los resultados de tres llamadas a funciones(f ...)
. Cada llamada de función pasa como argumento la cadena de entrada indexada en fragmentos de orden inverso como una matriz de caracteres, lo que significa, para la entrada de ejemplo,$a[4..0]
será igual@('0','E','R','0','a')
a cada entrada como un carácter, no una cadena.Ahora a la función, donde está la verdadera carne del programa. Tomamos la entrada como
$f
, pero solo se usa hacia el final, así que centrémonos allí, primero. Dado que se pasa como una matriz de caracteres (gracias a nuestra indexación anterior), podemos canalizarlo inmediatamente en un bucle con$f|%{...}
. Dentro del bucle, tomamos cada carácter y realizamos una coincidencia de expresiones regulares entre mayúsculas y minúsculas con la-cmatch
cual dará como resultado verdadero / falso si es mayúscula / de lo contrario. Lo convertimos como un entero con la encapsulación+()
, luego esa matriz de 1 y 0 se-join
edita para formar una cadena. Eso luego se pasa como el primer parámetro en la[convert]::ToInt32()
llamada .NET para cambiar el binario (base2
) en decimal. Usamos ese número decimal resultante para indexar en una cadena (-join(...)[...]
) La cadena se formula primero como un rango(65..90)
que se convierte como una matriz de caracteres, luego se concatena con el rango(0..5)
(es decir, la cadena es"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
). Todo eso es devolver el carácter apropiado de la cadena.fuente
Jolf, 30 bytes
Por último, ¡probablemente todavía sea un jolfable! Pruébalo aquí!
fuente
Python 3,
201174138bytesMuchas gracias a Trang Oul por señalar una declaración de función que ya no necesitaba existir. Y operadores ternarios de Python. Y alguna salida incorrecta. Solo ... solo dale los votos positivos.
fuente
z()
una vez, puede reemplazar su llamada y guardar 25 bytes. Además, su código se asigna incorrectamente en[
lugar de0
.if else
con esta construcción y el segundo con operador ternario.J, 36 bytes
Uso:
Pruébelo en línea aquí.
fuente
C,
120118 bytesFunciona para cualquier entrada cuya longitud sea múltiplo de 5 :)
Sin golf
fuente
{}
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
expresión, por lo que reemplazar con 442 no es una opción. Hasta!!isupper
esa función no devuelve 1 para verdadero en mi sistema, devuelve 256.!!
Es una forma corta de convertirlo a un valor de retorno 0/1 sin importar qué. YMMV.C #, 171 bytes
No estoy muy bien practicado en golf C #, pero aquí hay una oportunidad.
fuente
char.IsUpper(t)
se puede reemplazar cont>=65&t<=90
(&
en bool en C # es básicamente un campo de golf más&&
corto sin cortocircuito).447
es más corto que26*17
. No es necesario que lo haga por separadoSelect
: puede incluir el ternario directamente dentro delSum
. Considere reemplazar todos esos usos deSubstring
con un bucle basado en suTake
lugar, por ejemplofor(int i=0;i<3;i++)s.Skip(i*5).Take(5)
. Para referencia futura,u!=""
sería más corto queu.Length>0
(pero eso ya no es necesario si está usandoTake
).n/26*17
no es equivalente an/442
, pero aparte de eso, gracias por las sugerencias. Como se dijo, no tengo mucha experiencia en golf en C #, así que todo esto es algo excelente para mí para tener en cuenta en el futuro.C # 334
Si lo solicita, revertiré mi código a legible y lo publicaré.
fuente
Python 3, 87 bytes
fuente