Escreva uma função que, dados os primeiros 12 dígitos de um código ISBN-13 , calcule todo o ISBN, calculando e acrescentando um dígito de verificação apropriado.
A entrada da sua função é uma sequência que contém os primeiros 12 dígitos do ISBN. Sua saída é uma string contendo todos os 13 dígitos.
Especificação formal
Escreva uma função que, quando recebe uma sequência s composta exatamente por exatamente 12 dígitos decimais (e nenhum outro caractere), retorna uma sequência t com as seguintes propriedades:
- t consiste em exatamente 13 dígitos decimais (e nenhum outro caractere);
- s é um prefixo de t ;
- a soma de todos os dígitos em posições ímpares em t (ou seja, o primeiro, terceiro, quinto etc.), mais três vezes a soma de todos os dígitos em posições pares em t (ou seja, o segundo, quarto, sexto etc.), é um múltiplo de 10.
Exemplo / caso de teste
Entrada
978030640615
Saída
9780306406157
Condição de vitória
Como um desafio do código-golfe , a resposta mais curta vence.
Respostas:
Golfscript - 25 caracteres
A versão completa do programa tem apenas 19 caracteres
Volte aqui para análise mais tarde. Enquanto isso, confira minha antiga resposta não inspirada
Golfscript - 32 caracteres
Semelhante ao cálculo do número de luhn
Análise para 978030640615
fonte
{
e dos três últimos caracteres;}:f
. Eu me pergunto se a mesma coisa pode ser feita para a primeira solução ...:f
(sim, eu sei que as funções eram comumente nomeadas na época).Python - 44 caracteres
Python - 53 caracteres
fonte
Haskell - 54 caracteres
Isso requer suporte para compreensão de lista paralela , que é suportada pelo GHC (com o
-XParallelListComp
sinalizador) e Hugs (com o-98
sinalizador).fonte
[1,3]
por[9,7]
e remova o-
que economiza um byte :)APL (27 caracteres)
Estou usando o Dyalog APL como meu intérprete. Aqui está uma explicação rápida, principalmente da direita para a esquerda (dentro da definição da função
F←{ ... }
):⍎¨⍵
: Execute / avalie (⍎
) cada¨
caractere ( ) fornecido no argumento correto (⍵
).(12⍴1 3)
: Remodele (⍴
) o vetor1 3
em um12
vetor de elemento (repetindo para preencher as lacunas).+.×
: Pegue o produto escalar (+.×
) de seu argumento esquerdo ((12⍴1 3)
) e seu argumento direito (⍎¨⍵
).10-
: Subtraia de 10.10|
: Encontre o restante após a divisão por10
.⍕
: Formate o número (ou seja, forneça uma representação de caractere).⍵,
: Anexe (,
) nosso dígito calculado ao argumento correto.fonte
PHP -
868582 caracteresRe-formatar e explicação:
fonte
Windows PowerShell, 57
fonte
Haskell,
787166 caracteresfonte
Ruby -
7365 caracteresfonte
"\\1"
->'\1'
?f=->s{...}
. Economize 6 caracteres. Escreva também ems<<(...).to_s
vez de adicionar 48 e useFixnum#chr
.C # (94 caracteres)
Com linhas / espaços em branco para facilitar a leitura:
Testado em vários ISBNs de livros na minha estante, então eu sei que está funcionando!
fonte
Python -
91, 89fonte
for
(ein
o terceiro) em uma compreensão de lista, desde que possam ser divididos pelo analisador (sem usar um nome de variável). -2 caracteres lá.Perl, 53 caracteres
fonte
C # -
8977 caracteresFormatado para facilitar a leitura:
Nós não multiplicamos por um ou três, apenas adicionamos tudo, além de adicionarmos todos os caracteres pares mais uma vez, multiplicados por dois.
9992 é grande o suficiente para que a soma de todos os caracteres ASCII seja menor que isso (para que possamos modificar por 10 e ter certeza de que o resultado é positivo, sem necessidade de modificar por 10 duas vezes) e não seja divisível por zero, porque adicionamos até todos os 2 * 12 * 48 extras (doze dígitos ASCII, ponderados por 1 e 3) == 1152, o que nos permite poupar um caractere extra (em vez de subtrair duas vezes 48, subtraímos 0 apenas para converter de char para int, mas em vez de 990, precisamos escrever 9992).
Mas, novamente, apesar de muito menos bonita ;-), essa solução antiga nos leva a 80 caracteres (mas isso é quase compatível com C):
fonte
J -
554538por exemplo
à moda antiga:
fonte
(i.12)(".@{)y
pode ser substituído por"."0 y
Ruby - 80 caracteres
fonte
dc, 44 caracteres
Invoque como
lIx
, por exemplo:fonte
Q, 36 caracteres
fonte
D - 97 caracteres
Formatado de forma mais legível:
A verbosidade do operador de elenco de D definitivamente torna mais difícil escrever código obsessivamente curto.
fonte
Java - 161 caracteres :(
fonte
Q (44 caracteres)
fonte
Scala 84
Teste:
Resultado:
fonte
C,
8079 caracteresA função modifica a sequência no lugar, mas retorna o ponteiro da sequência original para atender aos requisitos do problema.
Alguma explicação: em vez de subtrair 48 (o valor ASCII do dígito
0
) de cada caractere de entrada, o acumuladors
é inicializado de modo que o módulo 10 seja igual a 48 + 3 * 48 + 48 + 3 * 48 ... + 48 + 3 * 48 = 24 * 48 = 1152. A etapa10-sum
pode ser evitada acumulandos
por subtração em vez de adição. No entanto, o operador do módulo%
em C não forneceria um resultado utilizável ses
fosse negativo; portanto, em vez de usars-=
os multiplicadores 3 e 1, são substituídos por -3 = 7 módulo 10 e -1 = 9 módulo 10, respectivamente.Equipamento de teste:
fonte
Groovy
75, 66 caracteresusar:
fonte
APL (25)
fonte
Perl 6 , 29 bytes
Experimente online!
fonte
Python 2 ,
7876 bytesExperimente online!
Toma uma string como argumento.
Explicação:
Usando a notação de fatia python, converte uma string em uma lista de pares de caracteres. ("978030640615" -> [("9", "7"), ("8", "0"), ("3", "0"), ("6", "4"), ("0 "," 6 "), (" 1 "," 5 ")])
Para essa lista de pares, converte cada item em um número inteiro e retorna + 3b.
Soma todos os resultados.
Obtém a soma do módulo 10, OU 10, se o restante for 0. (Isso impede que o dígito final seja 10 em vez de 0.)
Remove o restante de 10 para obter o dígito de verificação.
Converte o dígito de verificação calculado em uma string por meio da expressão de backtick obsoleta.
Retorna o número original mais o dígito de verificação calculado.
Editar:
Economizou 2 bytes removendo espaços (obrigado Jo King !).
fonte
for
eor
APL (Dyalog Unicode) , SBCS de 18 bytes
Função de prefixo tácito anônimo, usando string como argumento. Usando a abordagem de Bubbler .
Experimente online!
≢
duração do argumento (12)9 7⍴⍨
remodelar ciclicamente[9,7]
para esse comprimento+.×
dot dot do seguinte com isso:⍎¨
`avalie cada personagem10|
mod-10 desse,∘⍕
Anexar o seguinte a stringing disso:⊢
o argumento não modificadofonte
dc , 25 bytes
Experimente online!
Eu sei que já existe uma resposta dc aqui, mas 25 <44, então acho que me sinto bem com 19 bytes. Isso usa o fato de que
8+9^z
é equivalente a um-3
ou ao-1
mod 10, dependendo de z ser par ou ímpar. Então, eu usoA~
para dividir o número em dígitos na pilha, mas à medida que construo a pilha, multiplico cada dígito por8+9^z
onde z é o tamanho atual da pilha. Depois, adiciono todos eles à medida que a pilha de funções se desenrola e imprimo o último dígito.fonte
MATLAB - 82 caracteres
fonte
R, 147 caracteres
Uso:
fonte
J, 25
fonte