Вступление
В этой задаче ваша задача состоит в том, чтобы сгенерировать код ISBN-10 для книг с учетом кода ISBN-13, предполагая, что такой код существует. Такой код ISBN-13 состоит из нескольких частей, разделенных -
:
978-GG-PPPP-TTT-C
Буквы G
(группа), P
(издатель), T
(заголовок) и C
(контрольная сумма) обозначают одну цифру. Для этой задачи группировка и вычисление C
(см. Эту задачу ) не интересны, и мы упустим все дефисы, чтобы упростить эту задачу.
Номер ISBN-10 имеет очень похожую раскладку:
GG-PPPP-TTT-c
Буквы G
, P
и T
такие же , как для 13 цифр ISBN, однако c
отличаются (и вычисляются с использованием другого алгоритма). Цифра c
выбирается таким образом, чтобы выполнялась следующая эквивалентность (цифры по порядку):
10*G + 9*G + 8*P + … + 3*T + 2*T + 1*c = 0 (mod 11)
пример
Рассмотрим номер ISBN 9780345391803
: Для того, чтобы получить соответствующий ему ISBN-10 код , который мы просто уронить ведущим 978
и контрольная сумма 3
приносит 034539180
.
Далее нам нужно вычислить новую контрольную сумму:
10*0 + 9*3 + 8*4 + 7*5 + 6*3 + 5*9 + 4*1 + 3*8 + 2*0 = 185
Следующее число делится на 11
is 187
, поэтому новая контрольная сумма 2
и, следовательно, результирующий код ISBN-10 0345391802
.
правила
- Ваш ввод всегда будет иметь соответствующий номер ISBN-10 (т. Е. Он ровно 13 цифр и начинается с
978
) - Входные данные не обязательно должны быть действительными ISBN-13 (например,
9780000000002
) - Вы гарантировано, что полученный ISBN не закончится
X
- Вы можете принимать ввод как целое число или строку (с дефисами или без них), однако предварительно вычисленный список цифр не допускается.
- Ваш вывод должен быть действительным номером ISBN-10 (с дефисами или без них)
- Ваш вывод может быть целым числом или строкой (опять же нет списков цифр)
Testcases
9780000000002 -> 0000000000
9780201882957 -> 0201882957
9781420951301 -> 1420951300
9780452284234 -> 0452284236
9781292101767 -> 1292101768
9780345391803 -> 0345391802
Обратите внимание на ведущие нули!
0-684-84328-5
и99921-58-10-7
, первая часть (0
и ,99921
соответственно) является регистрация группы, вторая часть является издателем, и так далее.Ответы:
Retina ,
443928 байтПопробуйте онлайн!
объяснение
Время показать некоторые новые функции Retina. :)
Мы сопоставляем весь ввод с
.+
, возвращаем это совпадениеL
, но выбираем только символы от 3 (начиная с нуля) до -2 (предпоследний) включительно. Мы также печатаем результат без завершающего перевода строки (>
).Теперь вычитать вещи в Retina немного раздражает. Но, к счастью, мы работаем по модулю 11, поэтому мы можем просто инвертировать коэффициенты линейной комбинации (мод 11) и сложить все. Другими словами, если ограничение:
тогда мы получим:
Это многое упрощает здесь:
Мы заменяем каждого персонажа этой вещью внизу.
*
является оператором повторения Retina. Он ассоциативен справа и имеет неявные операнды$&
слева и_
справа, поэтому замена на самом деле коротка$.>`*$&*_
.$&*_
создает строку с подчеркиванием d , где d - это цифра, которую мы в настоящее время заменяем. Затем$.>`
длина строки до совпадения. 1 Следовательно, все выражение приводит к унарному представлению n- го члена нашей линейной комбинации.Выполнение фактического по модулю в унарном тривиально: мы просто отбрасываем все полные наборы из 11 подчеркиваний.
Наконец, мы подсчитываем, сколько осталось подчеркиваний, и печатаем результат, который завершает ISBN-10.
1 Как определить
$.>`
длину строки до совпадения? Вы можете быть знакомы с$`
подстановками регулярных выражений, которые дают вам строку до (но исключая) совпадения. Вставив a>
, мы можем сместить контекст$`
с в разделитель между текущим соответствием и следующим (то есть пустой строкой между текущей цифрой и следующей). Этот разделитель$`
будет включать текущее совпадение. Так что$>`
это более короткий способ написать$`$&
. Наконец, для всех$x
подстановочных элементов Retina позволяет вставлять.
после,$
чтобы получить его длину.источник
-2 ≡ 9 (mod 11)
(потому что добавление или вычитание 11 из числа не меняет его «значение» в моде класса конгруэнции 11). А сложение и умножение учитывают классы конгруэнтности, поэтому вы можете заменить любое значение в линейной комбинации эквивалентным значением в текущем модуле. Причина, по которой я говорю об отрицательных числах, заключается в том, что я просто перестроил уравнение, чтобы иметьc
одну сторону, а все остальные термины (как отрицательные) - с другой.c
чтобы стать,-c = ...
и вместо того, чтобы умножать на10 9 8...
вас, вычитаете11
из каждого, чтобы получить,-1 -2 -3...
а затем умножаете все на -1, чтобы получитьc
.05AB1E ,
17151312 байтПопробуйте онлайн!
объяснение
источник
PowerShell ,
9684 байтаПопробуйте онлайн!
Принимает ввод
"$args"
, выполняет регулярное выражение,-replace
чтобы получить только соответствующую часть, сохраняет ее в$x
виде строки. Затем мы приводим это какchar
массив и перебираем каждую букву. Внутри цикла мы предварительно уменьшаем$a
(что по умолчанию0
) и умножаем в соответствии с вычислением контрольной суммы. Обратите внимание на приведение кint
, иначе это будет использовать значения ASCII.Затем мы получим
-join
эти числа вместе+
и передадим ихiex
(Invoke-Expression
и аналогичноeval
). Мы берем это%11
и храним эту контрольную сумму в$y
. Наконец, мы объединяем строки$x + $y
и оставляем их на конвейере. Вывод неявный.Сохранено 12 байтов благодаря Emigna.
источник
Октава ,
46 41 3937 байтПопробуйте онлайн!
Код принимает входные данные в виде строки и возвращает строку.
Код разбивается следующим образом:
@(a)
создает анонимную функцию.С помощью
[c=a(4:12) ... ]
мы извлекаем символы, которые образуют основной код, сохраняя копиюc
для последующего использования и добавляя еще одну копию в окончательную строку вывода.На основе @ умный способ MartinEnter в замещающей
10:-1:2
в1:10
, мы можем легко генерировать этот диапазон и перенести его , чтобы получить вектор - столбец.c*(1:10)'
выполняет умножение массива вектора строки и вектораc
столбца диапазона. Это эквивалентно поэлементному умножению, а затем суммированию.Контрольной суммой обычно является
mod(11-sum,11)
вычисление числа, необходимого для того, чтобы сумма была кратна 11. Однако, поскольку этоc
была символьная строка, сумма на самом деле будет больше, чем должна быть на 2592 (48 * 54), потому что мы умножаем на числа это было на 48 больше, чем фактическое значение.Когда мы выполняем по модулю, он автоматически избавится от всего, кроме 7, от 2592. Таким образом, и с учетом отрицания диапазона, фактический расчет становится
48+mod(7+sum,11)
. Мы добавляем 48 к результату, чтобы преобразовать обратно в символ ASCII.Символ контрольной суммы добавляется в конец результата и возвращается значение.
источник
Желе , 12 байт
Это полная программа, которая использует строки для ввода / вывода.
Попробуйте онлайн!
Как это устроено
источник
JavaScript (ES6),
5956 байтПоказать фрагмент кода
-3 байта благодаря предложению @ Shaggy .
источник
Perl 5 , 49 + 1 (
-p
) = 50 байтПопробуйте онлайн!
источник
Pyth , 16 байт
Попробуй это здесь!
Pyth , 17 байт
Попробуй это здесь!
объяснение
источник
Japt ,
1615 байтПришел с этим в пабе прошлой ночью и забыл все об этом.
Попытайся
источник
s3J
иU+¬x_*°TÃuB
U
О!Гексагония ,
7761 байтПопробуйте онлайн!
Цветное:
Вот увеличенная версия. Есть некоторые пересечения путей, но, поскольку все эти ячейки
.
(без операции в Hexagony), вам не нужно беспокоиться о них:(Я тоже пытался сохранить старые зеркала, но иногда мне нужно что-то менять)
Выполненная линейная команда:
Пояснение: Вместо того чтобы вести счетчик и делать умножение на каждую цифру, эта программа:
p
иt
)(-p-t)%11
, где%
всегда возвращаются положительные результаты.источник
K (ок) ,
29252423 байтаРешение:
Попробуйте онлайн!
Примеры:
Объяснение:
Оценка выполняется справа налево.
Два трюка взяты из других решений:
Сломать:
Заметки:
7
к сумме)источник
C (gcc),
96 95 87 8685 байт(-1 благодаря потолочной кошке)
Попробуйте онлайн!
Вызывается как
f(s)
, гдеs
указатель на первый элемент изменяемого массива символов. Изменяет входной массив, возвращает указатель на входной массив.источник
Python 2 , 62 байта
Попробуйте онлайн!
Принимает строку в качестве ввода; и выводит строку.
источник
Желе , 14 байт
Тестирование!
Желе , 17 байт
Попробуйте онлайн! или тестовый набор!
Принимает ввод и вывод в виде строки.
источник
ECMAScript 6 ,
8667 байтПопробуйте онлайн!
Спасибо за комментарий Arnauld в , перешли от
reduce
кmap
и избавились отreturn
ключевого слова.источник
map()
, иreduce()
т.д. С некоторым дополнительным переписыванием, это часто можно избавиться{}
иreturn
. Кроме того, в данном конкретном случае,map()
вероятно, корочеreduce()
. ( Вот 65-байтовая версия.)f=
этом нет необходимости. Кроме того, вы можете инициализироватьc
приa=>{i=10;s=[...c=a.substr(3,9)].reduce((g,v)=>+g+(i--)*v,0)%11;return c+=s?11-s:0}
Сетчатка 0.8.2 ,
7251 байтПопробуйте онлайн! Потому что я еще не выучил Retina 1.0. Объяснение:
Удалите ненужные символы и сделайте вторую копию соответствующих цифр.
Суффикс каждой цифры во втором экземпляре с суффиксом. Это эффективно повторяет каждую цифру в суффиксе по ее позиции.
Преобразуйте цифры во второй копии в одинарные, таким образом, сложив их вместе.
Уменьшите по модулю 11. (В первой копии всего 9 цифр, поэтому это никак не повлияет).
Преобразуйте результат обратно в десятичную и снова удалите новую строку.
источник
APL (Dyalog Unicode) ,
2624 байтаПопробуйте онлайн!
Функция молчаливого префикса. Принимает ввод в виде строки.
2 байта сохранены благодаря @ngn.
Как?
источник
Чистый ,
10410298 байтПопробуйте онлайн!
источник
Котлин , 83 байта
украшенный
Тестовое задание
TIO
TryItOnline
источник
Рубин ,
69 6864 байтаПопробуйте онлайн!
источник
PHP, 64 байта
К сожалению, в PHP так
(-$c)%11
же, как-($c%11)
; поэтому я должен получить разницу как минимум до максимально возможной суммы (55 * 9 = 495 = 45 * 11), а не просто использовать-$c%11
.или
Запустите как трубу с
-nR
или попробуйте их онлайн .источник
Java 10, 110 байт
Принимает ввод и вывод в виде
long
целого числа. Попробуйте это онлайн здесь .Безголовая версия:
источник