Dalam Salesforce CRM , setiap objek memiliki ID alfanumerik 15 karakter, yang peka huruf besar-kecil. Kalau ada yang penasaran, sebenarnya itu nomor base-62 . Namun, alat yang digunakan untuk migrasi data dan integrasi mungkin atau mungkin tidak mendukung sensitivitas kasus. Untuk mengatasinya, ID dapat dikonversi dengan aman menjadi ID alfanumerik tidak sensitif huruf-18. Dalam proses itu checksum alfanumerik 3 karakter ditambahkan ke ID. Algoritma konversi adalah:
Contoh :
a0RE000000IJmcN
Pisahkan ID menjadi tiga potongan 5 karakter.
a0RE0 00000 IJmcN
Membalikkan setiap potongan.
0ER0a 00000 NcmJI
Ganti setiap karakter di setiap chunk dengan
1
huruf besar atau0
sebaliknya.01100 00000 10011
Untuk setiap nomor biner 5 digit
i
, dapatkan karakter pada posisii
dalam gabungan huruf besar dan angka 0-5 (ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
).00000 -> A, 00001 -> B, 00010 -> C, ..., 11010 -> Z, 11011 -> 0, ..., 11111 -> 5`
Menghasilkan:
M A T
Tambahkan karakter-karakter ini, checksum, ke ID asli.
Keluaran :
a0RE000000IJmcNMAT
Tulis program atau fungsi yang menggunakan string 15-karakter alfanumerik (ASCII) sebagai input dan mengembalikan ID 18-karakter.
Validasi input di luar cakupan pertanyaan ini. Program dapat mengembalikan nilai atau kerusakan apa pun pada input yang tidak valid.
Tolong, jangan gunakan fitur bahasa propretiaris Salesforce yang membuat tantangan ini sepele (seperti formula CASESAFEID()
, dikonversi Id
ke String
dalam APEX & c).
Uji Kasus
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);}}
. Hanya bekerja dengan ID Tenaga Penjualan yang valid.Jawaban:
Ruby, 97 byte
Yang ini punya beberapa trik yang sangat rapi.
Insting asli saya untuk memisahkan string ke dalam kelompok 5 karakter adalah
each_slice
:Ternyata itu waaay terlalu lama dibandingkan dengan regex sederhana (
x.chars.each_slice(5)
vsx.scan(/.{5}/)
). Tampaknya ini jelas, tetapi saya tidak pernah benar-benar memikirkannya ... mungkin saya dapat mengoptimalkan beberapa jawaban Ruby saya yang lama di sini.Namun, hal yang paling saya banggakan dalam jawaban ini adalah bagian kode ini:
Baiklah, jadi inilah beberapa latar belakang untuk yang bukan Ruby. Ruby benar-benar memisahkan booleans (
TrueClass
,FalseClass
) dari integer / angka (Numeric
) —yang berarti tidak ada konversi otomatis dari true ke 1 dan false ke 0 juga. Ini menjengkelkan saat bermain golf (tetapi hal yang baik ... untuk semua keperluan lainnya).Pendekatan naif untuk memeriksa apakah satu karakter huruf besar (dan mengembalikan 1 atau 0) adalah
Kita bisa turun sedikit lebih jauh (sekali lagi, dengan regex):
Tetapi kemudian saya benar-benar mulai berpikir. Hmm ...
=~
mengembalikan indeks kecocokan (jadi, untuk karakter tunggal kami, selalu0
jika ada kecocokan) atau jikanil
gagal mencocokkan, nilai palsu (semua yang lain kecualiFalseClass
benar di Ruby). The||
Operator mengambil operan pertama jika itu truthy, dan operan kedua sebaliknya. Oleh karena itu, kita dapat bermain golf ini hinggaBaiklah, mari kita lihat apa yang terjadi di sini. Jika
y
huruf besar, itu akan gagal cocok[^A-Z]
, sehingga bagian regex akan kembalinil
.nil || 1
adalah1
, jadi huruf besar menjadi1
. Jikay
apa pun selain huruf besar, bagian regex akan kembali0
(karena ada kecocokan pada indeks0
), dan karena0
itu benar,0 || 1
adalah0
.... dan hanya setelah menulis semua ini saya menyadari bahwa ini sebenarnya sama panjangnya
y=~/[A-Z]/?1:0
. Haha, oh well.sumber
Pyth,
2322 byte1 byte disimpan oleh FryAmTheEggman .
Cobalah online. Suite uji.
Ini mungkin pertama kalinya saya menggunakan
p
instruksi rintisan dalam bermain golf.Penjelasan
sumber
MATL , 24 byte
Menggunakan versi saat ini (9.1.0) dari bahasa / kompiler.
Contohnya
Penjelasan
sumber
JavaScript (ES6), 108
Uji
sumber
CJam, 27 byte
Jalankan semua test case.
Implementasi spec yang cukup mudah. Bagian yang paling menarik adalah konversi ke karakter dalam checksum. Kami menambahkan 17 ke hasil setiap potongan. Ambil modulo 43 itu dan tambahkan hasilnya ke karakter
'0
.sumber
Japt, 46 byte
Tidak terlalu senang dengan panjangnya, tetapi saya tidak dapat menemukan cara untuk menurunkannya. Cobalah online!
sumber
JavaScript (ES6),
137132 byte4 byte disimpan berkat @ ՊՓԼՃՐՊՃՈԲՍԼ !
Penjelasan
Tantangan ini tidak cocok untuk JavaScript sama sekali. Tidak ada cara pendek untuk membalikkan string dan sepertinya cara terpendek untuk mengubah angka menjadi karakter adalah dengan meng-hard-code setiap karakter yang mungkin.
Jika digit dalam checksum diizinkan menjadi huruf kecil, bisa dilakukan dalam 124 byte seperti ini:
Uji
Tampilkan cuplikan kode
sumber
parseInt([...n].reverse().join``,2)
bisa diubah menjadi+`0b${[...n].reverse().join``}`
..replace(/.{5}/g,n=>/*stuff*/)
.MATLAB,
10098 byteSebuah string akan diminta sebagai input dan output akan ditampilkan di layar.
Penjelasan
Saya mungkin menggunakan pendekatan yang paling mudah di sini:
Sekarang di bawah 100 byte, terima kasih kepada Luis Mendo!
sumber
e=['A':'Z',48:53]
PHP,
186181 byteTidak berlapis
Saya mulai berpikir saya bisa membuatnya lebih pendek dari ini, tetapi saya kehabisan ide untuk membuatnya lebih pendek.
sumber
Python 2, 97 byte
sumber
PowerShell, 162 byte
OK, banyak hal rapi terjadi dalam hal ini. Saya akan mulai dengan baris kedua.
Kami mengambil input sebagai string melalui
$args[0]
dan mengaturnya$a
untuk digunakan nanti. Ini dirangkum dalam()
sehingga dieksekusi dan hasilnya dikembalikan (yaitu,$a
) sehingga kita dapat segera menyatukannya dengan hasil dari tiga panggilan fungsi(f ...)
. Setiap panggilan fungsi dilewatkan sebagai argumen string input diindeks dalam urutan terbalik sebagai char-array - artinya, untuk input contoh,$a[4..0]
akan sama@('0','E','R','0','a')
dengan setiap entri sebagai char, bukan string.Sekarang untuk fungsi, di mana daging sebenarnya dari program ini. Kami mengambil input sebagai
$f
, tetapi hanya digunakan sebagai jalan menuju akhir, jadi mari kita fokus di sana, pertama. Karena ini dilewatkan sebagai char-array (terima kasih untuk pengindeksan kami sebelumnya), kami dapat langsung menyalurkannya ke dalam loop dengan$f|%{...}
. Di dalam loop, kita mengambil setiap karakter dan melakukan kecocokan dengan regex case-sensitive-cmatch
yang akan menghasilkan true / false jika huruf besar / sebaliknya. Kami melemparkan itu sebagai bilangan bulat dengan enkapsulasi+()
, maka array 1 dan 0 adalah-join
ed untuk membentuk string. Itu kemudian diteruskan sebagai parameter pertama dalam[convert]::ToInt32()
panggilan .NET untuk mengubah biner (basis2
) menjadi desimal. Kami menggunakan angka desimal yang dihasilkan untuk mengindeks menjadi string (-join(...)[...]
). String pertama kali dirumuskan sebagai rentang(65..90)
yang dilemparkan sebagai char-array, kemudian digabungkan dengan rentang(0..5)
(yaitu, string tersebut"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
). Semua itu untuk mengembalikan karakter yang sesuai dari string.sumber
Jolf, 30 byte
Akhirnya, mungkin masih bisa disayangi! Coba di sini!
sumber
Python 3,
201 174138 byteTerima kasih banyak kepada Trang Oul karena telah menunjukkan deklarasi fungsi yang tidak perlu lagi ada. Dan operator ternary Python. Dan beberapa output yang salah. Hanya ... beri dia upvotes.
sumber
z()
satu kali, Anda dapat mengganti panggilannya dan menghemat 25 byte. Juga, kode Anda salah memberikan[
bukan0
.if else
dengan konstruksi ini dan yang kedua dengan operator ternary.J, 36 byte
Pemakaian:
Cobalah online di sini.
sumber
C,
120118 byteBekerja untuk input apa pun yang panjangnya kelipatan 5 :)
Tidak disatukan
sumber
{}
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
ekspresi sehingga mengganti dengan 442 bukanlah opsi. Sejauh!!isupper
, fungsi itu tidak mengembalikan 1 untuk true pada sistem saya, ia mengembalikan 256. Ini!!
adalah cara singkat untuk mengubahnya menjadi nilai pengembalian 0/1 tidak peduli apa. YMMV.C #, 171 byte
Saya tidak terlalu terlatih dalam bermain golf C #, tapi ini dia.
sumber
char.IsUpper(t)
dapat diganti dengant>=65&t<=90
(&
pada bool di C # pada dasarnya adalah golf-pendek&&
tanpa hubungan arus pendek).447
lebih pendek dari26*17
. Anda tidak perlu melakukan yang terpisahSelect
: Anda dapat memasukkan ternary langsung di dalamSum
. Pertimbangkan untuk mengganti semua penggunaanSubstring
dengan loop berdasarkanTake
, misalnyafor(int i=0;i<3;i++)s.Skip(i*5).Take(5)
. Untuk referensi di masa mendatang,u!=""
akan lebih pendek dariu.Length>0
(tapi itu tidak perlu lagi jika Anda menggunakanTake
).n/26*17
tidak setara dengann/442
, tetapi selain itu, terima kasih atas sarannya. Seperti yang saya katakan, saya tidak terlalu berpengalaman dalam bermain golf di C # jadi ini semua hal yang bagus untuk saya pertimbangkan di masa depan.C # 334
Jika diminta, saya akan membalikkan kode saya kembali menjadi dapat dibaca dan mempostingnya.
sumber
Python 3, 87 byte
sumber