Máy tính ký tự điều khiển thẻ ID Tây Ban Nha


20

Đây là một thuật toán rất đơn giản, mà tôi chắc chắn có thể được giải bằng nhiều ngôn ngữ khác nhau. Ở Tây Ban Nha, thẻ ID (được gọi là DNI ) bao gồm 8 số và ký tự điều khiển. Ký tự điều khiển được tính toán với thuật toán sau: chia số cho 23, lấy phần còn lại của thao tác và thay thế bằng ký tự theo bảng này:

0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22  
T  R  W  A  G  M  Y  F  P  D  X  B  N  J  Z  S  Q  V  H  L  C  K  E

Nếu DNI thuộc về một người nước ngoài sinh sống tại Tây Ban Nha, chữ số đầu tiên được thay đổi để X, Yhay Zvà nó được gọi là một NIE . Trong trường hợp này, các thay thế sau được thực hiện trước khi tính toán ký tự điều khiển:

X Y Z
0 1 2

Có rất nhiều máy tính trực tuyến giúp bạn có được ký tự điều khiển, nhưng, bạn có thể viết mã đó ngắn đến mức nào? Viết một thuật toán (chương trình hoặc hàm) nhận được stringbằng số DNI (sẽ luôn bao gồm 8 ký tự chữ và số) và chỉ trả về một ký tự điều khiển duy nhất được tính và không có gì nữa (một dòng mới được chấp nhận).

Ghi chú:

  • DNI luôn được viết bằng chữ in hoa, nhưng trong thuật toán của bạn, bạn có thể chọn đầu vào và đầu ra là chữ hoa hoặc chữ thường, chỉ cần nhất quán.
  • Trong cuộc sống thực, một số NIE được phát hành trước năm 2008 có 8 chữ số sau X, Yhoặc Z, nhưng với mục đích của trò chơi này, bạn có thể xem xét chúng có 7 chữ số như hiện nay.
  • Bạn có thể xem xét rằng chuỗi đầu vào sẽ luôn có 8 ký tự, nhưng nếu chúng không ở định dạng "8 chữ số" cũng như định dạng "[XYZ] cộng với 7 chữ số", bạn phải trả về lỗi (do bạn chọn) hoặc chỉ ném một ngoại lệ.

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

00000010 -> X (HRM Juan Carlos I's DNI number)
01234567 -> L
98765432 -> M
69696969 -> T
42424242 -> Y
Z5555555 -> W (Z=2)
Y0000369 -> S (Y=1)
A1234567 -> <Error code or exception>
1231XX12 -> <Error code or exception>

Đây là , vì vậy có thể mã ngắn nhất cho mỗi ngôn ngữ sẽ giành chiến thắng!



2
Có thực sự quan trọng là mã có một hành vi cụ thể trên đầu vào không hợp lệ? Thông thường những thách thức ở đây không đòi hỏi phải lo lắng về việc xử lý lỗi.
Greg Martin

3
@GregMartin quan điểm của tôi chính xác, tôi chỉ muốn mã hiển thị một số hành vi cụ thể trên các đầu vào lỗi vì nó thường không được yêu cầu.
Charlie

Trong thế giới chia số cho 23, lấy phần còn lại của hoạt động, thuật ngữ chính xác là phần còn lại ; phần còn lại là quá thông tục.
Locoluis

2
@Latiouis trong tiếng Tây Ban Nha, chúng tôi nói resto , sau đó "nghỉ ngơi" thành một người bạn giả. Ít nhất tôi đã không sử dụng một thuật ngữ sai. :-) Cảm ơn bạn!
Charlie

Câu trả lời:


11

Python 3 , 83 byte

lambda n:'TRWAGMYFPDXBNJZSQVHLCKE'[int([n,str(ord(n[0])%4)+n[1:]][n[0]in'XYZ'])%23]

Hãy thử trực tuyến!

-5 nhờ AlixEinsenhardt (từ 99 đến 94). -1 cảm ơn Jonathan ALLan .


1
Bạn có thể thay thế str('XYZ'.index(n[0]))bằng str(ord(n[0])-88)và lưu 5 byte
Alix Eisenhardt

1
@AlixEisenhardt Gợi ý trên đã thôi thúc tôi thay đổi kỹ thuật thành lambda, cuối cùng tiết kiệm được 10 byte.
Ông Xcoder

Lưu một byte bằng cách thay thế -88bằng %4.
Jonathan Allan

8

Haskell , 107 93 92 byte

c(x:y)="TRWAGMYFPDXBNJZSQVHLCKE"!!mod(read(("X0Y1Z2"!x):y))23
(a:b:c)!x|x==a=b|2>1=c!x
_!x=x

Hãy thử trực tuyến!


Hành vi trên đầu vào không hợp lệ là gì?
Charlie

Họ sẽ làm hỏng chương trình, tôi đã thêm một ví dụ. (trong thực tế, nó ném ra một ngoại lệ mà không ai bắt được)
bartavelle

1
Tôi đã cập nhật bài nộp với bắt ngoại lệ, để tất cả các bài kiểm tra có thể được chạy.
bartavelle

5

Bình thường, 35 34 byte

Mã này chứa một số ký tự không thể in được, vì vậy đây là một xxdhexdump có thể đảo ngược .

00000000: 402e 5043 22fc eeff 1ffc adc7 e614 9451  @.PC"..........Q
00000010: 2247 2573 7358 637a 5d31 3e33 4755 3320  "G%ssXcz]1>3GU3
00000020: 3233                                     23

Sử dụng các tự chữ thường .

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

Phiên bản có thể in

@.P305777935990456506899534929G%ssXcz]1>3GU3 23

Giải trình

  • cz]1chia tách đầu vào tại vị trí 1, ví dụ như "y0000369"để ["y", "0000369"].
  • >3Gđược 3 ký tự cuối cùng của bảng chữ cái , "xyz".
  • U3được phạm vi [0, 3 [ , [0, 1, 2].
  • Xbản đồ xyzđể [0, 1, 2]trong mảng tách, ví dụ như ["y", "0000369"]để [1, "0000369"]. Điều này thay thế ký tự đầu tiên nếu nó là một trong số đó xyz, trong khi phần đuôi của 7 ký tự không được chạm tới vì bất kỳ chuỗi 7 ký tự nào cũng không thể bằng một ký tự.
  • stham gia các mảng với chuỗi rỗng, ví dụ như [1, "0000369"]để "10000369".
  • sphôi chuỗi này đến số nguyên, ví dụ như "10000369"để 10000369. Điều này sẽ gây ra lỗi nếu có bất kỳ ký tự không có chữ số nào còn lại trong chuỗi.
  • %... 23được giá trị modulo 23, ví dụ như 10000369để 15.
  • C"Bộ "chuyển đổi chuỗi nhị phân từ cơ sở 256 thành số nguyên (khoảng 3.06 × 10 26 ).
  • .P... Gđược các hoán vị của bảng chữ cái với chỉ số đó.
  • @ được các nhân vật chính xác từ hoán vị.

4

MATL , 62 59 byte

'RWAGMYFPDXBNJZSQVHLCKET'j'[\dXYZ]\d{7}'XXg'XYZ'I:47+XEU1))

Lỗi cho đầu vào không hợp lệ là A(I): index out of bounds(trình biên dịch chạy trong Octave) hoặc Index exceeds matrix dimensions(trình biên dịch chạy trong Matlab).

Hãy thử trực tuyến!

Giải trình

'RWAGMYFPDXBNJZSQVHLCKET' % Push this string (output letters circularly shifted by 1)
j                         % Unevaluated input
'[\dXYZ]\d{7}'            % Push this string (regexp pattern)
XX                        % Regexp. Returns cell arary with matching string, or empty
g                         % Convert to standard array. Will be empty if non-valid input
'XYZ'                     % Push this string
I:47+                     % Push [47 48 49] (ASCII codes of '012')
XE                        % Transliterate
U                         % Convert to number
1)                        % Get first entry. Gives an error if empty
)                         % Index (modular, 1-based) into initial string
                          % Implicitly display

4

ES6, 83 82 81 byte

i=>'TRWAGMYFPDXBNJZSQVHLCKE'[(/^[XYZ]/.test(i)?i.charCodeAt()%4+i.slice(1):i)%23]

Trong hành động!

Chỉ viết hoa, mã lỗi cho các số không hợp lệ là undefined.

Một byte được lưu nhờ Jonathan Allan.
Một byte khác được lưu nhờ Shaggy.


Có thể lưu một byte bằng cách sử dụng %4chứ không phải -88.
Jonathan Allan

Bạn sẽ có thể thả 0từ charCodeAt()quá.
Shaggy

3

Java 8, 154 145 104 byte

s->{s[0]-=s[0]<88|s[0]>90?0:40;return"TRWAGMYFPDXBNJZSQVHLCKE".charA‌​t(new Integer(new String(s))%23);}

-9 byte nhờ @ OliverGrégoire .
-41 byte nhờ vào @ OliverGrégoire một lần nữa, bằng cách lấy đầu vào là một mảng char ( char[]).

Nếu đầu vào không hợp lệ, nó sẽ thất bại với một java.lang.NumberFormatExceptionhoặc java.lang.StringIndexOutOfBoundsException.

Giải trình:

Hãy thử nó ở đây. (Các trường hợp kiểm tra không hợp lệ được bao quanh bởi try-Catch để nó không dừng ở lỗi đầu tiên.)

s->{                      // Method with char[] parameter and char return-type
  s[0]-=s[0]<88|s[0]>90?  // If the first character is not XYZ:
    0                     //  Leave the first character as is
   :                      // Else:
    40;                   //  Subtract 40 to convert it to 012
  return"TRWAGMYFPDXBNJZSQVHLCKE".charAt(
                          //    Get the char from the String
    new Integer(          //    by converting the following String to an integer:
      new String(s)       //     by converting the char-array to a String
    )%23);                //    And take modulo-23 of that integer
}                         // End of method

1
Bạn không cần |trong regex. Ngoài ra int t=s.charAt(0)-88& t<0?t+40:tdành cho bạn một byte.
Olivier Grégoire

1
Cuối cùng, bạn có thể trả lại mã lỗi. Chỉ cần quyết định rằng đó là 'a'hoặc '0'bất kỳ chữ cái viết hoa nào, và trả lại nó thay vì t/0và chuyển toàn bộ lô sang char. Bạn đoán bạn tiết kiệm được 7 byte theo cách này. Chơi theo cách này , bạn nhận được 145 byte.
Olivier Grégoire

1
@ OlivierGrégoire Cảm ơn! Tôi có cảm giác vẫn có thể sử dụng một cách xác nhận khác thay vì .matchesvới regex này, btw. Nhưng có lẽ tôi đã nhầm.
Kevin Cruijssen

1
Không, bạn hoàn toàn đúng! Điều này có thể thực hiện được như thế này: s->{s[0]-=s[0]<88?0:40;return"TRWAGMYFPDXBNJZSQVHLCKE".charAt(new Integer(new String(s))%23);}chỉ với 94 byte (với sa char[]): p
Olivier Grégoire

1
Hoặc nếu bạn muốn hoàn thành về xác thực: s[0]<88&s[0]>90thêm 8 byte.
Olivier Grégoire



1

q / kdb +, 68 byte

Dung dịch:

{"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}

Ví dụ:

q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"00000010"
"X"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"01234567"
"L"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"98765432"
"M"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"69696969"
"T"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"42424242"
"Y"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"Z5555555"
"W"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"Y0000369"
"S"
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"A1234567"
" "
q){"TRWAGMYFPDXBNJZSQVHLCKE"mod["J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x;23]}"1231XX12"
" "

Giải trình:

Nếu ký tự đầu tiên x 0, nằm trong chuỗi "XYZ"thì asẽ 0, 1hoặc 2. Nếu ký tự đầu tiên không có trong chuỗi, thì asẽ là 3. Nếu anhỏ hơn 3, chúng tôi chuyển ký tự đầu tiên cho chuỗi của một ( 0, 1hoặc 2), nếu không, chúng tôi sẽ chuyển sang ký tự đầu tiên (do đó không thực sự làm gì cả). Chuỗi này được truyền tới một ( "J"$) dài , sau đó là mod23 với phần còn lại. Phần còn lại này được sử dụng để lập chỉ mục vào bảng tra cứu.

{ "TRWAGMYFPDXBNJZSQVHLCKE" mod["J"$$[3>a:"XYZ"?x 0;string a;x 0],1_x;23] } / ungolfed solution
{                                                                         } / lambda function
                            mod[                                     ;23]   / performds mod 23 of the stuff in the gap
                                                                  1_x       / 1 drop input, drops the first character
                                                                 ,          / concatenation
                                    $[             ;        ;   ]           / if COND then TRUE else FALSE - $[COND;TRUE;FALSE]
                                        a:"XYZ"?x 0                         / "XYZ" find x[0], save result in a
                                      3>                                    / is this result smaller than 3
                                                    string a                / if so, then string a, e.g. 0 -> "0"
                                                             x 0            / if not, just return first character x[0]
                                "J"$                                        / cast to long
  "TRWAGMYFPDXBNJZSQVHLCKE"                                                 / the lookup table

Ghi chú:

" "được trả về trong các kịch bản lỗi, điều này là do các biểu mẫu trả về null và lập chỉ mục thành một chuỗi tại chỉ mục null là một char trống. Tôi có thể thêm 4 byte vào đầu ( "!"^) để làm rõ hơn rằng đã xảy ra lỗi:

q){"!"^"TRWAGMYFPDXBNJZSQVHLCKE"("J"$$[3>a:"XYZ"?x 0;($)a;x 0],1_x)mod 23}"1231XX12"
"!"

1

JavaScript (ES6), 121 byte

f=i=>{c=+i[0];a=3;while(a--){i[0]=="XYZ"[a]&&(c=a)}b=7;while(b--){c= +i[7-b]+c*10}return "TRWAGMYFPDXBNJZSQVHLCKE"[c%23]}

console.log([f("00000010"),f("01234567"),f("98765432"),f("69696969"),f("42424242"),f("Z5555555"),f("Y0000369"),f("A1234567"),f("1231XX12")])



1

Rust, 206 byte

Tôi không nghĩ rằng rỉ sét rất phù hợp để chơi gôn -_-

let b=|s:&str|{s.chars().enumerate().map(|(i,c)|match i{0=>match c{'X'=>'0','Y'=>'1','Z'=>'2',_=>c},_=>c}).collect::<String>().parse::<usize>().ok().and_then(|x|"TRWAGMYFPDXBNJZSQVHLCKE".chars().nth(x%23))};

1

05AB1E , 41 40 39 byte

ć…xyz2ÝJ‡ìDd_i.ǝ}23%.•Xk¦fΣT(:ˆ.Îðv5•sè

Lấy đầu vào bằng chữ thường (để lưu 1 byte yay )

Hãy thử trực tuyến!

In đầu vào thành STDERR nếu nó không đúng định dạng

Giải trình

ć…xyz2ÝJ‡ìDd_i.ǝ}23%.•Xk¦fΣT(:ˆ.Îðv5•sè
ć                                       # Get head of input and put the rest of the input under it on the stack
 …xyz                                   # Push xyz
     2ÝJ                                # Push 012
        ‡                               # Transliterate
         ì                              # Prepend to the rest of the input
          Dd_                           # Does the result contain something other than numbers?
             i.ǝ}                       # If so print input to STDERR
                 23%                    # Modulo 23
                    .•Xk¦fΣT(:ˆ.Îðv5•   # Pushes the character list
                                     sè # Get the char at the index of the modulo

0

APL Dyalog, 95 byte

{'TRWAGMYFPDXBNJZSQVHLCKE'[1+23|(10⊥¯1+'0123456789'⍳{(⍕{('XYZ'⍳⍵)<4:('XYZ'⍳⍵)-1⋄⍵} ⊃⍵),1↓⍵}⍵)]}

Đây là một toán tử đơn trị chấp nhận một chuỗi ký tự làm toán hạng của nó và trả về kết quả của nó.

CỐ ĐỊNH nó không kiểm tra đầu vào của nó. Nó không được đánh golf đúng cách.

Sử dụng:

    OP ← {'TRWAGMYFPDXBNJZSQVHLCKE'[1+23|(10⊥¯1+'0123456789'⍳{(⍕{('XYZ'⍳⍵)<4:('XYZ'⍳⍵)-1⋄⍵} ⊃⍵),1↓⍵}⍵)]}

      OP '01234567'
L

      OP '00000010'
X
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.