Introdução
Nesse desafio, sua tarefa é gerar o código ISBN-10 para livros, considerando seu código ISBN-13, assumindo que esse código exista. Esse código ISBN-13 consiste em várias partes separadas por -
:
978-GG-PPPP-TTT-C
As letras G
(grupo), P
(editor), T
(título) e C
(soma de verificação) representam um dígito. Para os propósitos deste desafio, o agrupamento e o cálculo de C
(veja este desafio ) não são interessantes, e todos os hífens serão eliminados para simplificar essa tarefa.
Um número do ISBN-10 tem um layout muito semelhante:
GG-PPPP-TTT-c
As letras G
, P
e T
são as mesmas do ISBN de 13 dígitos, no entanto, c
são diferentes (e são calculadas usando um algoritmo diferente). O dígito c
é escolhido de forma que a seguinte equivalência seja válida (dígitos em ordem):
10*G + 9*G + 8*P + … + 3*T + 2*T + 1*c = 0 (mod 11)
Exemplo
Vamos considerar o número do ISBN 9780345391803
: para obter seu código ISBN-10 correspondente, simplesmente eliminamos o líder 978
e o 3
rendimento da soma de verificação 034539180
.
Em seguida, precisamos calcular a nova soma de verificação:
10*0 + 9*3 + 8*4 + 7*5 + 6*3 + 5*9 + 4*1 + 3*8 + 2*0 = 185
O próximo número divisível por 11
é 187
, portanto, a nova soma de verificação é 2
e, portanto, o código ISBN-10 resultante 0345391802
.
Regras
- Sua entrada sempre terá um número ISBN-10 correspondente (ou seja, tem exatamente 13 dígitos e começa com
978
) - A entrada não precisa necessariamente ser um ISBN-13 válido (por exemplo,
9780000000002
) - Você tem a garantia de que o ISBN resultante não terminará com
X
- Você pode receber a entrada como um número inteiro ou sequência (com ou sem hífens), no entanto, uma lista pré-computada de dígitos não é permitida
- Sua saída deve ser um número ISBN-10 válido (com ou sem hífens)
- Sua saída pode ser um número inteiro ou string (novamente sem listas de dígitos)
Casos de teste
9780000000002 -> 0000000000
9780201882957 -> 0201882957
9781420951301 -> 1420951300
9780452284234 -> 0452284236
9781292101767 -> 1292101768
9780345391803 -> 0345391802
Observe os zeros à esquerda!
0-684-84328-5
e99921-58-10-7
, a primeira parte (0
e99921
respectivamente) é o grupo de registro, a segunda parte é o editor e assim por diante.Respostas:
Retina ,
443928 bytesExperimente online!
Explicação
Hora de mostrar alguns novos recursos da Retina. :)
Combinamos toda a entrada com
.+
, retornamos essa correspondênciaL
, mas selecionamos apenas os caracteres 3 (com base em zero) a -2 (penúltimo), inclusive. Também imprimimos o resultado sem um avanço de linha à direita (>
).Agora, subtrair coisas na Retina é um pouco chato. Mas, felizmente, estamos trabalhando no módulo 11, para podermos inverter os coeficientes da combinação linear (mod 11) e somar tudo. Em outras palavras, se a restrição for:
então temos:
Isso simplifica bastante as coisas aqui:
Substituímos cada personagem por aquela coisa na parte inferior.
*
é o operador de repetição da Retina. É associativo à direita e possui operandos implícitos$&
à esquerda e_
à direita, portanto a substituição é realmente curta$.>`*$&*_
.$&*_
cria uma sequência de d sublinhados, em que d é o dígito que estamos substituindo no momento. Então$.>`
é o comprimento da corda até e incluindo a correspondência. 1 Portanto, toda a expressão resulta em uma representação unária do n ésimo termo da nossa combinação linear.Fazer o módulo real é trivial em unário: nós apenas eliminamos todos os conjuntos completos de 11 sublinhados.
Por fim, contamos quantos sublinhados restam e imprimimos o resultado, o que completa o ISBN-10.
1 Como
$.>`
atribuir o comprimento da corda até e incluindo a correspondência? Você pode estar familiarizado com as$`
substituições de expressões regulares, que fornecem a string até (mas excluindo) a correspondência. Ao inserir a>
, podemos mudar o contexto de$`
para o separador entre a correspondência atual e a próxima (que é uma string vazia entre o dígito atual e o próximo). Esse separador$`
incluirá a correspondência atual. Portanto,$>`
é uma maneira mais curta de escrever$`$&
. Por fim, para$x
elementos de substituição de todos os tipos, o Retina permite inserir um.
após o$
para obter seu comprimento.fonte
-2 ≡ 9 (mod 11)
(porque adicionar ou subtrair 11 de um número não altera seu "valor" na classe de congruência mod 11). E adição e multiplicação respeitam classes de congruência, para que você possa substituir qualquer valor em uma combinação linear por um valor equivalente no módulo atual. A razão pela qual estou falando de números negativos é realmente apenas que reorganizei a equação para terc
de um lado e todos os outros termos (como negativos) do outro.c
a se tornar-c = ...
e, em vez de multiplicar,10 9 8...
subtrai11
de cada um para obter-1 -2 -3...
e multiplica tudo por -1 para obterc
.05AB1E ,
17151312 bytesExperimente online!
Explicação
fonte
PowerShell ,
9684 bytesExperimente online!
Recebe entrada
"$args"
, executa uma regex-replace
para obter apenas a parte pertinente, armazena-a$x
como uma sequência. Então, lançamos isso como umachar
matriz e percorremos cada letra. Dentro do loop, pré-decréscimos$a
(cujo padrão é0
) e multiplicamos de acordo com o cálculo da soma de verificação. Observe a conversão paraint
, caso contrário, isso usaria valores ASCII.Em seguida,
-join
esses números juntos+
e canalizamos isso paraiex
(Invoke-Expression
e semelhante aeval
). Pegamos isso%11
e armazenamos essa soma de verificação$y
. Por fim, concatenamos$x + $y
e deixamos isso no pipeline. A saída está implícita.Economizou 12 bytes graças a Emigna.
fonte
Oitava ,
46 41 3937 bytesExperimente online!
O código recebe a entrada como uma sequência e retorna uma sequência.
O código é dividido da seguinte maneira:
@(a)
cria uma função anônima.Com
[c=a(4:12) ... ]
extraímos os caracteres que formam o código principal, salvando uma cópia emc
para uso posterior e adicionando outra cópia à sequência de saída final.Baseado em @ maneira inteligente de MartinEnter de trocar
10:-1:2
para1:10
, podemos facilmente gerar desse intervalo e transpô-la para obter um vector coluna.c*(1:10)'
faz a multiplicação de vetor do vetor de linhac
e vetor de coluna de intervalo. Isso é equivalente a fazer uma multiplicação por elementos e depois somar.A soma de verificação normalmente seria
mod(11-sum,11)
calcular o número necessário para a soma ser um múltiplo de 11. No entanto, comoc
era uma sequência de caracteres, a soma será realmente maior do que deveria em 2592 (48 * 54), porque multiplicamos por números que eram 48 maiores que o valor real.Quando executamos o módulo, ele automaticamente se livra de todos, exceto 7, desse 2592. Como tal, e contabilizando a negação do intervalo, o cálculo real se torna
48+mod(7+sum,11)
. Adicionamos 48 ao resultado para converter novamente em um caractere ASCII.O caractere de soma de verificação é anexado ao final do resultado e o valor retornado.
fonte
Gelatina , 12 bytes
Este é um programa completo que usa cadeias de caracteres para E / S.
Experimente online!
Como funciona
fonte
JavaScript (ES6),
5956 bytesMostrar snippet de código
-3 bytes, graças à sugestão de @ Shaggy .
fonte
Perl 5 , 49 + 1 (
-p
) = 50 bytesExperimente online!
fonte
Pitão , 16 bytes
Experimente aqui!
Pitão , 17 bytes
Experimente aqui!
Explicação
fonte
Japonês ,
1615 bytesVeio com isso no pub na outra noite e esqueci tudo.
Tente
fonte
s3J
eU+¬x_*°TÃuB
U
- D'oh!Hexagonia ,
7761 bytesExperimente online!
Colori:
Aqui está uma versão maior. Existem alguns cruzamentos de caminho, mas porque todas essas células são
.
(não-op no Hexagony), você não precisa se preocupar com elas:(Eu também tentei manter os espelhos antigos, mas às vezes preciso mudar alguma coisa)
O comando linear executado é:
Explicação: Em vez de manter um contador e multiplicar a cada dígito, este programa:
p
et
)(-p-t)%11
,%
sempre retornando resultados positivos.fonte
K (oK) ,
29252423 bytesSolução:
Experimente online!
Exemplos:
Explicação:
A avaliação é realizada da direita para a esquerda.
Dois truques extraídos de outras soluções:
Demolir:
Notas:
7
à soma)fonte
C (gcc),
96 95 87 8685 bytes(-1 graças a ceilingcat)
Experimente online!
Para ser chamado como
f(s)
, ondes
está um ponteiro para o primeiro elemento de uma matriz de caracteres modificável. Modifica a matriz de entrada, retorna um ponteiro para a matriz de entrada.fonte
Python 2 , 62 bytes
Experimente online!
Pega uma string como entrada; e gera uma string.
fonte
Gelatina , 14 bytes
Suíte de teste!
Gelatina , 17 bytes
Experimente online! ou suíte de teste!
Toma entrada e saída como uma string.
fonte
ECMAScript 6 ,
8667 bytesExperimente online!
Obrigado pelo comentário de Arnauld , mudou de
reduce
paramap
e se livrou dareturn
palavra-chave.fonte
map()
,reduce()
etc. Com alguma reescrita adicional, muitas vezes é possível se livrar de{}
ereturn
. Além disso, nesse caso em particular,map()
é provavelmente menor quereduce()
. ( Aqui é uma versão 65-byte.)f=
não é necessário. Além disso, você pode inicializarc
no spread para algo como isto:a=>{i=10;s=[...c=a.substr(3,9)].reduce((g,v)=>+g+(i--)*v,0)%11;return c+=s?11-s:0}
(-4 bytes)Retina 0.8.2 ,
7251 bytesExperimente online!Porque eu não aprendi Retina 1.0 ainda. Explicação:
Exclua os caracteres indesejados e faça uma segunda cópia dos dígitos apropriados.
Sufixe cada dígito na segunda cópia com seu sufixo. Isso efetivamente repete cada dígito no sufixo por sua posição.
Converta os dígitos da segunda cópia em unários, adicionando-os.
Reduza o módulo 11. (Existem apenas 9 dígitos na primeira cópia, portanto isso nunca poderá afetá-lo.)
Converta o resultado novamente em decimal e remova a nova linha novamente.
fonte
APL (Dyalog Unicode) ,
2624 bytesExperimente online!
Função de prefixo tácito. Recebe entrada como string.
2 bytes salvos graças a @ngn.
Quão?
fonte
Limpo ,
10410298 bytesExperimente online!
fonte
Kotlin , 83 bytes
Embelezado
Teste
TIO
TryItOnline
fonte
Ruby ,
69 6864 bytesExperimente online!
fonte
PHP, 64 bytes
Infelizmente, no PHP
(-$c)%11
é o mesmo que-($c%11)
; então eu tenho que obter a diferença para pelo menos a maior soma possível (55 * 9 = 495 = 45 * 11) em vez de apenas usar-$c%11
.ou
Execute como pipe
-nR
ou experimente-os online .fonte
Java 10, 110 bytes
Toma entradas e saídas como um
long
número inteiro. Experimente online aqui .Versão não destruída:
fonte