Angka yang mudah dikalikan


34

Tugas Anda adalah menentukan apakah dua angka itu mudah dikalikan . Ini berarti bahwa multiplikasi panjang basis-10 mereka tidak memiliki carry (pengelompokan ulang) antara nilai-nilai tempat, melihat kedua langkah multiplikasi dan langkah penambahan. Ini terjadi ketika setiap pasangan digit yang dikalikan menghasilkan 9 atau kurang dan jumlah masing-masing kolom adalah 9 atau kurang.

Misalnya, 331dan 1021mudah dikalikan:

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

Dan hal yang sama juga benar (seperti biasa) jika kita mengalikan urutan lainnya:

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

Tapi, 431dan 1021tidak mudah untuk berkembang biak, dengan membawa terjadi di antara kolom yang ditunjukkan:

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

Juga, 12dan 16tidak mudah untuk berkembang biak karena carry-over terjadi ketika dikalikan 12 * 6untuk mendapatkan 72, meskipun tidak ada pembawaan yang terjadi pada langkah penambahan.

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

Input: Dua bilangan bulat positif atau representasi string mereka. Anda dapat berasumsi bahwa mereka tidak akan melimpahi tipe bilangan bulat bahasa Anda, dan produk mereka juga tidak.

Keluaran: Satu nilai konsisten jika mudah dikalikan, dan nilai konsisten lainnya jika tidak.

Kasus uji: 5 yang pertama mudah dikalikan, 5 yang terakhir tidak.

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

Papan peringkat:


1
Bisakah input untuk setiap nomor menjadi daftar digit?
dylnan

@dylnan Tidak, meskipun daftar karakter secara default sah untuk opsi string.
xnor

Jawaban:


14

Jelly , 7 byte

Dæc/>9Ẹ

Cobalah online!

Menggunakan konvolusi (yang saya berkontribusi pada Jelly: D)

Bagaimana itu bekerja

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

o wow konvolusi: DI saya pikir ini adalah pertama kalinya saya melihat konvolusi yang digunakan dalam kode-golf: D +1
HyperNeutrino



@LuisMendo Tidak, itu konvolusi berbeda.
Erik the Outgolfer

BTW Anda dapat mengganti 3 byte terakhir dengan <⁵Ạuntuk output tanpa boolean TIDAK dilakukan di atasnya.
Erik the Outgolfer

8

JavaScript (ES6), 67 byte

Mengambil input sebagai 2 string dalam sintaks currying (a)(b). Pengembalian falseuntuk yang mudah atau yang truetidak mudah.

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

Uji kasus


Alt. versi (cacat), 64 55 52 byte

Disimpan 3 byte dengan mengambil string, seperti yang disarankan oleh @Shaggy
Seperti yang ditunjukkan oleh @LeakyNun, metode ini akan gagal pada beberapa bilangan bulat spesifik besar

Mengambil input sebagai 2 string dalam sintaks currying (a)(b). Pengembalian trueuntuk yang mudah atau yang falsetidak mudah.

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

Uji kasus

Bagaimana?

Idenya di sini adalah untuk secara eksplisit mengekspos membawa dengan memasukkan nol sebelum setiap digit dari masing-masing faktor.

Contoh:

  • 331 x 1021 menjadi 30301 x 1000201 , yang menghasilkan 30307090501, bukan 337951 . Dengan menambahkan nol di depan ke hasil dan mengelompokkan semua digit dengan 2, ini dapat ditulis sebagai 03 03 07 09 05 01 . Semua kelompok kurang dari 10 , yang berarti tidak akan ada bawaan dalam perkalian standar.

  • 431 x 1021 menjadi 40301 x 1000201 , yang menghasilkan 40309100501 dan dapat ditulis sebagai 04 03 09 10 05 01 . Kali ini, kami memiliki 10 yang menunjukkan carry dalam multiplikasi standar.


Bisakah ... Bisakah kita memiliki penjelasan dasar tentang algoritma?
totallyhuman

@ sebenarnya manusia saya telah menambahkan penjelasan. (Ups ... dan juga memperbaiki bug.)
Arnauld

1
Sepertinya Anda harus dapat menghemat 3 byte dengan mengambil input sebagai string.
Shaggy

3
Butuh saya selamanya untuk menemukan (contoh) counter-contoh yang algoritma Anda akan gagal: tio.run/##y0rNyan8/9/l8LJk/f///… ( 108di tengah mengacaukan algoritma Anda)
Leaky Nun

@ LeakyNun Temukan yang bagus. Ya, secara teori bisa meluap.
Arnauld

6

Alice , 30 byte

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

Cobalah online!

Output 1untuk mudah dan 0sulit.

Angka-angka mudah dikalikan jika dan hanya jika jumlah digit produk sama dengan produk jumlah digit.

/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

Keluaran 0untuk mudah, 1untuk sulit.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

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

Cobalah online!

Mengambil input sebagai string.

Itu jelek tapi berhasil ™.

Ini sekarang menggunakan pendekatan konvolusi, seperti dalam jawaban Leaky Nun , sehingga dibutuhkan input sebagai bilangan bulat, dan kembali TRUEuntuk angka yang sulit dikalikan dan FALSEuntuk yang mudah dikalikan.

Saya selalu memiliki masalah dalam porting pendekatan konvolusi di masa lalu, tetapi hari ini saya akhirnya membaca dokumentasi :

Perhatikan bahwa definisi konvolusi dua urutan xdan ydiberikan olehconvolve(x, rev(y), type = "o")

Itu hanya konyol. Jadi ekstraksi digit dibalik untuk n, dan itu menjadi port jawaban Leaky Nun.


4

Python 2 , 88 byte

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

Mengambil dua bilangan bulat sebagai input dan mengembalikan False(mudah dikalikan) atau True(tidak).

Cobalah online! (terlalu lambat untuk salah satu kasus uji)



len(`n+m`)akan benar-benar gagal selama 40, 30 .
Dennis

len(`n+m`)+1?
Leaky Nun

Itu gagal untuk 400, 300 . len(`n`+`m`)harus dilakukan.
Dennis

4

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

Terima kasih @ Dennis untuk ide menggunakan interpolasi string dalam jawaban ini dan menghemat 4 byte!

Terima kasih @ ØrjanJohansen untuk -1!

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

Cobalah online!

Tentu saja ketika basis tujuan kurang dari basis asli (seperti dalam jawaban Jelly saya, basis 2) <harus dibalik.


Selamat telah menjadi yang pertama mengetahui untuk menggunakan konversi basis, yang saya berikan hadiahnya!
xnor

3

Bahasa Wolfram (Mathematica) , 75 66 65 56 byte

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

Cobalah online!

Menerima 2 input string

Penjelasan:

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 untuk mengubah menggunakan string sebagai input

-1 untuk menggunakan operator infiks

-9 Terima kasih @MartinEnder untuk Maxfungsinya



3

Julia 0,6 , 30 byte

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

Cobalah online!

Input adalah tupel angka, output trueuntuk angka yang sulit dikalikan dan yang falsemudah.

. adalah aplikasi fungsi elemen-bijaksana.

...memperluas tuple (daftar digit bilangan bulat) ke dua input convfungsi yang terpisah.



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

Cobalah online!

Port pendekatan oleh Nitrodon . Saya pikir ini adalah pertama kalinya saya mendefinisikan sebuah fungsi di SNOBOL, Duntuk jumlah digit.

	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

versi lama, 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

Cobalah online!

Input pada STDIN dipisahkan oleh baris baru, output ke STDOUT: baris baru tunggal untuk mudah dikalikan, dan tidak ada output untuk tidak mudah dikalikan.

Ini tidak akan memenangkan penghargaan apa pun, tetapi memberikan pendekatan lain (yah, sungguh ini adalah pendekatan naif). Saya tidak berpikir saya bisa menulis ini di cubix, tetapi SNOBOL cukup sulit untuk digunakan.

Karena mengambil input sebagai string, ini akan berfungsi untuk input apa pun dengan masing-masing kurang dari 512 digit; Saya tidak 100% yakin seberapa besar ARRAYSNOBOL.

INPUT buffered dalam versi SNOBOL ini untuk memiliki lebar maksimum 1024 karakter; semua karakter lain kemudian hilang. Tampaknya ARRAY bisa sangat besar; lebih dari 2048 sel yang diperlukan.

	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

Arang , 38 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Output a -ketika angkanya mudah dikalikan. Penjelasan:

≔E⁺θη⁰ζ

Inisialisasi zke array angka (jumlah panjang input) yang cukup besar.

FLθFLη

Loop di atas indeks input qdan h.

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

Lakukan satu langkah penggandaan panjang.

‹⌈ζχ

Periksa untuk membawa.



2

Haskell, 82 81 byte

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

Angka-angka yang diambil sebagai string. Kembali Falsejika jumlahnya mudah untuk dikalikan dan Truesebaliknya.

Cobalah online!

Saya pikir itu cukup berbeda dari jawaban @ Laikoni . Bagaimana itu bekerja:

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

Solusi bagus! Saya mencari cara untuk menyingkirkan impor, tetapi mereka berakhir lebih lama.
Laikoni

2

Haskell , 45 44 byte

Edit:

  • -1 byte diubah ==menjadi <.

Saya memikirkan hal ini sebelum melihat jawaban yang lain, kemudian menemukan bahwa yang Alice menggunakan ide dasar yang sama. Tetap memposting karena lebih pendek daripada jawaban Haskell lainnya.

?membutuhkan dua bilangan bulat dan mengembalikan a Bool. Gunakan sebagai 331?1021. Falseberarti penggandaannya mudah.

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

Cobalah online!

  • sadalah fungsi yang menghitung jumlah digit bilangan bulat. ( read.pureMengonversi karakter satu digit ke integer.)
  • Jika sepasang angka mudah untuk dikalikan, jumlah digit produk sama dengan produk jumlah digit.
  • Sebaliknya, semua carry selama multiplikasi panjang akan mengurangi jumlah digit produk dari ideal itu.


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

Cobalah online! Contoh penggunaan: "331" % "1021"hasil 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$\

Cobalah online!

output false untuk mudah, benar untuk tidak mudah.


1

Jelly , 8 byte

;PDḄµṪ⁼P

Cobalah online!

Port jawaban Javascript saya . Tidak lebih pendek dari jawaban Jelly yang ada karena Jelly memiliki konvolusi bawaan yang kuat.

Ambil input sebagai daftar dua angka. Pengembalian 1untuk mudah, 0karena tidak mudah.


Penjelasan:


;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

Pada dasarnya lakukan perkalian "dengan tangan" ke r [] dan atur nilai kembali jika ada kolom yang lebih tinggi dari 9, karena itu berarti carry telah terjadi.

Anehnya, ini lebih pendek dari upaya pertama saya yang mengambil string sebagai argumen.

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

Cobalah online!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.