Chuyển đổi ID nhân viên Salesforce 15 ký tự thành 18 ký tự


20

Trong Salesforce CRM , mọi đối tượng đều có ID chữ và số gồm 15 ký tự, phân biệt chữ hoa chữ thường. Nếu ai đó tò mò, thực sự đó là số cơ sở 62 . Tuy nhiên, các công cụ được sử dụng để di chuyển và tích hợp dữ liệu có thể hoặc không thể hỗ trợ độ nhạy trường hợp. Để khắc phục điều đó, ID có thể được chuyển đổi một cách an toàn thành ID chữ và số không phân biệt chữ hoa chữ thường. Trong quá trình đó, tổng kiểm tra chữ và số gồm 3 ký tự được gắn vào ID. Thuật toán chuyển đổi là:

Ví dụ :

a0RE000000IJmcN
  1. Tách ID thành ba khối 5 ký tự.

    a0RE0  00000  IJmcN
    
  2. Đảo ngược từng khúc.

    0ER0a  00000  NcmJI
    
  3. Thay thế mỗi ký tự trong mỗi đoạn bằng 1chữ hoa hoặc 0nếu khác.

    01100  00000  10011
    
  4. Đối với mỗi số nhị phân 5 chữ số i, lấy ký tự ở vị trí inối của bảng chữ cái in hoa và chữ số 0-5 ( ABCDEFGHIJKLMNOPQRSTUVWXYZ012345).

    00000 -> A,
    00001 -> B,
    00010 -> C, ..., 
    11010 -> Z, 
    11011 -> 0, ...,
    11111 -> 5`
    

    Năng suất:

    M  A  T
    
  5. Nối các ký tự này, tổng kiểm tra vào ID gốc.

Đầu ra :

a0RE000000IJmcNMAT

Viết chương trình hoặc hàm lấy chuỗi ký tự gồm 15 ký tự (ASCII) làm đầu vào và trả về ID 18 ký tự.

Xác nhận đầu vào nằm ngoài phạm vi của câu hỏi này. Các chương trình có thể trả về bất kỳ giá trị hoặc sự cố trên đầu vào không hợp lệ.

Xin vui lòng, không sử dụng các tính năng của ngôn ngữ chính của Salesforce khiến cho thách thức này trở nên tầm thường (như công thức CASESAFEID(), chuyển đổi Idsang Stringtrong APEX & c).

Các trường hợp thử nghiệm

a01M00000062mPg    -> a01M00000062mPgIAI
001M000000qfPyS    -> 001M000000qfPySIAU
a0FE000000D6r3F    -> a0FE000000D6r3FMAR
0F9E000000092w2    -> 0F9E000000092w2KAA
aaaaaaaaaaaaaaa    -> aaaaaaaaaaaaaaaAAA
AbCdEfGhIjKlMnO    -> AbCdEfGhIjKlMnOVKV
aBcDEfgHIJKLMNO    -> aBcDEfgHIJKLMNO025

3
Đáng buồn thay, việc chuyển đổi một chuỗi thành Id trong Apex Code vẫn sẽ không ngắn hơn một số câu trả lời được cung cấp ở đây, đặc biệt là nếu mã phải được khép kín. Apex Code không phù hợp để chơi gôn.
phyrfox

2
@phyrfox là một cựu nhân viên bán hàng dev. Apex không phù hợp với nhiều ...
Mike McMahon

2
APEX, 56 byte : public class X{public X(Id i){System.debug((String)i);}}. Tuy nhiên, chỉ hoạt động với ID Salesforce hợp lệ.
Trang Oul

Tôi đến đây để thực sự làm việc này cho công việc ( thành công.jitterbit.com / display / DOC / bia ) , không phải chơi gôn, nhưng tôi hơi bối rối khi mô tả thuật toán. Bạn nói rằng mỗi đoạn đảo ngược và khử trùng trong bước 4 sẽ là một "số nhị phân", nhưng bạn không bao giờ thay thế các chữ số 2-8 bằng 0 và 1. Chính xác thì tôi phải làm gì cho bước 4 khi các bước 1-3 trên một đoạn như "62mPg" đã dẫn đến một số như "01026"?
k ..

Câu trả lời:


6

Ruby, 97 byte

->s{s+s.scan(/.{5}/).map{|x|[*?A..?Z,*?0..?5][x.reverse.gsub(/./){|y|y=~/[^A-Z]/||1}.to_i 2]}*''}
->s{               # define an anonymous lambda
s+                 # the original string plus...
s.scan(/.{5}/)     # get every group of 5 chars
.map{|x|           # map over each group of 5 chars...
[*?A..?Z,*?0..?5]  # build the array of A-Z0-5
[                  # index over it with...
x.reverse          # the 5-char group, reversed...
.gsub(/./){|y|     # ... with each character replaced with...
y=~/[^A-Z]/||1     # ... whether it's uppercase (0/1)...
}.to_i 2           # ... converted to binary
]                  # (end index)
}*''               # end map, join into a string
}                  # end lambda

Điều này có một số thủ thuật thực sự gọn gàng.

Bản năng ban đầu của tôi để chia chuỗi thành các nhóm 5 ký tự là each_slice:

irb(main):001:0> [*1..20].each_slice(5).to_a
=> [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]

Hóa ra đó là quá lâu so với một regex đơn giản ( x.chars.each_slice(5)so với x.scan(/.{5}/)). Điều này có vẻ rõ ràng trong nhận thức muộn màng, nhưng tôi chưa bao giờ thực sự nghĩ về nó ... có lẽ tôi có thể tối ưu hóa một số câu trả lời cũ của Ruby ở đây.

Tuy nhiên, điều tôi tự hào nhất trong câu trả lời này là đoạn mã này:

y=~/[^A-Z]/||1

Được rồi, đây là một số nền tảng cho những người không phải là Ruby. Ruby tách hoàn toàn booleans ( TrueClass, FalseClass) khỏi số nguyên / số ( Numeric) Tậpthat có nghĩa là không có chuyển đổi tự động từ true thành 1 và false thành 0. Điều này gây khó chịu trong khi chơi golf (nhưng một điều tốt ... cho tất cả các mục đích khác).

Cách tiếp cận ngây thơ để kiểm tra xem một ký tự có phải là chữ hoa hay không (và trả về 1 hoặc 0) là

y.upcase==y?1:0

Chúng ta có thể đưa nó xuống một chút nữa (một lần nữa, với biểu thức chính quy):

y=~/[A-Z]/?1:0

Nhưng sau đó tôi thực sự bắt đầu suy nghĩ. Hmm ... =~trả về chỉ số của một trận đấu (vì vậy, đối với một nhân vật duy nhất của chúng ta, luôn luôn 0nếu có một trận đấu) hoặc nilkhông khớp, một giá trị giả (mọi thứ khác ngoại trừ FalseClasslà sự thật trong Ruby). Các ||nhà khai thác có toán hạng đầu tiên của nó nếu nó truthy, và toán hạng thứ hai của nó bằng cách khác. Vì vậy, chúng ta có thể đánh gôn này xuống

y=~/[^A-Z]/||1

Được rồi, chúng ta hãy nhìn vào những gì đang xảy ra ở đây. Nếu ylà một chữ cái viết hoa, nó sẽ không khớp [^A-Z], vì vậy phần regex sẽ trở lại nil. nil || 11, vì vậy chữ in hoa trở thành 1. Nếu ylà bất cứ điều gì ngoại trừ một chữ cái viết hoa, phần regex sẽ trở lại 0(vì có một kết quả khớp với chỉ mục 0), và vì đó 0là sự 0 || 1thật 0.

... và chỉ sau khi viết tất cả những điều này ra, tôi mới nhận ra rằng đây thực sự là cùng một chiều dài y=~/[A-Z]/?1:0. Haha, tốt quá


6

Bình thường, 23 22 byte

1 byte được lưu bởi FryAmTheEggman .

sm@s+JrG1U6i}RJ_d2c3pz

Hãy thử trực tuyến. Bộ thử nghiệm.

Đây có thể là lần đầu tiên tôi sử dụng phướng dẫn rint trong chơi golf.

Giải trình

     JrG1                   save uppercase alphabet in J
                     z      input string
                    p       print it without newline
                  c3        split into 3 parts
 m              d           for each part:
               _              reverse
            }R                map characters to being in
              J                 uppercase alphabet (saved in J)
           i     2            parse list of bools as binary
  @                           get correct item of
     J                          uppercase alphabet (saved in J)
   s+    U6                     add nums 0-5 to it
s                           concatenate and print

4

MATL , 24 byte

j1Y24Y2hG5IePtk=~!XB1+)h

Sử dụng phiên bản hiện tại (9.1.0) của ngôn ngữ / trình biên dịch.

Ví dụ

>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a0RE000000IJmcN
a0RE000000IJmcNMAT

>> matl
 > j1Y24Y2hG5IePtk=~!XB1+)h
 >
> a01M00000062mPg
a01M00000062mPgIAI

Giải trình

j            % input string
1Y2          % predefined literal: 'ABC...Z'
4Y2          % predefined literal; '012...9'
h            % concatenate into string 'ABC...Z012...9'
G            % push input string
5Ie          % reshape into 5x3 matrix, column-major order
P            % flip vertically
tk=~         % 1 if uppercase, 0 if lowercase
!XB1+        % convert each column to binary number and add 1
)            % index 'ABC...Z012...9' with resulting numbers
h            % concatenate result with original string

3

JavaScript (ES6), 108

x=>x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0)+[0,5,10].map(n=>x+='ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'[t>>n&31])&&x

Kiểm tra

f=x=>x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0)+[0,5,10].map(n=>x+='ABCDEFGHIJKLMNOPQRSTUVWXYZ012345'[t>>n&31])&&x

// Less golfed

U=x=>{
  x.replace(/[A-Z]/g,(x,i)=>t|=1<<i,t=0); // build a 15 bit number (no need to explicit reverse)
  // convert 't' to 3 number of 5 bits each, then to the right char A..Z 0..5
  [0,5,10].forEach(n=> // 3 value for shifting
    x += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345' // to convert value to char
     [ t>>n&31 ] // shift and mask
  );
  return x
}

console.log=x=>O.innerHTML+=x+'\n';

;[
  ['a01M00000062mPg','a01M00000062mPgIAI']
, ['001M000000qfPyS','001M000000qfPySIAU']
, ['a0FE000000D6r3F','a0FE000000D6r3FMAR']
, ['0F9E000000092w2','0F9E000000092w2KAA']
, ['aaaaaaaaaaaaaaa','aaaaaaaaaaaaaaaAAA']
, ['AbCdEfGhIjKlMnO','AbCdEfGhIjKlMnOVKV']
, ['aBcDEfgHIJKLMNO','aBcDEfgHIJKLMNO025']
].forEach(t=>{
  var i=t[0],x=t[1],r=f(i);
  console.log(i+'->'+r+(r==x?' OK':' Fail (expected '+x+')'));
})
<pre id=O></pre>


2

CJam, 27 byte

l_5/{W%{_el=!}%2bH+43%'0+}%

Chạy tất cả các trường hợp thử nghiệm.

Một thực hiện khá đơn giản của spec. Phần thú vị nhất là chuyển đổi thành các ký tự trong tổng kiểm tra. Chúng tôi thêm 17 vào kết quả của mỗi đoạn. Lấy modulo 43 đó và thêm kết quả của nó vào nhân vật '0.



2

JavaScript (ES6), 137 132 byte

s=>s+s.replace(/./g,c=>c>"9"&c<"a").match(/.{5}/g).map(n=>"ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"[0|"0b"+[...n].reverse().join``]).join``

4 byte được lưu nhờ @ ՊՓԼՃՐՊՃՈԲՍԼ !

Giải trình

Thách thức này không phù hợp với JavaScript. Không có cách nào ngắn để đảo ngược một chuỗi và có vẻ như cách ngắn nhất để chuyển đổi số thành ký tự là mã hóa cứng từng ký tự có thể.

s=>
  s+                                   // prepend the original ID
  s.replace(/./g,c=>c>"9"&c<"a")       // convert each upper-case character to 1
  .match(/.{5}/g).map(n=>              // for each group of 5 digits
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"
    [0|"0b"+                            // convert from binary
      [...n].reverse().join``]          // reverse the string
  ).join``

Nếu các chữ số trong tổng kiểm tra được phép viết thường, nó có thể được thực hiện trong 124 byte như thế này:

s=>s+s.replace(/./g,c=>c>"9"&c<"a").match(/.{5}/g).map(n=>((parseInt([...n].reverse().join``,2)+10)%36).toString(36)).join``

Kiểm tra


Nếu tôi không nhầm, parseInt([...n].reverse().join``,2)có thể đổi thành +`0b${[...n].reverse().join``}`.
Mama Fun Roll

@ Đúng rồi bạn ạ! Tôi đã lưu một byte khác trên đầu trang đó, cảm ơn.
dùng81655

Lưu 10 byte toàn bộ bằng cách sử dụng .replace(/.{5}/g,n=>/*stuff*/).
Neil

2

MATLAB, 100 98 byte

s=input('');a=flip(reshape(s,5,3))';e=['A':'Z',48:53];disp([s,e(bin2dec(num2str(a~=lower(a)))+1)])

Một chuỗi sẽ được yêu cầu làm đầu vào và đầu ra sẽ được hiển thị trên màn hình.

Giải trình

Có lẽ tôi đang sử dụng cách tiếp cận đơn giản nhất ở đây:

  • Yêu cầu đầu vào
  • Định hình lại thành 5 (hàng) x 3 (cột)
  • Lật thứ tự hàng
  • Chuyển đổi ma trận để chuẩn bị cho nó được đọc dưới dạng nhị phân
  • Phân bổ mảng ABC ... XYZ012345
  • So sánh các chỉ số ký tự của ma trận chuyển đổi với tương đương chữ thường của nó và chuyển đổi các booleans thành các chuỗi, sau đó được đọc dưới dạng nhị phân và được chuyển đổi thành số thập phân.
  • Giải thích các số thập phân này (tăng thêm 1) dưới dạng các chỉ số của mảng được phân bổ.
  • Hiển thị đầu vào với 3 ký tự bổ sung

Bây giờ dưới 100 byte nhờ Luis Mendo!


1
Bạn có thể tiết kiệm một chút bằng cách sử dụnge=['A':'Z',48:53]
Luis Mendo

Tôi thấy cách tiếp cận của tôi gần giống như của bạn :-)
Luis Mendo

2

PHP, 186 181 byte

<?$z=$argv[1];$x=str_split($z,5);$l="ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";foreach($x as$y){foreach(str_split(strrev($y))as$a=>$w)$y[$a]=ctype_upper($w)?1:0;$z.=$l[bindec($y)];}echo $z;

Không được ủng hộ

<?php
$z = $argv[1];
$x = str_split($z,5);
$l = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
foreach($x as $y) {
    foreach( str_split( strrev($y) ) as $a => $w) {
        $y[$a] = ctype_upper($w) ? 1 : 0;
    }
    $z .= $l[bindec($y)];
}
echo $z;

Tôi bắt đầu nghĩ rằng tôi có thể làm cho nó ngắn hơn nhiều so với điều này, nhưng tôi đã hết ý tưởng để làm cho nó ngắn hơn.


1

Python 2, 97 byte

lambda i:i+''.join(chr(48+(17+sum((2**j)*i[x+j].isupper()for j in range(5)))%43)for x in[0,5,10])

1

PowerShell, 162 byte

function f{param($f)-join([char[]](65..90)+(0..5))[[convert]::ToInt32(-join($f|%{+($_-cmatch'[A-Z]')}),2)]}
($a=$args[0])+(f $a[4..0])+(f $a[9..5])+(f $a[14..10])

OK, rất nhiều thứ gọn gàng xảy ra trong cái này. Tôi sẽ bắt đầu với dòng thứ hai.

Chúng tôi lấy đầu vào là một chuỗi thông qua $args[0]và đặt nó để $asử dụng sau. Điều này được gói gọn ()để nó được thực thi và kết quả được trả về (nghĩa là $a) , vì vậy chúng ta có thể nối chuỗi nó ngay lập tức với kết quả của ba lệnh gọi hàm (f ...). Mỗi lệnh gọi hàm chuyển qua làm đối số, chuỗi đầu vào được lập chỉ mục theo các khối thứ tự ngược lại dưới dạng mảng char - có nghĩa là, cho ví dụ đầu vào,$a[4..0] sẽ bằng @('0','E','R','0','a')với mỗi mục nhập dưới dạng char, không phải là chuỗi.

Bây giờ đến chức năng, nơi thịt thực sự của chương trình. Chúng tôi lấy đầu vào là $f, nhưng nó chỉ được sử dụng theo cách cuối cùng, vì vậy trước tiên hãy tập trung vào đó. Vì nó được truyền dưới dạng một mảng char (nhờ lập chỉ mục trước đó của chúng tôi), chúng tôi có thể ngay lập tức chuyển nó thành một vòng lặp với $f|%{...}. Trong vòng lặp, chúng tôi lấy từng ký tự và thực hiện khớp regex phân biệt -cmatchchữ hoa chữ thường với kết quả sẽ đúng / sai nếu viết hoa / ngược lại. Chúng tôi sử dụng số nguyên đó với số nguyên được đóng gói +(), sau đó mảng 1 và 0 được -jointạo thành một chuỗi. Đó đó sau đó được thông qua như là tham số đầu tiên trong .NET[convert]::ToInt32() lời kêu gọi thay đổi nhị phân (cơ sở 2) vào thập phân. Chúng tôi sử dụng số thập phân kết quả đó để lập chỉ mục thành một chuỗi (-join(...)[...]). Chuỗi đầu tiên được xây dựng dưới dạng một phạm vi(65..90) tạo thành một mảng char, sau đó được nối với phạm vi(0..5)(tức là chuỗi là "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"). Tất cả điều đó là để trả về ký tự thích hợp từ chuỗi.


1

Jolf, 30 byte

Cuối cùng, một người có lẽ vẫn còn vui vẻ! Hãy thử nó ở đây!

+i mZci5d.p1CρA_Hpu1"[^1]'0"2
    Zci5                      split input into groups of 5
  _m                          map it
        d                      with this function
               _H              reverse H
              A  pu1            and replace in it all uppercase letters with 1
             ρ      "[^1]'0"    replace all non-ones with zeroes
            C               2   parse as binary integer
         .p1                    get the (^)th member of "A...Z0...9"

1

Python 3, 201 174 138 byte

Xin chân thành cảm ơn Trang Oul đã chỉ ra một tuyên bố chức năng không còn cần thiết để tồn tại. Và toán tử ternary Python. Và một số đầu ra không chính xác. Chỉ cần ... đưa cho anh ta những lời khen ngợi.

i=input();n='';c=l=15;
while c:c-=1;n+=('0','1')[i[c].isupper()]
while l:v=int(n[l-5:l],2);l-=5;i+=(chr(v+65),str(v-26))[v>25]
print(i)

Bạn sử dụng chức năng z()một lần, bạn có thể thay thế cuộc gọi của nó và lưu 25 byte. Ngoài ra, mã của bạn gán không chính xác [thay vì 0.
Trang Oul

Vâng, đó là một sự giám sát đáng xấu hổ về phía tôi. Cảm ơn.
Steve Eckert

1
Bạn có thể tiết kiệm nhiều hơn bằng cách thay thế đầu tiên if elsebằng công trình này và thứ hai bằng toán tử tạm thời.
Trang Oul


1

C, 120 118 byte

n,j;main(c,v,s)char**v,*s;{for(printf(s=v[1]);*s;s+=5){for(n=0,j=5;j--;)n=n*2+!!isupper(s[j]);putchar(n+65-n/26*17);}}

Hoạt động cho bất kỳ đầu vào nào có độ dài là bội số của 5 :)

Ung dung

n,j;

main(c,v,s) char **v, *s;
{
    for(printf(s = v[1]); *s; s+=5)
    {
        for(n=0, j=5; j--;)
            n=n*2+!!isupper(s[j]);

        putchar(n+65-n/26*17);
    }
}

Để lưu một vài byte, bạn có thể xóa n, khỏi không gian tên toàn cục nếu bạn sử dụng hàm chính (n, v, s) cho chữ ký của mình do bạn không sử dụng argc.
cleblanc

Đồng thời thay thế 26 * 17 bằng đơn vị cũ đơn giản tiết kiệm một byte khác
cleblanc

Với một vài chỉnh sửa nữa, tôi đã giảm phiên bản của mình xuống còn 110 byte. Tôi không hiểu tại sao bạn lại có !! isupprer () khi isupper () dường như hoạt động tốt với tôi. Ngoài ra tôi đã cấu trúc lại các vòng lặp của bạn để loại bỏ một số thứ không cần thiết{} 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]));}
cleblanc

@cleblanc Gợi ý tuyệt vời, cảm ơn rất nhiều. Thứ tự của các hoạt động là rất quan trọng trên n/26*17biểu thức vì vậy thay thế bằng 442 không phải là một lựa chọn. Theo như !!isupper, hàm đó không trả về 1 cho đúng trên hệ thống của tôi, nó trả về 256. Đây !!là một cách ngắn để chuyển đổi nó thành giá trị trả về 0/1 bất kể là gì. YMMV.
Cole Cameron

1

C #, 171 byte

Tôi không thực sự giỏi trong việc chơi golf C #, nhưng đây là một cú đánh.

s=>{for(var u=s;u.Length>0;u=u.Substring(5)){int p=0,n=u.Substring(0,5).Select(t=>char.IsUpper(t)?1:0).Sum(i=>(int)(i*Math.Pow(2,p++)));s+=(char)(n+65-n/26*17);}return s;}

Gợi ý: char.IsUpper(t)có thể được thay thế bằng t>=65&t<=90( &trên bool trong C # về cơ bản là ngắn hơn &&mà không cần đoản mạch). 447ngắn hơn 26*17. Bạn không cần phải làm riêng Select: bạn có thể bao gồm chim nhạn trực tiếp trong Sum. Thay Substringvào Takeđó, hãy xem xét thay thế tất cả các cách sử dụng bằng một vòng lặp dựa trên , ví dụ for(int i=0;i<3;i++)s.Skip(i*5).Take(5). Để tham khảo trong tương lai, u!=""sẽ ngắn hơn u.Length>0(nhưng không còn cần thiết nếu bạn đang sử dụng Take).
Bob

Biểu thức n/26*17không tương đương n/442, nhưng khác hơn, cảm ơn vì những gợi ý. Như đã nói, tôi không có nhiều kinh nghiệm chơi golf trong C # nên đây là tất cả những thứ tuyệt vời để tôi xem xét trong tương lai.
Cole Cameron

À, xin lỗi - tôi đã đọc sai điều đó.
Bob

1

C # 334

string g(string c){string[]b=new string[]{c.Substring(0,5),c.Substring(5, 5),c.Substring(10)};string o="",w="";for(int i=0,j=0;i<3;i++){char[]t=b[i].ToCharArray();Array.Reverse(t);b[i]=new string(t);o="";for(j=0;j<5;j++){o+=Char.IsUpper(b[i][j])?1:0;}int R=Convert.ToInt32(o,2);char U=R>26?(char)(R+22):(char)(R+65);w+=U;}return c+w;}

Nếu được yêu cầu, tôi sẽ đảo ngược mã của mình trở lại để có thể đọc và đăng nó.


1

Python 3, 87 byte

lambda s:s+bytes(48+(17+sum((~s[i+j]&32)>>(5-i)for i in range(5)))%43 for j in(0,5,10))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.