Мой штрих-код действителен?


33

EAN-8 штрих - кода включает в себя 7 цифр информации и 8 - й контрольной цифрой.

Контрольная сумма рассчитывается путем поочередного умножения цифр на 3 и 1, сложения результатов и вычитания из следующего кратного 10.

Например, учитывая цифры 2103498:

Digit:        2   1   0   3   4   9   8
Multiplier:   3   1   3   1   3   1   3
Result:       6   1   0   3  12   9  24

Сумма этих итоговых цифр равна 55 , поэтому контрольная сумма равна 60 - 55 = 5.


Соревнование

Ваша задача состоит в том, чтобы при наличии 8-значного штрих-кода проверить, является ли он действительным, - вернуть истинное значение, если контрольная сумма действительна, и неверно в противном случае.

  • Вы можете принять участие в любой из следующих форм:
    • Строка длиной 8 символов, представляющая цифры штрих-кода
    • Список из 8 целых чисел, цифры штрих-кода
    • Неотрицательное целое число (вы можете принять начальные нули там, где их нет, т.е. 1= 00000001, или запросить ввод с данными нулями)
  • Встроенные функции, которые вычисляют контрольную сумму EAN-8 (то есть принимают первые 7 цифр и вычисляют последние), запрещены.
  • Это , поэтому выигрывает самая короткая (в байтах) программа!

Тестовые случаи

20378240 -> True
33765129 -> True
77234575 -> True
00000000 -> True

21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False


1
Этот вопрос на самом деле не о штрих-коде (это черно-белая полосатая вещь), а о числе, закодированном штрих-кодом. Номер может существовать без штрих-кода, и штрих-код может кодировать другие вещи, кроме EAN. Может быть, просто « Является ли мой EAN-8 действительным » лучше название?
Пауло Эберманн

2
@ PaŭloEbermann не совсем то же самое кольцо ...
FlipTack

7
Читая о штрих-кодах, я ожидаю некоторого чтения изображения (или, по крайней мере, битовой строки), не проверяя контрольную сумму.
Paŭlo Ebermann

Сильно связаны , так как ISBN-13 является EAN.
Оливье Грегуар

Ответы:


5

Желе , 7 байт

s2Sḅ3⁵ḍ

Попробуйте онлайн!

Как это работает

s2Sḅ3⁵ḍ  Main link. Argument: [a,b,c,d,e,f,g,h] (digit array)

s2       Split into chunks of length 2, yielding [[a,b], [c,d], [e,f], [g,h]].
  S      Take the sum of the pairs, yielding [a+c+e+g, b+d+f+h].
   ḅ3    Convert from ternary to integer, yielding 3(a+c+e+g) + (b+d+f+h).
     ⁵ḍ  Test if the result is divisible by 10.

13

JavaScript (ES6), 41 40 38 байт

Сохранено 2 байта благодаря @ETHProductions и 1 байт благодаря @Craig Ayre.

s=>s.map(e=>t+=e*(i^=2),t=i=1)|t%10==1

Вводит в виде списка цифр.

Определяет сумму всех цифр, включая контрольную сумму.

Если сумма кратна 10, то это действительный штрих-код.

Тестовые случаи


Я собирался сказать, что вы можете сэкономить 3 байта, переключившись с g=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1
ETHproductions

Спасибо, @ETHproductions, я перешел на map, что, я думаю, работает лучше, поскольку input может быть списком цифр вместо строки.
Рик Хичкок

Возможно, сохранить еще один байт s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1?
ETHproductions

Да, блестящее, спасибо:)
Рик Хичкок

Отличное решение! Не могли бы вы заменить &&с |на выходе 1/0 , поскольку truthy / falsy разрешено?
Крейг Эйр,


8

Желе , 8 байт

m2Ḥ+µS⁵ḍ

Попробуйте набор тестов.

Желе , 9 байт

JḂḤ‘×µS⁵ḍ

Попробуйте онлайн или попробуйте набор тестов.

Как это работает

m2Ḥ + µS⁵ḍ ~ Полная программа.

m2 ~ Modular 2. Вернуть каждый второй элемент ввода.
  Double ~ Удвойте каждый.
   + µ ~ Добавить вход и начать новую монадическую цепочку.
     Сумма
      ⁵ḍ ~ Делится на 10?
JḂḤ '× µS⁵ḍ ~ Полная программа (монадическая).

J ~ 1-индексированный диапазон длин.
 Bit ~ Бит; По модулю каждое число в диапазоне выше на 2.
  Double ~ Удвойте каждый.
   '~ Увеличивать каждый.
    × ~ Парное умножение со входом.
     µ ~ Запускает новую монадическую цепочку.
      Сумма
       ⁵ḍ ~ Сумма делится на 10?

Результат для первых 7 цифр штрих-кода и цифры контрольной суммы должен быть кратен 10, чтобы он был действительным. Таким образом, контрольная сумма действительна, если алгоритм, примененный ко всему списку, делится на 10 .


Все еще 9 байтов, но с постоянными значениями:JḂḤ‘×µS⁵ḍ
HyperNeutrino

@HyperNeutrino Спасибо, я знал, что для этого есть атом!
г-н Xcoder

Также 9 байтов:: JḂaḤ+µS⁵ḍP
HyperNeutrino

@HyperNeutrino Ну, есть много альтернатив: P
Мистер Xcoder

1
8 байтов или 8 символов? m2Ḥ+µS⁵ḍсоставляет 15 байт в UTF-8, если я не рассчитал это неправильно.
ta.speot.is

7

MATL , 10 байт

Спасибо @Zgarb за указание на ошибку, теперь исправленную.

IlhY"s10\~

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

Ilh     % Push [1 3]
Y"      % Implicit input. Run-length decoding. For each entry in the
        % first input, this produces as many copies as indicated by
        % the corresponding entry of the second input. Entries of
        % the second input are reused cyclically
s       % Sum of array
10\     % Modulo 10
~       % Logical negate. Implicit display

7

Befunge-98 (PyFunge) , 16 14 байт

Сэкономили 2 байта, пропустив вторую часть, используя jвместо ;s, а также поменяв местами a ~и +в первой части, чтобы избавиться от a +во второй.

~3*+~+6jq!%a+2

Входные данные состоят из 8 цифр (с ведущими 0, если применимо) и больше ничего

Выводится через код выхода (откройте выпадающий список отладки на TIO), где 1 равно true, а 0 - false.

Попробуйте онлайн!

объяснение

Эта программа использует различные приемы.

Прежде всего, он принимает цифры по одной через их значения ASCII. Обычно для этого требуется вычитать 48 из каждого значения, когда мы читаем его из входных данных. Однако, если мы не изменим его, у нас останется 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) дополнительных копий из 48 в нашей сумме, что означает, что наша общая сумма будет на 768 больше, чем что это "должно" быть. Поскольку нас интересует только мод mod 10, мы можем просто добавить 2 к сумме позже. Таким образом, мы можем принимать необработанные значения ASCII, сохраняя 6 байтов или около того.

Во-вторых, этот код только проверяет, является ли каждый другой символ EOF, потому что входные данные гарантированно будут иметь длину всего 8 символов.

В-третьих, #в конце строки первый символ не пропускается, но пропускается, ;если идет в другом направлении. Это лучше, чем поставить #;на передний план вместо.

Поскольку вторая часть нашей программы запускается только один раз, нам не нужно настраивать ее так, чтобы она пропускала первую половину при запуске в обратном направлении. Это позволяет нам использовать команду прыжка, чтобы перепрыгнуть через вторую половину, когда мы выходим перед тем, как выполнить ее, возвращаясь назад.

Шаг за шагом

Примечание: «Нечетные» и «Четные» символы основаны на 0-индексированной системе. Первый символ четный, с индексом 0.

~3*+~+      Main loop - sum the digits (with multiplication)
~           If we've reached EOF, reverse; otherwise take char input. This will always
                be evenly indexed values, as we take in 2 characters every loop.
 3*+        Multiply the even character by 3 and add it to the sum.
    ~       Then, take an odd digit - we don't have to worry about EOF because
                the input is always 8 characters.
     +      And add it to the sum.
      6j    Jump over the second part - We only want to run it going backwards.

        q!%a+2    The aftermath (get it? after-MATH?)
            +2    Add 2 to the sum to make up for the offset due to reading ASCII
          %a      Mods the result by 10 - only 0 if the bar code is valid
         !        Logical not the result, turning 0s into 1s and anything else into 0s
        q         Prints the top via exit code and exits


6

Wolfram Language (Mathematica) , 26 21 байт

10∣(2-9^Range@8).#&

Попробуйте онлайн!

Вводит в виде списка из 8 цифр.

Как это работает

2-9^Range@8является конгруэнтным по модулю 10 к 2-(-1)^Range@8, то есть {3,1,3,1,3,1,3,1}. Мы берем скалярное произведение этого списка с входными данными и проверяем, делится ли результат на 10.

Wolfram Language (Mathematica) , 33 байта и неконкурентный

Check[#~BarcodeImage~"EAN8";1,0]&

Попробуйте онлайн!

Принимает ввод в виде строки. Возвращает 1действительные штрих-коды и 0недействительные.

Как это работает

Лучшее, что я мог найти на пути встроенного (так как Mathematica это все о них).

Внутренний бит, #~BarcodeImage~"EAN8";1генерирует изображение штрих-кода EAN8, затем полностью его игнорирует и оценивает в 1. Однако, если штрих-код недействителен, BarcodeImageгенерируется предупреждение, которое Checkперехватывает, возвращая в этом случае 0.


3
Вы делаете вычисления вручную, потому что они короче или потому что у Wolfram еще нет функции ValidateEAN8BarCode () где-то в его стандартной библиотеке?
Отметить

1
@Mark Mathematica не может проверить штрих-код напрямую, но я только что обнаружил BarcodeImage, что генерирует изображение штрих-кода и проверяет штрих-код в процессе. Так Check[#~BarcodeImage~"EAN8";0,1]<1&будет работать (но это дольше).
Миша Лавров

5

Java 8, 58 56 55 байт

a->{int r=0,m=1;for(int i:a)r+=(m^=2)*i;return r%10<1;}

-2 байта косвенно благодаря @RickHitchcock , используя (m=4-m)*iвместо m++%2*2*i+iтого, чтобы видеть его в своем ответе JavaScript .
-1 байт косвенно благодаря @ETHProductions@RickHitchcock ), используя (m^=2)*iвместо (m=4-m)*i.

Объяснение:

Попробуй это здесь.

a->{              // Method with integer-array parameter and boolean return-type
  int r=0,        //  Result-sum
      m=1;        //  Multiplier
  for(int i:a)    //  Loop over the input-array
    r+=           //   Add to the result-sum:
       (m^=2)     //    Either 3 or 1,
       *i;        //    multiplied by the digit
                  //  End of loop (implicit / single-line body)
  return r%10<1;  //  Return if the trailing digit is a 0
}                 // End of method

1
Вы можете сохранить другой байт с помощью трюка, который мне показали @ETHProductions: изменить m=4-mна m^=2.
Рик Хичкок

@RickHitchcock А, конечно .. Я использую ^=1довольно часто в ответах, когда я хочу изменить между 0и 1. ^=2работает в этом случае, чтобы изменить между 1и 3. Хороший трюк, и спасибо за комментарий, чтобы упомянуть об этом. :)
Кевин Круйссен

4

05AB1E , 14 байтов

θ¹¨3X‚7∍*O(T%Q

Попробуйте онлайн!

Требуется ведущий 0s, принимает список цифр.


Кажется, провалиться 3100004(должно быть правдой).
Згарб

@ Zgarb Вы пропустили 0там.
Эрик Outgolfer

О, это занимает строку? Хорошо, тогда мой плохой.
Згарб

@Zgarb Ну, вы можете опустить кавычки, но да, вам нужно ведущий 0. Этот ответ на самом деле использует числовые функции для строк, одну из особенностей 05AB1E.
Эрик Outgolfer

@ Mr.Xcoder Вопрос не очень ясен по этому поводу, я добавлю еще один код, который обрабатывает это ниже.
Эрик Outgolfer

4

Pyth , 8 байт

!es+*2%2

Проверьте все контрольные примеры!

Pyth , 13 байт

Если мы можем предположить, что ввод всегда имеет ровно 8 цифр:

!es.e*bhy%hk2

Проверьте все контрольные примеры!


Как это работает?

! es + * 2% 2 ~ Полная программа.

      % 2 ~ Ввод [:: 2]. Каждый второй элемент ввода.
    * 2 ~ Double (повторить список дважды).
   + ~ Добавить вход.
  сумма
 e ~ Последняя цифра
! ~ Логическое НЕ.
! es.e * sbhy% hk2 ~ Полная программа.

               ~ Преобразовать ввод в строку.
   .e ~ Нумерованная карта, хранящая текущее значение в b и индекс в k.
          % hk2 ~ Инвертированная четность индекса. (k + 1)% 2.
        Hy ~ Double, приращение. Это отображает нечетные целые числа в 1 и четные 3.
      б ~ текущая цифра.
     * ~ Умножить.
  сумма
 e ~ Последняя цифра
! ~ Логическое отрицание.

Если сумма первых 7 цифр после применения алгоритма вычитается из 10, а затем сравнивается с последней цифрой, это эквивалентно проверке, является ли сумма всех цифр после применения алгоритма кратной 10 .


Кажется, провалиться 3100004(должно быть правдой).
Згарб

@Zgarb Подождите, мы должны сделать 3*3+1*1+0*3+...или 0*3+3*1+1*0..? Я думал, что мы должны сделать первое
г-н Xcoder

В новой спецификации добавляются начальные цифры, чтобы их было ровно 8 (если я правильно понимаю).
Згарб

@ Zgarb Хорошо, исправлено.
г-н Xcoder

4

Haskell , 40 38 байт

a=3:1:a
f x=mod(sum$zipWith(*)a x)10<1

Попробуйте онлайн!

Вводит в виде списка из 8 целых чисел. Практический пример использования бесконечных списков.

Изменить: Сохранено 2 байта благодаря GolfWolf


2
Использование рекурсивного определения вместо cycle сохранения 2 байтов .
Кристиан Лупаску

4

Сетчатка , 23 22 байта

-1 байт благодаря Мартину Эндеру !

(.).
$1$1$&
.
$*
M`
1$

Попробуйте онлайн!

объяснение

Пример ввода: 20378240

(.).
$1$1$&

Замените каждую пару цифр первой цифрой, повторенной дважды, а затем самой парой. Мы получаем2220333788824440

.
$*

Конвертировать каждую цифру в одинарный. С скобками, добавленными для ясности, мы получаем(11)(11)(11)()(111)(111)...

M`

Подсчитайте количество совпадений пустой строки, которое на единицу больше, чем количество совпадений в строке. (За последние два шага мы в основном взяли сумму каждой цифры +1) Результат:60

1$

Совпадение 1в конце строки. Мы поочередно умножили цифры на 3 и 1 и суммировали их, для правильного штрих-кода это должно делиться на 10 (последняя цифра 0); но мы также добавили 1 в последнем шаге, поэтому мы хотим , чтобы последняя цифра будет 1. Конечный результат: 1.


2
Я думаю, что вы можете бросить .на стадии матча и матч 1$в конце.
Мартин Эндер

@MartinEnder очень мило, я сделаю это, спасибо!
Лев

3

PowerShell , 85 байт

param($a)(10-(("$a"[0..6]|%{+"$_"*(3,1)[$i++%2]})-join'+'|iex)%10)%10-eq+"$("$a"[7])"

Попробуйте онлайн! или проверить все контрольные примеры

Реализует алгоритм как определено. Принимает ввод $a, вытаскивает каждую цифру с помощью "$a"[0..6]и просматривает их с помощью |%{...}. На каждой итерации мы берем цифру, приводим ее как строку, "$_"затем приводим ее как целое число, а +затем умножаем на 1 3или 1(выбираем, увеличивая $iпо модулю2 ).

Эти результаты собраны воедино и суммированы -join'+'|iex. Мы берем этот мод результата 10, вычитаем его из 10и снова берем мод результата 10(этот второй мод необходим для учета 00000000тестового случая). Затем мы проверяем, соответствует ли это -eqпоследней цифре. Этот логический результат остается в конвейере, а вывод неявным.


Кажется, провалиться 3100004(должно быть правдой).
Згарб

@ Zgarb у меня работает? Попробуйте онлайн!
AdmBorkBork

Ах, хорошо, я проверил это без кавычек.
Згарб

@ Zgarb Ах да. Без кавычек PowerShell будет неявно приводиться как целое число, удаляя лидирующие нули.
AdmBorkBork

3

Желе , 16 байт

ż3,1ṁ$P€SN%⁵
Ṫ=Ç

Попробуйте онлайн!

принимает входные данные в виде списка цифр


Nitpick: ваши тайм-ауты TIO. Также 16 байтов .
Эрик Outgolfer

@EriktheOutgolfer Подождите, что, как. Это работает, когда я положил Dв нижний колонтитул. И да, спасибо! : D
HyperNeutrino

@EriktheOutgolfer Я что-то не так делаю? Ваш 16-байтовый, кажется, является недействительным?
HyperNeutrino

Может быть, это работает немного по-другому, но ваш, кажется, тоже немного недействителен ... особенно я думаю, что последняя строка должна быть DµṪ=Ç.
Эрик Outgolfer

1
Кажется, провалиться 3100004(должно быть правдой).
Згарб

3

APL (Dyalog) , 14 байтов

Эквивалентно решению стритстера .

Полное тело программы. Запрашивает список номеров из STDIN.

0=10|+/⎕×83 1

Попробуйте онлайн!

Является…

0= ноль равен

10| мод-10 из

+/ сумма

⎕× время ввода

8⍴3 1 восемь элементов циклически взяты из [3,1]

?


1
Вы имеете в виду, что APL не может сделать это одним персонажем из чего-то вроде Древнего Шумера или Линейного Б?
Марк

поезд: 0 = 10 | - / + 2 × + /
нгн

3

05AB1E , 9 байтов

3X‚7∍*OTÖ

Попробуйте онлайн!

3X‚7∍*OTÖ    # Argument a
3X‚          # Push [3, 1]
   7∍        # Extend to length 7
     *       # Multiply elements with elements at same index in a
      O      # Total sum
       TÖ    # Divisible by 10

Ницца! Первое, что я подумал, было «расширить до длины», когда я увидел это, еще не использовал это.
Волшебная Осьминог Урна

31×S*OTÖдля 8 байтов. ×просто толкает 31 nколичество раз. Когда вы умножаете, он автоматически сбрасывает лишние 31.
Волшебная Осьминог Урна

@MagicOctopusUrn Кажется, что это не сработало на 6-м 69165430 -> 1
тесте

3

J, 17 байт

-10 байт благодаря Коул

0=10|1#.(8$3 1)*]

Попробуйте онлайн!

При этом используется умножение списков одинакового размера, чтобы избежать комбинирования zip / multiply исходного решения, а также «трюк base 1» 1#.для сложения продуктов. Подход высокого уровня похож на оригинальное объяснение.

оригинал, 27 байт

0=10|{:+[:+/[:*/(7$3 1),:}:

Попробуйте онлайн!

объяснил

0 =                                        is 0 equal to... 
    10 |                                   the remainder when 10 divides...
         {: +                              the last input item plus...
              [: +/                        the sum of...
                    [: */                  the pairwise product of...
                          7$(3 1) ,:       3 1 3 1 3 1 3 zipped with...
                                     }:    all but the last item of the input

0=10|1#.(8$3 1)*]должен работать на 17 байт (тоже делает тот же алгоритм). Я почти уверен, что в бета-версии у вас может быть крючок с правой стороны, оканчивающийся на правую сторону, поэтому 0=10|1#.]*8$3 1может работать на 15 (я бы проверил tio, но он, кажется, не работает?)
Коул

@ Cole, я люблю это улучшение. Я узнал и забыл 1#.трюк как 2 или 3 раза ... спасибо, что напомнил мне. О, кстати, 15-байтовая версия не работает в TIO.
Иона

3

C (gcc), 84 82 72 61 54 байта

c;i;f(x){for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;c=c%10<1;}

-21 байт из Нила

-7 байтов от Науэля Фуйе

Попробуйте онлайн!

Разработано независимо от ответа Steadybox

'f' - это функция, которая принимает штрих-код в качестве intи возвращает значения 1True и 0False.

  • fсохраняет последнюю цифру xв s( s=x%10),

  • Затем вычисляет сумму в c( for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;)

    • cэто сумма, iэто счетчик

    • для каждой цифры, включая первую, добавьте число 1+2*i%4раз ( x%10) к контрольной сумме и приращение i(значение i++in 3-2*i++%4)

      • 1+2*i%41, когда iчетное и 0, когда iнечетное
  • Затем возвращает значение, кратное десяти, и, поскольку мы добавили последнюю цифру (умноженную на 1), сумма будет кратна десяти, если штрих-код действителен. (использует GCC-зависимое неопределенное поведение, чтобы пропустить return).


Я думаю, что все (x%10)может быть так, xкак вы принимаете c%10позже. Также я думаю, что вы можете использовать, i<8а затем просто проверить, c%10является ли ноль в конце.
Нил

@Neil Спасибо! Это получил -10 байтов.
pizzapants184

На самом деле я считаю sненужным:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
Нил

ссылка tio составляет 61 байт, но в ответе это 72, также не знаю, почему x=c%10<1или c=c%10<1вместо этого return c%10<1все еще работает
Nahuel Fouilleul

также i<8может быть заменено наx
Науэль Фуйе

3

C, 63 байта

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

Предполагается, что 0есть trueи любое другое значение false.

+3 байта для лучшего возвращаемого значения

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10==0;}

Добавьте ==0к returnзаявлению.

Ungolfed

int check(int* values)
{
    int result = 0;
    for (int index = 0; index < 8; index++)
    {
        result += v[i] * 3 + v[++i]; // adds this digit times 3 plus the next digit times 1 to the result
    }
    return result % 10 == 0; // returns true if the result is a multiple of 10
}

При этом используется альтернативное определение контрольных сумм EAN, где контрольная цифра выбрана так, что контрольная сумма всего штрих-кода, включая контрольную цифру, кратна 10. Математически это работает так же, но записать намного проще.

Инициализация переменных внутри цикла, как предлагает Steadybox, 63 байта

i;s;c(int*v){for(i=s=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

Удаление фигурных скобок в соответствии с предложением Steadybox, 61 байт

i;s;c(int*v){for(i=s=0;i<8;i++)s+=v[i]*3+v[++i];return s%10;}

Использование, <1а не ==0для лучшего возвращаемого значения, как это было предложено Кевином Круйссеном

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10<1;}

Добавьте <1к returnоператору, это добавляет только 2 байта, а не добавление, ==0которое добавляет 3 байта.


Вы можете сохранить два байта , удалив {}после for. Кроме того, представления функции должны быть многократно используемыми , поэтому вам нужно инициализировать sвнутри функции (просто измените i;s=0;на i,s;и i=0;на i=s=0;).
Steadybox

@Steadybox Как убрать фигурные скобки?
Майкл Джонсон

В них только одно утверждение. Если после него нет фигурных скобок for, тело цикла будет следующим оператором. for(i=0;i<8;i++){s+=v[i]*3+v[++i];}так же, как for(i=0;i<8;i++)s+=v[i]*3+v[++i];.
Steadybox

@Steadybox О, конечно. Это одна из особенностей синтаксиса Си, о которой я обычно забываю, потому что при написании нормального кода я всегда включаю фигурные скобки, даже если они не нужны, потому что это делает код более читабельным.
Майкл Джонсон

В вашем истинном / ложном ответе вместо +3, добавив, вы ==0можете использовать +2 <1вместо. :)
Кевин Круйссен

2

JavaScript (Node.js) , 47 байт

e=>eval(e.map((a,i)=>(3-i%2*2)*a).join`+`)%10<1

Хотя здесь уже есть гораздо более короткий ответ, это моя первая попытка игры в гольф на JavaScript, поэтому я хотел бы услышать рекомендации по игре в гольф :-)

тестирование

Кроме того, вы можете попробовать это онлайн!


2

Perl 5, 37 32 + 1 (-p) байт

s/./$-+=$&*(--$|*2+1)/ge;$_=/0$/

-5 байт благодаря Дому Гастингсу. 37 +1 байт было

$s+=$_*(++$i%2*2+1)for/./g;$_=!!$s%10

попробуйте это онлайн


1
Немного поигрался с этим и подумал, что поделюсь полезным трюком: --$|переключается между ними, 1и 0поэтому вы можете использовать его вместо ++$i%2чередующегося логического значения! Кроме того, все, что имеет значение, это то, что total ( $s) соответствует /0$/, удалось получить 33 байта, объединяя эти изменения с s///: Попробуйте онлайн! ( -lтолько для наглядности)
Дом Гастингс

да, хотя s/./(something with $&)/geи чтобы /0$/соответствовать, но не два вместе взятых.
Науэль Фуйе

2

Brainfuck, 228 байт

>>>>++++[<++>-]<[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]>[->]<<<<[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]>>>>[>>[<<[>>+<<-]]>>]<<<++++[<---->-]+++++[<++<+++>>-]<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

Вероятно, может быть улучшено немного. Ввод принимается по 1 цифре за раз, вывод 1 для истины, 0 для ложной.

Как это работает:

>>>>++++[<++>-]<

Поставьте 8 в положение 3.

[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]

Принимает ввод 8 раз, меняя его с значения ascii на фактическое значение +2 каждый раз. Входы разнесены теми, которые будут удалены, чтобы позже было легче умножить.

>[->]

Вычтите одно из каждого элемента. Наша лента теперь выглядит примерно так

0 0 0 0 4 0 4 0 8 0 7 0 6 0 2 0 3 0 10 0 0
                                         ^

С каждым значением на 1 больше, чем должно быть. Это потому, что нули испортят наш процесс умножения.

Теперь мы готовы начать умножение.

<<<<

Перейти ко второму последнему пункту.

[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]

При нулевом значении умножьте элемент на три, затем переместите два элемента влево. Теперь мы умножили все, что нам нужно, на три, и мы находимся на самой первой позиции на ленте.

>>>>[>>[<<[>>+<<-]]>>]

Суммируйте весь список.

<<<++++[<---->-]

Значение у нас на 16 больше, чем фактическое значение. Исправьте это, вычитая 16.

+++++[<++<+++>>-]

Нам нужно проверить, является ли сумма кратной 10. Максимальная сумма равна всем 9, то есть 144. Поскольку никакая сумма не будет больше 10 * 15, поместите 15 и 10 на ленту в этом порядке и вправе право на сумму.

<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]

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

Остальное для вывода:

<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

Перейти к сумме позиции. Если он ненулевой (отрицательный), штрих-код недействителен; установите положение -1. Теперь добавьте 49, чтобы получить правильное значение ascii: 1, если оно действительно, 0, если оно недействительно.


2

Java 8, 53 байта

Golfed:

b->(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

Прямой расчет в лямбде оказывается кратчайшим решением. Он помещается в одном выражении, сводя к минимуму издержки лямбды и удаляя лишние объявления переменных и точки с запятой.

public class IsMyBarcodeValid {

  public static void main(String[] args) {
    int[][] barcodes = new int[][] { //
        { 2, 0, 3, 7, 8, 2, 4, 0 }, //
        { 3, 3, 7, 6, 5, 1, 2, 9 }, //
        { 7, 7, 2, 3, 4, 5, 7, 5 }, //
        { 0, 0, 0, 0, 0, 0, 0, 0 }, //
        { 2, 1, 0, 3, 4, 9, 8, 4 }, //
        { 6, 9, 1, 6, 5, 4, 3, 0 }, //
        { 1, 1, 9, 6, 5, 4, 2, 1 }, //
        { 1, 2, 3, 4, 5, 6, 7, 8 } };
    for (int[] barcode : barcodes) {
      boolean result = f(b -> (3 * (b[0] + b[2] + b[4] + b[6]) + b[1] + b[3] + b[5] + b[7]) % 10 < 1, barcode);
      System.out.println(java.util.Arrays.toString(barcode) + " = " + result);
    }
  }

  private static boolean f(java.util.function.Function<int[], Boolean> f, int[] n) {
    return f.apply(n);
  }
}

Выход:

[2, 0, 3, 7, 8, 2, 4, 0] = true
[3, 3, 7, 6, 5, 1, 2, 9] = true
[7, 7, 2, 3, 4, 5, 7, 5] = true
[0, 0, 0, 0, 0, 0, 0, 0] = true
[2, 1, 0, 3, 4, 9, 8, 4] = false
[6, 9, 1, 6, 5, 4, 3, 0] = false
[1, 1, 9, 6, 5, 4, 2, 1] = false
[1, 2, 3, 4, 5, 6, 7, 8] = false

2

QBasic, 54 52 байта

Тьфу, скучный ответ оказался самым коротким:

INPUT a,b,c,d,e,f,g,h
?(3*a+b+3*c+d+3*e+f+3*g+h)MOD 10=0

Это вводит цифры через запятую. Мое оригинальное 54-байтовое решение, которое вводит одну цифру за раз, использует более приятный подход:

m=3
FOR i=1TO 8
INPUT d
s=s+d*m
m=4-m
NEXT
?s MOD 10=0

2

C # (.NET Core) , 65 62 байта

b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}

Попробуйте онлайн!

Подтверждения

-3 байта благодаря @KevinCruijssen и изящному трюку с использованием оператора exclusive или.

DeGolfed

b=>{
    int s=0,i=0,t=1;

    while(i<8)
        s+=b[i++]*(t^=2); // exclusive-or operator alternates t between 3 and 1.

    return s%10<1;
}

C # (.NET Core) , 53 байта

b=>(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

Попробуйте онлайн!

Прямой порт ответа @ Snowman .


Для вашего первого ответа: b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}( 62 байта ) или, альтернативно, с foreach, также 62 байта: b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}(это порт моего ответа Java 8 ).
Кевин Круйссен

1

MATLAB / Octave , 32 байта

@(x)~mod(sum([2*x(1:2:7),x]),10)

Попробуйте онлайн!

Я собираюсь опубликовать это несмотря на другой ответ Octave, так как я разработал этот код и подход, не глядя на другие ответы.

Здесь у нас есть анонимная функция, которая принимает входные данные в виде массива из 8 значений и возвращает true, если допустимый штрих-код, в противном случае - false.

Результат рассчитывается следующим образом.

              2*x(1:2:7)
             [          ,x]
         sum(              )
     mod(                   ,10)
@(x)~
  1. Нечетные цифры (одна проиндексированная) умножаются на 2.
  2. Результат добавляется к входному массиву, давая массив, сумма которого будет содержать нечетные цифры три раза, а четные - один раз.
  3. Мы делаем сумму, которая будет также включать предоставленную контрольную сумму в нашу сумму.
  4. Затем выполняется модуль 10. Если предоставленная контрольная сумма была действительной, сумма всех умноженных цифр, включая значение контрольной суммы, в конечном итоге была бы кратна 10. Поэтому только действительный штрих-код вернул бы 0.
  5. Результат инвертируется, чтобы получить логический вывод true, если он действителен.

1

Excel, 37 байт

Интерпретация «списка из 8 целых чисел» как допускающего 8 отдельных ячеек в Excel:

=MOD(SUM(A1:H1)+2*(A1+C1+E1+G1),10)=0

= MOD (SUM ((A1: H1) + 2 * (A1 + C1 + E1 + G1)), 10) = 0 эта формула существует в Excel?
РосЛюП

@RosLuP, не предопределено, нет. Но Модуло, Сумма, и т. Д. Делают ;-)
Верниш

Я хочу только сказать, что кажется, что в APL идет хорошо, делая сначала y = (A1: H1) + 2 * (A1 + C1 + E1 + G1), а после суммы и мода; в APL не получается первая сумма (A1: H1) и т. д. что-то вроде (1,2,3) + 4 = (5,6,7) и чем сумма (5,6,7) = 18; обратите внимание, что сумма (1,2,3) = 6 и 6 + 4 = 10 отличается от 18. Но возможно я могу сделать ошибку в чем-то
РосЛюП

@RosLuP, извиняюсь, пропустил изменения ()в вашем комментарии.
Верниш

Проблема в том, как Excel интерпретирует =(A1:H1): это не обрабатывается как массив. Недопустимо, если помещено в любой столбец вне A-Hдиапазона. Если помещено в столбец в AH, возвращает значение только для этого столбца. (Формула в% приводит к%: C2 -> C1 H999 -> H1 K1 -> # ЗНАЧЕНИЕ!)
Wernisch

1

Рубин, 41 байт

Принимает массив целых чисел. -6 байт благодаря Джордану.

->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}

Ницца! FWIW вам здесь совсем не нужно map: zipзанимает блок. Вы можете сохранить еще пару байтов, используя $.вместо инициализации s:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
Иордания

1

TI-Basic (серия 83), 18 байт

not(fPart(.1sum(2Ans-Ans9^cumSum(binomcdf(7,0

Принимает ввод в виде списка в Ans . Возвращает 1действительные штрих-коды и 0недействительные.

Порт моего ответа Mathematica . Включает скриншот вместо среды онлайн-тестирования:

скриншот штрих-кода

Заметная особенность: binomcdf(7,0 используется для генерации списка {1,1,1,1,1,1,1,1}(списка вероятностей того, что из 7 испытаний с вероятностью успеха 0 будет не более N успехов, для N = 0,1, ..., 7). Затем cumSum(превращает это в {1,2,3,4,5,6,7,8}.

Это на один байт короче, чем при использовании seq(команды, хотя исторически сложилось так, что она также значительно быстрее.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.