Numeri facili da moltiplicare


34

Il tuo compito è determinare se due numeri sono facili da moltiplicare . Ciò significa che la loro lunga moltiplicazione base-10 non ha alcun valore di trasporto (raggruppamento) tra i valori dei luoghi, osservando sia i passaggi di moltiplicazione sia il passaggio di addizione. Questo accade quando ogni coppia di cifre moltiplicata dà 9 o meno e la somma di ogni colonna è 9 o meno.

Ad esempio, 331e 1021sono facili da moltiplicare:

   331
x 1021
------
+  331
  662
   0
331
------
337951

E lo stesso vale (come sempre) se moltiplichiamo nell'altro ordine:

  1021
x  331
------
+ 1021
 3063
3063
------
337951

Ma, 431e 1021non sono facili da moltiplicare, con carry che si verificano tra le colonne indicate:

   431
x 1021
------
+  431
  862
   0
431
------
440051
 ^^^

Inoltre, 12e 16non sono facili da moltiplicare perché si verifica un riporto quando si moltiplica 12 * 6per ottenere 72, anche se non si verificano carry nella fase di aggiunta.

  12
x 16
----
+ 72
 12
----
 192

Input: due numeri interi positivi o le loro rappresentazioni di stringa. Puoi presumere che non supereranno il tipo intero della tua lingua, né il loro prodotto.

Output: un valore coerente se sono facili da moltiplicare e un altro valore coerente in caso contrario.

Casi di prova: i primi 5 sono facili da moltiplicare, gli ultimi 5 no.

331 1021
1021 331
101 99
333 11111
243 201

431 1021
12 16
3 4
3333 1111
310 13

[(331, 1021), (1021, 331), (101, 99), (333, 11111), (243, 201)]
[(431, 1021), (12, 16), (3, 4), (3333, 1111), (310, 13)]

Classifica:


1
L'input per ciascun numero può essere un elenco di cifre?
dylnan,

@dylnan No, sebbene un elenco di caratteri sia valido per impostazione predefinita per l'opzione stringa.
xnor

Risposte:


14

Gelatina , 7 byte

Dæc/>9Ẹ

Provalo online!

Usa la convoluzione (che ho contribuito a Jelly: D)

Come funziona

Dæc/>9Ẹ
D        converts to decimal list
 æc      convolution
    >9Ẹ  checks if any number is greater than 9

o wow convolution: DI penso che questa sia la prima volta che vedo la convoluzione usata in un code-golf: D +1
HyperNeutrino,



@LuisMendo No, questa è una convoluzione diversa.
Erik the Outgolfer,

BTW È possibile sostituire gli ultimi 3 byte con <⁵Ạfor output senza un booleano NON eseguito su di esso.
Erik the Outgolfer,

8

JavaScript (ES6), 67 byte

Accetta input come 2 stringhe nella sintassi del curry (a)(b). Restituisce falseper facile o trueper non facile.

a=>b=>[...a].some((x,i,a)=>[...b].some(y=>(a[-++i]=~~a[-i]+x*y)>9))

Casi test


Alt. versione (imperfetta), 64 55 52 byte

Salvato 3 byte prendendo le stringhe, come suggerito da @Shaggy
Come sottolineato da @LeakyNun, questo metodo fallirebbe su alcuni numeri interi specifici di grandi dimensioni

Accetta input come 2 stringhe nella sintassi del curry (a)(b). Restituisce trueper facile o falseper non facile.

a=>b=>/^.(0.)*$/.test((g=n=>[...n].join`0`)(a)*g(b))

Casi test

Come?

L'idea qui è di esporre esplicitamente i carry inserendo zeri prima di ogni cifra di ciascun fattore.

Esempi:

  • 331 x 1021 diventa 30301 x 1000201 , che fornisce 30307090501 anziché 337951 . Aggiungendo uno zero iniziale al risultato e raggruppando tutte le cifre per 2, questo può essere scritto come 03 03 07 09 05 01 . Tutti i gruppi sono meno di 10 , il che significa che non ci sarebbe stato alcun riporto nella moltiplicazione standard.

  • 431 x 1021 diventa 40301 x 1000201 , che fornisce 40309100501 e può essere scritto come 04 03 09 10 05 01 . Questa volta, abbiamo un 10 che rivela un riporto nella moltiplicazione standard.


Possiamo ... Possiamo avere una spiegazione di base sull'algoritmo?
totalmente umano il

@totallyhuman Ho aggiunto una spiegazione. (Oops ... e anche risolto un bug.)
Arnauld il

1
Sembra che dovresti essere in grado di salvare 3 byte prendendo gli input come stringhe.
Shaggy,

3
Mi ci è voluta un'eternità per trovare un contro-esempio (teorico) che il tuo algoritmo fallirà: tio.run/##y0rNyan8/9/l8LJk/f///… ( 108nel mezzo si incasina il tuo algoritmo)
Leaky Nun

@LeakyNun Nice find. Sì, teoricamente può traboccare.
Arnauld,

6

Alice , 30 byte

/Q.\d3-&+k!*?-n/ o @
\ic/*2&w~

Provalo online!

Uscite 1per facile e 0per duro.

I numeri sono facili da moltiplicare se e solo se la somma delle cifre del prodotto è uguale al prodotto delle somme delle cifre.

/i    Input both numbers as a single string
.     Duplicate this string
/*    Coerce into two integers and multiply
2&w   Push return address twice (do the following three times)
~\Q     Swap the top two stack entries, then reverse the stack
        This produces a 3-cycle, and the first iteration coerces
        the original input string into two integers
c       Convert into individual characters
\d3-&+  Add all numbers on the stack except the bottom two (i.e., add all digits)
k     Return to pushed address (end loop)
      At this point, all three numbers are replaced by their digit sums
!*?   Multiply the digit sums of the original two numbers
-     Subtract the digit sum of the product
n     Logical negate: convert to 1 or 0
/o@   Output as character and terminate

4

MATL , 10 byte

,j!U]Y+9>a

Uscite 0per facile, 1per difficile.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

,       % Do twice
  j     %   Input as a string
  !     %   Transpose into a column vector of characters
  U     %   Convert each character to number. Gives a numeric column vector
]       % End
Y+      % Convolution, full size
9>      % Greatear than 1? Element-wise
a       % Any: true if there is some true entry. Implicitly display

4

R , 135 110 109 86 byte

function(m,n)any(convolve(m%/%10^(nchar(m):1-1)%%10,n%/%10^(1:nchar(n)-1)%%10,,"o")>9)

Provalo online!

Accetta input come stringhe.

È brutto ma funziona ™.

Questo ora utilizza un approccio di convoluzione, come nella risposta di Leaky Nun , quindi accetta input come numeri interi e restituisce TRUEnumeri difficili da moltiplicare e FALSEfacili da moltiplicare.

Ho sempre avuto dei problemi nel porting degli approcci di convoluzione in passato, ma oggi ho finalmente letto la documentazione :

Si noti che la solita definizione di convoluzione di due sequenze xed yè data daconvolve(x, rev(y), type = "o")

Che è solo stupido. Quindi l'estrazione delle cifre viene invertita ne si risolve in una porta della risposta di Leaky Nun.



4

JavaScript (Node.js) , 43 41 37 36 byte

Grazie a Dennis per l'idea di usare l'interpolazione di stringhe in questa risposta e risparmia 4 byte!

Grazie @ ØrjanJohansen per -1!

a=>b=>eval(`0x${a}*0x${b}<0x${a*b}`)

Provalo online!

Ovviamente quando la base di destinazione è inferiore alla base originale (come nella mia risposta Jelly, la base è 2) è <necessario capovolgere.


Congratulazioni per essere il primo a capire di usare la conversione di base, per la quale ti do la generosità!
xnor

3

Wolfram Language (Mathematica) , 75 66 65 56 byte

f:=#~FromDigits~x&
g:=Max@CoefficientList[f@#2f@#,x]<=9&

Provalo online!

Ricezione di 2 input di stringa

Spiegazione:

f:=#~FromDigits~x&                      (* Turns the number to a polynomial
                                           with the digits as coefficients      *)
g:=Max@CoefficientList[f@#2f@#,x]<=9&   (* Polynomial multiplication, and check
                                           whether all coefficients are smaller
                                           than 10                              *)

-9 per cambiare per usare la stringa come input

-1 per l'utilizzo dell'operatore infix

-9 Grazie a @MartinEnder per la Maxfunzione



3

Julia 0.6 , 30 byte

~x=any(conv(digits.(x)...).>9)

Provalo online!

L'input è una tupla di numeri, l'output è trueper numeri difficili da moltiplicare e falseper quelli facili.

. è un'applicazione con funzione di elemento.

...espande la tupla (di elenchi di cifre intere) in due input separati della convfunzione.



3

SNOBOL4 (CSNOBOL4) , 268 264 247 246 243 131 byte

	DEFINE('D(A)')
	M =INPUT
	N =INPUT
	OUTPUT =EQ(D(M) * D(N),D(M * N)) 1	:(END)
D	A LEN(1) . X REM . A	:F(RETURN)
	D =D + X	:(D)
END

Provalo online!

Porta l'approccio di Nitrodon . Penso che sia la prima volta che definisco una funzione in SNOBOL, Dper la somma delle cifre.

	DEFINE('D(A)')					;* function definition
	M =INPUT					;* read input
	N =INPUT					;* read input
	OUTPUT =EQ(D(M) * D(N),D(M * N)) 1	:(END)	;* if D(M)*D(N)==D(M*N),
							;* print 1 else print nothing. Goto End
D	A LEN(1) . X REM . A	:F(RETURN)		;* function body
	D =D + X	:(D)				;* add X to D
END

vecchia versione, 243 byte:

	M =INPUT
	N =INPUT
	P =SIZE(M)
	Q =SIZE(N)
	G =ARRAY(P + Q)
Z	OUTPUT =LE(P)	:S(E)
	M LEN(P) LEN(1) . A
	J =Q
Y	GT(J)	:F(D)
	N LEN(J) LEN(1) . B
	W =I + J
	X =G<W> + A * B
	G<W> =LE(A * B,9) LE(X,9) X	:F(E)
	J =J - 1	:(Y)
D	P =P - 1	:(Z)
E
END

Provalo online!

Input su STDIN separato da newline, output su STDOUT: un singolo newline per una facile moltiplicazione e nessun output per non facile da moltiplicare.

Questo non vincerà alcun premio ma presenta un altro approccio (beh, in realtà questo è l'approccio ingenuo). Non credo di poterlo scrivere in cubix, ma SNOBOL è abbastanza duro da lavorare così com'è.

Poiché accetta input come stringa, questo funzionerà per qualsiasi input con meno di 512 cifre ciascuno; Non sono sicuro al 100% di quanto ARRAYpossano essere grandi in SNOBOL.

INPUT è bufferato in questa versione di SNOBOL per avere una larghezza massima di 1024 caratteri; tutti gli altri personaggi vengono quindi persi. Sembra che un ARRAY possa essere abbastanza grande; ben oltre le 2048 celle necessarie.

	M =INPUT				;*read input
	N =INPUT				;*read input
	P =SIZE(M)				;*P = number of M's digits, also iteration counter for outer loop
	Q =SIZE(N)				;*Q = number of N's digits
	G =ARRAY(P + Q)				;*G is an empty array of length P + Q
Z	GE(P)	:F(T)				;*if P<0, goto T (outer loop condition)
	M LEN(P) LEN(1) . A			;*A = P'th character of M
	J =Q					;*J is the iteration counter for inner loop
Y	GT(J)	:F(D)				;*if J<=0, goto D (inner loop condition)
	N LEN(J) LEN(1) . B			;*B = J'th character of N
	W =I + J				;*W=I+J, column number in multiplication
	X =G<W> + A * B				;*X=G[W]+A*B, temp variable for golfing
	G<W> =LE(A * B,9) LE(X,9) X	:F(END)	;*if A*B<=9 and X<=9, G[W]=X otherwise terminate with no output
	J =J - 1	:(Y)			;*decrement J, goto Y
D	P =P - 1	:(Z)			;*decrement P, goto Z
T	OUTPUT =				;*set output to ''; OUTPUT automatically prints a newline.
END

2

Carbone , 38 byte

≔E⁺θη⁰ζFLθFLη§≔ζ⁺ικ⁺§ζ⁺ικ×I§θιI§ηκ‹⌈ζχ

Provalo online! Il collegamento è alla versione dettagliata del codice. Emette a -quando i numeri sono facili da moltiplicare. Spiegazione:

≔E⁺θη⁰ζ

Inizializzazione zsu una matrice abbastanza grande (somma di lunghezze di input) di zeri.

FLθFLη

Passa sopra gli indici degli input qe h.

§≔ζ⁺ικ⁺§ζ⁺ικ×I§θιI§ηκ

Esegui un passaggio della lunga moltiplicazione.

‹⌈ζχ

Verificare la presenza di carry.



2

Haskell, 82 81 byte

q=map$read.pure
f a=any(>9).concat.scanr((.(0:)).zipWith(+).(<$>q a).(*))(0<$a).q

I numeri sono presi come stringhe. Restituisce Falsese i numeri sono facili da moltiplicare e in Truealtro modo.

Provalo online!

Penso che sia abbastanza diverso dalla risposta di @ Laikoni . Come funziona:

q                    -- helper function to turn a string into a list of digits

f a =                -- main function, first number is parameter 'a' 
      scanr    .q    -- fold the following function from the right (and collect
                     -- the intermediate results in a list) into the list of
                     -- digits of the second number
            0<$a     --   starting with as many 0s as there are digits in 'a'
                     -- the function is, translated to non-point free:
  \n c->zipWith(+)((*n)<$>q a)$0:c 
                     -- 'n': next digit of 'b'; 'c': value so far
        (*n)<$>a     --    multiplay each digit in 'a' with 'n'
        0:c          --    prepend a 0 to 'c'
        zipWith(+)   --    add both lists element wise
                     --    (this shifts out the last digit of 'c' in every step)
   concat            -- flatten the collected lists into a single list
 any(>9)             -- check if any number is >9

Bella soluzione! Stavo cercando modi per sbarazzarmi dell'importazione, ma sono finiti ancora più a lungo.
Laikoni,

2

Haskell , 45 44 byte

Modificare:

  • -1 byte che cambia ==in <.

Ci ho pensato prima di guardare le altre risposte, poi ho scoperto che quella di Alice usava la stessa idea di base. Pubblicare comunque poiché è più breve delle altre risposte di Haskell.

?accetta due numeri interi e restituisce a Bool. Usa come 331?1021. Falsesignifica che la moltiplicazione è facile.

a?b=s(a*b)<s a*s b
s=sum.map(read.pure).show

Provalo online!

  • sè una funzione che calcola la somma delle cifre di un numero intero. ( read.pureconverte un carattere a una cifra in un numero intero).
  • Se una coppia di numeri è facile da moltiplicare, la somma delle cifre del prodotto è uguale al prodotto delle somme delle cifre.
  • Al contrario, qualsiasi trasporto durante la lunga moltiplicazione ridurrà la somma delle cifre del prodotto da quell'ideale.


1

Haskell , 123 byte

import Data.List
r=read.pure
a%b|l<-transpose[reverse$map((*r d).r)b++(0<$e)|d:e<-scanr(:)""a]=all(<10)$concat l++map sum l

Provalo online! Esempio di utilizzo: "331" % "1021"rese True.


1

Perl 5 , 100 + 2 ( -F) = 102 byte

push@a,[reverse@F]}{map{for$j(@{$a[0]}){$b[$i++].='+'.$_*$j}$i=++$c}@{$a[1]};map$\||=9>eval,@b;say$\

Provalo online!

produce false per facile, vero per non facile.


1

Gelatina , 8 byte

;PDḄµṪ⁼P

Provalo online!

Una porta della mia risposta Javascript . Non più breve della risposta esistente di Jelly perché Jelly ha una potente convoluzione integrata.

Prendi input come un elenco di due numeri. Restituisce 1per facile, 0per non facile.


Spiegazione:


;PDḄµṪ⁼P     Main link. Let input = [101, 99]
;P           Concatenate with product. Get [101, 99, 9999]
  D          Convert to decimal. Get [[1,0,1], [9,9], [9,9,9,9]]
   Ḅ         Convert from binary. Get [1 * 2^2 + 0 * 2^1 + 1 * 2^0, 
             9 * 2^1 + 9 * 2^0, 9 * 2^3 + 9 * 2^2 + 9 * 2^1 + 9 * 2^0]
             = [5, 27, 135]
    µ        With that value,
     Ṫ       Take the tail from that value. Get 135, have [5, 27] remain.
      ⁼      Check equality with...
       P       The product of the remaining numbers (5 and 17).

1

C (gcc) , 104 byte

Fondamentalmente fai una moltiplicazione "a mano" in r [] e imposta il valore di ritorno se una colonna diventa superiore a 9, poiché ciò significherebbe che si è verificato un carry.

Sorprendentemente, questo è stato più breve del mio primo tentativo che ha preso le stringhe come argomenti.

f(a,b){int*q,r[10]={0},*p=r,R=0,B;for(;a;a/=10)for(q=p++,B=b;B;B/=10)R|=(*q+++=a%10*(B%10))>9;return R;}

Provalo online!

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.