Алгоритм Луна для проверки номеров кредитных карт и т. Д.


50

Вызов

Напишите самую короткую программу или функцию для расчета алгоритма Луна для проверки номеров (кредитных карт).

Алгоритм Луна объяснил

От 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, но вы можете сделать что-нибудь, потому что они слишком короткие, чтобы соответствовать строгой приверженности спецификации.


Если что-либо из вышеперечисленного лишает законной силы существующие ответы (хотя я считаю, что это не должно быть возможно), то эти ответы все еще действительны. Тем не менее, новые ответы, чтобы быть действительными, должны соответствовать спецификации выше.

Leaderboard

Ответы:


21

Golfscript - 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 для номера примера в Википедии (49927398716)
gnibbler

нм. Я забыл использоватьecho -n
gnibbler

1
@gnibbler: Ха-ха, провал. :-P (Серьезно, меня тоже ужалило во время первоначального тестирования.)
Крис Джестер-Янг

1
Несколько мест, где можно сохранить несколько простых персонажей. -1% 2/могут быть объединены в -2/. 1,может быть заменено на 0(0 приводится к массиву, затем +сцепляется). 9>9*-можно заменить на 9>+(поскольку нас интересует только последняя цифра). Кроме того, проверка нечетных длин немного длиннее, использование .,2%,\+короче. После этого мы также можем изменить {16%}%и (\0=в {16}/(внутри цикла). После того, как вы сделали все , что, это будет выглядеть примерно так: .,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!.
Набб

@Nabb: Спасибо! Я включу их в свое решение, хотя, похоже, у вас уже есть тот, который пинает серьезную задницу. :-)
Крис Шестер-Янг

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 Кай


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» в вашей первой лямбде должно быть индексом символа в строке. Это работает как надо? Если так, почему вы переворачиваете строку только для того, чтобы затем изменить ее на основе позиции индекса? Кажется, немного избыточно, нет?
Неллиус

Я проверил только одну из моих кредитных карт и несколько ошибок по одному TBH. (С использованием отладчика VS 2008) Предполагается, что алгоритм удваивает каждую вторую цифру, начиная с последней цифры. Если бы я не перевернул строку, это было бы неправильно для строк с нечетной длиной.
mootinator

Оказывается, у меня был результат i%2<1?1:2задом наперед. Благодарю.
mootinator

8

Golfscript - 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
Крис Шестер-Янг

Тем не менее, GolfScript нуждается в операторе разбиения, поэтому вам не нужно делать эту бессмыслицу «отбросить конечный элемент и повторить». :-)
Крис Шутер-Янг

1
@ Крис, я узнал об этом много лет назад под названием «изгнание девяток». Это аккуратный способ дважды проверять сложения и умножения
gnibbler

3
Это не будет работать при удвоении значения 0 ( 0(9%)равно 9, а не 0).
Набб

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"$'(|)другим способом удвоить нечетные индексы.
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|⍳⍴⍵}⍎¨
Адам

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/регулярное выражение меняет все $&еще в стеке оценки, поэтому их необходимо изменить
Тон Хоспел

Ой. Brilliant! И спасибо за объяснение.
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

x86-16 ASM , IBM PC DOS, 23 байта

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

Использует (злоупотребляет) инструкцию x86 в двоично-двоичном формате AAMдля обработки разделения и modulo 10проверки отдельных цифр .

Указатель строки номера входной карты в SI, длина в CX. Вывод: ZFесли допустимо.

Пример тестовой программы:

введите описание изображения здесь

Загрузите тестовую программу 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)
  • map (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$&

С самого начала rмы неоднократно сопоставляем две цифры и удваиваем левую. Таким образом мы избегаем дорогостоящего изменения списка.

\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. вернуть true, если остаток от деления на 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

GNU sed, 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/

Сед почти никогда не является самым естественным языком для арифметики, но здесь мы идем:

#!/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.