Алгоритм Луна для перевірки номерів кредитних карт тощо


49

Виклик

Напишіть найкоротшу програму чи функцію для обчислення алгоритму Луна для підтвердження чисел (кредитної картки).

Алгоритм Луна пояснив

Від 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 ; якщо ви вважаєте, що хтось неправий або у вас є питання, просто пінг @cat.

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 і зберігає його (все є змінною), тому у нас є 1 на першій ітерації, 0 на другій і т.д.
    3. )* додає одне до цього значення і помножує його, тому ми множимо на 2, потім 1, потім 2 і т.д.
    4. 109% є залишком модуля 109. Це впливає лише на значення 5-9, які були подвоєні, і зменшує їх до правильного значення.
    5. + додає це значення до поточної суми
  3. }*закінчує блок і робить операцію "складання". Спочатку натискається перший символ (оскільки ми перевернули, це контрольна цифра). Потім по черзі натискання та виконання блоку. Таким чином, ми використовуємо значення ascii першого символу як вихідне значення для запущеної суми.
  4. 10% займає залишок по модулю 10.
  5. 8= поверне 1, якщо значення дорівнює 8. Ми використовуємо це, тому що ми не нормалізували перший натиснутий символ (контрольну цифру).

Можна подумати, що ми можемо використовувати 8-замість того, 2+щоб зберегти символ, змінивши 109%на 89%, за винятком випадків, нам потрібно буде додати пробіл, щоб -це віднімання (замість -0).


11

GolfScript, 44 символи

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

Вибраний коментар

Цікаво, що перші два пункти нижче демонструють три абсолютно різних використання %оператора: вибір масиву, карта та мод. Більшість операторів GolfScript є "контекстно-залежними", що надає їм дуже різну поведінку в залежності від типу аргументів.

  1. -1%обертає рядок. Це важливо, оскільки цифри пар рахуються праворуч.
  2. {16%}% перетворює всі цифри ASCII в числа, модеруючи їх з 16.
  3. 2/ розбиває масив на групи по 2.
  4. 1,це дешевий спосіб зробити [0].
  5. \+ефективно попереджує 0 до масиву цифр. Це робиться шляхом заміни, а потім об'єднання.

0 готується під час підготовки до наступної складки. Замість того, щоб брати явне початкове значення, складка GolfScript використовує перший елемент у масиві як початкове значення.

Тепер давайте розглянемо фактичну функцію складання. Ця функція бере два аргументи: складене значення та поточний елемент масиву (який у даному випадку буде масивом 2 або (нечасто) 1 через 2/попередній). Припустимо, аргументи є 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 з числа, якщо воно більше ніж 9. Здійснюється як: скопіюйте число, порівняйте з 9, помножте результат (який або 0, або 1) на 9, а потім відніміть. 1 2 6
    4. + нарешті додає це до першого числа. 1 8
  4. +(після if) додає результат ifдо вихідного значення, в результаті чого нове складене значення.

Після завершення складання ми просто модифікуємо 10 ( 10%) і заперечуємо результат ( !), так що повертаємо 1, якщо сума є кратною 10.


Здається, це повертає 0 для прикладу номер у wikipedia (49927398716)
gnibbler

нм. Я забув скористатися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: Дякую! Я включу їх у своє рішення, хоча, схоже, у вас уже є одна, яка б'є серйозну дупу. :-)
Кріс Єстер-Янг

11

Пітон, 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
Чорна сова Кай


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;}

Я не дуже поганий для коду golf 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;}

Це гарна ідея та цікавий підхід, але, схоже, це не працює. Принаймні, не з моїми кількома тестами. Схоже, що "я" у вашій першій лямбда має бути індексом символу в рядку. Чи працює це як слід? Якщо так, то чому ви обернете рядок лише для того, щоб потім змінити його на основі позиції індексу? Здається, трохи зайвим, ні?
Нелліус

Я перевірив лише одну зі своїх кредитних карток і кілька помилок, викладених з неї TBH. (Використання відладчика VS 2008) Алгоритм повинен подвоювати кожну другу цифру, починаючи з ОСТАНОЇ цифри. Якби я не перевернув рядок, це було б неправильно для рядків з непарною довжиною.
мотиватор

Виявляється, у мене був результат i%2<1?1:2назад. Дякую.
мотиватор

8

Гольфскрипт - 34 символи

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

Приклад номер зі сторінки вікіпедії 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
Кріс Єстер-Янг

Хоча Srsly, GolfScript потребує оператора розділення, тому вам не потрібно робити це "випадання кінця і повторення" дурниць. :-)
Кріс Єстер-Янг

1
@Chris, я дізнався про те, що багато років тому називав "викиданням дев'яти". Це акуратний спосіб подвійної перевірки додавання та множення на
довгі руки

3
Це не буде працювати при подвоєнні значення 0 ( 0(9%)це 9, а не 0).
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

Ви, напевно, знаєте про це, але ви могли б зробити .sum замість .inject (: +), щоб зберегти 7 байт
Håvard Nygård

7

Haskell, 96 байт

Має бути кращий / коротший шлях, але ось моє рішення Haskell у 96 символах :

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

Windows 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

Q, 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

47 байт з {0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)іншим способом подвоїти непарні показники.
Стрітер

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|⍳⍴⍵}⍎¨
Адам

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

Perl, 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/регулярний вимір змінюється $&на стеці оцінювання, тому їх потрібно змінювати
Тон Євангелія

Ой. Блискуче! І дякую за пояснення.
msh210

3

JavaScript (ES6), 61 байт

Без конкуренції, оскільки JavaScript в 2011 році був дуже різним.

Сума цифр - 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

Використовує (зловживає) інструкціями BCD до бінарних даних x86 для обробки розбиття та modulo 10перевірки окремих цифр . Виявляється, що вказівки AAMта AADінструкції виконують BCD / бінарне перетворення значень байтів (що може бути дуже зручно), незважаючи на те, що вони не задокументовані або описані як виконання цієї функції загально.

Для всіх офіційних версій IBM / MS DOS, AXі BXне започатковано 0000під час запуску ( ісй , реф ) і DXдо CS, який є 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

JavaScript 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 байт

Сітківка (набагато) новіша, ніж ця проблема.


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

Провідна порожня лінія є суттєвою.

Відбитки 0для помилкових 1результатів.

Спробуйте в Інтернеті! (Трохи модифікований для запуску всіх тестових випадків одночасно.)

Пояснення


;

Вставте ;в кожну позицію, щоб розділити цифри.

r`(.);.
$1$&

З right ми кілька разів співставляємо дві цифри та подвоюємо ліву. Таким чином ми уникаємо дорогого перегляду списку.

\d
$*

Ми співставляємо кожну цифру і перетворюємо її на стільки 1s (тобто перетворюємо кожну цифру в одинарну).

1+
$.&

Це відповідає кожному унарному номеру і перетворює його назад у десятковий, замінюючи його довжиною. Разом з попереднім етапом до цього додаються подвоєні цифри.

.
$*

Знову ми підбираємо кожного персонажа і перетворюємо його на стільки 1s. Тобто ми перетворюємо кожну цифру окремо назад в одинакову. Це також відповідає ;роздільникам, які трактуються як нулі при перетворенні, а значить, їх просто видаляють. Оскільки всі одинарні числа тепер зібрані разом, ми автоматично додали одинарні представлення всіх цифр разом.

$
$._

В кінці ми вставляємо довжину всього рядка, тобто десяткове представлення одинарної контрольної суми.

0$

Нарешті ми підраховуємо кількість збігів цього регулярного виразу, тобто перевіряємо, чи закінчується десятковий подання у 0друку 0чи 1відповідно.


2

Powershell, 74 байти

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

Пояснення

  1. для кожного символу рядка аргументу, у зворотному порядку
  2. отримати цифру подвійного значення цифри
  3. подвійне значення цифри не може бути більшим за 18. Тому ми накопичуємо значення мінус 9, якщо значення> 9
  4. повернути істину, якщо решта ділення на 10 дорівнює 0

Тестовий сценарій

$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

Sed GNU, 140 байт

(включаючи +1 для -rпрапора)

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 в іншому випадку.

Збережено три байти завдяки пропозиціям Луїса Мендо.

Пояснення

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 не існувала, коли запитання було задано, тому воно не відповідає дійсності.
Еллі

3
Досить впевнений, що існував мета-консенсус, який сказав, що мови, які були зроблені після виклику, більше не є "неконкурентоспроможними"
mudkip201
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.