Multiplikasi ritsleting


20

pengantar

Mari kita mendefinisikan operasi aritmatika baru, yang saya sebut multiplikasi ritsleting . Untuk melipatgandakan dua bilangan bulat non-negatif, Anda menambahkan nol di depan untuk membuat panjangnya cocok, kalikan basis-10 angka yang sesuai, tambahkan nol di depan dengan hasil untuk mendapatkan angka 2 digit, menyatukannya, dan akhirnya menjatuhkan nol di depan.

Berikut ini contoh dengan A = 1276 dan B = 933024 :

1. Add leading zeros
 A = 001276
 B = 933024

2. Multiply digit-wise
 A = 0  0  1  2  7  6
 B = 9  9  3  0  2  4
 ->  0  0  3  0 14 24

3. Pad to 2 digits
 -> 00 00 03 00 14 24

4. Concatenate
 -> 000003001424

5. Drop leading zeros
 -> 3001424

Operasi diperluas ke semua bilangan bulat dengan aturan tanda yang biasa: waktu positif negatif adalah negatif, waktu negatif negatif adalah positif dan sebagainya.

Tugas

Input Anda adalah dua bilangan bulat, dan output Anda adalah kelipatan ritsleting. Anda harus dapat menangani input besar secara sewenang-wenang. Input dan / atau output dapat dalam format string (dan memang harus demikian, jika bahasa Anda tidak mendukung bilangan bulat besar secara sewenang-wenang). Catat itu-0 ini bukan input atau output yang valid.

Aturan dan penilaian

Anda dapat menulis program atau fungsi lengkap, dan jumlah byte terendah menang.

Uji kasus

0 0 -> 0
302 40 -> 0
302 -40 -> 0
-4352 448 -> -122016
0 6623 -> 0
0 -6623 -> 0
20643 -56721 -> -1000420803
63196 21220 -> 1203021800
1276 933024 -> 3001424
-1276 933024 -> -3001424
-1276 -933024 -> 3001424
5007204555 350073039 -> 12001545
-612137119 -8088606033 -> 816060042000327
3389903661 -6619166963 -> -18180881090018543603
-23082746128560880381 1116941217 -> -8050600723200060807
-668336881543038127783364011867 896431401738330915057436190556 -> -485448120906320001351224000900090235004021121824000900403042
402878826066336701417493206805490000415 312487283677673237790517973105761463808 -> 120004325656161618004242182118140007280900200921180018080025285400000000320040

Jawaban:


8

Jelly , 11 10 byte

ƓDUz0P€Uḅ³

Cobalah online!

Saya tidak bisa mendapatkan ini sampai 10 byte sendiri, tetapi @ Pietu1998 menunjuk saya ke atom yang saya lewatkan, ini memberikan solusi 10-byte ini. Tidak biasa untuk Jelly, yang ini mengambil input dari input standar (dalam bentuk 1276,933024), bukan dari baris perintah (ini memungkinkan penggunaan ³perintah, yang mengembalikan argumen baris perintah, default ke 100).

Penjelasan:

ƓDUz0P€Uḅ³
Ɠ           read standard input
 D          convert to base 10
  U         reverse elements
   z0       transpose, padding the end with zeroes
     P€     take the product of each (€) inner list
       U    reverse elements back
        b³  convert from base 100

Penggunaan basis 100 adalah cara sederhana untuk menerapkan teknik "pad ke 2 digit, lalu konversikan ke basis 10". Satu-satunya hal halus di sini adalah pembalikan; kami ingin menggunakan nol di awal nomor, tetapi zperintah Jelly cocok di akhir, jadi membalikkan daftar berarti bahwa zakan pad dengan benar.


3
Anda dapat mengganti b⁵dengan Duntuk mendapatkan 10 byte. : P
PurkkaKoodari

4

Python 2, 99 byte

a,b=input();o=0;p=1-2*(a*b<0);a,b=abs(a),abs(b)
while a:o+=a%10*(b%10)*p;p*=100;a/=10;b/=10
print o

Banyak byte yang ada untuk memperhitungkan tanda jika input negatif. Dalam Python, n%dselalu non-negatif jika dpositif 1 . Menurut pendapat saya ini umumnya diinginkan, tetapi di sini tampaknya tidak nyaman: menghapus panggilan absakan merusak kode di atas. Sementara itup melacak "nilai tempat" (yang, ratusan, dll.) Dan juga mengingat tanda output yang diinginkan.

Kode ini pada dasarnya simetris adan bkecuali dalam whilekondisi: kita terus berjalan sampai anol, dan berakhir pada waktu itu. Tentu saja jika bnol dulu, maka kita akan menambahkan nol untuk sementara waktu sampai anol juga.


1 Misalnya, (-33)%10mengembalikan 7, dan hasil bagi bilangan bulat dari (-33)/10adalah -4. Ini benar karena (-4)*10 + 7 = -33. Namun, produk ritsleting (-33)dengan 33harus berakhir di 3*3 = 09bukan 7*3 = 21.


3

JavaScript (ES6), 44 byte

f=(x,y)=>x&&f(x/10|0,y/10|0)*100+x%10*(y%10)

Mudahnya ini otomatis berfungsi untuk angka negatif.


@ Jakube Saya selalu melakukan itu, meskipun setidaknya saya termasuk f=dalam jumlah byte. Juga, |0ini karena saya butuh pembagian bilangan bulat, saya tidak tahu bagaimana menurut Anda Anda mendapatkan jawaban yang tepat tanpa itu.
Neil

Ah, itu masuk akal. Sekarang saya juga mendapatkan jawaban yang salah saat menghapus |0. Mungkin pengalihan fungsi baru ke f tidak bekerja dan saya masih menguji versi lama dengan |0.
Jakube

2

C, 77 byte

-2 byte untuk menghapus kawat gigi redundan ( *asosiatif).

r,t;f(a,b){t=1;r=0;while(a|b)r+=t*(a%10)*(b%10),a/=10,b/=10,t*=100;return r;}

t= 1.100.10000, ... digunakan untuk pengisian. Selama aatau btidak nol teruslah mengalikan digit terakhir %10dengan tdan menumpuk. Kemudian erease digit terakhir dari adan b( /=10) dan bergeser tdengan 2 digit ( *=100).

Tidak digabungkan dan digunakan:

r,t;
f(a,b){
 t=1;
 r=0;
 while(a|b)
  r+=t*(a%10)*(b%10),
  a/=10,
  b/=10,
  t*=100;
 return r;
}

main(){
 printf("%d\n", f(1276,933024));
}

Sarankan for(r=0;a|b;t*=100)r+=a%10*t*(b%10),a/=10,b/=10alih-alihr=0;while(a|b)r+=t*(a%10)*(b%10),a/=10,b/=10,t*=100
ceilingcat

1

Sebenarnya , 23 19 byte

Input diambil sebagai dua string. Juga, tampaknya berusaha untuk mengkonversi dari basis 100, seperti yang dilakukan ais523 dalam jawaban Jelly mereka, tidak bekerja dengan baik di Sebenarnya. Akan menghemat 9 byte juga jika berhasil: / Saran Golf selamat datang! Cobalah online!

Edit: -4 byte dari mengubah bagaimana hasilnya dibangun menjadi nomor baru.

k`♂≈R`M┬ñ`iτ╤@π*`MΣ

Tidak melakukanolf

          Implicit input a and b.
k         Wrap a and b into a list.
`...`M    Map over the list of strings.
  ♂≈        Convert each digit to its own int.
  R         Reverse for later.
┬         Transpose to get pairs of digits from a and b.
ñ         enumerate(transpose) to get all of the indices as well.
`...`M    Map over the transpose.
  i         Flatten (index, pair) onto the stack.
  τ╤        Push 10**(2*index) == 100**index to the stack.
  @π        Swap and get the product of the pair of integers.
  *         Multiply the product by 100**index.
Σ         Sum everything into one number.
          Implicit return.

1

Mathematica 66 Bytes

i=IntegerDigits;p=PadLeft;FromDigits@Flatten@p[i/@Times@@p[i/@#]]&

Tidak Terkumpul:

IntegerDigits/@{1276,933024}
PadLeft[%]
Times@@%
IntegerDigits/@%
PadLeft[%]
Flatten@%
FromDigits@%

di mana% berarti hasil keluaran sebelumnya

{{1,2,7,6},{9,3,3,0,2,4}}
{{0,0,1,2,7,6},{9,3,3,0,2,4}}
{0,0,3,0,14,24}
{{0},{0},{3},{0},{1,4},{2,4}}
{{0,0},{0,0},{0,3},{0,0},{1,4},{2,4}}
{0,0,0,0,0,3,0,0,1,4,2,4}
3001424

1

R, 182 110 107 86 byte

Tidak lagi jawaban terpanjang (terima kasih, Racket), dan bahkan lebih pendek dari solusi Python (yang jarang terjadi)! Fungsi anonim yang mengambil dua bilangan bulat sebagai input.

function(a,b)sum((s=function(x)abs(x)%%10^(99:1)%/%(e=10^(98:0))*e)(a)*s(b))*sign(a*b)

Begini cara kerjanya.

Penggandaan ritsleting melibatkan pemisahan angka-angka input ke dalam digit konstituennya. Kami mengambil nilai absolut dari angka dan melakukan modulo untuk menurunkan daya 10:

abs(x) %% 10^(99:1)

Jadi di sini kita mengambil satu angka x,, dan menerapkan modulo dengan 99 nomor lainnya ( 10^99sampai 10^1). R mengulangi secara implisit x99 kali, mengembalikan vektor (daftar) dengan 99 elemen. ( x %% 10^99, x %% 10^98, x %% 10^97, Dll)

Kami menggunakan 10^99melalui 10^1. Implementasi yang lebih efisien akan menggunakan nilai jumlah digit dalam jumlah terpanjang (periksa riwayat edit posting ini; versi sebelumnya melakukan ini), tetapi hanya mengambil99..1 menggunakan byte lebih sedikit.

Untuk x = 1276ini memberi kita

1276 1276 1276 ... 1276 276 76 6

Selanjutnya, kami menggunakan divisi integer dengan menurunkan kekuatan 10 untuk melengkapi angka:

abs(x) %% 10^(99:1) %/% 10^(98:0)

Ini menghasilkan

0 0 0 ... 1 2 7 6

yang merupakan representasi yang kita inginkan. Dalam kode, kami akhirnya ingin menggunakan 10^(98:0)lagi nanti, jadi kami menetapkannya ke variabel:

abs(x) %% 10^(99:1) %/% (e = 10^(98:0))

(Membungkus ekspresi dalam tanda kurung di R umumnya mengevaluasi ekspresi (dalam hal ini, menetapkan nilai 10^(98:0)untuke ), dan kemudian juga mengembalikan output dari ekspresi, memungkinkan kami untuk menanamkan penugasan variabel dalam perhitungan lain.)

Selanjutnya, kami melakukan penggandaan digit secara berpasangan pada input. Outputnya kemudian diisi hingga dua digit dan digabungkan. Padding ke dua digit dan penggabungan setara dengan mengalikan setiap angka dengan 10^n, di mana njarak dari tepi kanan, dan kemudian menjumlahkan semua angka.

 A = 0         0         1         2         7         6
 B = 9         9         3         0         2         4
 ->  0         0         3         0        14        24
 -> 00        00        03        00        14        24
 ->  0*10^6 +  0*10^5 +  3*10^4 +  0*10^3 + 14*10^2 + 24*10^1
 =  000003001424

Terutama, karena perkalian komutatif, kita dapat melakukan perkalian dengan 10^n sebelum kita kalikan A dengan B . Jadi, kami mengambil perhitungan sebelumnya dan mengalikannya dengan 10^(98:0):

abs(x) %% 10^(99:1) %/% 10^(98:0) * 10^(98:0)

yang setara dengan

abs(x) %% 10^(99:1) %/% (e = 10^(98:0)) * e

Setelah menerapkan ini untuk A , kita kemudian akan ingin mengulang seluruh operasi ini pada B . Tapi itu membutuhkan byte yang berharga, jadi kita mendefinisikan suatu fungsi jadi kita hanya perlu menulisnya sekali:

s = function(x) abs(x) %% 10^(99:1) %/% (e=10^(98:0)) * e

Kami melakukan trik embedding-in-kurung kami untuk memungkinkan kami mendefinisikan dan menerapkan fungsi pada saat yang sama, untuk memanggil fungsi ini pada A dan B dan melipatgandakannya bersama-sama. (Kita bisa mendefinisikannya pada baris terpisah, tetapi karena kita akhirnya akan menempatkan semua ini ke dalam fungsi anonim, jika kita memiliki lebih dari satu baris kode maka semuanya perlu dibungkus dengan kurung kurawal, yang harganya berharga byte.)

(s = function(x) abs(x) %% 10^(99:1) %/% (e=10^(98:0)) * e)(a) * s(b)

Dan kita mengambil jumlah semua ini, dan kita hampir selesai:

sum((s = function(x) abs(x) %% 10^(99:1) %/% (e=10^(98:0)) * e)(a) * s(b))

Satu-satunya hal yang perlu dipertimbangkan sekarang adalah tanda input. Kami ingin mengikuti aturan perkalian reguler, jadi jika satu dan hanya satu dari A dan B negatif, hasilnya negatif. Kami menggunakan fungsi signyang mengembalikan 1ketika diberi angka positif dan -1ketika diberi angka negatif, untuk menghasilkan koefisien yang kami kalikan seluruh perhitungan kami dengan:

sum((s = function(x) abs(x) %% 10^(99:1) %/% (e=10^(98:0)) * e)(a) * s(b)) * sign(a * b)

Akhirnya, semuanya dibungkus menjadi fungsi anonim yang mengambil adan bsebagai input:

function(a, b) sum((s = function(x) abs(x) %% 10^(99:1) %/% (e=10^(98:0)) * e)(a) * s(b)) * sign(a * b)

Hapus spasi dan itu 86 byte.


Akan sangat bagus jika Anda bisa memberikan versi yang tidak dikenali dan dijelaskan untuk keuntungan semua orang.
rnso

Saya telah memperbarui posting dengan penjelasan.
rturnbull

Kerja bagus. Metode yang sangat pintar digunakan.
rnso

1

Python 3 , 92 byte , 119 byte

lambda m,n:(1-(n*m<0)*2)*int(''.join([f"{int(a)*int(b):02}"for a,b in zip(str(abs(n))[::-1],str(abs(m))[::-1])][::-1]))

Cobalah online!

Biaya perbaikan untuk menangani angka negatif 29 byte: /


Jawaban bagus! Saya pikir Anda dapat mengganti lstripbagian dengan membungkus semuanya di dalam int()dan mengembalikan nomor.
ArBo

Kamu benar. Kemudian saya merasa ingin menjaga antarmuka yang konsisten. Mengambil string sebagai argumen alih-alih int, lalu mengembalikan int terlihat aneh bagi saya;) Saya lebih suka mengubah zip + untuk loop untuk panggilan peta, tapi itu tidak akan berfungsi: /
movatica

Saya tidak akan terlalu khawatir tentang konsistensi dalam kode golf, tetapi terserah Anda :). Pemetaan biasanya tidak terlalu golf di Python jika Anda perlu membuat lambda ekstra untuk melakukannya.
ArBo

Fungsi ini tampaknya gagal untuk input negatif
ArBo

Anda benar: / Perbaikannya cukup mahal, mungkin ada lebih banyak potensi untuk bermain golf.
movatica


0

PHP, 84 byte

for(list(,$a,$b)=$argv,$f=1;$a>=1;$a/=10,$b/=10,$f*=100)$r+=$a%10*($b%10)*$f;echo$r;

sedikit lebih lama dengan penggabungan string (86 byte):

for(list(,$a,$b)=$argv;$a>=1;$a/=10,$b/=10)$r=sprintf("%02d$r",$a%10*($b%10));echo+$r;

0

Racket 325 byte

(let*((g string-append)(q quotient/remainder)(l(let p((a(abs a))(b(abs b))(ol'()))(define-values(x y)(q a 10))
(define-values(j k)(q b 10))(if(not(= 0 x j))(p x j(cons(* y k)ol))(cons(* y k)ol)))))(*(string->number
(apply g(map(λ(x)(let((s(number->string x)))(if(= 2(string-length s)) s (g "0" s))))l)))(if(<(* a b)0)-1 1)))

Tidak Terkumpul:

(define (f a b)
  (let* ((sa string-append)
         (q quotient/remainder)
         (ll (let loop ((a (abs a))
                        (b (abs b))
                        (ol '()))
               (define-values (x y) (q a 10))
               (define-values (j k) (q b 10))
               (if (not(= 0 x j))
                   (loop x j (cons (* y k) ol))
                   (cons (* y k) ol)))))
    (*(string->number (apply sa
                             (map (λ (x)
                                    (let ((s (number->string x)))
                                      (if (= 2 (string-length s))
                                          s
                                          (sa "0" s))))
                                  ll)))
      (if (< (* a b) 0) -1 1))))

Pengujian:

(f 1276 933024)
(f 302 40)
(f 0 6623)
(f 63196 21220)
(f 20643 -56721)

Keluaran:

3001424
0
0
1203021800
-1000420803

0

PowerShell , 153 151 byte

param($a,$b)do{$x,$y=$a[--$i],$b[$i]|%{if($_-eq45){$s+=$_;$_=0}$_}
$r=(+"$x"*"$y"|% t*g "00")+$r}while($x+$y)$s+$r-replace'(?<!\d)0+(?=\d)|--|-(?=0+$)'

Cobalah online!

Kurang bermain golf:

param($a,$b)
do{
    $x,$y=$a[--$i],$b[$i]|%{
        if($_-eq45){                                # [char]45 is '-'
            $signs+=$_
            $_=0
        }
        $_                                          # a digit or $null
    }
    $res=(+"$x"*"$y"|% toString "00")+$res          # "00" is the custom format to get 2-digit number
}
while($x+$y)
$signs+$res-replace'(?<!\d)0+(?=\d)|--|-(?=0+$)'    # cleanup and return

0

Perl 5 -MList::Util=min , 140 byte

@a=<>=~/\S/g;@F=<>=~/\S/g;$q=1+min$#a,$#F;say+('-'x("@a@F"=~y/-//%2).sprintf'%02d'x$q,map$F[$_]*$a[$_],-$q..-1)=~s/^-?\K0+//r=~s/^-0*$//r||0

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.