Einfach zu multiplizierende Zahlen


34

Ihre Aufgabe ist es, festzustellen, ob zwei Zahlen leicht zu multiplizieren sind . Dies bedeutet, dass ihre lange Multiplikation zur Basis 10 kein Übertragen (Umgruppieren) zwischen Ortswerten aufweist, wenn sowohl die Multiplikationsschritte als auch der Additionsschritt betrachtet werden. Dies geschieht, wenn jedes multiplizierte Ziffernpaar 9 oder weniger ergibt und die Summe jeder Spalte 9 oder weniger beträgt.

Zum Beispiel 331und 1021sind leicht zu multiplizieren:

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

Und dasselbe gilt (wie immer), wenn wir in der anderen Reihenfolge multiplizieren:

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

Aber, 431und 1021sind nicht leicht zu multiplizieren, mit Träge geschieht zwischen den Spalten angezeigt:

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

Auch 12und 16ist nicht leicht zu vermehren , weil ein Übertrag geschieht , wenn die Multiplikation 12 * 6zu erhalten 72, auch wenn nicht passieren trägt im Additionsschritt.

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

Eingabe: Zwei positive ganze Zahlen oder deren Zeichenfolgendarstellungen. Sie können davon ausgehen, dass weder der Integer-Typ Ihrer Sprache noch deren Produkt überläuft.

Ausgabe: Ein konsistenter Wert, wenn sie leicht zu multiplizieren sind, und ein anderer konsistenter Wert, wenn nicht.

Testfälle: Die ersten 5 sind leicht zu multiplizieren, die letzten 5 nicht.

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)]

Bestenliste:


1
Kann die Eingabe für jede Nummer eine Ziffernliste sein?
Dylnan

@dylnan Nein, obwohl eine Liste von Zeichen standardmäßig für die Zeichenfolgeoption gültig ist.
Xnor

Antworten:


14

Gelee , 7 Bytes

Dæc/>9Ẹ

Probieren Sie es online!

Verwendet Faltung (die ich zu Jelly beigetragen habe: D)

Wie es funktioniert

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

o Wow Convolution: Ich denke, dies ist das erste Mal, dass ich Convolution in einem
Codegolf sehe



@ LuisMendo Nein, das ist eine andere Faltung.
Erik der Outgolfer

Übrigens: Sie können die letzten 3 Bytes durch <⁵Ạfür die Ausgabe ersetzen, ohne dass ein Boolescher Wert für NOT ausgeführt wird.
Erik der Outgolfer

8

JavaScript (ES6), 67 Byte

Nimmt Eingaben als 2 Zeichenfolgen in der Currying-Syntax an (a)(b). Rückgabe falseeinfach oder truenicht einfach.

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

Testfälle


Alt. version (fehlerhaft), 64 55 52 bytes

Durch die Verwendung von Zeichenfolgen wurden 3 Bytes gespart, wie von @Shaggy vorgeschlagen.
Wie von @LeakyNun hervorgehoben, schlägt diese Methode bei einigen großen spezifischen Ganzzahlen fehl

Nimmt Eingaben als 2 Zeichenfolgen in der Currying-Syntax an (a)(b). Rückgabe trueeinfach oder falsenicht einfach.

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

Testfälle

Wie?

Die Idee hier ist, Überträge durch Einfügen von Nullen vor jeder Ziffer jedes Faktors explizit freizulegen.

Beispiele:

  • 331 x 1021 wird zu 30301 x 1000201 , was 30307090501 anstelle von 337951 ergibt . Durch Hinzufügen einer führenden Null zum Ergebnis und Gruppieren aller Ziffern nach 2 kann dies als 03 03 07 09 05 01 geschrieben werden . Alle Gruppen sind kleiner als 10 , was bedeutet, dass die Standardmultiplikation keinen Übertrag enthält.

  • 431 x 1021 wird zu 40301 x 1000201 , was 40309100501 ergibt und als 04 03 09 10 05 01 geschrieben werden kann . Diesmal haben wir eine 10, die einen Übertrag in der Standardmultiplikation aufdeckt.


Kann ... Können wir eine grundlegende Erklärung zum Algorithmus haben?
Totalhuman

@totallyhuman Ich habe eine Erklärung hinzugefügt. (Hoppla ... und auch einen Fehler behoben.)
Arnauld

1
Sieht so aus, als ob Sie in der Lage sein sollten, 3 Bytes zu speichern, indem Sie die Eingaben als Zeichenfolgen verwenden.
Shaggy

3
Ich habe eine Ewigkeit gebraucht , um ein (theoretisches) Gegenbeispiel zu finden, bei dem Ihr Algorithmus versagt: tio.run/##y0rNyan8/9/l8LJk/f///… (das 108in der Mitte Ihren Algorithmus durcheinanderbringt )
Leaky Nun

@LeakyNun Schöne Entdeckung. Ja, es kann theoretisch überlaufen.
Arnauld

6

Alice , 30 Bytes

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

Probieren Sie es online!

Ausgänge 1für einfach und 0für schwer.

Die Zahlen lassen sich nur dann leicht multiplizieren, wenn die Ziffernsumme des Produkts mit dem Produkt der Ziffernsummen übereinstimmt.

/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 Bytes

,j!U]Y+9>a

Ausgänge 0für leicht, 1für schwer.

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

,       % 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 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als Zeichenfolge.

Es ist hässlich, aber es funktioniert ™.

Dies verwendet nun einen Faltungsansatz, wie in der Antwort von Leaky Nun , also werden Eingaben als ganze Zahlen verwendet und es werden TRUEhart zu multiplizierende und FALSEleicht zu multiplizierende Zahlen zurückgegeben .

Ich hatte in der Vergangenheit immer Probleme, Faltungsansätze zu portieren, aber heute habe ich endlich die Dokumentation gelesen :

Beachten Sie, dass die übliche Definition der Faltung von zwei Sequenzen xund yist gegeben durchconvolve(x, rev(y), type = "o")

Welches ist nur albern. Daher wird die Ziffernextraktion für umgekehrt nund in eine Portierung von Leaky Nuns Antwort aufgelöst.


4

Python 2 , 88 Bytes

lambda n,m:any(sum(n/10**(k-j)%10*(m/10**j%10)for j in range(k+1))>9for k in range(n+m))

Nimmt zwei Ganzzahlen als Eingabe und gibt False(einfach zu multiplizieren) oder True(nicht) zurück.

Probieren Sie es online! (zu langsam für einen der Testfälle)



len(`n+m`)würde eigentlich für 40, 30 scheitern .
Dennis

len(`n+m`)+1?
Undichte Nonne

Das scheitert bei 400, 300 . len(`n`+`m`)sollte aber tun.
Dennis

4

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

Vielen Dank an @ Dennis für die Idee, in dieser Antwort String-Interpolation zu verwenden und 4 Bytes zu sparen!

Danke @ ØrjanJohansen für -1!

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

Probieren Sie es online!

Wenn die Zielbasis kleiner als die ursprüngliche Basis ist (wie in meiner Gelee-Antwort, die Basis ist 2), <muss natürlich gewendet werden.


Herzlichen Glückwunsch, dass Sie als erster herausgefunden haben, ob Sie die Basisumwandlung verwenden, für die ich Ihnen die Prämie gebe!
xnor

3

Wolfram Language (Mathematica) , 75 66 65 56 Bytes

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

Probieren Sie es online!

Empfangen von 2 String-Eingaben

Erläuterung:

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 zum Ändern der Zeichenfolge als Eingabe

-1 für die Verwendung des Infix-Operators

-9 Danke @MartinEnder für die MaxFunktion



3

Julia 0,6 , 30 Bytes

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

Probieren Sie es online!

Die Eingabe ist ein Tupel von Zahlen, die Ausgabe ist truefür schwer zu multiplizierende und falsefür einfache Zahlen .

. ist eine elementweise Funktionsanwendung.

...Erweitert das Tupel (von Listen mit ganzzahligen Ziffern) auf zwei separate Eingänge der convFunktion.



3

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

	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

Probieren Sie es online!

Portiert den Ansatz von Nitrodon . Ich denke, dies ist das erste Mal, dass ich in SNOBOL eine Funktion Dfür die Ziffernsumme definiert habe .

	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

alte Version, 243 Bytes:

	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

Probieren Sie es online!

Eingabe in STDIN, durch Zeilenumbrüche getrennt, Ausgabe in STDOUT: eine einzelne Zeile zum einfachen Multiplizieren und keine Ausgabe zum nicht einfachen Multiplizieren.

Dies wird keine Preise gewinnen, aber es präsentiert einen anderen Ansatz (nun, das ist wirklich der naive Ansatz). Ich glaube nicht, dass ich das in Cubix schreiben könnte, aber SNOBOL ist hart genug, um damit zu arbeiten.

Da die Eingabe als Zeichenfolge verwendet wird, funktioniert dies für jede Eingabe mit jeweils weniger als 512 Stellen. Ich bin mir nicht 100% sicher, wie groß ARRAYs in SNOBOL sein kann.

INPUT wird in dieser Version von SNOBOL mit einer maximalen Breite von 1024 Zeichen gepuffert. Alle anderen Zeichen gehen dann verloren. Es scheint, dass ein ARRAY ziemlich groß sein kann; weit über die 2048 Zellen notwendig.

	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

Kohle , 38 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Gibt ein aus, -wenn die Zahlen leicht zu multiplizieren sind. Erläuterung:

≔E⁺θη⁰ζ

Initialisieren Sie zauf ein ausreichend großes Array (Summe der Längen der Eingaben) von Nullen.

FLθFLη

Durchlaufen Sie die Indizes der Eingänge qund h.

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

Führen Sie einen Schritt der langen Multiplikation durch.

‹⌈ζχ

Auf Tragekomfort prüfen.



2

Haskell, 82 81 Bytes

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

Die Zahlen werden als Zeichenfolgen verwendet. Gibt zurück, Falseob die Zahlen leicht zu multiplizieren sind oder Truenicht.

Probieren Sie es online!

Ich denke, es unterscheidet sich genug von der Antwort von @ Laikoni . Wie es funktioniert:

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

Schöne lösung! Ich suchte nach Wegen, um den Import loszuwerden, aber sie endeten noch länger.
Laikoni

2

Haskell , 45 44 Bytes

Bearbeiten:

  • -1 Byte wechselt ==zu <.

Ich dachte darüber nach, bevor ich mir die anderen Antworten ansah, und stellte dann fest, dass die Alice dieselbe Grundidee verwendete. Poste trotzdem, da es kürzer ist als die anderen Antworten von Haskell.

?Nimmt zwei ganze Zahlen und gibt a zurück Bool. Verwenden Sie als 331?1021. Falsebedeutet, dass die Multiplikation einfach ist.

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

Probieren Sie es online!

  • sist eine Funktion, die die Summe der Ziffern einer ganzen Zahl berechnet. ( read.pureKonvertiert ein einstelliges Zeichen in eine Ganzzahl.)
  • Wenn sich ein Zahlenpaar leicht multiplizieren lässt, ist die Ziffernsumme des Produkts gleich dem Produkt der Ziffernsummen.
  • Umgekehrt verringert jeder Übertrag während der langen Multiplikation die Ziffernsumme des Produkts von diesem Ideal.


1

Haskell , 123 Bytes

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

Probieren Sie es online! Anwendungsbeispiel: "331" % "1021"Erträge True.


1

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

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

Probieren Sie es online!

Ausgaben falsch für leicht, wahr für nicht leicht.


1

Gelee , 8 Bytes

;PDḄµṪ⁼P

Probieren Sie es online!

Ein Port meiner Javascript- Antwort . Nicht kürzer als die bestehende Gelee- Antwort da Jelly eine leistungsstarke Faltung enthält.

Nehmen Sie die Eingabe als Liste mit zwei Zahlen. Rückgabe 1einfach, 0nicht einfach.


Erläuterung:


;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 Bytes

Im Grunde genommen multiplizieren Sie "von Hand" r [] und setzen Sie den Rückgabewert, wenn eine Spalte höher als 9 wird, da dies bedeuten würde, dass ein Übertrag stattgefunden hat.

Überraschenderweise war dies kürzer als mein erster Versuch, bei dem Zeichenfolgen als Argumente herangezogen wurden.

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;}

Probieren Sie es online!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.