Moltiplica due numeri


21

Input: due numeri decimali. Questi possono essere dati al codice in input standard, come argomenti per il programma o la funzione o come elenco.

Output: il loro prodotto, come numero intero decimale. Ad esempio, l'input 5 16porterebbe all'output 80.

Restrizioni: nessuna scappatoia standard per favore. Questo è , la risposta nella quantità più bassa di byte vince.

Note: Layout rubato dalla mia precedente sfida, Aggiungi due numeri .

Casi 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

O come 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

Classifica


4
@FlipTack Supponendo che l'aggiunta e la moltiplicazione siano facili in qualsiasi lingua, il che non so se sia effettivamente vero.
Fatalizza il

16
Non credo sia giusto permettere la sfida "aggiungi due numeri" ma chiudi questa. Anche se è molto banale nella maggior parte dei linguaggi di programmazione, è ancora una valida sfida. Se questo è troppo ampio, anche la sfida "aggiungi due numeri" deve essere troppo ampia.
Mego

32
Chiunque è libero di sottovalutare le sfide banali se non le piacciono, ma questa è una sfida perfettamente valida e in tema e non è affatto "troppo ampia" (semmai, si potrebbe definire una sfida banale troppo stretta). Lo sto riaprendo. Detto questo, se qualcuno ritiene che sfide insignificanti insultino la propria intelligenza, le incoraggio a cercare lingue che rendano l'attività meno banale.
Martin Ender,

16
Prossimo prossimo: Sottrai due numeri!
Steenbergh,

7
@wat Non lasciando il fondo del barilotto non raschiato, eh?
Gareth,

Risposte:


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

*

È possibile modificare questa risposta per aggiungere altre lingue per le quali *è una risposta valida.


Polygot, 05AB1E e come altre 5 lingue.
Magic Octopus Urn

13
Ho modificato Underload in questo. È forse il più interessante di questi, perché Underload non ha un metodo a 1 byte per eseguire sottrazioni, divisioni o addizioni.


Questo non è valido in Pyth. Pyth non accetta input impliciti in questo modo.
Isaacg,

Aggiunta Julia, ad es.*(5,16)
gggg

32

C (GCC), 13 byte

Non funziona su tutte le implementazioni, ma va bene.

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

Provalo su TIO!


6
Aspetta, questo dovrebbe in qualche modo tornare a? Non capisco ...
Erik the Outgolfer

2
Una spiegazione di come funziona sarebbe utile. ( aè una variabile dello stack locale in f()- perché viene restituito il suo valore?). +1, a proposito - abuso molto intelligente dell'ABI.
Trauma digitale

6
@EriktheOutgolfer La returnparola chiave inserisce semplicemente il redult del suo argomento nel registro EAX. In questo caso, l'eseguibile generato esegue il calcolo a*bin quel registro, quindi returnnon fa nulla.
Dennis,

7
Ehi, quello era il mio trucco! codegolf.stackexchange.com/a/106067/18535 :-)
GB

12
Sono così felice di vedere C in cima per una volta! In realtà puoi radere circa 9 byte semplicemente sostituendo la f(a,b){a*=b;}parte con 1##&e quindi semplicemente cambiando la tua lingua in Mathematica.
Albert Renshaw,

21

Beatnik , 888 byte

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

Provalo online!

Sto usando l'interprete C perché l'interprete Python su TIO esegue fastidiosamente l'indirizzo se la condizione per saltare all'indietro non è soddisfatta. Una soluzione semplice per l'interprete Python è quella di riempire alcuni nops per rendere l'indirizzo nop. Credo che nessuno dei due sia corretto:

                                   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'input dovrebbe essere due numeri interi separati da uno spazio, senza trascinare le nuove righe.

Questa risposta funziona in teoria per tutti i numeri interi, se ogni cella può memorizzare un valore arbitrariamente grande, non limitato a 0 - 255. Ma trabocca se | A | + | B | > 22. E funziona molto lentamente se | A | + | B | > 6. Quindi non ci sono molti casi che puoi effettivamente testare e una soluzione if-else per quei casi potrebbe essere ancora più breve.

L'idea è di calcolare i numeri triangolari T (N) = N (N + 1) / 2 decrementando il valore su 0 e sommando tutti i valori intermedi. Quindi possiamo ottenere la risposta A * B = T (A + B) - T (A) - T (B).

Ma è difficile calcolare tutti e 3 i valori. Lo fa innanzitutto calcolando T (A + B) - A, lasciando una copia di A nello stack da aggiungere in seguito, e utilizzando l'input B. Quindi, ricorsivamente, trova il numero triangolare più grande più piccolo di quello, che è T ( A + B-1) ad eccezione dei casi speciali zero. Possiamo tornare indietro B = T (A + B) - A - T (A + B-1) e calcolare T (B) da lì.

Un numero N è un numero triangolare se è uguale al massimo numero triangolare più piccolo di N, più il numero di numeri triangolari non negativi più piccoli di N. Questo funziona in O (2 ^ (T (A + B) -A)) ed è la parte più lenta del programma.

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. Solo ... woah. Ho messo la taglia, la riceverai tra 7 giorni.
NieDzejkob,

19

Mathematica, 4 byte

1##&

Esempio di utilizzo: 1##&[7,9]ritorna 63. In effetti, questa stessa funzione moltiplica un numero qualsiasi di argomenti di qualsiasi tipo.

Come sanno i codegolfer di Mathematica, questo funziona perché si ##riferisce all'intera sequenza di argomenti a una funzione e la concatenazione in Mathematica (spesso) rappresenta la moltiplicazione; quindi 1##fa riferimento a (1 volte) il prodotto di tutti gli argomenti della funzione. Il &è solo breve per il Functioncomando che definisce una funzione pura (senza nome).

All'interno di un altro codice, il simbolo comune *funge da moltiplicazione. Lo stesso fa uno spazio, così 7 9viene interpretato come 7*9(in effetti, l'attuale versione REPL di Mathematica mostra effettivamente spazi come segni di moltiplicazione!). Ancora meglio, tuttavia, se Mathematica è in grado di dire dove inizia un token e ne termina un altro, allora non sono necessari byte per un operatore di moltiplicazione: 5yviene automaticamente interpretato come 5*ye 3.14Log[9]come 3.14*Log[9].


Cosa rende ##&non valido?
Lynn,

##&restituisce la sua lista di argomenti come un oggetto 'Sequence' - adatto per collegarsi ad altre funzioni che accettano più argomenti. In questo contesto, ##&non fa nulla al suo elenco di argomenti; vogliamo che tale elenco venga moltiplicato insieme.
Greg Martin,

19

Retina , 38 37 31 byte

Approccio completamente nuovo, quello vecchio è sotto.

M!`-
*\)`-¶-

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

Provalo online!

Spiegazione

Innanzitutto, trattiamo il segno:

M!`-

corrisponde a tutti -nella stringa e li restituisce separati da nuove righe

*\)`-¶-

(con una seguente riga vuota)
*\)significa che il risultato di questo e le fasi precedenti dovrebbero essere stampate senza una nuova riga, e quindi la stringa ripristinata a quello che era prima (la stringa di input). La parte rimanente ne rimuove due -separate da una nuova riga.

Quindi convertiamo il primo numero in unario:

.* 
$*_

(c'è uno spazio alla fine della prima riga). Usiamo _come nostra cifra unaria in questo caso, perché la cifra standard 1può essere presente nel secondo numero e questo sarebbe in conflitto in seguito.

Ora arriviamo alla moltiplicazione effettiva:

_
$'$*_

Ognuno _è sostituito dalla rappresentazione unaria di tutto ciò che lo segue (ancora usando _come cifra unaria). Poiché la conversione in unario ignora i caratteri non numerici, questo ripeterà la rappresentazione unaria del secondo numero per "volte il primo numero". Il secondo numero rimarrà nella rappresentazione decimale alla fine della stringa.

Alla fine, con un singolo _restituiamo il numero di _nella stringa, che sarà il risultato della moltiplicazione.


Risposta precedente: (avviso: emette una stringa vuota quando dovrebbe essere emessa 0)

Retina ,  45  42 41 byte

Facciamo un gioco! Moltiplica i numeri relativi con una lingua che non ha operatori aritmetici e supporto limitato solo per i numeri naturali ... Sembra divertente :)

O^`^|-
--

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

Spiegazione

Le prime tre righe trattano il segno:

O^`^|-

Questo ordina Oe quindi inverte ^tutte le stringhe corrispondenti alla regex ^|-. In pratica, questo corrisponde alla stringa vuota all'inizio e all'eventuale segno meno prima del secondo numero e li riordina posizionando la stringa vuota al posto del segno meno. Dopodiché, tutti -sono all'inizio della stringa e una coppia di essi può essere rimossa facilmente con le due righe successive.

Dopodiché, utilizziamo un builtin per convertire i numeri in rappresentazione unaria e quindi arriva la moltiplicazione effettiva:

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

Abbiniamo qualsiasi 1e sostituiamo ciascuno di essi con tutto il 1dopo uno spazio seguente. Ogni cifra del primo numero verrà sostituita dal secondo numero intero, mentre ogni cifra del secondo numero verrà sostituita dalla stringa vuota.

L'ultima parte è di nuovo un builtin per riconvertire da unario a decimale.

Provalo online!


2
Vorrei poter votare l'invio ogni volta che lo giochi, bel lavoro!
Kritixi Lithos,

Caspita, quel nuovo approccio è sorprendente. Penso che tu vinca. :) (E mi convince ancora di più che $*dovrebbe essere il personaggio predefinito _.)
Martin Ender

A proposito, ecco una soluzione solo ASCII con lo stesso numero di byte nel caso in cui preferisci: tio.run/nexus/retina#U9VwT/…
Martin Ender,

1
Curiosità: apparentemente avevo capito il trucco di mescolare un operatore unario e uno decimale a un certo punto.
Martin Ender,

1
Ho provato ad aggiornare questo a Retina 1.0 e grazie ai nuovi limiti e al nuovo operatore di ripetizione, ora ha bisogno solo di 23 byte: tio.run/##K0otycxLNPyvpxqj4Z7wX8vOR9dQxyBBl0tPW4dLiyueS0UdSP7/… ... puoi anche fare una moltiplicazione di numeri positivi stage ora ( .+,(.+)a $.($1**) ma in realtà qui ci sono più byte.
Martin Ender


15

Brain-Flak , 56 byte

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

Questo deve essere eseguito come programma completo in quanto non è pulito dallo stack e gli input devono essere gli unici elementi in entrambi gli stack.

Provalo online!


Spiegazione: (chiamare gli ingressi xey)

Parte 1:

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

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

A questo punto abbiamo [x, y] su uno stack e [-x, -y] sull'altro.

Parte 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
Wow! Sicuramente la risposta più impressionante finora
DJMcMayhem

@DJMcMayhem E (leggermente modificato) batte quello sul wiki di 18 byte
Riley

Hai accesso in scrittura al wiki brain-flak? Mi piacerebbe caricare una versione più breve.
DJMcMayhem

@DJMcMayhem Non ho accesso. Ho pubblicato quello più breve nella chat di Brain-Flak se vuoi dare un'occhiata e caricarlo.
Riley,

So che è passato un po 'di tempo, ma hai un po' di concorrenza ;)
Wheat Wizard

11

JavaScript (ES6), 9 byte

ES6 ha una funzione dedicata per numeri interi a 32 bit, più veloce *dell'operatore più generico .

Math.imul

Per inciso, questo è solo quanto:

a=>b=>a*b

Fantastico, ora conosco Math.imul, grazie!
Chau Giang,

9

Brain-Flak , 56 54 52 byte

2 byte salvati grazie a un errore rilevato da Nitrodon

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

Provalo online!

Stack versione pulita, 62 60 byte

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

Provalo online!

Spiegazione

Questa spiegazione è più una spiegazione dell'algoritmo coinvolto e lascia fuori qualsiasi codice reale. Presuppone che tu sappia leggere con competenza Brain-Flak. Se hai bisogno di aiuto per comprendere il codice o l'algoritmo, sarei felice di modificare o rispondere se lasci un commento.

Questo è un po 'strano e usa una strana matematica che a malapena risolve. La prima cosa che ho fatto è stato fare un loop che sarebbe sempre terminato con i passaggi O (n) . Il modo normale per farlo è quello di mettere n e -n su pile opposte e aggiungerne una a ciascuna fino a quando non si arriva a zero, tuttavia l'ho fatto in un modo leggermente più strano. Nel mio metodo ho messo un contatore sotto l'input e ad ogni passo incremento il contatore lo aggiungo a n e capovolgere il segno di n .

Vediamo un esempio. Dì 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

Non lo dimostrerò qui, ma questo terminerà sempre per qualsiasi input e lo farà in circa 2n passaggi. In effetti terminerà con passaggi 2n se n è positivo e passi 2n-1 se n è negativo. Puoi provarlo qui .

Ora abbiamo circa 2n passaggi nel nostro ciclo come possiamo moltiplicare per n ? Bene, ecco un po 'di magia matematica. Ecco cosa facciamo: facciamo un accumulatore, ad ogni fase del processo aggiungiamo il secondo input ( m ) all'accumulatore e capovolgiamo il segno di entrambi, quindi spingiamo il totale su tutti i loop che si verificano, questo è il Prodotto.

Perché mai è così?

Bene, facciamo un esempio e speriamo che diventi chiaro. In questo esempio stiamo moltiplicando 5 per 3 , mostrerò solo i valori importanti

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

Speriamo che il meccanismo sia evidente qui. Stiamo esaminando tutti i multipli di m in ordine di valori assoluti. Sarà quindi notare che il 2n esimo termine è sempre m * n e il termine prima sempre * -m n . Questo rende il nostro loop perfettamente in linea con i risultati desiderati. Un po 'di una felice coincidenza;)



8

R, 3 byte

'*'

Questa è una funzione che accetta esattamente due argomenti. Esegui come '*'(a,b).

Vedi anche prodche fa la stessa cosa ma può accettare un numero arbitrario di argomenti.


È un'espressione valida a sé stante? In caso contrario, deve essere inviato come '*'.

@ ais523 Ah, hai ragione, non è un'espressione valida da sola. Ho modificato il post per chiarire. Grazie!
rturnbull,

4
Ai downvoter: questo è stato risolto.
Rɪᴋᴇʀ

8

ArnoldC , 152 byte

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

Provalo online!


1
+1 ENOUGH TALK (newline) PARLA ALLA MANO
MilkyWay90

8

Esagonia , 9 byte

?{?/*!@'/

Provalo online!

Questo è in realtà abbastanza semplice. Ecco la versione spiegata:

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

Il /solo reindirizzare il flusso di controllo per la seconda linea di salvare byte sul terzo. Ciò riduce il codice a questo programma lineare:

?{?'*!@

Questo codice lineare da solo sarebbe effettivamente una soluzione valida se l'input fosse limitato a numeri strettamente positivi, ma a causa della possibilità di risultati non positivi, questo non è garantito per terminare.

Il programma utilizza tre bordi di memoria a forma di Y:

A   B
 \ /
  |
  C

Il puntatore della memoria inizia sul bordo Arivolto verso il centro.

?   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.

Ho eseguito una ricerca della forza bruta per soluzioni a 7 byte (ovvero quelle che si adattano alla lunghezza laterale 2) e se non ho commesso un errore (o c'è una soluzione trafficata-castoro che richiede molto tempo per il completamento, di cui dubito) quindi non esiste una soluzione a 7 byte. Potrebbe esserci una soluzione a 8 byte (ad esempio riutilizzando ?o utilizzando solo un comando di reindirizzamento anziché due /), ma questo è al di là di ciò che la mia ricerca della forza bruta può fare e non ne ho ancora trovato uno a mano.


7

Piet , 16 byte

5bpiaibpikibptai

Interprete online disponibile qui.

Spiegazione

Per eseguire, incolla il codice sopra nella casella di testo sul lato destro della pagina collegata. Di seguito è riportata una rappresentazione grafica di questo codice con dimensioni del codice 31. La griglia è leggibile e può interferire con gli interpreti Piet tradizionali.
Il codice scorre in modo lineare da sinistra a destra, andando lungo la parte superiore dell'immagine fino al primo blocco verde, dove il flusso del programma si sposta sulla riga centrale di codici. Il codice bianco solitario bianco è necessario per il flusso del programma. Potrebbe essere sostituito con un codice di qualsiasi colore diverso dal verde o blu scuro, ma ho scelto il bianco per la leggibilità.

Visualizzazione del codice

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]

Se ritieni che il testo non sia il modo migliore per rappresentare un programma Piet o hai un problema con la dimensione in byte dei programmi Piet in generale, ti preghiamo di far conoscere la tua opinione nella discussione su meta .


7

BitCycle -U , 68 byte

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

Provalo online!

Moltiplicare due numeri non è un problema banale in BitCycle, specialmente quando i segni devono essere gestiti! Questo è il mio secondo tentativo; il primo (essenzialmente lo stesso algoritmo, layout diverso) era di 81 byte, quindi è del tutto possibile accorciare anche questo.

Il programma accetta i due numeri come argomenti della riga di comando e li invia a stdout. Il -Uflag è di convertire i numeri decimali in unari firmati , poiché BitCycle conosce solo 0 e 1.

Spiegazione

Questa spiegazione presuppone che tu comprenda le basi di BitCycle (vedi Esolangs o il file Leggimi di GitHub). Baserò la mia spiegazione su questa versione non golfata, vista qui i -2tempi di calcolo 3:

Moltiplicazione firmata in BitCycle

Panoramica

I numeri unari firmati sono costituiti dal segno ( 0per non positivo, vuoto per positivo) seguito dalla magnitudine (un numero di 1s pari al valore assoluto del numero). Per moltiplicare due di questi, abbiamo bisogno di XOR i segni (emettere un 0se esattamente uno di essi è 0, o niente se entrambi o nessuno lo sono) e quindi moltiplicare le magnitudini (e produrre così tanti1 s). Otterremo la moltiplicazione per aggiunta ripetuta.

Bit di segno

A partire dalle due fonti ?, abbiamo diviso i segni dalle magnitudini usando +. 0s (bit di segno) gira a sinistra e sono diretti lungo la fila superiore, mentre 1s (magnitudo) gira a destra e finisce nei due Braccoglitori.

La sezione che gestisce i segni è simile alla seguente:

  v

  \  v
> \  /

! <

Se entrambi i numeri non sono propositivi, due 0bit entrano dall'alto v. Il primo si riflette sulla parte superiore \, viene inviato verso sud e si riflette sulla /. Nel frattempo, il secondo bit passa attraverso la parte superiore disattivata \e si riflette sulla parte inferiore\ . I due bit si incrociano, passano direttamente attraverso gli splitter ora disattivati ​​nella riga inferiore e scendono dal campo di gioco.

Se solo uno dei numeri non è positivo, si 0arriva dall'alto. Rimbalza intorno a tutti e tre i divisori e finisce nuovamente verso nord, fino a quando non colpisce ve viene nuovamente inviato a sud. Questa volta, passa attraverso gli splitter disattivati ​​e raggiunge il <, che lo invia nel lavandino !.

Anelli per conservare le magnitudini

L'entità del primo numero viene inserita nel Braccoglitore in questa sezione:

B v
  \
  C v
^   <

0 A ^

Prima che il Braccoglitore si apra, il Araccoglitore rilascia il singolo 0che è stato inserito in esso, che quindi va alla fine della coda B. Lo useremo come valore flag per terminare il loop quando tutti i 1bit in Bsono spariti.

Ogni volta che i Bcollettori si aprono, lo \splitter si stacca dal primo bit dalla coda e lo invia alla logica di elaborazione nel mezzo. Il resto dei bit entra Ce, quando i Ccollettori si aprono, vengono rimandati B.

L'entità del secondo numero viene inserita nel Braccoglitore in questa sezione:

v   ~
C B ~
    <

Quando i Bcollettori si aprono, i bit vanno nel dupneg inferiore ~. I 1bit originali girano a destra e vengono inviati a ovest nella logica di elaborazione nel mezzo. Le copie negate 0girano a sinistra e colpiscono immediatamente un altro dupneg. Qui la 0s gira a destra ed esce dal campo di gioco, mentre la (ora doppiamente negata) 1s gira a sinistra e viene inviata C. Quando si Capre, tornano in B.

Aggiunta ripetuta

La logica di elaborazione centrale è questa parte:

   v
   v


@  =  !

I bit di entrambi gli anelli (uno dal lato occidentale e tutto dal lato orientale) vengono inviati a sud nell'interruttore =. Il tempismo deve essere impostato in modo che il bit del circuito occidentale arrivi prima. Se è a 1, l'interruttore cambia in }, inviando i seguenti bit verso est nel sink !per essere emessi. Una volta che tutti gli 1s sono andati, otteniamo il 0, che cambia l'interruttore in {. Questo invia i seguenti bit in @, che termina il programma. In breve, produciamo la grandezza (unaria) del secondo numero tante volte quante sono le 1s nella grandezza (unaria) del primo numero.



6

Java 8, 10 9 byte

a->b->a*b

Provalo qui.

Java 7, 31 byte

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

Provalo qui.

Come programma completo ( 99 90 byte) :

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

Provalo qui.


2
C'è un errore di battitura nel tuo programma completo, dovrebbe essere *instaurato +.
corvus_192,

Non hai bisogno di parentesi a,bnell'espressione lambda.
FlipTack

5

Pyth, 2 byte

*E

Provalo qui!

La valutazione automatica di Pyth si frappone qui. Per aggirare il problema, sto usando una valutazione esplicita per uno degli argomenti


Wow che bello. Questo sarà utile in futuro.
Gurupad Mamadapur,


5

PHP, 21 byte

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

accetta input dagli argomenti della riga di comando. Funziona anche con i galleggianti.


5

Retina , 39 35 byte

Grazie a Leo per avermi permesso di usare una sua idea che ha finito per salvare 4 byte.

[^-]

*\)`--

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

L'ingresso è separato dall'alimentazione di linea.

Provalo online! (Suite di test separata dallo spazio per comodità.)

Spiegazione

I primi due stadi stampano un segno meno se esattamente uno dei due ingressi è negativo. Lo fanno senza cambiare effettivamente l'input. Questo viene fatto raggruppandoli nel secondo stadio con )e trasformandoli in una corsa a secco con *. L' \opzione sul secondo stadio impedisce la stampa di un avanzamento riga finale.

[^-]

Innanzitutto, rimuoviamo tutto tranne i segni meno.

*\)`--

Quindi cancelliamo i segni meno se ne rimangono due.

.+
$*

Ora convertiamo ogni riga nella rappresentazione unaria del suo valore assoluto. Questo eliminerà il segno meno perché $*cerca solo il primo numero non negativo nella partita (cioè non conosce i segni meno e li ignora).

\G1
_

La prima riga viene convertita in _, abbinando le singole 1s purché le loro adiacenti alla corrispondenza precedente (quindi, non possiamo abbinare le 1s sulla seconda riga, perché l'alimentazione della linea interrompe questa catena).

_|1+
$'

Ciò esegue la moltiplicazione effettiva. Sostituiamo ogni _(sulla prima riga) e l'intera seconda riga tutto dopo quella partita. Le _corrispondenze includeranno quindi l'intera seconda riga (moltiplicandola per il numero di 0s nella prima riga) e la seconda riga verrà rimossa perché non c'è nulla dopo quella corrispondenza. Ovviamente il risultato includerà anche un po 'di spazzatura sotto forma di _s e linefeed, ma non importa.

1

Concludiamo semplicemente contando il numero di 1s nel risultato.


5

MATLAB, 5 4 byte

@dot

dotprende il prodotto punto di due vettori di uguale lunghezza. Se lo alimentiamo con due scalari, moltiplica semplicemente i due numeri.

prodprende il prodotto dei valori in tutte le righe di ogni colonna di una matrice. Se la matrice è monodimensionale (cioè un vettore), allora agisce lungo la dimensione non singleton, prendendo il prodotto di tutti gli elementi nel vettore.

dotè un byte più corto di quello prodche è un byte più corto del builtin ancora più ovvio times.

Chiamalo come tale:

@dot
ans(3,4)
ans = 
   12


4

Perl 6 , 4 byte

&[*]

Questo è solo l'operatore di moltiplicazione infisso ordinario *, espresso come una normale funzione. Come bonus, se dato un numero restituisce quel numero, e se non viene dato alcun numero restituisce 1, l'identità moltiplicativa.


Soluzione alternativa a 4 UTF-8 byte:*×*
nwellnhof

4

> <>, 5 byte

i|;n*

Accetta l'input come carattere ASCII, genera un numero.

Spiegazione:

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

Potresti anche fare

ii*n;

Ma sento la mia soluzione è mooolto più fresco.

Un'altra possibilità è l'eliminazione del punto e virgola, che comporterebbe il rimbalzo del puntatore dallo specchio, il comando di stampa e il lancio di un errore poiché lo stack è vuoto.


4

Codice macchina Intel 8080 , MITS Altair 8800 , 28 byte

Questo implementa la moltiplicazione binaria sulla CPU Intel 8080 (c. 1974) che non aveva istruzioni di moltiplicazione o divisione. Gli input sono valori a 8 bit e il prodotto è un valore a 16 bit restituito nella BCcoppia di registri.

Ecco il codice macchina insieme alle istruzioni passo-passo per caricare il programma in un Altair 8800 utilizzando gli interruttori del pannello frontale.

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

Provalo online!

Se hai inserito tutto correttamente, sul cassetto di stato della macchina nel simulatore il contenuto della tua RAM sarà simile a:

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

Ingresso

Moltiplicatore nel Cregistro e multiplicand in D. Lo stock di Altair non ha STDINquindi input è solo da interruttori del pannello frontale.

Produzione

Il risultato viene visualizzato sul D7- D0luci (riga in alto a destra) in binario.

5 x 16 = 80 (0101 0000)

inserisci qui la descrizione dell'immagine

4 x 5 = 20 (0001 0100)

inserisci qui la descrizione dell'immagine

7 x 9 = 63 (0011 1111)

inserisci qui la descrizione dell'immagine

8 x -9 = -72 (1011 1000)

inserisci qui la descrizione dell'immagine

Nota di compatibilità: questo dovrebbe funzionare anche su IMSAI 8080 , sebbene attualmente non testato.




3

Clojure, 1 byte

*

: P Come bonus funziona su qualsiasi numero di argomenti:

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

È interessante notare che puoi facilmente ottenere il suo codice sorgente:

(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 byte

λx.λy.x*y

Questo può essere assegnato a una funzione come questa:

multiply:λx.λy.x*y

e chiamato così:

result<multiply(a,b)

Questo non funziona? Per favore, spiega il voto di Doe.
Conor O'Brien,

Non ero il downvoter, ma penso di poter indovinare cosa è successo: questa è una domanda molto banale (e quindi fortemente ridimensionata, ma con molti voti che lo annullano), e probabilmente attirerà persone che votano domande banali. Questa risposta è anche abbastanza banale, ed è probabile che ad alcune delle persone che votano a bassa domanda piacciano anche quelle a basso valore. (Personalmente, preferisco lasciare risposte insignificanti a 0, quindi non voterò in nessun modo su questo.)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.