Çarpması kolay sayılar


34

Göreviniz iki sayının çarpmanın kolay olup olmadığını belirlemektir . Bu, 10 taban uzunluğundaki çarpma işleminin, hem çarpma adımlarına hem de toplama adımına bakarak, yer değerleri arasında hiçbir taşıma (yeniden gruplandırma) olmadığı anlamına gelir . Bu, çarpılan her hane çifti 9 veya daha az verdiğinde ve her sütunun toplamı 9 veya daha az olduğunda gerçekleşir.

Örneğin 331ve 1021çarpılması kolaydır:

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

Ve aynı şekilde (her zaman olduğu gibi) diğer sırayla çarparsak da geçerlidir:

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

Ancak, belirtilen sütunlar arasında gerçekleşen taşıyıcılarla, çarpılması kolay değildir 431ve 1021:

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

Ayrıca, 12ve 16çarpılması zaman carry-over olur çarpın çünkü kolay değildir 12 * 6almak için 72hiçbir ekleme adımında meydana taşır rağmen.

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

Girdi: İki pozitif tam sayı veya dizge gösterimleri. Dilinizin tamsayı türünü aşmayacaklarını veya ürünlerini taşmayacaklarını varsayabilirsiniz.

Çıktı: Çarpmaları kolaysa bir tutarlı değer, değilse çoğaltılması gereken tutarlı bir değer.

Test durumları: İlk 5 çarpmak kolaydır, son 5 değildir.

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

Liderler Sıralaması:


1
Her numara için giriş bir rakam listesi olabilir mi?
dylnan

@dylnan Hayır, karakter listesi varsayılan olarak string seçeneği için geçerli olsa da.
xnor

Yanıtlar:


14

Jöle , 7 bayt

Dæc/>9Ẹ

Çevrimiçi deneyin!

Evrişimi kullanır (Jelly: D'ye katkıda bulundum)

Nasıl çalışır

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

o wow konvolüsyon: DI, kod-
golfde



@ LouisMendo Hayır, bu farklı bir evrişim.
Outgolfer Erik

BTW Üzerinde <⁵Ạbir NOT boolean olmadan son 3 baytı çıktıyla değiştirebilirsiniz .
Outgolfer Erik

8

JavaScript (ES6), 67 bayt

Körme sözdiziminde girişi 2 dize olarak alır (a)(b). İade falsekolay veya truekolay değil için.

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

Test durumları


Alt. sürüm (hatalı), 64 55 52 bayt

@Shaggy tarafından önerildiği gibi , dizeleri alarak 3 bayt kurtarıldı @LeakyNun tarafından belirtildiği
gibi, bu yöntem bazı büyük tam sayılarda başarısız olur

Körme sözdiziminde girişi 2 dize olarak alır (a)(b). İade truekolay veya falsekolay değil için.

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

Test durumları

Nasıl?

Buradaki fikir, her bir faktörün her bir basamağının önüne sıfır ekleyerek taşıyıcıları açıkça ortaya koymaktır.

Örnekler:

  • 331 x 1021 , 30301 x 1000201 olur ve bu, 337951 yerine 30307090501 verir . Sonuca baştaki bir sıfır ekleyerek ve tüm basamakları 2 ile gruplayarak, bu 03 03 07 09 05 01 olarak yazılabilir . Tüm gruplar 10'dan daha küçüktür , yani standart çarpmada herhangi bir taşıma olmazdı.

  • 431 x 1021 , 40309 x 1000201 olur ; bu, 40309100501'i verir ve 04 03 09 10 05 01 gibi yazılabilir . Bu kez, we have a 10 standart çarpma içinde bir taşıma ortaya koymaktadır.


Can ... Algoritma hakkında temel bir açıklama yapabilir miyiz?
tamamen insanlık

@totallyhuman Bir açıklama ekledim. (Hata! Ve ayrıca bir hata düzeltildi.)
Arnauld

1
Girdileri dizge olarak alarak 3 bayt kaydedebilmelisiniz gibi görünüyor.
Shaggy

3
Algoritmanızın başarısız olacağı (teorik) bir karşı-örnek bulmak bana sonsuz geldi : tio.run/##y0rNyan8/9/l8LJk/f///… ( 108ortadaki algoritmada algoritmalar)
Leaky Nun

@LeakyNun Güzel bul. Evet, teorik olarak taşabilir.
Arnauld

6

Alice , 30 bayt

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

Çevrimiçi deneyin!

1Kolay ve 0zor için çıkışlar .

Rakamların çarpılması kolaydır ve yalnızca ürünün hane toplamı hane toplamının ürününe eşitse.

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

,j!U]Y+9>a

0Kolay çıkışlar , 1zor için.

Çevrimiçi deneyin! Veya tüm test durumlarını doğrulayın .

açıklama

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

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

Çevrimiçi deneyin!

Girdiyi dizge olarak alır.

Çirkin ama işe yarıyor ™.

Bu, Leaky Nun'un cevabında olduğu gibi, bir evrişim yaklaşımı kullanıyor , bu yüzden tamsayı olarak girdi alıyor ve sayıları TRUEçoğaltması ve FALSEçoğaltması kolay olanları için geri dönüyor .

Geçmişte evrişim yaklaşımlarını benimseme konusunda her zaman bazı sıkıntılar yaşadım, ancak bugün nihayet belgeleri okudum :

İki dizi sanhşmm genel tanımı bu Not xve yverilirconvolve(x, rev(y), type = "o")

Bu sadece saçma. Böylece rakam çıkarımı tersine çevrilir nve Leaky Nun'un cevabının limanı haline gelir.




3

Wolfram Dili (Mathematica) , 75 66 65 56 bayt

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

Çevrimiçi deneyin!

2 dize girişi alma

Açıklama:

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 dizeyi girdi olarak kullanmak için

İnfix operatörünü kullanmak için -1

İçin -9 teşekkürler @MartinEnder Maxfonksiyonu



3

Julia 0.6 , 30 bayt

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

Çevrimiçi deneyin!

Giriş bir sayı dizisidir, çıktı truesayıları çarpmak zor ve falsekolay sayılar içindir.

. element-bilge fonksiyon uygulamasıdır.

...convİşlevin iki ayrı girişine kadar dizgiyi (tam sayı basamaklarının listesi) genişletir .



3

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

	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

Çevrimiçi deneyin!

Nitrodon ile yaklaşımı gösterir . Sanırım ilk defa SNOBOL’da, Drakam toplamı için bir işlev tanımladım .

	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

eski sürüm, 243 bayt:

	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

Çevrimiçi deneyin!

Yeni satırlarla ayrılmış STDIN'e giriş, STDOUT'a çıkış: çarpma kolaylığı için tek bir yeni satır ve çarpma işleminin kolay olmadığı için çıkış yok.

Bu herhangi bir ödül kazanmayacak ama başka bir yaklaşım sunuyor (peki, bu gerçekten naif yaklaşımdır). Bunu cubix'e yazabileceğimi sanmıyorum, ancak SNOBOL olduğu gibi çalışacak kadar zor.

Bir dize olarak girdi aldığı için, her biri 512 haneden az olan herhangi bir girdi için çalışacaktır; ARRAYSNOBOL’da ne kadar büyük olabileceğinden % 100 emin değilim .

INPUT, SNOBOL'un bu sürümünde, maksimum 1024 karakterlik bir genişliğe sahip olacak şekilde tamponlanır; diğer tüm karakterler daha sonra kaybolur. Bir ARRAY oldukça büyük olabilir gibi görünüyor; gerekli 2048 hücrelerin üzerinde iyi.

	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

Kömür , 38 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. -Sayıların çarpılması kolay olduğunda bir çıktı verir. Açıklama:

≔E⁺θη⁰ζ

zYeterince büyük (girişlerin toplam uzunluğu) bir dizeye sıfırlayın .

FLθFLη

Girdilerin indeksleri üzerinde döngü qve h.

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

Uzun çarpmanın bir adımını gerçekleştirin.

‹⌈ζχ

Taşıyıcıları kontrol et.



2

Haskell, 82 81 bayt

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

Sayı olarak alınan sayılar. Döndürür Falsesayılar çarpma ve kolay olmadığını Trueaksi.

Çevrimiçi deneyin!

Sanırım @ Laikoni'nin cevabından yeterince farklı . Nasıl çalışır:

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

Güzel çözüm! İthalattan kurtulmanın yollarını arıyordum, ancak daha da uzun sürdüler.
Laikoni

2

Haskell , 45 44 bayt

Düzenle:

  • -1 bayt değiştirmek ==için< .

Bunu diğer cevaplara bakmadan önce düşündüm, sonra Alice'in aynı temel fikri kullandığını keşfettim. Diğer Haskell cevaplarından daha kısa olduğu için yine de mesaj atmak.

?iki tamsayı alır ve a değerini döndürür Bool. Olarak kullanın 331?1021. Falseçarpımın kolay olduğu anlamına gelir.

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

Çevrimiçi deneyin!

  • sbir tamsayının rakamlarının toplamını hesaplayan bir fonksiyondur. (read.pure bir tek sayı karakterini bir tamsayıya dönüştürür.)
  • Bir sayının çarpılması kolaysa, ürünün basamak toplamı, basamak toplamının ürününe eşittir.
  • Tersine, uzun çarpma sırasındaki herhangi bir taşıma, ürünün rakamsal toplamını bu idealden düşürür.


1

Haskell , 123 bayt

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

Çevrimiçi deneyin! Örnek kullanım: "331" % "1021"verim True.


1

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

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

Çevrimiçi deneyin!

çıktılar kolay için yanlış, kolay değil için doğru olur.


1

Jöle , 8 bayt

;PDḄµṪ⁼P

Çevrimiçi deneyin!

Javascript cevabımın bir portu . Mevcut Jelly cevabından daha kısa değil çünkü Jelly'in içinde güçlü bir evrişim var.

Girişi iki sayının listesi olarak alın. 1Kolay 0için döner , kolay değil.


Açıklama:


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

Temel olarak "elle" çarpımını r [] olarak yapın ve herhangi bir sütun 9'dan daha yüksek olursa, dönüşün değerini ayarlayın, çünkü bu bir taşıma gerçekleştiğini gösterir.

Şaşırtıcı bir şekilde, bu tartışmaları dizge haline getiren ilk denememden daha kısaydı.

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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.