신용 카드 번호 확인을위한 Luhn 알고리즘


49

도전

(신용 카드) 번호 확인을위한 Luhn 알고리즘 을 계산 하는 가장 짧은 프로그램 또는 함수 를 작성하십시오 .

Luhn 알고리즘 설명

RosettaCode로부터 ,이 챌린지를위한이 알고리즘은 다음과 같은 입력 예와 함께 지정됩니다 49927398716.

Reverse the digits, make an array:
    6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4
Double the numbers in odd indexes:
    6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4
Sum the digits in each number:
    6, 2, 7, 7, 9, 6, 7, 4, 9, 9, 4
Sum all of the numbers:
    6 + 2 + 7 + 7 + 9 + 6 + 7 + 4 + 9 + 9 + 4 = 70
If the sum modulo 10 is 0, then the number is valid:
    70 % 10 = 0 => valid

IO 규칙

입력 : 선택한 언어의 입력 / 출력 형식으로 된 문자열 또는 숫자 (선택)

출력 : 위의 테스트에 따라 입력이 유효한지 여부를 나타내는 진위 또는 거짓 값 .

노트 / 팁

  • 테스트를 위해 신용 카드 나 계좌 번호를 실수로 게시하지 마십시오.

  • 입력이 유효하지 않고 지정된 알고리즘 으로 처리 할 수없는 경우 (즉, 작업하기에는 너무 짧음) 컴퓨터 폭파를 포함하여 원하는 모든 작업을 수행 할 수 있습니다.

  • 그러나 이전 글 머리 기호는 언어가 처리하기에 너무 큰 숫자로 원하는 언어를 수행 할 수 있음을 의미하지는 않습니다. 언어가 테스트 사례를 처리 할 수없는 경우 문자열을 입력으로 고려하십시오.

다음 예제는 이 Python 스크립트 로 검증되었습니다 . 당신이 잘못 생각하거나 질문이 있으면 @ ping을 핑하십시오.

49927398716      True
49927398717      False
1234567812345670 True    
1234567812345678 False
79927398710      False
79927398711      False
79927398712      False
79927398713      True
79927398714      False
79927398715      False
79927398716      False
79927398717      False
79927398718      False
79927398719      False
374652346956782346957823694857692364857368475368 True
374652346956782346957823694857692364857387456834 False
8 False **
0 True  **

** Python 구현에 따르면, 사양이 엄격히 준수하기에는 너무 짧기 때문에 어떤 작업을 수행 할 수 있습니다.


위의 내용 중 하나라도 기존 답변을 무효화하는 경우 (그렇지 않아야한다고 생각하지만) 해당 답변은 여전히 ​​유효합니다. 그러나 새로운 답변은 유효하려면 위의 사양을 따라야합니다.

리더 보드

답변:


21

골프 스크립트-24 자

-1%{2+0!:0)*109%+}*10%8=

설명:

  1. -1% 문자열을 뒤집습니다
  2. {루프를 시작하는 블록을 시작합니다. 문자열의 각 문자는 ASCII 값으로 푸시됩니다.
    1. 2+ 2를 더합니다 (숫자의 ASCII 값은 48 + n이므로 이제 50 + n을 가지며 마지막 숫자는 n입니다)
    2. 0!:0 0의 값을 반전시키고 저장합니다 (모든 것이 변수 임)
    3. )* 이 값에 1을 더하고 곱하면 2, 1, 2 등을 곱합니다.
    4. 109% 이것은 나머지 모듈로 109입니다. 이것은 두 배가 된 5-9 값에만 영향을 미치며 올바른 값으로 감소시킵니다.
    5. + 이 값을 누계에 더합니다.
  3. }*블록을 끝내고 '접기'작업을 수행합니다. 먼저 첫 번째 문자가 푸시됩니다 (반전되었으므로 확인 숫자 임). 그런 다음 블록을 밀고 실행하십시오. 따라서 첫 번째 문자의 ASCII 값을 누적 합계의 시작 값으로 사용합니다.
  4. 10% 나머지 모듈로 10을 취합니다.
  5. 8= 값이 8이면 1을 반환합니다. 첫 번째로 밀린 문자 (체크 숫자)를 정규화하지 않았기 때문에이 값을 사용합니다.

로 변경 하여 문자를 저장하는 8-대신 사용할 수 있다고 생각할 수 있습니다 . 단, 공백 대신 공백을 추가해야합니다 .2+109%89%--0


11

GolfScript, 44 자

-1%{16%}%2/1,\+{(\.{0=2*.9>9*-+}{;}if+}*10%!

선택된 논평

흥미롭게도, 아래의 첫 두 항목은 %배열 선택, 맵 및 mod의 세 가지 완전히 다른 연산자 사용법을 보여줍니다 . 대부분의 GolfScript 연산자는 "문맥에 민감"하므로 인수의 유형에 따라 매우 다양한 동작을 제공합니다.

  1. -1%문자열을 반대로 바꿉니다. 숫자 쌍이 오른쪽에서 계산되므로 중요합니다.
  2. {16%}% 모든 ASCII 숫자를 16으로 수정하여 숫자로 변환합니다.
  3. 2/ 배열을 2 개의 그룹으로 나눕니다.
  4. 1,하는 싼 방법 [0]입니다.
  5. \+효과적으로 숫자 배열에 0을 추가합니다. 스왑 한 다음 연결 하여이 작업을 수행합니다.

다음에 오는 접기에 대비하여 0이 앞에 붙습니다. GolfScript의 접기는 명시적인 초기 값을 취하는 대신 배열의 첫 번째 항목을 초기 값으로 사용합니다.

이제 실제 접기 기능을 살펴 보겠습니다. 이 함수는 접힌 값과 배열의 현재 항목 (이 경우 2/이전의 이유로 인해 2 또는 (흔하지 않게) 1의 배열 임)의 두 가지 인수를 사용합니다 . 인수가이라고 가정합니다 1 [2 3].

  1. (\.가장 왼쪽 배열 요소를 분리하고 나머지 배열을 앞쪽으로 이동 한 다음 복사합니다. 이제 스택은 다음과 같습니다 1 2 [3] [3].
  2. if체크 어레이 (홀수 크기 계좌 번호 다루는 마지막 그룹에 대한 경우이다) 비어있는 경우. 그렇다면 특별한 처리가 발생하지 않습니다 (빈 배열을 튀기십시오).
  3. 짝수 그룹의 경우 :
    1. 0= 배열의 첫 번째 (이 경우에만) 요소를 가져옵니다. 1 2 3
    2. 2* 수를 두배로합니다. 1 2 6
    3. .9>9*- 다음과 같이 구현됩니다. 숫자를 복사하고 9와 비교 한 다음 결과 (0 또는 1)에 9를 곱한 다음 빼십시오. 1 2 6
    4. + 마지막으로 첫 번째 숫자에 추가합니다. 1 8
  4. +(뒤에 if)는의 결과를 if원래 값에 더하여 새로운 접힌 값을 만듭니다.

폴딩이 완료된 후에는 간단히 10 ( 10%)으로 수정 하고 결과 ( !)를 무시하여 합계가 10의 배수 인 경우 1을 반환합니다.


wikipedia의 예제 번호로 0을 반환하는 것 같습니다 (49927398716)
gnibbler

nm. 나는 사용을 잊었다echo -n
gnibbler

1
@gnibbler : 하하, 실패. :-P (진심으로, 나는 초기 테스트
Chris Jester-Young

1
몇 가지 쉬운 캐릭터를 저장할 수있는 몇 곳. -1% 2/로 결합 할 수 있습니다 -2/. 1,로 대체 할 수 있습니다 0(0은 배열로 강제 변환 된 다음 +연결됨). 9>9*-로 대체 할 수 있습니다 9>+(마지막 숫자에만 관심이 있으므로). 또한 홀수 길이 검사는 약간 길며 사용 시간 .,2%,\+이 짧습니다. 이 작업을 수행 한 후 루프 내부 로 변경 {16%}%하여 (\0=들어갈 수도 있습니다 {16}/. 모든 작업을 완료하면 다음과 같이 보일 것 .,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!입니다.
Nabb

@Nabb : 감사합니다! 나는 당신이 이미 심각한 논쟁을 일으키는 것을 가지고있는 것처럼 보이지만 그것들을 내 솔루션에 통합시킬 것입니다. :-)
Chris Jester-Young

11

Python, 73 69 자

def P(x):D=map(int,x);return sum(D+[d-d/5*9for d in D[-2::-2]])%10==0

4
당신은 거꾸로 반복하지 않고 두 개의 문자를 더 절약 할 수 있습니다 : D[-2::-2]-> D[1::2]합의 순서는 중요하지 않기 때문에 :)
ThinkChaos

==0<1
Black Owl Kai

10

파이썬 3, 77 바이트

c=lambda a:sum(sum(divmod(int(a[-e-1])<<e%2,10))for e in range(len(a)))%10==0

9

C # 119 자 :

bool l(string n){return(String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2<1?1:2)+"").ToArray()).Sum(x=>x-48))%10<1;}

아니 너무 정적으로 입력 된 언어 코드 골프 n00b 나쁜, 나는 희망한다.

이것은 100 으로 줄일 수 있습니다 :

bool l(string n){return String.Join("",n.Reverse().Select((x,i)=>(x-48)*(i%2+1))).Sum(x=>x+2)%10<1;}

좋은 생각이자 재미있는 접근 방법이지만 작동하지 않는 것 같습니다. 적어도 몇 가지 테스트는 아닙니다. 첫 번째 람다의 "i"는 문자열의 문자 색인으로 간주됩니다. 그것이 제대로 작동합니까? 그렇다면 왜 문자열을 뒤집어 인덱스 위치를 기준으로 수정합니까? 약간 중복되는 것 같습니까?
Nellius

TBH에서 내 신용 카드 중 하나와 하나의 오류로 몇 가지만 테스트했습니다. (VS 2008 디버거 사용) 알고리즘은 마지막 숫자부터 시작하여 두 번째 숫자마다 두 배씩 증가합니다. 문자열을 반대로 바꾸지 않으면 길이가 홀수 인 문자열에는 올바르지 않습니다.
mootinator 2019

내가 i%2<1?1:2거꾸로 한 결과가 나왔다 . 감사.
mootinator

8

골프 스크립트-34 자

{15&}%.-2%\);-2%{.+(9%)}%+{+}*10%!

Wikipedia 페이지의 예제 번호 4992739871

{15&}%  does a bitwise and of each ascii digit with 00001111
        now I have a list of digits 
        [4 9 9 2 7 3 9 8 7 1 6]
.       makes a copy of the list, now I have two identical lists
        [4 9 9 2 7 3 9 8 7 1 6] [4 9 9 2 7 3 9 8 7 1 6]
-2%     like [::-2] in python takes every second element in reverse
        [4 9 9 2 7 3 9 8 7 1 6] [6 7 9 7 9 4]
\       swap the two lists around
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1 6]
);      drop the last digit off the list
        [6 7 9 7 9 4] [4 9 9 2 7 3 9 8 7 1]
-2%     same as before
        [6 7 9 7 9 4] [1 8 3 2 9]
{       for each item in the list ...
.+      ... double it ...
(       ... subtract 1 ...
9%      ... mod 9 ...
)}%     ... add 1 ...
        [6 7 9 7 9 4] [2 7 6 4 9]
+       join the two lists
        [6 7 9 7 9 4 2 7 6 4 9]
{+}*    add the elements up
        70
10%     mod 10
        0
!       invert the result
        1

.+(9%)(어쨌든, 나를 위해) 매우 혁신적이다. 나는 좋아한다! +1
Chris Jester-Young

그러나 GolfScript에는 분할 연산자가 필요하기 때문에 "드롭 엔드 항목을 삭제하고 반복"할 필요가 없습니다. :-)
Chris Jester-Young

1
@Chris, 나는 몇 년 전에 "9를 던지기"라고 배웠습니다. 긴 덧셈과 곱셈을
재확인

3
0의 값이 두 배가되면 (0이 0(9%)아닌 9) 작동하지 않습니다.
Nabb

8

PHP, 108 바이트

<?function v($s,$t=0){for($i=strlen($s);$i>=0;$i--,$c=$s[$i])$t+=$c+$i%2*(($c>4)*-4+$c%5);return!($t % 10);}

7

루비-85 자

def f s
l=s.size
s.chars.map{|k|(i=k.to_i*((l-=1)%2+1))%10+i/10}.inject(:+)%10==0
end

아마도 이것에 대해 알고 있지만 .inject (: +) 대신 .sum을 사용하여 7 바이트를 절약 할 수 있습니다.
Håvard Nygård

7

하스켈, 96 바이트

더 좋고 짧은 방법이 있어야하지만 여기 96 자의 Haskell 솔루션이 있습니다 .

l=(==0).(`mod`10).sum.zipWith($)(cycle[id,\x->x`mod`5*2+x`div`5]).reverse.map((+(-48)).fromEnum)

안타깝게도이 digitToInt기능은 import Data.Char처음 사용하는 경우에만 사용할 수 있습니다 . 그렇지 않으면 내가 대체하여 88 자까지 얻을 수 ((+(-48)).fromEnum)와 함께 digitToInt.


6

윈도우 PowerShell, 82

filter f{!((''+($_[($_.length)..0]|%{+"$_"*($i++%2+1)})-replace'.','+$&'|iex)%10)}

역사:

  • 2011-02-13 03:08 (84) 첫 번째 시도.
  • 2011-02-13 12:13 (82) 공간이 아프지 않기 때문에 가입 할 필요가 없습니다. +1 + +3여전히 평가할 수 있습니다.

5

문 63

{0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}

용법

q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398711"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398712"
0b
q){0=mod[(+/)"I"$(,/)($)($)@["I"$'x;1+2*'(!)(_)((#)x)%2;*;2];10]}"79927398713"
1b

{0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)홀수 인덱스를 두 배로 늘리는 다른 방법으로 47 바이트 .
streetster

5

D, 144 바이트

bool f(S)(S s){int t(C)(C c){return to!int(c)-'0';}int n,v;foreach(i,c;array(retro(s))){v=i&1?t(c)*2:t(c);n+=v>=10?v%10+v/10:v;}return n%10==0;}

더 읽기 :

bool f(S)(S s)
{
    int t(C)(C c)
    {
        return to!int(c) - '0';
    }

    int n, v;

    foreach(i, c; array(retro(s)))
    {
        v = i & 1 ? t(c) * 2 : t(c);

        n += v >= 10 ? v % 10 + v / 10 : v;
    }

    return n % 10 == 0;
}

5

APL, 28 바이트

{0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵}

분해도

{                     v←⍎¨⍵}  ⍝ turn the string into a numeric vector of its digits, v
                2-2|⍳⍴v       ⍝ make a vector of the same length, with 2 in every 2nd place
             v×⌽              ⍝ multiply it with v, starting from the right
          ∊⍕¨                 ⍝ turn each component into a string and collect all the digits
      +/⍎¨                    ⍝ turn each digit again into a number and sum them
 0=10|                        ⍝ check whether the sum is a multiple of 10

      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '79927398713'
1
      {0=10|+/⍎¨∊⍕¨v×⌽2-2|⍳⍴v←⍎¨⍵} '123456789'
0

1
-2 :{0=10|+/⍎¨∊⍕¨⍵×⌽2-2|⍳⍴⍵}⍎¨
Adám

4

PowerShell 123

filter L($x){$l=$x.Length-1;$l..0|%{$d=$x[$_]-48;if($_%2-eq$l%2){$s+=$d}elseif($d-le4){$s+=$d*2}else{$s+=$d*2-9}};!($s%10)}

4

펄, 46 42 41 바이트

에 +1 포함 -p

STDIN에 입력하십시오 :

luhn.pl <<< 79927398713

luhn.pl:

#!/usr/bin/perl -p
s%.%$=-=-$&-$&*1.2*/\G(..)+$/%eg;$_=/0$/

이것이 어떻게 작동하는지 설명해 주시겠습니까? 당신은 경기에 의해 감소 ​​한 다음 경기 시간 1.2만큼 감소하지만 올바른 위치에만 있습니다. 왜 1.2입니까? 그렇지 $=-=-$&-$&*/\G(..)+$/않습니까?
msh210

3
@ msh210 : 그것은 2로 곱셈의 효과를 인코딩 0..4* 2 제공 0, 2, 4, 6, 8하지만 5..9제공 10,12,14,16,18되는 합계 1 3 5 7 9의 같은 마지막 자리로이 11 13 15 17 19같이있는 값과 동일을 0..9 * 2.2당신이 정수로 잘라 경우. 첫 번째는 $&이미 인자 1를 제공하므로 수정 1.2이 여전히 필요합니다. $=정수만 가질 수 있고 0으로 끝나는 값으로 시작하므로 잘림을 처리합니다. /\G/정규 표현식 $&이 평가 스택에서 여전히 변경 되기 때문에 음수 값이 필요하므로 변경 해야합니다.
Ton Hospel

오. 훌륭한! 설명해 주셔서 감사합니다.
msh210

3

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

2011 년 JavaScript는 매우 다르기 때문에 비경쟁입니다.

의 숫자의 합 2*n입니다 2*n경우 n in 0..4, 2*n-9경우 n in 5..9. 즉, 모든 합은 한 단계로 계산 될 수 있습니다.

s=>!([...s].reduceRight((t,d)=>t-d-i++%2*(d>4?d-9:d),i=0)%10)

3

젤리 , 12 11 바이트

ṚḤJḤ$¦DFS⁵ḍ

온라인으로 사용해보십시오! (모든 테스트 사례와 함께)

작동 원리

ṚḤJḤ$¦DFSḍ⁵  - Main link. Argument: n (integer) e.g. 49927398716
Ṛ            - Reverse. Casts a number to digits     [6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4]
     ¦       - Sparse application. Apply the next command to the given indicies
 Ḥ           -   Command: Double
    $        -   Indicies:
  J          -     range(length)...                  [1, 2 , 3, 4, 5, 6, 7, 8, 9, 10, 11]
   Ḥ         -     doubled.                          [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
             - Doubles elements at odd indicies      [6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4]
      D      - Split each into digits                [6, 2, 7, [1, 6], 9, 6, 7, 4, 9, [1, 8], 4]
       F     - Flatten                               [6, 2, 7, 1, 6, 9, 6, 7, 4, 9, 1, 8, 4]
        S    - Sum                                   70
          ḍ  - Divisible by... 
         ⁵   -   10?                                 1

또는 12 바이트의 경우 :

ṚḤJḤ$¦DFSḍ@⁵

3

8086 어셈블리 , IBM PC DOS,29 28 25 23 바이트

; Perform LUHN check
; Input: SI = card num string, CX = length
; Output: ZF = 1 if valid, ZF = 0 if not valid
    LUHN    MACRO
            LOCAL DIGIT_LOOP, EVEN
03 F1       ADD  SI, CX         ; start at end of input string 
FD          STD                 ; set LODSB direction to decrement 
    DIGIT_LOOP:
AC          LODSB               ; load next digit into AL, decrement SI
2C 30       SUB  AL, '0'        ; convert ASCII char to binary value 
F7 DA       NEG  DX             ; flip DX to alternate odd/even index
78 06       JS   EVEN           ; if even index, do not double and sum digits 
D0 E0       SHL  AL, 1          ; double the value 
D4 0A       AAM                 ; BCD convert to split digits (ex: 18 = 12H --> 0108H) 
02 DC       ADD  BL, AH         ; add tens digit to running sum 
    EVEN:
02 D8       ADD  BL, AL         ; add ones digit to running sum 
E2 ED       LOOP DIGIT_LOOP 
93          XCHG BX, AX         ; sum is in BL, move to AL for conversion
D4 0A       AAM                 ; BCD convert AL, set ZF=1 if low digit is 0
    ENDM

x86의 BCD- 이진 명령을 사용하여 개별 숫자 분리 및 modulo 10확인 을 처리합니다 . 그것은 밝혀 AAMAAD설명은 그 설명되지 또는 일반적으로 그 기능을 수행하는 것으로 설명에도 불구하고 (매우 유용 할 수있다) 바이트 값의 BCD / 이진 변환을한다.

모든 공식 IBM / MS DOS 버전의 경우 AXBX초기화됩니다 0000시작 (에 심판 , 심판 )과 DXCS그렇게 비 - 제로 긍정적 보장 12 비트 값이다. 이것은 우리가 보장 할 수있는 방법입니다 BX입니다 0및 플롭 / 플립 수 DX홀수 / 짝수 자리 장소를 결정합니다.

출력 예 :

여기에 이미지 설명을 입력하십시오

LUHN.COM IBM PC DOS 테스트 프로그램을 다운로드하십시오 .


2

스칼라 : 132

def q(x:Int)=x%10+x/10
def c(i:String)={val s=i.reverse
(s(0)-48)==10-(s.tail.sliding(2,2).map(n=>(q((n(0)-48)*2)+n(1)-48)).sum%10)}

기도:

c("79927398713")
  • 역전 ( "79927398713") = 31789372997
  • s (0), s.tail : (3) (1789372997)
  • 슬라이딩 (2,2) = (17 89 37 29 97)
  • 지도 (q ((n (0) -48 * 2 + n (1) -48))) => q (( '1'- '0') * 2) + '7'- '0') = 1 * 2 + 7

2

자바 스크립트 1.8 : 106 자

이것은이 게시물을 발견하기 전에 생각해 낸 원래 솔루션입니다.

function(n){return!(n.split('').reverse().reduce(function(p,c,i){return(+c&&((c*(1+i%2)%9)||9))+p},0)%10)}

읽을 수있는 형태 :

function luhnCheck(ccNum) {
    return !(                                  // True if the result is zero.
             ccNum.split('').
               reverse().                      // Iterate over the string from rtl.
               reduce(function(prev, cur, idx) {
                 return prev +                 // Sum the results of each character.
                        (+cur &&               // If the current digit is 0, move on.
                         ((cur * (1 + idx % 2) // Double cur at even indices.
                           % 9) || 9));        // Sum the digits of the result.
               }, 0)
            % 10);                             // Is the sum evenly divisible by 10?
}


2

레티 나 , 43 42 바이트

레티 나 (Retina)는이 도전보다 훨씬 더 최신입니다.


;
r`(.);.
$1$&
\d
$*
1+
$.&
.
$*
$
$._
0$

선행 빈 줄이 중요합니다.

0거짓과 1진실한 결과를 위해 인쇄 합니다.

온라인으로 사용해보십시오! (모든 테스트 사례를 한 번에 실행하도록 약간 수정했습니다.)

설명


;

;모든 자리에 숫자를 구분하여 삽입하십시오 .

r`(.);.
$1$&

로부터 right, 우리는 반복적으로 두 자리 숫자를 두 번 왼쪽을 일치합니다. 이런 식으로 목록의 값 비싼 반전을 피할 수 있습니다.

\d
$*

우리는 각 숫자를 일치시키고 그 숫자로 변환합니다 1(즉, 각 숫자를 단항으로 변환합니다).

1+
$.&

이것은 각 단항 수를 일치시키고 길이로 대체하여 십진수로 다시 변환합니다. 이전 단계와 함께 두 배의 숫자가 추가됩니다.

.
$*

다시, 우리는 모든 캐릭터를 일치시키고 그것을 많은 것으로 1바꿉니다. 즉, 각 숫자를 개별적으로 단항으로 다시 변환합니다. 또한 ;변환에서 0으로 처리되는 구분 기호 와 일치하므로 간단히 제거됩니다. 모든 단항 숫자가 함께 스 쿼지되었으므로 모든 자릿수의 단항 표현이 자동으로 추가되었습니다.

$
$._

마지막으로 전체 문자열의 길이, 즉 단항 체크섬의 10 진수 표현을 삽입합니다.

0$

마지막으로이 정규식과 일치하는 횟수를 계산합니다. 즉, 소수점 표시가로 끝나는 지 0, 인쇄로 끝나는 지 0또는 1그에 따라 끝나는 지 확인합니다 .


2

파워 쉘, 74 바이트

param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)

설명

  1. 인수 문자열의 각 문자에 대해 역순으로
  2. 두자리 수의 숫자를 얻는다
  3. 숫자의 이중 값은 18보다 클 수 없습니다. 따라서 값> 9 인 경우 값에서 9를 뺀 값을 누적합니다.
  4. 10으로 나눈 나머지가 0이면 true를 반환합니다.

테스트 스크립트

$f = {

param($s)$s[$s.Length..0]|%{(1+$i++%2)*"$_"}|%{$r+=$_-9*($_-gt9)}
!($r%10)

}

@(
    ,("49927398716"      , $True)
    ,("49927398717"      , $False)
    ,("1234567812345670" , $True)
    ,("1234567812345678" , $False)
    ,("79927398710"      , $False)
    ,("79927398711"      , $False)
    ,("79927398712"      , $False)
    ,("79927398713"      , $True)
    ,("79927398714"      , $False)
    ,("79927398715"      , $False)
    ,("79927398716"      , $False)
    ,("79927398717"      , $False)
    ,("79927398718"      , $False)
    ,("79927398719"      , $False)
    ,("374652346956782346957823694857692364857368475368" , $True)
    ,("374652346956782346957823694857692364857387456834" , $False)
    ,("8" , $False)
    ,("0" , $True)
) | % {
    $s, $expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}

산출

True: True : 49927398716
True: False : 49927398717
True: True : 1234567812345670
True: False : 1234567812345678
True: False : 79927398710
True: False : 79927398711
True: False : 79927398712
True: True : 79927398713
True: False : 79927398714
True: False : 79927398715
True: False : 79927398716
True: False : 79927398717
True: False : 79927398718
True: False : 79927398719
True: True : 374652346956782346957823694857692364857368475368
True: False : 374652346956782346957823694857692364857387456834
True: False : 8
True: True : 0


1

하스켈 : 97

어떤 이유로 든 이것이 작동하지 않으므로 여기에 내 버전이 있습니다.

l=(\x->(==0)$(`mod`10).sum$zipWith($)(cycle[id,sum.map(read.(:"")).show.(*2)])(map(read.(:""))x))

1

GNU sed, 140 바이트

( -r플래그에 +1 포함 )

s/^(..)*.$/0&/
s/(.)./\1x&/g
s/x[5-9]/1&/g
s/[0x]//g
s/[789]/&6/g
s/[456]/&3/g
s/[369]/&11/g
s/[258]/&1/g
s/.{10}//g
s/.+/false/
s/^$/true/

Sed는 산술을위한 가장 자연스런 언어는 아니지만 거의 여기에 있습니다.

#!/bin/sed -rf

# zero-pad to even length
s/^(..)*.$/0&/
# double every other digit
s/(.)./\1x&/g
# add carry (converts mod-9 to mod-10)
s/x[5-9]/1&/g
# convert sum to unary
s/[0x]//g
s/[789]/&6/g
s/[456]/&3/g
s/[369]/&11/g
s/[258]/&1/g
# remove whole tens
s/.{10}//g
# output 'true' or false
s/.+/false/
s/^$/true/

1

APL, 38 바이트

d←10∘⊥⍣¯1⋄{0=10|+/+/d x×1+~2|⍳⍴x←⌽d ⍵}

숫자는 문자열이 아닌 숫자로 예상되지만 tryAPL은 이해할 수 없으므로 구현되지 않기 때문입니다.

추가로 환원 가능합니다.


1

PHP-136 자

function t($c){foreach($a=str_split(strrev($c)) as $k=>&$v){$v=array_sum(str_split(($k % 2)!==0?2*$v:$v));}return !(array_sum($a)% 10);}

1

MATL , 23 20 바이트 (비경쟁)

P!Utn:2X\!*t9>+s10\~

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

유효한 숫자는 1을, 그렇지 않으면 0을 출력합니다.

Luis Mendo의 제안으로 3 바이트를 절약했습니다.

설명

P       % flip the order of elements
!       % transpose into column vector
U       % convert char matrix to numeric
t       % duplicate the vector
n       % find the length
:       % create a new vector length n (1, 2, 3, ... n)
2       % number literal
X\      % take it mod 2, to make the new vector (1, 2, 1, ..., (n-1) mod 2 +1)
!       % transpose
*       % element-wise product
t       % duplicate
9       % push 9
>       % 1 if it is greater than 9
+       % add the vectors, this makes the last digit of each the same as the sum of the digits
s       % add them
10      % number literal
\       % mod 10
~       % logical 'not' (element-wise)
        % (implicit) convert to string and display

1

젤리 , 14 바이트

DUḤJḤ$¦DS$€S⁵ḍ

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

설명:

D              get digits
 U             reverse array
   JḤ$         for every other index,
  Ḥ   ¦        double the value
          €    for each value,
       D $     get the digits
        S$     and sum them
           S   sum the list
            ⁵ḍ check if it's divisible by 10

이것이 경쟁이 아닌 이유는 무엇입니까?
mudkip201

@ mudkip201 내가 틀렸다면 바로 잡으십시오.하지만 질문 할 때이 버전의 Jelly는 존재하지 않으므로 질문에 유효하지 않습니다.
ellie

3
도전 이후에 만들어진 언어는 더 이상 '비 경쟁적이지 않다'는 메타 컨센서스가 있다고 확신합니다.
mudkip201
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.