introduction
Dans ce défi, votre tâche consiste à générer le code ISBN-10 pour les livres étant donné son code ISBN-13, en supposant qu'un tel code existe. Un tel code ISBN-13 se compose de plusieurs parties séparées par -
:
978-GG-PPPP-TTT-C
Les lettres G
(groupe), P
(éditeur), T
(titre) et C
(somme de contrôle) représentent toutes un chiffre. Aux fins de ce défi, le regroupement et le calcul de C
(voir ce défi ) ne sont pas intéressants et nous allons supprimer tous les tirets pour simplifier cette tâche.
Un numéro ISBN-10 a une disposition très similaire:
GG-PPPP-TTT-c
Les lettres G
, P
et T
sont les mêmes que pour l'ISBN à 13 chiffres, cependantc
différentes (et sont calculées à l'aide d'un algorithme différent). Le chiffre c
est choisi de manière à ce que l'équivalence suivante soit respectée (chiffres dans l'ordre):
10*G + 9*G + 8*P + … + 3*T + 2*T + 1*c = 0 (mod 11)
Exemple
Considérons le numéro ISBN 9780345391803
: pour obtenir son code ISBN-10 correspondant, il suffit de supprimer le début 978
et la somme de contrôle3
qui donne 034539180
.
Ensuite, nous devons calculer la nouvelle somme de contrôle:
10*0 + 9*3 + 8*4 + 7*5 + 6*3 + 5*9 + 4*1 + 3*8 + 2*0 = 185
Le prochain nombre divisible par 11
est 187
, donc la nouvelle somme de contrôle est2
et donc le code ISBN-10 résultant 0345391802
.
Règles
- Votre entrée aura toujours un numéro ISBN-10 correspondant (c'est-à-dire qu'elle est exactement de 13 chiffres et commence par
978
) - L'entrée ne doit pas nécessairement être un ISBN-13 valide (par exemple.
9780000000002
) - Vous êtes assuré que l'ISBN résultant ne se terminera pas
X
- Vous pouvez prendre l'entrée comme un entier ou une chaîne (avec ou sans tirets), mais une liste de chiffres précalculés n'est pas autorisée
- Votre sortie doit être un numéro ISBN-10 valide (avec ou sans tirets)
- Votre sortie peut être un entier ou une chaîne (là encore aucune liste de chiffres)
Cas de test
9780000000002 -> 0000000000
9780201882957 -> 0201882957
9781420951301 -> 1420951300
9780452284234 -> 0452284236
9781292101767 -> 1292101768
9780345391803 -> 0345391802
Notez les zéros non significatifs!
0-684-84328-5
et99921-58-10-7
, la première partie (0
et99921
respectivement) est le groupe d'inscription, la deuxième partie est l'éditeur, etc.Réponses:
Rétine ,
443928 octetsEssayez-le en ligne!
Explication
Il est temps de montrer de nouvelles fonctionnalités Retina. :)
Nous faisons correspondre l'intégralité de l'entrée avec
.+
, renvoyons cette correspondanceL
, mais ne sélectionnons que les caractères 3 (base zéro) à -2 (avant-dernier), inclus. Nous imprimons également le résultat sans retour à la ligne (>
).Maintenant, soustraire des choses dans Retina est un peu ennuyeux. Mais heureusement, nous travaillons sur modulo 11, nous pouvons donc simplement inverser les coefficients de la combinaison linéaire (mod 11) et tout additionner. En d'autres termes, si la contrainte est:
on obtient alors:
Cela simplifie beaucoup les choses ici:
Nous remplaçons chaque personnage par cette chose en bas.
*
est l'opérateur de répétition de Retina. Il est associatif à droite et il a des opérandes implicites$&
à gauche et_
à droite, donc la substitution est en fait abrégée$.>`*$&*_
.$&*_
crée une chaîne de d soulignements, où d est le chiffre que nous remplaçons actuellement. Ensuite$.>`
est la longueur de la chaîne jusqu'à et y compris le match. 1 Par conséquent, les résultats entiers d'expression dans une représentation unaire du n ième terme de notre combinaison linéaire.Faire le modulo réel est trivial en unaire: nous déposons simplement tous les ensembles complets de 11 traits de soulignement.
Enfin, nous comptons le nombre de soulignements restants et imprimons le résultat, ce qui complète l'ISBN-10.
1 Comment
$.>`
donne la longueur de la chaîne jusqu'au match inclus? Vous connaissez peut-être les$`
substitutions d'expression régulière, ce qui vous donne la chaîne jusqu'à (mais à l'exclusion) la correspondance. En insérant a>
, nous pouvons déplacer le contexte de la$`
vers le séparateur entre la correspondance actuelle et la suivante (qui est une chaîne vide entre le chiffre actuel et le suivant). Ce séparateur$`
inclura la correspondance actuelle. Il en$>`
va de même pour l'écriture$`$&
. Enfin, pour les$x
éléments de substitution de tout type, Retina vous permet d'insérer un.
après le$
pour obtenir sa longueur.la source
-2 ≡ 9 (mod 11)
(parce que l'ajout ou la soustraction de 11 d'un nombre ne change pas sa "valeur" dans la classe de congruence mod 11). De plus, l'addition et la multiplication respectent les classes de congruence, vous pouvez donc remplacer n'importe quelle valeur dans une combinaison linéaire par une valeur équivalente sous le modulo actuel. La raison pour laquelle je parle de nombres négatifs est vraiment juste que j'ai réarrangé l'équation pour avoirc
d'un côté et tous les autres termes (en tant que négatifs) de l'autre.c
pour devenir-c = ...
et plutôt que de multiplier par10 9 8...
vous soustrayez11
de chacun pour obtenir-1 -2 -3...
, puis multipliez tout par -1 pour obtenirc
.05AB1E ,
17151312 octetsEssayez-le en ligne!
Explication
la source
PowerShell ,
9684 octetsEssayez-le en ligne!
Prend des entrées
"$args"
, effectue une regex-replace
pour obtenir uniquement la partie pertinente, stocke cela dans$x
une chaîne. Ensuite, nouschar
transcrivons cela en un tableau et parcourons chaque lettre. À l'intérieur de la boucle, nous pré-décrémentons$a
(par défaut0
) et multiplions selon le calcul de la somme de contrôle. Notez la distribution àint
, sinon cela utiliserait des valeurs ASCII.Nous avons ensuite
-join
ces nombres avec+
et le diriger versiex
(Invoke-Expression
et similaire àeval
). Nous prenons cela%11
et stockons cette somme de contrôle dans$y
. Enfin, nous enchaînons les chaînes$x + $y
et laissons cela dans le pipeline. La sortie est implicite.Enregistré 12 octets grâce à Emigna.
la source
Octave ,
46 41 3937 octetsEssayez-le en ligne!
Le code prend l'entrée sous forme de chaîne et renvoie une chaîne.
Le code se décompose comme suit:
@(a)
crée une fonction anonyme.Avec
[c=a(4:12) ... ]
nous extrayons les caractères qui forment le code principal, en enregistrant une copie dansc
une utilisation ultérieure et ajoutons une autre copie à la chaîne de sortie finale.Sur la base de @ manière intelligente de MartinEnter d'échange
10:-1:2
dans1:10
, nous pouvons facilement générer cette gamme et la transposer pour obtenir un vecteur de colonne.c*(1:10)'
effectue la multiplication de tableaux du vecteur lignec
et du vecteur colonne colonne. Cela revient à faire une multiplication par élément puis à additionner.La somme de contrôle serait normalement
mod(11-sum,11)
de calculer le nombre requis pour que la somme soit un multiple de 11. Cependant, parce quec
c'était une chaîne de caractères, la somme sera en fait plus grande qu'elle ne devrait l'être de 2592 (48 * 54) parce que nous l'avons multiplié par des nombres qui étaient 48 plus grandes que la valeur réelle.Lorsque nous effectuons le modulo, il supprimera automatiquement tout sauf 7 de ce 2592. En tant que tel, et en tenant compte de la négation de la plage, le calcul réel devient
48+mod(7+sum,11)
. Nous ajoutons 48 au résultat pour reconvertir en caractère ASCII.Le caractère de somme de contrôle est ajouté à la fin du résultat et la valeur renvoyée.
la source
Gelée , 12 octets
Il s'agit d'un programme complet qui utilise des chaînes pour les E / S.
Essayez-le en ligne!
Comment ça marche
la source
JavaScript (ES6),
5956 octetsAfficher l'extrait de code
-3 octets grâce à la suggestion de @ Shaggy .
la source
Perl 5 , 49 + 1 (
-p
) = 50 octetsEssayez-le en ligne!
la source
Pyth , 16 octets
Essayez-le ici!
Pyth , 17 octets
Essayez-le ici!
Explication
la source
Japt ,
1615 octetsJe suis venu avec ça dans le pub l'autre soir et j'ai tout oublié.
Essayez-le
la source
s3J
etU+¬x_*°TÃuB
U
- D'oh!Hexagonie ,
7761 octetsEssayez-le en ligne!
Coloré:
Voici une version plus grande. Il y a des croisements de chemins, mais parce que toutes ces cellules sont
.
(sans opération dans Hexagony), vous n'avez pas à vous en préoccuper:(J'ai aussi essayé de garder les vieux miroirs, mais parfois j'ai besoin de changer quelque chose)
La commande linéaire exécutée est:
Explication: Au lieu de garder un compteur et de multiplier à chaque chiffre, ce programme:
p
ett
)(-p-t)%11
, où%
toujours retourner des résultats positifs.la source
K (oK) ,
29252423 octetsSolution:
Essayez-le en ligne!
Exemples:
Explication:
L'évaluation s'effectue de droite à gauche.
Deux astuces tirées d'autres solutions:
Panne:
Remarques:
7
à la somme)la source
C (gcc),
96 95 87 8685 octets(-1 grâce au plafond)
Essayez-le en ligne!
À appeler comme
f(s)
, oùs
est un pointeur sur le premier élément d'un tableau de caractères modifiables. Modifie le tableau d'entrée, renvoie un pointeur dans le tableau d'entrée.la source
Python 2 , 62 octets
Essayez-le en ligne!
Prend une chaîne en entrée; et sort une chaîne.
la source
Gelée , 14 octets
Suite de tests!
Gelée , 17 octets
Essayez-le en ligne! ou Suite de tests!
Prend les entrées et sorties sous forme de chaîne.
la source
ECMAScript 6 ,
8667 octetsEssayez-le en ligne!
Merci pour le commentaire d' Arnauld , passé de
reduce
àmap
et débarrassé dereturn
mot - clé.la source
map()
,reduce()
etc. Avec une réécriture supplémentaire, il est souvent possible de se débarrasser de{}
etreturn
. De plus, dans ce cas particulier, ilmap()
est probablement plus court quereduce()
. ( Voici une version de 65 octets.)f=
n'est pas nécessaire. En outre, vous pouvez initialiserc
à la propagation pour quelque chose comme ceci:a=>{i=10;s=[...c=a.substr(3,9)].reduce((g,v)=>+g+(i--)*v,0)%11;return c+=s?11-s:0}
(-4 octets)Retina 0.8.2 ,
7251 octetsEssayez-le en ligne!Parce que je n'ai pas encore appris Retina 1.0. Explication:
Supprimez les caractères indésirables et faites une deuxième copie des chiffres appropriés.
Suffixez chaque chiffre de la deuxième copie avec son suffixe. Cela répète efficacement chaque chiffre du suffixe par sa position.
Convertissez les chiffres de la deuxième copie en unaire et ajoutez-les ensemble.
Réduisez le module 11. (Il n'y a que 9 chiffres dans la première copie, cela ne peut donc jamais l'affecter.)
Convertissez le résultat en décimal et supprimez à nouveau la nouvelle ligne.
la source
APL (Dyalog Unicode) ,
2624 octetsEssayez-le en ligne!
Fonction de préfixe tacite. Prend l'entrée comme chaîne.
2 octets enregistrés grâce à @ngn.
Comment?
la source
Nettoyer ,
10410298 octetsEssayez-le en ligne!
la source
Kotlin , 83 octets
Embellie
Tester
TIO
TryItOnline
la source
Rubis ,
69 6864 octetsEssayez-le en ligne!
la source
PHP, 64 octets
Malheureusement, en PHP
(-$c)%11
est le même que-($c%11)
; donc je dois obtenir la différence à au moins la plus grande somme possible (55 * 9 = 495 = 45 * 11) au lieu de simplement utiliser-$c%11
.ou
Exécuter en tant que pipe avec
-nR
ou essayer en ligne .la source
Java 10, 110 octets
Prend les entrées et les sorties sous forme d'
long
entier. Essayez-le en ligne ici .Version non golfée:
la source