Fermuar çarpımı


20

Giriş

Fermuar çarpımı dediğim yeni bir aritmetik işlemi tanımlayalım . Fermuar, iki negatif olmayan tamsayıyı çarpmak için, uzunlukların eşleşmesi için önde gelen sıfırları ekler, sayıların karşılık gelen taban-10 basamaklarını çarpar, 2 basamaklı sayıları almak, sonuçlara bitirir ve son olarak önde gelen sıfırları düşürürsünüz.

A = 1276 ve B = 933024 ile bir örnek :

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

İşlem, olağan işaret kurallarıyla tüm tamsayılara genişletilir: pozitif zaman negatif, negatif zaman negatif, pozitif vb.

Görev

Girdileriniz iki tamsayıdır ve çıktınız onların fermuar çarpımıdır. İsteğe bağlı olarak büyük girdileri işleyebilmelisiniz. Giriş ve / veya çıkış dize biçiminde olabilir (ve diliniz keyfi olarak büyük tamsayıları desteklemiyorsa) olmalıdır. Bunun -0geçerli bir girdi veya çıktı olmadığını unutmayın .

Kurallar ve puanlama

Tam bir program veya işlev yazabilirsiniz ve en düşük bayt sayısı kazanır.

Test senaryoları

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

Yanıtlar:


8

Jöle , 11 10 bayt

ƓDUz0P€Uḅ³

Çevrimiçi deneyin!

Bunu kendim 10 bayta indiremedim, ama @ Pietu1998 beni kaçırdığım bir atomu gösterdi, bu da bu 10 baytlık çözümü verdi. Jelly için olağandışı bir şekilde, bu girdi 1276,933024komut satırından değil , standart girdiden (formda ) alınır (bu ³, komut satırı bağımsız değişkenini döndüren komutun kullanılmasını sağlar , varsayılan olarak 100'dür).

Açıklama:

Ɠ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

Baz 100 kullanımı "ped 2 haneye, daha sonra baz 10 dönüştürmek" tekniği uygulamak için basit bir yoludur. Buradaki tek ince şey tersine dönme; sayının başlangıcında sıfırlarla doldurmak istiyoruz, ancak zsonunda Jelly'in komut pedleri var, bu yüzden listelerin tersine çevrilmesi zdoğru bir şekilde yastığı anlamına geliyor .


3
10 bayt almak için b⁵ile değiştirebilirsiniz D. : P
PurkkaKoodari

4

Python 2, 99 bayt

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

Negatif girdi durumunda işareti hesaba katmak için bir çok bayt vardır. Python'da, pozitifse n%dher zaman negatif değildir 1 . Bence bu genellikle arzu edilir, ancak burada rahatsız edici görünüyor: çağrıları kaldırmak yukarıdaki kodu kıracaktır. Bu arada "yer değeri" ni (olanlar, yüzlerce, vb.) Takip eder ve aynı zamanda çıktının istenen işaretini hatırlar.dabsp

Kod temelde simetriktir avebwhile koşulda dışında : asıfır olana kadar devam ediyoruz ve o zaman sonlandırıyoruz. Tabii ki bönce sıfır ise , o zaman sıfır olana kadar bir süre sıfır ekleyeceğiz a.


1 Örneğin, (-33)%10döndürür 7ve (-33)/10öğesinin tamsayı bölümü -4. Bu doğru çünkü (-4)*10 + 7 = -33. Bununla birlikte, fermuar ürünü (-33)ile 33sona ermelidir3*3 = 09 yerine 7*3 = 21.


3

JavaScript (ES6), 44 bayt

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

Uygun şekilde bu otomatik olarak negatif sayılar için çalışır.


@ Jakube Bunu her zaman yapıyorum, en azından f=bayt sayısına dahil ettim . Ayrıca, |0tamsayı bölümüne ihtiyacım olduğu için, onsuz doğru cevabı aldığınızı nasıl düşündüğünüzü bilmiyorum.
Neil

Ah, bu mantıklı. Şimdi kaldırırken de yanlış cevaplar alıyorum |0. Belki de yeni fonksiyonun f'ye yeniden atanması işe yaramadı ve hala eski sürümü test ettim |0.
Jakube

2

C, 77 bayt

Fazlalıklı parantezleri kaldırmak için -2 bayt ( *ilişkilendirilebilir).

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, ... dolgu için kullanılır. Sıfır olduğu sürece aveya bolmadığı sürece son basamağı çarpmaya devam %10edin tve birikin. Ardından ave b( /=10) öğelerinin son basamağını kaldırın ve t2 basamak (*=100 ) .

Ungolfed ve kullanımı:

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

for(r=0;a|b;t*=100)r+=a%10*t*(b%10),a/=10,b/=10Bunun yerine önerr=0;while(a|b)r+=t*(a%10)*(b%10),a/=10,b/=10,t*=100
ceilingcat

1

Aslında , 23 19 bayt

Giriş iki dize olarak alınır. Ayrıca, görünüşe göre ais523'ün Jelly cevabında yaptığı gibi, taban 100'den dönüştürmeye çalışmak Aslında aslında iyi çalışmıyor. Çalışırsa 9 bayt da kurtarmış olurdu: / Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

Düzenleme: Sonucun yeni bir sayıya nasıl dönüştürüldüğünü değiştirmekten -4 bayt.

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

Ungolfing

          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 Bayt

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

Ungolfed:

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

burada%, önceki çıktı verimi anlamına gelir

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

Artık en uzun cevap (teşekkürler, Raket) ve aslında Python çözümünden daha kısa (nadir bir tedavi)! İki tamsayıyı girdi olarak alan anonim bir işlev.

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

İşte böyle.

Fermuar çarpımı, giriş sayılarını kurucu basamaklarına bölmeyi içerir.

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

Yani burada biz, bir rakam alıyoruz xve 99 diğer numaralar ile (modulo uygulanarak 10^99yoluyla 10^1). R dolaylı olarak x99 kez tekrar eder ve 99 elemanlı bir vektör (liste) döndürür. ( x %% 10^99, x %% 10^98,x %% 10^97 Vs.)

Biz kullanmak 10^99yoluyla 10^1. Daha verimli bir uygulama, en uzun sayıdaki basamak sayısının değerini kullanır (bu yayının düzenleme geçmişini kontrol edin; önceki sürümler bunu yaptı), ancak basitçe99..1 daha az bayt kullanır.

Bunun için x = 1276bize

1276 1276 1276 ... 1276 276 76 6

Daha sonra, sayıları yuvarlamak için 10'un gücünü azaltarak tamsayı bölmesini kullanıyoruz:

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

Bu,

0 0 0 ... 1 2 7 6

tam da istediğimiz temsil. Kodda, 10^(98:0)daha sonra tekrar kullanmak istiyoruz , bu yüzden onu bir değişkene atarız:

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

(Değerini atayarak, genel olarak, bu durumda ifade (değerlendirir R parantez içinde bir ifade sarılması 10^(98:0)içine ) ve daha sonra da diğer hesaplamalarda yerleştirme değişken atamaları bize izin ifade çıkış verir.)

Ardından, girişteki rakamların çift çarpımı yapılır. Çıkış daha sonra iki rakama kadar doldurulur ve birleştirilir. İki basamağa dolgu ve birleştirme, her sayının çarpılmasıyla eşdeğerdir 10^n, burada nsağ kenardan uzaklık ve daha sonra tüm sayıların toplanması.

 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

Çarpma değişmeli çünkü Özellikle, biz tarafından çarpma gerçekleştirebilirsiniz 10^n önce biz çarpın A tarafından B . Bu yüzden, daha önceki hesaplamalarımızı yaparız ve çarparız 10^(98:0):

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

eşdeğer

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

Bunu A'ya uyguladıktan sonra , tüm bu işlemi B'de tekrarlamak isteriz . Ama bu değerli baytlar gerektirir, bu yüzden bir işlevi tanımlarız, böylece sadece bir kez yazmamız gerekir:

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

Parantez içine gömme işlemimizi aynı anda bir işlevi tanımlayıp uygulamamıza, bu işlevi A ve B'de çağırıp bunları çoğaltmamıza izin vermek için yapıyoruz . (Bunu ayrı bir satırda tanımlayabilirdik, ancak sonunda tüm bunları anonim bir işleve koyacağımız için, birden fazla kod satırımız varsa, her şeyin kıvırcık parantezlerle sarılması gerekir, bu da değerli bayt.)

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

Ve bunların toplamını alıyoruz ve neredeyse bitti:

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

Şimdi dikkate alınması gereken tek şey girdinin işaretidir. Düzenli çarpma kurallarına uymak istiyoruz, bu yüzden A ve B'den biri ve sadece biri negatifse, çıktı negatiftir. Pozitif bir sayı verildiğinde ve negatif bir sayı verildiğinde signdönen fonksiyonu , tüm hesaplamalarımızı şu şekilde çarptığımız bir katsayı çıkarmak için kullanırız:1-1

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

Son olarak, her şey girdi olarak ave bgiriş olarak anonim bir işleve sarılır :

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

Boşluğu kaldırın ve 86 bayt.


Herkesin yararına, açıklanmamış, açıklanmış bir versiyon sunabilmeniz harika olacaktır.
rnso

Gönderiyi bir açıklama ile güncelledim.
rturnbull

İyi iş. Çok akıllı bir yöntem kullanılmıştır.
rnso

1

Python 3 , 92 bayt , 119 bayt

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

Çevrimiçi deneyin!

Negatif sayıları ele almak için düzeltme 29 bayt: /


Güzel cevap! lstripİçerideki her şeyi sararak int()ve bir sayı döndürerek parçayı değiştirebileceğinizi düşünüyorum .
ArBo

Haklısın. Sonra tutarlı bir arayüz tutmak gibi hissettim. İnt yerine argümanlar olarak dizeleri almak, sonra bir int döndürmek bana garip görünüyor;) Bir harita görüşmesi için döngü için zip + değiştirmek umuyordum, ama bu işe yaramaz: /
movatica

Ben kod golf tutarlılık hakkında çok endişe olmaz, ama size kalmış :). Bunu yapmak için ekstra bir lambda yapmanız gerekiyorsa, haritalama Python'da genellikle çok golf değildir.
ArBo

Bu işlev negatif girişler için başarısız görünüyor
ArBo

Haklısın: / Düzeltme oldukça pahalı, belki de golf oynamak için daha fazla potansiyel var.
movatica


0

PHP, 84 bayt

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

dize birleştirme ile biraz daha uzun (86 bayt):

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

0

Raket 325 bayt

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

Ungolfed:

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

Test yapmak:

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

Çıktı:

3001424
0
0
1203021800
-1000420803

0

PowerShell , 153 151 bayt

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+$)'

Çevrimiçi deneyin!

Daha az 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 bayt

@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

Ç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.