Multipliez deux nombres


21

Entrée: deux entiers décimaux. Ceux-ci peuvent être donnés au code en entrée standard, comme arguments au programme ou à la fonction, ou comme liste.

Sortie: leur produit, sous forme d'entier décimal. Par exemple, l'entrée 5 16mènerait à la sortie 80.

Restrictions: Pas d'échappatoires standard s'il vous plaît. Il s'agit de , réponse dans le plus petit nombre d'octets gagne.

Remarques: Disposition volée de mon défi précédent, ajoutez deux chiffres .

Cas de test:

1 2   -> 2
4 5   -> 20
7 9   -> 63
-2 8  -> -16
8 -9  -> -72
-8 -9 -> 72
0 8   -> 0
0 -8  -> 0
8 0   -> 0
-8 0  -> 0
0 0   -> 0

Ou en CSV:

a,b,c
1,2,2
4,5,20
7,9,63
-2,8,-16
8,-9,-72
-8,-9,72
0,8,0
0,-8,0
8,0,0
-8,0,0
0,0,0

Classement


4
@FlipTack Cela suppose que l'addition et la multiplication sont aussi faciles dans n'importe quelle langue, ce que je ne sais pas si c'est vraiment vrai.
Fatalize

16
Je ne pense pas qu'il soit juste d'autoriser le défi «ajouter deux numéros», mais fermez celui-ci. Même si c'est très trivial dans la plupart des langages de programmation, c'est toujours un défi valable. Si cela est trop large, le défi "ajouter deux nombres" doit également être trop large.
Mego

32
N'importe qui est libre de voter contre des défis triviaux s'il ne les aime pas, mais c'est un défi parfaitement valide et sur le sujet et il est loin d'être "trop ​​large" (si vous le souhaitez, vous pourriez appeler un défi trivial trop étroit). Je rouvre ça. Cela dit, si quelqu'un pense que des défis insignifiants insultent leur intelligence, je les encourage à rechercher des langues qui rendent la tâche moins triviale.
Martin Ender

16
Uo suivant: soustrayez deux nombres!
steenbergh

7
@wat Ne laissant aucun fond de canon non gratté, hein?
Gareth

Réponses:


39

Brachylog V1, 05AB1E, J, K, Underload, MATL, Forth, PigeonScript, Stacked, Implicit, Jolf, Clojure, Braingolf, 8th, Common Lisp, Julia, Pyt, Appleseed, Stax, Reality, dc 1 byte

*

Vous pouvez modifier cette réponse pour ajouter d'autres langues pour lesquelles la *réponse est valide.


Polygot, 05AB1E et comme 5 autres langues.
Magic Octopus Urn

13
J'ai édité Underload dedans. C'est probablement le plus intéressant d'entre eux, car Underload n'a pas de méthode à 1 octet pour effectuer la soustraction, la division ou l'addition.


Ce n'est pas valable en Pyth. Pyth ne prend pas d'entrée implicite comme celle-ci.
isaacg

Ajouté Julia, par exemple*(5,16)
gggg

32

C (GCC), 13 octets

Ne fonctionne pas sur tous implémentations, mais c'est OK.

f(a,b){a*=b;}

Essayez-le sur TIO!


6
Attendez, est-ce censé revenir en quelque sorte a? Je ne comprends pas ...
Erik the Outgolfer

2
Une explication de la façon dont cela fonctionne serait utile. ( aest une variable de pile locale pour f()- pourquoi sa valeur est-elle retournée?). +1, btw - abus très intelligent de l'ABI.
Digital Trauma

6
@EriktheOutgolfer Le returnmot-clé place simplement la redult de son argument dans le registre EAX. Dans ce cas, l'exécutable généré effectue le calcul a*bdans ce registre, donc returnne fait rien.
Dennis

7
Hé, c'était mon truc! codegolf.stackexchange.com/a/106067/18535 :-)
GB

12
Tellement heureux de voir C au sommet pour une fois! Vous pouvez réellement raser environ 9 octets en remplaçant simplement la f(a,b){a*=b;}pièce par 1##&et en changeant simplement votre langue en Mathematica.
Albert Renshaw

21

Beatnik , 888 octets

k I
j k ZZZZX z
xw k C vp yQ KD xw z j k ZZZZX z
j k ZZZD z xw bZ ZX
k XX z qs xw vp xw xw vp xw vp vp vp k I Xj ZZD hd
xw yQ K k ZZZZX xo exx
qs yQ XA xw xw xw xw z xw bZ K
xw xw k I
j k ZZZZX z
xw k C vp yQ XA hd k I z j k ZZZZX z
j xw k A vp bZ ZX
k ZZZZX z qs xw vp xw xw vp xw vp vp vp k I Xj ZZD hd
xw yQ K k ZZZZX xo exx
qs yQ F k ZZZZK xo
vp
xw xw z qs xw bZ X xw k I z xw Xj K
qs xw bZ KA vp qs xw Xj C hd
qs z xw xw xw xw z qs
xw xw xw xw z qs k I qs k I z xw Xj ZC
qs bZ ZZZX qs xw yQ C hd xw
k I vp qs k I qs
xw Xj ZZC hd hd z Kz ZZD
k I z xw xw xw xw z qs k I qs k I Xj ZZZZF
z
xw xw z qs xw bZ X xw k I z xw Xj K
qs xw bZ KA vp qs xw Xj C hd
z qs xw
xw xw z qs xw bZ X xw k I z xw Xj K
qs xw bZ KA vp qs xw Xj C hd
z vp
xw xw z qs
xw xw z qs
k I qs
xw bZ ZZX k I z qs k I vp
xw k ZA z yQ ZA hd qs k I vp qs k I Xj ZZKD
qs xw Xj ZZK
hd qs xw Xj ZZZZ hd
k ZZZZKD vp xo xw Xj K

Essayez-le en ligne!

J'utilise l'interpréteur C parce que l'interpréteur Python sur TIO exécute de manière ennuyeuse l'adresse si la condition pour sauter en arrière n'est pas remplie. Une solution de contournement facile pour l'interpréteur Python consiste à remplir certains nops pour rendre l'adresse nop. Je crois que ni l'un ni l'autre n'est correct:

                                   C       Python  My interpretation
IP after skiping N words           IP+N+1  IP+N+2  IP+N+2
IP after skiping back N words      IP-N    IP-N+1  IP-N+2
IP after not skiping N words       IP+2    IP+2    IP+2
IP after not skiping back N words  IP+2    IP+1    IP+2

L'entrée doit être deux entiers séparés par un espace, sans retour à la ligne.

Cette réponse fonctionne en théorie pour tous les entiers, si chaque cellule peut stocker une valeur arbitrairement grande, non limitée à 0 - 255. Mais elle déborde si | A | + | B | > 22. Et cela fonctionne très lentement si | A | + | B | > 6. Il n'y a donc pas beaucoup de cas que vous pouvez réellement tester et une solution if-else pour ces cas pourrait être encore plus courte.

L'idée est de calculer les nombres triangulaires T (N) = N (N + 1) / 2 en décrémentant la valeur à 0 et en additionnant toutes les valeurs intermédiaires. Ensuite, nous pouvons obtenir la réponse A * B = T (A + B) - T (A) - T (B).

Mais il est difficile de calculer les 3 valeurs. Pour ce faire, il calcule d'abord T (A + B) - A, en laissant une copie de A dans la pile pour l'ajouter plus tard, et en utilisant l'entrée B.Recursivement, trouvez le plus grand nombre triangulaire plus petit que celui, qui est T ( A + B-1) sauf pour les cas spéciaux zéro. Nous pouvons récupérer B = T (A + B) - A - T (A + B-1) et calculer T (B) à partir de là.

Un nombre N est un nombre triangulaire ssi il est égal au plus grand nombre triangulaire plus petit que N, plus le nombre de nombres triangulaires non négatifs plus petits que N. Cela s'exécute en O (2 ^ (T (A + B) -A)) et est la partie la plus lente du programme.

k I                                         Push 1
j k ZZZZKAAA z                              Input and decrement by 48.
xw k AAA vp yQ (input_a_loop)               If the character was '-':
xw z j k ZZZZKAAA z                           Replace with 0 and input another.
input_a_loop:
j k ZZZAA z xw bZ (input_a_end)             Input and break if it is a space.
k ZKA z qs xw vp xw xw vp xw vp vp vp       Otherwise multiply the previous
                                              value by 10 and add.
k I Xj (input_a_loop)                       Continue the loop.
input_a_end: hd                             Discard the space.
xw yQ (check_sign) k ZZZZKAAA xo exx        If A=0, print 0 and exit.
                                            Stack: ?, A_is_positive, A
check_sign:
qs yQ (check_sign_else)                     If A is positive... or not,
xw xw xw xw z xw bZ (check_sign_end)          in either cases, push 2 copies
check_sign_else: xw xw k I                    of A and the negated flag back
check_sign_end:                               as a constant.
                                            Stack: A, A, A, A_is_negative
j k ZZZZKAAA z                              Similar for B.
xw k AAA vp yQ (input_b_loop)               If the character was '-':
hd k I z j k ZZZZKAAA z                       Decrement the flag and input another.
input_b_loop:
j xw k A vp bZ (input_b_end)                EOF is checked instead of a space.
k ZZZZKAAA z qs xw vp xw xw vp xw vp vp vp
k I Xj (input_b_loop)
input_b_end: hd
xw yQ (output_sign) k ZZZZKAAA xo exx       If B=0, print 0 and exit.
                                            Stack: A, A, A, A*B_is_negative, B
output_sign:
qs yQ (output_sign_end) k ZZZZK xo          If negative, output '-'.
output_sign_end:

vp                                          Add.        Stack: A, A, A+B
xw xw z qs                                  Insert a 0. Stack: A, A, 0, A+B.
xw bZ { xw k I z xw Xj }                    Copy and decrement while nonzero.
                                            Stack: A, A, 0, A+B, A+B-1, ..., 0
qs xw bZ { vp qs xw Xj } hd                 Add while the second value in the
                                              stack is nonzero.
                                            Stack: A, A, T(A+B)
qs z xw xw xw xw z qs                       Stack: A, C0=T(A+B)-A, C0, F0=0, C0

expand_loop:
xw xw xw xw z qs k I qs                     Stack: A, C0, C0, F0=0,
                                              ..., [P=C, P, S=0, F=1], C
dec_expand: k I z xw Xj (expand_loop)       Decrement and continue if nonzero.
                                            Stack: [P=1, P, S, F], C=0
                                            The last number 0 is assumed to
                                              be a triangular number.
test: qs bZ (extract_end)                   If F=0, break.
qs xw yQ (test_not_first) hd xw             If S=0, it's the first triangular
                                              number below previous C. Set S=C.
test_not_first: k I vp qs k I qs            S+=1 and restore F=1.
xw Xj (dec_expand)                          If C!=0, recursively expand from C-1.
hd hd z Kz (test)                           If S=P, P is a triangular number,
                                              return to the previous level.
k I z xw xw xw xw z qs k I qs               Otherwise, decrement P and try again.
k I Xj (dec_expand)
extract_end:                                Stack: A, C0, C0, T(A+B-1)

z                                           Subtract and get B.
xw xw z qs xw bZ { xw k I z xw Xj }         Computes T(B).
qs xw bZ { vp qs xw Xj } hd
                                            Stack: A, C0, T(B)
z qs xw                                     Stack: C0-T(B), A, A

xw xw z qs xw bZ { xw k I z xw Xj }         Computes T(A).
qs xw bZ { vp qs xw Xj } hd
z vp                                        Get A*B=(C0-T(B))+(A-T(A))
xw xw z qs                                  Stack: 0, X=A*B

divide: xw xw z qs                          Stack: 0, ..., Y=0, X
subtract: k I qs                            Stack: 0, ..., Y, Z=1, X
xw bZ {                                     While X!=0:
k I z qs k I vp                               X-=1, Z+=1.
xw k ZA z yQ (not_ten)                        But if Z=11:
hd qs k I vp qs k I Xj (subtract)               Y+=1, reset Z and restart the loop.
not_ten: qs xw Xj }
hd qs xw Xj (divide)                        Put Z under Y and make Y the new X,
                                              continue the loop if X!=0.
hd                                          Discard X.

print_loop:
k ZZZZKAA vp xo xw Xj (print_loop)          Add each cell by 47 and print.

Woah. Juste ... woah. J'ai placé la prime, vous l'obtiendrez dans 7 jours.
NieDzejkob

19

Mathematica, 4 octets

1##&

Exemple d'utilisation: 1##&[7,9]retours 63. En effet, cette même fonction multiplie un nombre illimité d'arguments de n'importe quel type.

Comme les connaisseurs de code de Mathematica le savent, cela fonctionne car ##fait référence à la séquence entière d'arguments d'une fonction, et la concaténation dans Mathematica représente (souvent) la multiplication; 1##fait donc référence (1 fois) au produit de tous les arguments de la fonction. Le &est juste court pour leFunction commande qui définit une fonction pure (sans nom).

À l'intérieur d'un autre code, le symbole commun *agit comme une multiplication. Il en va de même pour un espace, ce qui 7 9est interprété comme 7*9(en effet, la version REPL actuelle de Mathematica affiche en fait ces espaces comme des signes de multiplication!). Encore mieux, si Mathematica peut dire où un jeton commence et où un autre se termine, alors aucun octet n'est nécessaire pour un opérateur de multiplication: 5yest automatiquement interprété comme 5*y, et 3.14Log[9]comme 3.14*Log[9].


Qu'est-ce qui rend ##&invalide?
Lynn

##&renvoie sa liste d'arguments en tant qu'objet 'Sequence' - adapté pour se connecter à d'autres fonctions qui acceptent plusieurs arguments. Dans ce contexte, ##&ne fait rien à sa liste d'arguments; nous voulons que cette liste soit multipliée.
Greg Martin

19

Rétine , 38 37 31 octets

Entièrement nouvelle approche, l'ancienne est ci-dessous.

M!`-
*\)`-¶-

.* 
$*_
_
$'$*_
_

Essayez-le en ligne!

Explication

Tout d'abord, nous traitons du signe:

M!`-

correspond à tous -dans la chaîne et les renvoie séparés par des retours à la ligne

*\)`-¶-

(avec une ligne vide suivante)
*\) signifie que le résultat de cela et les étapes précédentes doivent être imprimés sans nouvelle ligne, puis la chaîne est revenue à ce qu'elle était avant (la chaîne d'entrée). La partie restante en supprime deux -séparés par une nouvelle ligne.

Ensuite, nous convertissons le premier nombre en unaire:

.* 
$*_

(il y a un espace à la fin de la première ligne). Nous utilisons _comme chiffre unaire dans ce cas, car le chiffre standard1 peut être présent dans le deuxième nombre, et cela entrerait en conflit plus tard.

Nous arrivons maintenant à la multiplication réelle:

_
$'$*_

Chacun _est remplacé par la représentation unaire de tout ce qui le suit (toujours en utilisant_ comme chiffre unaire). Étant donné que la conversion en unaire ignore les caractères non numériques, cela répétera la représentation unaire du deuxième nombre pour le "premier nombre" fois. Le deuxième nombre restera en représentation décimale à la fin de la chaîne.

Au final, avec un seul _on renvoie le nombre de_ dans la chaîne, qui sera le résultat de la multiplication.


Réponse précédente: (avertissement: sort une chaîne vide quand elle devrait sortir 0 )

Rétine ,  45  42 41 octets

Jouons à un jeu! Multipliez les nombres relatifs avec une langue qui n'a pas d'opérateurs arithmétiques et un support limité uniquement pour les nombres naturels ... Ça a l'air drôle :)

O^`^|-
--

\d+
$*
1(?=1* (1*))?
$1
1+
$.&

Explication

Les trois premières lignes concernent le signe:

O^`^|-

Cela trie Opuis inverse ^toutes les chaînes correspondant à l'expression régulière ^|-. En pratique, cela correspond à la chaîne vide au début et au signe moins éventuel avant le deuxième nombre, et les réordonne en plaçant la chaîne vide à la place du moins. Après cela, tous -sont au début de la chaîne, et une paire d'entre eux peut être supprimée facilement avec les deux lignes suivantes.

Après cela, nous utilisons une fonction intégrée pour convertir les nombres en représentation unaire, puis vient la multiplication réelle:

1(?=1* (1*))?
$1

Nous faisons correspondre 1chacun d'entre eux et les remplaçons par tous les 1espaces suivants. Chaque chiffre du premier numéro sera remplacé par le deuxième numéro complet, tandis que chaque chiffre du deuxième numéro sera remplacé par la chaîne vide.

La dernière partie est à nouveau une fonction intégrée pour reconvertir de unaire en décimal.

Essayez-le en ligne!


2
J'aimerais pouvoir soumettre ma candidature à chaque fois que vous jouez au golf, beau travail!
Kritixi Lithos

Wow, cette nouvelle approche est incroyable. Je pense que tu gagnes. :) (Et cela me convainc encore plus que le caractère par défaut de $*devrait être _.)
Martin Ender

Btw, voici une solution ASCII uniquement avec le même nombre d'octets au cas où vous préférez: tio.run/nexus/retina#U9VwT/…
Martin Ender

1
Fait amusant: apparemment, j'avais compris l'astuce de mélanger moi-même un opérateur unaire et un opérateur décimal à un moment donné.
Martin Ender

1
J'ai essayé de le mettre à jour vers Retina 1.0 et grâce aux nouvelles limites et au nouvel opérateur de répétition, il n'a plus besoin que de 23 octets maintenant: tio.run/##K0otycxLNPyvpxqj4Z7wX8vOR9dQxyBBl0tPW4dLiyueS0UdSP7/… ... vous pouvez même multiplier des nombres positifs en un seul. stade maintenant ( .+,(.+)à $.($1**) mais c'est en fait plus d'octets ici.
Martin Ender


15

Brain-Flak , 56 octets

([({}<([({})<>])<>>)<>]){({}[()]<(({})<({}{})>)>)<>}{}{}

Cela doit être exécuté comme un programme complet car il n'est pas propre à la pile et les entrées doivent être les seuls éléments de l'une ou l'autre pile.

Essayez-le en ligne!


Explication: (appelez les entrées x et y)

Partie 1:

([({}<([({})<>])<>>)<>])

([                    ]) # Push negative x on top of:
      ([      ])         # negative y. After...
  ({}<            >)     # pushing x and...
        ({})             # y...
            <>  <>  <>   # on the other stack (and come back)

À ce stade, nous avons [x, y] sur une pile et [-x, -y] sur l'autre.

Partie 2:

{({}[()]<(({})<({}{})>)>)<>}{}{}
{                          }     # Loop until x (or -x) is 0
 ({}[()]<              >)        # Decrement x
         (({})<      >)          # Hold onto y
               ({}{})            # Add y and the number under it (initially 0)
                         <>      # Switch stacks
                            {}{} # Pop x and y leaving the sum

1
Hou la la! Certainement la réponse la plus impressionnante à ce jour
DJMcMayhem

@DJMcMayhem Et (légèrement modifié) il bat celui du wiki de 18 octets
Riley

Avez-vous accès en écriture au wiki brain-flak? J'adorerais télécharger une version plus courte.
DJMcMayhem

@DJMcMayhem Je n'ai pas accès. J'ai posté le plus court dans le salon de discussion Brain-Flak si vous voulez jeter un œil et le télécharger.
Riley

Je sais que ça fait un moment mais vous avez de la concurrence ;)
Wheat Wizard

11

JavaScript (ES6), 9 octets

ES6 a une fonction dédiée pour les entiers 32 bits, plus rapide que l' *opérateur plus générique .

Math.imul

Soit dit en passant, c'est aussi long que:

a=>b=>a*b

Génial, maintenant je connais Math.imul, merci!
chau giang

9

Brain-Flak , 56 54 52 octets

2 octets économisés grâce à une erreur rattrapée par Nitrodon

({}(<()>)<>)({<([{}({}())])><>([{}]([{}]))<>}<{}{}>)

Essayez-le en ligne!

Stack clean version, 62 60 octets

({}(<()>)(<>))({<([{}({}())])><>([{}]([{}]))<>}<{}{}<>{}{}>)

Essayez-le en ligne!

Explication

Cette explication est plus une explication de l'algorithme impliqué et laisse de côté tout code réel. Cela suppose que vous savez lire Brain-Flak avec compétence. Si vous avez besoin d'aide pour comprendre le code ou l'algorithme, je serais heureux de modifier ou de répondre si vous laissez un commentaire.

C'est un peu étrange et utilise des mathématiques étranges qui fonctionnent à peine. La première chose que j'ai faite a été de créer une boucle qui se terminerait toujours par étapes O (n) . La façon normale de le faire est de mettre n et -n sur des piles opposées et d'en ajouter un jusqu'à ce que l'un atteigne zéro, mais je l'ai fait d'une manière légèrement plus étrange. Dans ma méthode, je mets un compteur sous l'entrée et à chaque étape, j'incrémente le compteur, je l'ajoute à n et je retourne le signe de n .

Voyons un exemple. Dites n = 7

7  -8   6  -9   5 -10   4 -11   3 -12   2 -13   1 -14   0
0   1   2   3   4   5   6   7   8   9  10  11  12  13  14

Je ne le prouverai pas ici, mais cela se terminera toujours pour toute entrée et le fera en environ 2n étapes. En fait, il se terminera en 2n étapes si n est positif et 2n-1 étapes si n est négatif. Vous pouvez tester cela ici .

Maintenant, nous avons environ 2n étapes dans notre boucle, comment multiplions-nous par n ? Eh bien, voici de la magie mathématique. Voici ce que nous faisons: nous créons un accumulateur, à chaque étape du processus, nous ajoutons la deuxième entrée ( m ) à l'accumulateur et retournons le signe des deux, nous poussons ensuite le total sur toutes les boucles qui se produisent, c'est la produit.

Pourquoi diable est-ce le cas?

Passons en revue un exemple et j'espère qu'il deviendra clair. Dans cet exemple, nous multiplions 5 par 3 , je ne montrerai que les valeurs importantes

total       -> 0  -5   5 -10  10 -15  15
accumulator -> 0  -5  10 -15  20 -25  30
m           -> 5  -5   5  -5   5  -5   5

Espérons que le mécanisme soit apparent ici. Nous parcourons tous les multiples de m par ordre de leurs valeurs absolues. Vous remarquerez alors que le 2n e terme est toujours m * n et le terme avant toujours -m * n . Cela fait en sorte que notre boucle s'aligne parfaitement avec les résultats que nous voulons. Une heureuse coïncidence;)



8

R, 3 octets

'*'

Il s'agit d'une fonction qui prend exactement deux arguments. Exécuter en tant que '*'(a,b).

Voir aussi prodqui fait la même chose mais peut prendre un nombre arbitraire d'arguments.


Est-ce une expression valable à part entière? Sinon, il doit être soumis en tant que '*'.

@ ais523 Ah, vous avez raison, ce n'est pas une expression valable en soi. J'ai édité le message pour clarifier. Merci!
rturnbull

4
Pour les downvoters: Cela a été corrigé.
Rɪᴋᴇʀ

8

ArnoldC , 152 octets

HEY CHRISTMAS TREE c
YOU SET US UP 0
GET TO THE CHOPPER c
HERE IS MY INVITATION a
YOU'RE FIRED b
ENOUGH TALK
TALK TO THE HAND c
YOU HAVE BEEN TERMINATED

Essayez-le en ligne!


1
+1 ASSEZ PARLER (nouvelle ligne) PARLEZ À LA MAIN
MilkyWay90

8

Hexagonie , 9 octets

?{?/*!@'/

Essayez-le en ligne!

C'est en fait assez simple. Voici la version dépliée:

  ? { ?
 / * ! @
' / . . .
 . . . .
  . . .

Il /suffit de rediriger le flux de contrôle vers la deuxième ligne pour économiser des octets sur la troisième. Cela réduit le code à ce programme linéaire:

?{?'*!@

Ce code linéaire à lui seul serait en fait une solution valable si l'entrée était limitée à des nombres strictement positifs, mais en raison de la possibilité de résultats non positifs, il n'est pas garanti que cela se termine.

Le programme utilise trois bords de mémoire en forme de Y:

A   B
 \ /
  |
  C

Le pointeur de mémoire commence sur le bord Apointant vers le centre.

?   Read first input into edge A.
{   Move forward to edge B.
?   Read second input into edge B.
'   Move backward to edge C.
*   Multiply edges A and B and store the result in C.
!   Print the result.
@   Terminate the program.

J'ai exécuté une recherche par force brute pour des solutions de 7 octets (c'est-à-dire celles qui correspondent à la longueur de côté 2), et si je n'ai pas fait d'erreur (ou s'il y a une solution occupée-castor-y qui prend beaucoup de temps à compléter, dont je doute), il n’existe pas de solution sur 7 octets. Il pourrait y avoir une solution à 8 octets (par exemple en réutilisant ?ou en utilisant une seule commande de redirection au lieu de deux /), mais c'est au-delà de ce que ma recherche par force brute peut faire, et je n'en ai pas encore trouvé une à la main.


7

Piet , 16 octets

5bpiaibpikibptai

Interprète en ligne disponible ici.

Explication

Pour exécuter, collez le code ci-dessus dans la zone de texte sur le côté droit de la page liée. Ci-dessous est une représentation graphique de ce code avec la taille de codel 31. La grille est pour la lisibilité et peut interférer avec les interprètes Piet traditionnels.
Le code s'exécute linéairement de gauche à droite, en longeant le haut de l'image jusqu'au premier bloc vert, où le flux du programme se déplace vers la rangée centrale de codels. Le codel blanc seul blanc est nécessaire pour le déroulement du programme. Il pourrait être remplacé par un codel de toute couleur autre que le vert ou le bleu foncé, mais j'ai choisi le blanc pour la lisibilité.

Code Visualization

Instruction    Δ Hue    Δ Lightness    Stack
-----------    -----    -----------    -----
In (Number)    4        2              m
In (Number)    4        2              n, m
Multiply       1        2              m*n
Out (Number)   5        1              [Empty]
[Exit]         [N/A]    [N/A]          [Empty]

Si vous pensez que le texte n'est pas la meilleure façon de représenter un programme Piet ou avez un problème avec la taille d'octet des programmes Piet en général, veuillez faire connaître votre opinion dans la discussion sur les méta .


7

BitCycle -U , 68 octets

  >    > v
 ?+ >  +
Bv ?^ v ~
 \  v<CB~\v
 Cv  ^  <\/
^ <@=!   <
0A^

Essayez-le en ligne!

La multiplication de deux nombres n'est pas un problème trivial dans BitCycle, surtout lorsque les signes doivent être manipulés! Ceci est ma deuxième tentative; le premier (essentiellement le même algorithme, une disposition différente) était de 81 octets, il est donc tout à fait possible que celui-ci puisse également être raccourci.

Le programme prend les deux nombres comme arguments de ligne de commande et les renvoie vers stdout. L' -Uindicateur consiste à convertir les nombres décimaux en unaires signés , car BitCycle ne connaît que les 0 et les 1.

Explication

Cette explication suppose que vous comprenez les bases de BitCycle (voir Esolangs ou le fichier Lisez - moi de GitHub). Je baserai mon explication sur cette version non golfée, vue ici les -2temps de calcul 3:

Signed multiplication in BitCycle

Présentation

Les nombres unaires signés sont constitués du signe ( 0pour non positif, vide pour positif) suivi de la magnitude (un nombre de 1s égal à la valeur absolue du nombre). Pour multiplier deux d'entre eux, nous devons XOR les signes (produire un 0si exactement l'un d'eux est 0, ou rien si les deux ou aucun ne le sont), puis multiplier les grandeurs (et produire autant1 s). Nous réaliserons la multiplication par addition répétée.

Signer les bits

En partant des deux sources ?, nous séparons les signes des grandeurs utilisant +. 0s (bits de signe) tournent à gauche et sont dirigés le long de la rangée supérieure, tandis que 1s (magnitudes) tournent à droite et se retrouvent dans les deux Bcollecteurs.

La section qui gère les signes ressemble à ceci:

  v

  \  v
> \  /

! <

Si les deux nombres ne sont pas positifs, deux 0bits viennent du haut v. Le premier est réfléchi par le haut \, est envoyé vers le sud et réfléchi par le /. Pendant ce temps, le deuxième bit passe par le haut désactivé \et se reflète sur le bas \. Les deux bits se croisent, traversent directement les séparateurs désormais désactivés de la rangée inférieure et quittent le terrain de jeu.

Si un seul des nombres n'est pas positif, on 0arrive par le haut. Il rebondit autour des trois séparateurs et finit par repartir vers le nord, jusqu'à ce qu'il touche le vet qu'il soit à nouveau envoyé vers le sud. Cette fois, il passe à travers les séparateurs désactivés et atteint le <, qui l'envoie dans l'évier !.

Boucles pour stocker les grandeurs

La magnitude du premier nombre va dans le Bcollecteur dans cette section:

B v
  \
  C v
^   <

0 A ^

Avant l'ouverture du Bcollecteur, le Acollecteur libère le single 0qui y était placé, qui passe ensuite à la fin de la file d'attente dans B. Nous l'utilisons comme valeur de drapeau pour terminer la boucle lorsque tous les 1bits Bsont partis.

Chaque fois que les Bcollecteurs s'ouvrent, le \séparateur décolle le premier bit de la file d'attente et l'envoie à la logique de traitement au milieu. Le reste des bits entre C, et lorsque les Ccollecteurs s'ouvrent, ils sont renvoyés dans B.

L'amplitude du deuxième nombre va dans le Bcollecteur dans cette section:

v   ~
C B ~
    <

Lorsque les Bcollecteurs s'ouvrent, les bits entrent dans le dupneg inférieur ~. Les 1bits d' origine tournent à droite et sont envoyés vers l'ouest dans la logique de traitement au milieu. Les copies annulées 0tournent à gauche et frappent immédiatement un autre dupneg. Ici, le 0s tourne à droite et sort du terrain de jeu, tandis que le (maintenant doublement) 1s tourne à gauche et est envoyé dans C. Lorsqu'elles Cs'ouvrent, elles y retournent B.

Addition répétée

La logique de traitement centrale est cette partie:

   v
   v


@  =  !

Les bits des deux boucles (un du côté ouest et tout du côté est) sont envoyés au sud dans le commutateur =. Le timing doit être réglé de sorte que le bit de la boucle ouest arrive en premier. Si c'est le cas 1, le commutateur passe à }, envoyant les bits suivants vers l'est dans le récepteur !pour être émis. Une fois que tous les 1s ont disparu, nous obtenons le 0, qui change le commutateur en {. Cela envoie les bits suivants dans le @, qui termine le programme. En bref, nous émettons la grandeur (unaire) du deuxième nombre autant de fois qu'il y a de 1s dans la grandeur (unaire) du premier nombre.



6

Java 8, 10 9 octets

a->b->a*b

Essayez-le ici.

Java 7, 31 octets

int c(int a,int b){return a*b;}

Essayez-le ici.

En programme complet ( 99 90 octets) :

interface M{static void main(String[]a){System.out.print(new Long(a[0])*new Long(a[1]));}}

Essayez-le ici.


2
Il y a une faute de frappe dans votre programme complet, devrait être *installée +.
corvus_192

Vous n'avez pas besoin de parenthèses a,bdans l'expression lambda.
FlipTack

5

Pyth, 2 octets

*E

Essayez-le ici!

L'évaluation automatique de Pyth fait obstacle ici. Pour contourner cela, j'utilise une évaluation explicite pour l'un des arguments


Wow c'est cool. Ce sera utile à l'avenir.
Gurupad Mamadapur

5

TI-Basic, 2 octets

Très simple.

prod(Ans

1
Ans is not an allowed I/O method.
Mego

2
According to who? That link shows seven votes
Timtech

1
@Timtech it wasn't at the time of the comment but it was posted in chat so just became valid
Blue

Alright, thanks for the tip @muddyfish
Timtech

5

PHP, 21 bytes

<?=$argv[1]*$argv[2];

takes input from command line arguments. Also works with floats.


5

Retina, 39 35 bytes

Thanks to Leo for letting me use an idea of his that ended up saving 4 bytes.

[^-]

*\)`--

.+
$*
\G1
_
_|1+
$'
1

Input is linefeed-separated.

Try it online! (Space-separated test suite for convenience.)

Explanation

Les deux premières étapes affichent un signe moins si exactement l'une des deux entrées est négative. Ils le font sans modifier réellement l'entrée. Cela se fait en les regroupant dans la deuxième étape avec )et en les transformant en run-dry avec *. L' \option de la deuxième étape empêche l'impression d'un saut de ligne de fin.

[^-]

Tout d'abord, nous supprimons tout sauf les signes moins.

*\)`--

Ensuite, nous annulons les signes moins s'il en reste deux.

.+
$*

Maintenant, nous convertissons chaque ligne en la représentation unaire de sa valeur absolue. Cela supprimera le signe moins car il $*ne recherche que le premier nombre non négatif de la correspondance (c'est-à-dire qu'il ne connaît pas les signes moins et les ignore).

\G1
_

La première ligne est convertie en _, en faisant correspondre les 1s tant qu'ils sont adjacents à la correspondance précédente (par conséquent, nous ne pouvons pas faire correspondre les 1s sur la deuxième ligne, car le saut de ligne rompt cette chaîne).

_|1+
$'

This performs the actual multiplication. We replace each _ (on the first line) as well as the entire second line everything after that match. The _ matches will therefore include the entire second line (multiplying it by the number of 0s in the first line), and the second line will be removed because there is nothing after that match. Of course the result will also include some junk in the form of _s and linefeeds, but that won't matter.

1

We finish by simply counting the number of 1s in the result.


5

MATLAB, 5 4 bytes

@dot

dot takes the dot product of two vectors of equal length. If we feed it with two scalars, it will simply multiply the two numbers.

prod takes the product of the values in all rows of each column of a matrix. If the matrix is one-dimensional (i.e. a vector), then it acts along the non-singleton dimension, taking the product of all elements in the vector.

dot is one byte shorter than prod which is one byte shorter than the even more obvious builtin times.

Call it as such:

@dot
ans(3,4)
ans = 
   12


4

Perl 6, 4 bytes

&[*]

This is just the ordinary infix multiplication operator *, expressed as an ordinary function. As a bonus, if given one number it returns that number, and if given no numbers it returns 1, the multiplicative identity.


Alternative 4 UTF-8 byte solution: *×*
nwellnhof

4

><>, 5 Bytes

i|;n*

Takes input as an ascii character, outputs a number.

Explanation:

i                        | Get input.
 |                       | Mirror: Change the pointer's direction.
i                        | Get input again.
    *                    | Loop around to the right side. Multiply
   n                     | Print the value on the stack, as a number
  ;                      | End the program

You could also do

ii*n;

But I feel my solution is waaay cooler.

Another possibility is dropping the semicolon, which would result in the pointer bouncing off the mirror, hitting the print command, and throwing an error since the stack is empty.


4

Intel 8080 machine code, MITS Altair 8800, 28 bytes

This implements binary multiplication on the Intel 8080 CPU (c. 1974) which did not have multiplication or division instructions. Inputs are 8-bit values and the product is a 16-bit value returned in the BC register pair.

Here is the machine code along with step-by-step instructions to load the program into an Altair 8800 using the front panel switches.

Step    Switches 0-7    Control Switch  Instruction Comment
1                       RESET
2       00 001 110      DEPOSIT         MVI  C, 5   Load multiplier into C
3       00 000 101      DEPOSIT NEXT                value is 5
4       00 010 110      DEPOSIT NEXT    MVI  D, 16  Load multiplicand into D
5       00 010 000      DEPOSIT NEXT                value is 16
6       00 000 110      DEPOSIT NEXT    MVI  B, 0   clear B register (high byte of result)
7       00 000 000      DEPOSIT NEXT
8       00 011 110      DEPOSIT NEXT    MVI  E, 9   set loop counter E multiplier size
9       00 001 001      DEPOSIT NEXT                (8 bits + 1 since loop ends in middle)
10      01 111 001      DEPOSIT NEXT    MOV  A, C   move multiplier into A for shift
11      00 011 111      DEPOSIT NEXT    RAR         shift right-most bit to CF
12      01 001 111      DEPOSIT NEXT    MOV  C, A   move back into C
13      00 011 101      DEPOSIT NEXT    DCR  E      decrement loop counter
14      11 001 010      DEPOSIT NEXT    JZ   19 00  loop until E=0, then go to step 27
15      00 011 001      DEPOSIT NEXT
16      00 000 000      DEPOSIT NEXT
17      01 111 000      DEPOSIT NEXT    MOV  A, B   move sum high byte into A
18      11 010 010      DEPOSIT NEXT    JNC  14 00  add if right-most bit of 
19      00 010 100      DEPOSIT NEXT                multiplier is 1, else go to 22
20      00 000 000      DEPOSIT NEXT
21      10 000 010      DEPOSIT NEXT    ADD  D      add shifted sums
22      00 011 111      DEPOSIT NEXT    RAR         shift right new multiplier/sum
23      01 000 111      DEPOSIT NEXT    MOV  B, A   move back into B
24      11 000 011      DEPOSIT NEXT    JMP  08 00  go to step 10
25      00 001 000      DEPOSIT NEXT
26      00 000 000      DEPOSIT NEXT
27      11 010 011      DEPOSIT NEXT    OUT  255    display contents of A on data panel
28      11 111 111      DEPOSIT NEXT
30      01 110 110      DEPOSIT NEXT    HLT         Halt CPU
31                      RESET                       Reset program counter to beginning
32                      RUN
33                      STOP

Try it online!

If you've entered it all correctly, on the machine state drawer in the simulator your RAM contents will look like:

0000    0e 05 16 10 06 00 1e 09 79 1f 4f 1d ca 19 00 78 
0010    d2 14 00 82 1f 47 c3 08 00 d3 ff 76

Input

Multiplier in C register, and multiplicand into D. The stock Altair has no STDIN so input is by front panel switches only.

Output

The result is displayed on the D7-D0 lights (top right row) in binary.

5 x 16 = 80 (0101 0000)

enter image description here

4 x 5 = 20 (0001 0100)

enter image description here

7 x 9 = 63 (0011 1111)

enter image description here

8 x -9 = -72 (1011 1000)

enter image description here

Compatibility note: this should also run on the IMSAI 8080, though currently untested.




3

Clojure, 1 byte

*

:P As a bonus this works on any number of arguments:

[(*)
 (* 2)
 (* 2 3)
 (* 2 3 4)
 (* 2 3 4 5)] => [1 2 6 24 120]

Interestingly you can easily get its source code:

(source *)
(defn *
  "Returns the product of nums. (*) returns 1. Does not auto-promote
  longs, will throw on overflow. See also: *'"
  {:inline (nary-inline 'multiply 'unchecked_multiply)
   :inline-arities >1?
   :added "1.2"}
  ([] 1)
  ([x] (cast Number x))
  ([x y] (. clojure.lang.Numbers (multiply x y)))
  ([x y & more]
     (reduce1 * (* x y) more)))

3

Owk, 11 bytes

λx.λy.x*y

This can be assigned to a function like this:

multiply:λx.λy.x*y

and called like this:

result<multiply(a,b)

Does this not work? Please explain the doe vote.
Conor O'Brien

I wasn't the downvoter, but I think I can guess what happened: this is a very trivial question (and thus very heavily downvoted, but with many upvotes cancelling that out), and likely to attract people who downvote trivial questions. This answer's also fairly trivial, and it's likely that some of the people who downvote trivial questions also like to downvote trivial answers. (Personally, I prefer to leave trivial answers at 0, so I'm not voting either way on this one.)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.