On vous donne en entrée deux chaînes représentant des entiers positifs en base 10, tels que "12345"
et "42"
. Votre tâche consiste à sortir une chaîne contenant leur produit, "518490"
dans ce cas.
La torsion est que vous ne pouvez pas utiliser de types numériques dans votre code. Non ints
, float
s, unsigned long
s, etc., pas de types de nombres complexes intégrés ou d'entiers de précision arbitraires, ou quoi que ce soit dans ce sens. Vous n'utilisez pas beaucoup de littéraux de ces types, ni aucune fonction, méthode, opérateur, etc. qui les renvoie.
Vous pouvez utiliser des chaînes, des booléens, des tableaux ou tout autre élément qui ne serait normalement pas utilisé pour représenter un nombre. (Mais notez que ni l'indexation dans un tableau ni l'obtention de sa longueur ne seront probablement possibles sans invoquer un type numérique.) char
S sont autorisés, mais vous ne pouvez effectuer aucune opération arithmétique ou au niveau du bit sur eux ou les traiter autrement comme autre chose que un jeton représentant une partie d'une chaîne. (La comparaison lexicographique de char
s est autorisée.)
Vous ne pouvez pas contourner la restriction. Cela inclut (mais sans s'y limiter) l'utilisation de types numériques à l'intérieur d'une eval
fonction de type, les conversions implicites de types en types numériques, l'utilisation d'opérateurs numériques ou au niveau du bit sur les types non numériques qui les prennent en charge, l'utilisation de types numériques stockés à l'intérieur de types de conteneurs, ou l'appel de fonctions ou programmes externes qui renvoient des résultats numériques sous forme de chaîne. (Je me réserve le droit d'ajouter à cette liste si d'autres solutions de contournement apparaissent dans les réponses.) Vous devez implémenter la multiplication vous-même en utilisant uniquement des types non numériques.
L'entrée et la sortie peuvent se faire par n'importe quelle méthode pratique, tant que les données entrent et sortent de votre code sous la forme d'une chaîne. Vous pouvez supposer que chacun des deux arguments d'entrée ne contient que les caractères ASCII [0-9]
et ne commencera pas par 0
. Votre sortie ne doit pas non plus comporter de zéros non significatifs.
Une dernière chose: votre code doit gérer correctement les entrées d' au moins 10 caractères et doit s'exécuter en moins d'une minute sur un ordinateur moderne pour toutes les entrées de cette plage. Avant de poster, veuillez vérifier que lorsque vous avez reçu des entrées 9999999999
et 9999999999
, votre programme donne une sortie de 99999999980000000001
, en moins d'une minute. Cette restriction existe spécifiquement pour empêcher les réponses qui fonctionnent en allouant un tableau de taille a*b
puis en itérant dessus, donc gardez à l'esprit que les réponses de ce formulaire ne seront pas éligibles pour gagner.
Il s'agit de code-golf , donc la solution valide la plus courte (en octets) l'emporte.
la source
"12345"
de STDIN plutôt que12345
? Ou pouvons-nous accepter les deux numéros comme"12345", "42"
?m
etn
et retourner un argument de longueurm*n
. Mais comme les chaînes doivent littéralement contenir la représentation ASCII des nombres, je suppose que c'est contraire aux règles.a,b="0123456789x".split('0');c=iter(b).next()
if c=='x':
c='0'
a,b="0123456789x".split(x);c,*d=b
if c=='x':
c='0'
d='123456789';I=dict(zip('0'+d,d+'0'))
Réponses:
Haskell - 180
206 214 214Met en œuvre la multiplication via des ajouts répétés, et toutes sortes de magie des chiffres sont gérées en décalant et en filtrant la
['0'..'9']
liste. Définit un opérateur#
du typeString -> String -> String
:la source
"0123456789"
est la liste['0'..'9']
. Deuxièmement, dans Haskell [a..b] est une énumération, les types qui ont déclaré des instances de laEnum
classe de types peuvent être énumérés comme ça, et la déclaration décrit comment fonctionne l'énumération.Bool
, le type booléen a également une instance, et vous pouvez donc également le faire[False..True]
. Il n'y a pratiquement pas de chiffres impliqués.sed,
339338 octetsJe sais que c'est un ancien, mais je parcourais et cela a piqué mon intérêt. De quoi s'enregistrer en tant qu'utilisateur! Je suppose que j'ai été influencé par " Je voudrais bien voir une solution complète sed - Nathaniel " ...
Ce script sed attend deux nombres décimaux en entrée, séparés par un espace
tests:
Vous pouvez reconnaître les deux derniers comme RSA-100 (50 x 50 chiffres) et RSA-768 (116 x 116 chiffres).
En utilisant GNU sed sur un système pas très moderne (Intel Core 2 de l'ère 2007), le dernier de ceux-ci prend plus d'une minute, mais il arrive plus rapidement sur un processeur plus récent:
La multiplication chétive à 10 chiffres spécifiée dans la question prend bien moins d'une seconde sur l'un d'entre eux (bien qu'il soit plein de neuf pathologiques).
Je crois que c'est standard sed, sans extensions. POSIX garantit un espace de 8192 octets uniquement, ce qui nous limite à multiplier les nombres à 400x400 chiffres, mais les implémentations peuvent en fournir davantage. GNU sed n'est limité que par la mémoire disponible, donc pourrait gérer quelque chose de beaucoup plus gros, si vous êtes prêt à attendre.
Et je suis convaincu que j'ai respecté les règles - c'est presque une donnée dans une langue qui n'a pas de chiffres. :-)
Explication
J'utilise un hybride unaire / décimal, convertissant les nombres décimaux en une séquence unaire:
En décimal unaire, l'addition est facile. Nous itérons du chiffre le moins significatif au chiffre le plus significatif, en concaténant les x:
Nous supprimons ensuite les espaces blancs et traitons le report en convertissant 10 x consécutifs en l'une des unités suivantes:
Une fois que nous avons l'addition, la multiplication est possible. Nous multiplions x * y en considérant le dernier chiffre de y. Ajoutez x à l'accumulateur autant de fois, puis passez au chiffre suivant et décalez x d'une décimale vers la gauche. Répétez jusqu'à ce que y soit zéro.
Code développé
la source
sed, 379 octets
Le mérite de cette brillante réponse revient à @LuigiTiburzi via Unix et Linux.SE: https://unix.stackexchange.com/a/37213/34061 . Je suis tombé sur ce sujet il y a quelques jours:
Explication générale
12*3
devient<1<2*<3
|
caractères. ainsi<1<2*<3
devient<|<||*<|||
|<
par<||||||||||
afin de décaler les décimales supérieures vers la position des unités. ainsi<|<||*<|||
devient<||||||||||||*<|||
<
. ainsi<||||||||||||*<|||
devient||||||||||||*|||
|
de la RHS du*
. ainsi||||||||||||*|||
devient||||||||||||*||
|
sur le RHS par tous les|
sur le LHS. Cela a pour effet de multiplier le nombre LHS et RHS de|
pour donner le numéro de produit de|
Ainsi||||||||||||*||
devient||||||||||||||||||||||||||||||||||||*
*
. ainsi||||||||||||||||||||||||||||||||||||*
devient||||||||||||||||||||||||||||||||||||
|
retour en décimal par l'inverse des premières étapes. Ainsi||||||||||||||||||||||||||||||||||||
devient36
.Sortie:
Malheureusement, il échoue lamentablement sur l'exigence de temps -
200*1000
prend 41 secondes sur ma machine virtuelle Ubuntu, et l'exécution semble empiriquement augmenter avec le carré du produit final.la source
length()
qui renvoie un nombre. Celui-ci utilise une substitution purement regex sans type numérique. Je pense que votre réponse est potentiellement gagnante si vous pouvez supprimer lelength()
- peut-être pourriez-vous faire une substitution de regex similaire à la place?Python -
312286273Si (beaucoup) de zéros non significatifs sont autorisés, les 12 derniers caractères ne sont pas nécessaires.
Cela effectue essentiellement la multiplication standard à la main. Les chiffres sont représentés comme des chaînes de
I
s répétés (comme les chiffres romains primitifs). Les nombres sont représentés sous forme de listes de chiffres dans l'ordre inverse. L'ajout de chiffres uniques est effectué en cocaténant les chaînes et en supprimant dixI
s si nécessaire.Voici une version non golfée:
la source
def A(x,y):\n S=[];o=""
->def A(x,y,S=[],o=""):
. De plus, malheureusement, ce["","1"][t in i]
n'est pas autorisé; il utilise un booléen pour indexer, le traitant comme un nombre. Je pense que celat in i and"1"or""
devrait fonctionner.S
comme un argument avec un défaut n'aurait pas fonctionné, car ce serait toujours la même liste même pour différents appels de la fonction et donc pas réinitialisé[]
. Vous aviez raison["","1"][t in i]
, j'ai corrigé cela. J'ai également ajouté une explication.Rubis:
752698C'est juste pour obtenir une réponse, juste par curiosité. Édité: maintenant un peu joué au golf.
Utilisation: je l'avais dans un fichier appelé peasant.rb:
Explication: c'est la multiplication paysanne, donc je divise et double à plusieurs reprises. La réduction de moitié se fait en divisant par deux les chiffres et en marquant les restes comme suit: 1234 -> 0b1a1b2a; puis recherchez et remplacez sur les b: 06a17a; puis nettoyage -> 617.
L'addition se fait comme ça ... tout d'abord, je rembourre les deux cordes à la même longueur et fais des paires à partir des chiffres. Ensuite, j'ajoute les chiffres en construisant une chaîne qui a la longueur de chaque chiffre et en concaténant; Je supprime une chaîne de cette longueur au début de «0123456789abcdefghij», puis je conserve le premier caractère. Ainsi, par exemple, "9" + "9" -> "i". NB J'évite réellement d'utiliser des fonctions de longueur ici pour éviter complètement les types de nombres; la suppression du préfixe se fait à la place avec une expression rationnelle.
Alors maintenant, j'ai une chaîne contenant un mélange de chiffres et de lettres. Les lettres représentent des nombres avec un chiffre de retenue; J'ajoute 0 au nombre, puis je remplace à plusieurs reprises les motifs chiffres-lettres par le résultat du report jusqu'à ce que l'ajout soit terminé.
la source
Brainfuck (1328 octets)
Considérations dans un premier temps:
Je n'ai testé le programme qu'avec mon propre interprète, vous pouvez le trouver ici .
L'entrée doit être les deux nombres séparés par un seul espace ASCII.
Golfé:
Non golfé:
J'ai pris le code pour la sortie de la valeur de cette réponse , merci à l'auteur pour cela!
Le programme n'est peut- être pas valide, mais dans les deux cas, je voulais le partager avec vous ^^
Mise à jour: Vous pouvez maintenant le tester (uniquement pour les petites multiplications) ici, grâce à la réponse de @ Sp3000 à ce concours et aux nouveaux extraits de pile de SE!
la source
Python,
394349340 caractèresCourez comme:
Prend 50 millisecondes.
Utilise la multiplication des paysans russes . Lors de l'ajout de chiffres, nous les convertissons en unaires ('5' => [R, R, R, R, R]), concaténons les listes, puis reconvertissons.
U
convertit en unaire, en utilisantR
comme chiffre unaire. Nous calculonsb/=2
commeb=b*5/10
.la source
def A(a,b):\n r='';c=[]
->def A(a,b,r='',c=[]):
, de même pourdef M
. Vous pouvez peut-être passerfor z in D:d.pop()\n c=['X']
à[d.pop()for z in D];c=['X']
, auquel cas vous pouvez même le réduire au précédentif
. En outre, peut-ilif list(b).pop()in'13579'
simplement êtreif b[:].pop()in'13579'
?b
est une chaîne, pas une liste.M
et écrire un programme complet;a,b=input()
est autorisée.reduce
, ce qui vous permet de nicenA(b,A(b,A(b,A(b,b))))
àreduce(A,[b,b,b,b,b])
. Malheureusement, cela n'affecte pas le nombre de caractères.JavaScript (E6) 375
395 411 449Edit Golfed
Edit Bug corrigé: manque d'effacement d'un indicateur de portage
Cela peut être fait avec une simple manipulation de symboles en un temps proche de 0.
Dans cette version, vous pouvez utiliser n'importe quel caractère au lieu des chiffres, tant que le symbole est dans l'ordre croissant.
Remarques: utilisation de chaînes, hashmap avec clé de chaîne, tableaux utilisés comme liste. Pas d'indexation, les tableaux sont parcourus en utilisant 'map' ou tournés en utilisant push & shift.
Tous les «+» sont des concaténations de chaînes.
Moins de golf ( peut-être une explication demain)
Tester dans la console FireFox / FireBug
Sortie
la source
9999999999
affaire devrait être99999999980000000001
, non99999999980000000081
Haskell, 231 octets
Ceci définit un opérateur # qui multiplie deux représentations de chaînes de nombres naturels. Il fonctionne en définissant une opération élémentaire d'incrémentation / décrémentation sur les chaînes, puis l'utilise pour construire l'addition et la multiplication. Un peu de magie supplémentaire donne des accélérations exponentielles qui rendent tout cela possible.
Cette approche est suffisamment rapide pour que même sur un ordinateur portable 2008 dans le ghci REPL non optimisé, le cas de test ne prenne qu'une fraction de seconde:
Voici une vérification que tous les produits à deux chiffres sont corrects:
la source
Bash + ImageMagick: 52
Attend que l'entrée soit dans les variables du shell
a
etb
. Ce n'est pas particulièrement intelligent ou efficace, mais cela fait le travail. Cela a probablement déjà été fait.Notez que le
x
dénote les dimensions de l'image; ce n'est pas un opérateur arithmétique dans ce contexte.Je n'ai pas testé cela, mais je suis prêt à supposer que pour une entrée non extrême, cela se terminera en moins d'une minute. Je peux le tester demain.
En cas de problème avec les versions d'ImageMagick, c'est celle que j'utilise:
ImageMagick 6.7.7-10
la source
9999999999
et9999999999
.dd if=/dev/zero bs=$a count=$b 2>&-|wc -c
.9999999999x9999999999
image au format 8 bits occupera tout l'espace du disque dur qui existe actuellement sur Terre. Bien sûr, un png serait beaucoup plus petit, si vous pouvez le créer sans d'abord créer l'image brute. (Bien que je soupçonne fortement que vous auriez des problèmes de débordement d'entier avec une image de cette taille.) Mais quand même, une telle méthode tomberait presque certainement dans la faille de l'appel des choses qui renvoient les résultats numériques en tant que chaînes.$b
au lieu de${b}
.grep -vc g
au lieu degrep -v g|wc -l
.Python 2 (preuve de concept)
Cette solution fonctionne en utilisant uniquement des chaînes et des listes, et une petite expression régulière. Je crois que cela correspond parfaitement aux spécifications, sauf qu'il n'y a aucun moyen que cela puisse faire
9999999999x9999999999
en une minute. Bien que suffisamment de temps, cela fonctionnerait. Il peut multiplier les nombres à 4 chiffres assez rapidement.Puisqu'il est techniquement invalide, je n'ai pas encore pris la peine de jouer au golf complètement. Je le ferai si les règles changent.
Exemples:
la source
Python 2 (555)
Normalement, je ne répondrais pas à mon propre défi aussi rapidement (ou pas du tout), mais je voulais prouver que cela pouvait être fait. (Heureusement, d'autres réponses l'ont fait avant celle-ci, mais je ne pouvais m'empêcher de vouloir le terminer.) Il y a encore du golf qui pourrait être fait, mais je pense que c'est raisonnable. Il gère le
9999999999x9999999999
boîtier en moins de 0,03s sur ma machine.Exemple d'utilisation:
m("12345","42")
Cela fonctionne en faisant une longue multiplication en utilisant des manipulations de chaînes. Parfois, les variables sont des chaînes et parfois ce sont des itérateurs sur les chaînes, ce qui permet d'obtenir le premier élément sans utiliser un littéral entier. Tout est stocké avec les chiffres inversés, de sorte que le premier élément est le chiffre le moins significatif.
Voici une explication fonction par fonction:
r
ets
sont des fonctions de comptabilité. (r
est juste un alias pourreversed
, qui fait un itérateur inverse ets
convertit les itérateurs en chaînes.)i
incrémente le nombre dans une chaîne de 1, y compris les cas comme39+1=40
et99+1=100
.b
ajoutex
ety
, mais ney
doit comporter qu'un seul chiffre. Il fonctionne en incrémentant lesx
y
temps.a
ajoute deux numéros ensemble qui peuvent tous deux avoir plusieurs chiffres, en appelantb
pour chaque chiffre entranty
.n
multipliex
ety
, mais ney
doit être qu’un seul chiffre. Il fonctionne en ajoutantx
à lui - mêmey
temps.o
multipliex
ety
, où les deux arguments peuvent avoir plusieurs chiffres. Il utilise une longue multiplication classiquem
convertit simplement ses entrées de chaîne en itérateurs inversés et les leur remeto
, puis inverse le résultat et le convertit en chaîne.la source
def a(x,y):
->def a(x,y,z=''):
et supprimez la ligne suivante; astuces similaires pour d'autres fonctions, dansdef o(x,y):
, changez lex=s(x)
enx=s(x);l='';z=''
, dans celui pour la boucle, supprimez de la même manière les sauts de ligne +; utilisez plutôt;
. De plus, je pense que celaif h!='0':h+=s(x)\nelse:h+=i(x)
peut être tout simplementh+=h!='0'and i(x)or s(x)
; peut-être mêmeh+=(h!='0'and i or s)(x)
; sinon, changez simplement enif'0'!=h
. Des choses commedef r(x):return reversed(x)
->r=reversed
s
,m
:s=lambda x:''.join(x)
,m=lambda x,y:s(r(o(r(x),r(y))))
au lieu de la déclaration de fonction entière. Avec juste ce que je sais fonctionner, cela ramène votre nombre d'octets à 521.for
boucles:for c in'0'+d:\nif c==y:break\nz=a(iter(z),x)
->for c in'0'+d:\nif c!=y:z=a(iter(z),x)
, bien que cela puisse changer considérablement la vitesse de votre programme.JavaScript:
37103604 octetsLe golf:
Non golfé avec des tests:
Cela produit:
la source
Haskell
507496Cela fonctionne pour des entiers arbitrairement grands. Je définis des représentations personnalisées pour les nombres naturels de 0 à 18 (le plus grand nombre naturel égal à la somme de deux chiffres), et je définis la multiplication en petits nombres en termes de multiplication chiffre * nombre, que je définis en termes de nombre + addition de nombre , que je définis en termes d'addition chiffre + chiffre. J'ai une fonction de réduction qui étend les valeurs 10 à 18 dans leur décomposition numérique. Cela lit et inverse simplement les deux chaînes, se traduit par les liaisons personnalisées, se multiplie et se traduit en arrière, inversant pour obtenir le bon résultat.
Modifier 2
J'ai enregistré quelques caractères en créant de courts alias locaux pour les commandes à plusieurs caractères que j'utilise plusieurs fois, ainsi qu'en supprimant les espaces et les parenthèses, et en remplaçant
(
-)
paires par$
, si possible.Pour référence, S est le type de données de type entier personnalisé,
p
est «plus» (chiffre + addition de chiffre),s
est soustrait (pour réduction),r
est réduit (se développe en décomposition numérique),a
est addition (nombre + addition de nombre),m
est multiplier (multiplication de chiffres * nombres),t
est multiplié par (multiplication de nombres * nombres),i
est 'interpréter' (convertir la chaîne en listeS
),b
est 'en arrière' (liste de S en chaîne), et f et g ne sont que des raccourcis pour le golf fins. Je n'ai pas utilisé de chiffres, même implicitement; le plus proche que j'ai obtenu était d'utiliser des successeurs et des prédécesseurs, qui sont des concepts mathématiques de niveau beaucoup plus élevé que l'addition et la multiplication de nombres naturels.modifier
J'ai oublié d'inclure le profil horaire.
Juste pour faire bonne mesure:
Allons fou!
confirmation
la source
Python 2 -
1165, 712, 668664Notez que je n'utilise pas d'indexation logique comme
Z = [X, Y][N == "0"]
, car cela pourrait être interprété comme un booléen transtypé en index numérique.Non golfé:
la source
Scala, 470 caractères
(les
⇒
scala sont standard mais peuvent être remplacés de manière équivalente par=>
si nous comptons les octets)Ici, nous émulons des chiffres en utilisant la longueur des listes, en faisant attention à ne pas utiliser d'opérations numériques - uniquement des plis, des cartes, des zips et autres. Un nombre est une liste de ces chiffres (ordre stratégiquement inversé à mi-parcours du calcul); nous multiplions les chiffres individuels avec
flatMap
et nos rangées avecreduce
.u
gère le calcul du report (en le comparant directement à une liste de> 10 éléments et la récurrence) et la conversion des chiffres en caractères, et nous utilisons un/:
pour travailler notre chemin à travers la pile avec cela. L'exemple requis se termine en moins d'une seconde.la source