스페인어 ID 카드 제어 문자 계산기


20

이것은 매우 간단한 알고리즘으로 많은 다른 언어로 해결할 수 있다고 확신합니다. 스페인에서는 ID 카드 ( DNI 라고 함 )가 8 개의 숫자와 제어 문자로 구성됩니다. 제어 문자는 다음 알고리즘으로 계산됩니다. 숫자를 23으로 나누고 나머지 연산을 수행하여이 표에 따라 문자로 바꿉니다.

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

DNI 스페인에 살고있는 외국 사람에 속하는 경우, 첫 번째 숫자로 변경되고 X, Y또는 Z생각에 이것은이라고 NIE . 이 경우 제어 문자를 계산하기 전에 다음과 같이 대체됩니다.

X Y Z
0 1 2

제어 문자를 얻는 데 도움이되는 많은 계산기가 온라인에 있지만 그 코드를 얼마나 짧게 작성할 수 있습니까? stringDNI 번호 (항상 8 자리 영숫자로 구성됨 )를 수신하고 계산 된 단일 제어 문자 만 반환하고 후행 줄 바꿈은 허용하지 않는 알고리즘 (프로그램 또는 함수)을 작성 하십시오.

노트:

  • DNI는 항상 대문자로 작성되지만 알고리즘에서 입력 및 출력을 대문자 또는 소문자로 선택할 수 있습니다.
  • 실제로 2008 년 이전에 발행 된 일부 NIE는 X, Y또는 뒤에 8 자리 숫자를 Z갖지만이 게임의 목적 상 현재 7 자리 숫자를 고려할 수 있습니다.
  • 입력 문자열에 항상 8자가 있다고 생각할 수 있지만 "8 자리"형식이나 "[XYZ] 더하기 7 자리"형식이 아닌 경우 오류를 선택하거나 원하는대로 입력해야합니다. 예외.

테스트 사례 :

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>

이것은 이므로 각 언어마다 가장 짧은 코드가 이길 수 있습니다!



2
코드가 유효하지 않은 입력에 대해 특정 행동을하는 것이 정말로 중요합니까? 일반적으로 여기서 문제는 오류 처리에 대해 걱정할 필요가 없습니다.
Greg Martin

3
@GregMartin 내 요점을 정확하게 말하면, 코드가 일반적으로 필요하지 않기 때문에 오류 입력에 대한 특정 동작을 보여주기를 원했습니다.
Charlie

"숫자를 23으로 나누고 나머지 연산을 취하십시오 "에서 올바른 용어는 나머지입니다 . 나머지 는 구어체입니다.
Locoluis

2
@Locoluis는 스페인어 로 "rest"를 거짓 친구로 만들고 resto 라고 말합니다 . 적어도 나는 잘못된 용어를 사용하지 않았습니다. :-) 고맙습니다!
Charlie

답변:


11

파이썬 3 , 83 바이트

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

온라인으로 사용해보십시오!

AlixEinsenhardt 덕분에 -5 (99 ~ 94). JonathanAllan 에게 -1 감사합니다 .


1
당신은 대체 할 수 있습니다 str('XYZ'.index(n[0]))에 의해 str(ord(n[0])-88)5 바이트 저장
로 Alix Eisenhardt

1
@AlixEisenhardt 위의 제안은 기술을 람다로 변경하여 결국 10 바이트를 절약하도록 영감을주었습니다.
Mr. Xcoder

대체하여 바이트를 저장 -88하여 %4.
Jonathan Allan

8

하스켈 , 107 93 92 바이트

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

온라인으로 사용해보십시오!


유효하지 않은 입력의 동작은 무엇입니까?
Charlie

그들은 프로그램을 중단시킬 것입니다, 나는 예제에서 하나를 추가했습니다. (실제로 아무도

1
모든 테스트를 실행할 수 있도록 예외 포착으로 제출을 업데이트했습니다.
bartavelle

5

Pyth, 35 34 바이트

이 코드에는 인쇄 할 수없는 문자가 포함되어 있으므로 뒤집을 수있는 xxd16 진 덤프가 있습니다.

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

소문자를 사용 합니다.

온라인으로 사용해보십시오. 테스트 스위트.

인쇄용 버전

@.P305777935990456506899534929G%ssXcz]1>3GU3 23

설명

  • cz]1위치 1에서 입력을 분할합니다 (예 : "y0000369"로) ["y", "0000369"].
  • >3G알파벳의 마지막 3자를 가져옵니다 "xyz".
  • U3범위 [0, 3 [ ,을 얻습니다 [0, 1, 2].
  • X지도 xyz[0, 1, 2]분할 배열의 예 ["y", "0000369"][1, "0000369"]. 이는 xyz7 자 문자열이 단일 문자와 같을 수 없으므로 7 자 중 꼬리는 그대로두고 7 자 중 하나 인 경우 첫 문자를 대체합니다 .
  • s배열을 빈 문자열로 결합합니다 (예 : [1, "0000369"]to) "10000369".
  • s정수 문자열, 예를 들면 캐스트 "10000369"로를 10000369. 숫자가 아닌 다른 문자가 문자열에 남아 있으면 오류가 발생합니다.
  • %23모듈로 23 값을 얻습니다 (예 : 10000369~) 15.
  • C""이진 문자열을 기본 256에서 정수 (약 3.06 × 10 26 ) 로 변환합니다 .
  • .PG해당 인덱스의 알파벳 순열을 가져옵니다.
  • @ 순열에서 올바른 문자를 가져옵니다.

4

MATL , 62 59 바이트

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

유효하지 않은 입력에 대한 오류는 A(I): index out of bounds (Octave에서 실행되는 컴파일러) 또는 Index exceeds matrix dimensions(Matlab에서 실행되는 컴파일러)입니다.

온라인으로 사용해보십시오!

설명

'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 바이트

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

행동에!

대문자 만 유효하지 않은 숫자에 대한 오류 코드는 undefined 입니다.

Jonathan Allan 덕분에 1 바이트가 절약되었습니다.
Shaggy 덕분에 다른 바이트가 절약되었습니다.


어쩌면 사용하여 바이트를 저장 %4하는 대신 -88.
Jonathan Allan

당신은 드롭 할 수 있어야 0에서 charCodeAt()너무.
얽히고 설킨

3

자바 (8) 154 145 104 바이트

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

@ OliverGrégoire 덕분에 -9 바이트 . @ OliverGrégoire
덕분에 입력을 문자 배열 ( ) 로 다시 가져와 -41 바이트char[]

입력이 유효하지 않으면 a java.lang.NumberFormatException또는로 실패합니다 java.lang.StringIndexOutOfBoundsException.

설명:

여기에서 시도하십시오. (잘못된 테스트 사례는 try-catch로 둘러싸여 있으므로 첫 번째 오류에서 멈추지 않습니다.)

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
|정규식에 필요하지 않습니다 . 또한 int t=s.charAt(0)-88t<0?t+40:t바이트 당신에게 여분.
Olivier Grégoire

1
마지막으로 오류 코드를 반환 할 수 있습니다. 그냥이 있다고 결정 'a'하거나 '0'또는 비 대문자, 그리고 대신에를 반환 t/0하고에 훨씬 캐스팅 char. 이 방법으로 7 바이트를 절약 할 수 있습니다. 이 방법으로 골프를 치면 145 바이트를 얻습니다.
Olivier Grégoire

1
@ OlivierGrégoire 감사합니다! 나는 .matches이 정규 표현식 대신에 다른 검증 방법을 사용할 수 있다고 생각합니다 . 그러나 아마 나는 틀렸다.
Kevin Cruijssen

1
아뇨, 당신 말이 맞아요! 그것은이 같은 해 드리겠습니다 : s->{s[0]-=s[0]<88?0:40;return"TRWAGMYFPDXBNJZSQVHLCKE".charAt(new Integer(new String(s))%23);}만 94 바이트 (에 s있는 Being char[]) : P
올리비에 그레 구 아르

1
또는 유효성 검사를 완료하려면 s[0]<88&s[0]>908 바이트 이상하십시오.
Olivier Grégoire



1

q / kdb +, 68 바이트

해결책:

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

예 :

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"
" "

설명:

첫 번째 문자가있는 경우 x 0, 문자열에 "XYZ"다음 a0, 1또는 2. 첫 번째 문자가 문자열에없는 경우, 다음 a될 것입니다 3. 경우 a적은 3보다, 우리의 문자열의 첫 번째 문자를 전환 A ( 0, 1또는 2), 그렇지 않으면 우리는 첫 번째 문자 (따라서 효과적으로 아무것도하지)를 위해 밖으로 전환합니다. 이 문자열은 long ( "J"$)으로 캐스트되고 mod나머지는 23으로 캐스트됩니다 . 이 나머지는 찾아보기 테이블에 색인을 작성하는 데 사용됩니다.

{ "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

노트:

" "캐스트가 널을 리턴하고 인덱스 널에서 문자열로 인덱싱하는 것은 빈 문자이기 때문입니다. "!"^오류가 발생했음을보다 명확하게하기 위해 시작 부분 ( )에 4 바이트를 추가 할 수 있습니다 .

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

1

자바 스크립트 (ES6), 121 바이트

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

녹, 206 바이트

녹이 코드 골프에 적합하지 않다고 생각합니다 -_-

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 바이트

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

입력을 소문자로 가져옵니다 (1 바이트 yay 저장 )

온라인으로 사용해보십시오!

입력이 잘못되면 STDERR에 입력을 인쇄합니다

설명

ć…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

Dyalog APL, 95 바이트

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

이것은 문자열을 피연산자로 받아들이고 결과를 반환하는 모나드 연산자입니다.

FIXME 입력을 확인하지 않습니다. 제대로 골프되지 않았습니다.

용법:

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

      OP '01234567'
L

      OP '00000010'
X
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.