Mnożenie zamka błyskawicznego


20

Wprowadzenie

Zdefiniujmy nową operację arytmetyczną, którą nazywam mnożeniem suwaka . Aby zignorować pomnożenie dwóch nieujemnych liczb całkowitych, dodajesz zera wiodące, aby dopasować długości, mnożymy odpowiadające im 10-cyfrowe cyfry liczb, dodajesz zera wiodące do wyników, aby uzyskać 2-cyfrowe liczby, konkatenować je, a na końcu upuszczać zera wiodące.

Oto przykład z A = 1276 i 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

Operacja jest rozszerzona na wszystkie liczby całkowite ze zwykłymi regułami znakowania: czasy dodatnie ujemne są ujemne, czasy ujemne ujemne są dodatnie i tak dalej.

Zadanie

Twoje dane wejściowe to dwie liczby całkowite, a wynikiem jest ich pomnożenie przez suwak. Powinieneś być w stanie obsłużyć dowolnie duże dane wejściowe. Dane wejściowe i / lub wyjściowe mogą mieć format łańcuchowy (i rzeczywiście muszą być, jeśli twój język nie obsługuje dowolnie dużych liczb całkowitych). Pamiętaj, że -0nie jest to prawidłowe wejście lub wyjście.

Zasady i punktacja

Możesz napisać pełny program lub funkcję, a wygrywa najniższa liczba bajtów.

Przypadki testowe

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

Odpowiedzi:


8

Galaretka , 11 10 bajtów

ƓDUz0P€Uḅ³

Wypróbuj online!

Sam nie mogłem sprowadzić tego do 10 bajtów, ale @ Pietu1998 wskazało mi atom, za którym tęskniłem, co daje to 10-bajtowe rozwiązanie. Niezwykle w przypadku Jelly pobiera dane ze standardowego wejścia (w formie 1276,933024), a nie z wiersza poleceń (umożliwia to użycie ³polecenia, które zwraca argument wiersza poleceń, domyślnie 100).

Wyjaśnienie:

Ɠ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

Zastosowanie bazy 100 jest prostym sposobem na wdrożenie techniki „pad do 2 cyfr, a następnie konwersję do bazy 10”. Jedyną subtelną rzeczą jest tutaj cofanie; chcemy wstawić zera na początku liczby, ale Jellyz poleceń na końcu, więc odwrócenie list oznacza, że zbędzie padać poprawnie.


3
Można wymienić b⁵z Daby uzyskać 10 bajtów. : P
PurkkaKoodari

4

Python 2, 99 bajtów

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

Wiele bajtów ma na celu uwzględnienie znaku w przypadku negatywnych danych wejściowych. W Pythonie n%djest zawsze nieujemny, jeślid jest dodatni 1 . Moim zdaniem jest to na ogół pożądane, ale tutaj wydaje się niewygodne: usunięcie wywołań absspowoduje uszkodzenie powyższego kodu. Tymczasem pśledzi „wartość miejsca” (jedynki, setki itp.), A także zapamiętuje pożądany znak wyniku.

Kod jest zasadniczo symetryczny ai bpoza whilewarunkiem: kontynuujemy doa zera i w tym czasie. Oczywiście, jeśli bnajpierw jest zero, to przez pewien czas dodamy zera, aż do azera.


1 Na przykład (-33)%10zwraca 7, a iloraz liczby całkowitej (-33)/10wynosi -4. Jest to poprawne, ponieważ (-4)*10 + 7 = -33. Jednak produkt z zamkiem błyskawicznym (-33)z 33musi kończyć się 3*3 = 09raczej niż 7*3 = 21.


3

JavaScript (ES6), 44 bajty

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

Dogodnie działa to automatycznie dla liczb ujemnych.


@Jakube Zawsze to robię, chociaż przynajmniej uwzględniłem f=liczbę bajtów. Również |0dlatego, że muszę podział liczby całkowitej, nie wiem, jak myślisz, że jesteś coraz właściwą odpowiedź bez niego.
Neil,

Ach, to ma sens. Teraz również otrzymuję błędne odpowiedzi podczas usuwania |0. Być może ponowne przypisanie nowej funkcji do f nie zadziałało i nadal testowałem starą wersję |0.
Jakube,

2

C, 77 bajtów

-2 bajty do usuwania zbędnych nawiasów klamrowych ( *jest skojarzone).

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, ... służy do wypełnienia. Dopóki alub bnie jest zero keep multiplicating ostatnią cyfrę %10z ti akumuluj. Następnie usuń ostatnią cyfrę ai b( /=10) i przesuń to 2 cyfry ( *=100).

Niegolfowane i użytkowanie:

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

Zaproponuj for(r=0;a|b;t*=100)r+=a%10*t*(b%10),a/=10,b/=10zamiastr=0;while(a|b)r+=t*(a%10)*(b%10),a/=10,b/=10,t*=100
ceilingcat

1

Faktycznie , 23 19 bajtów

Dane wejściowe są traktowane jako dwa ciągi. Ponadto, najwyraźniej próba konwersji z bazy 100, jak robi ais523 w ich odpowiedzi na żelki, nie działa tak dobrze w rzeczywistości. Zaoszczędziłbym również 9 bajtów, gdyby zadziałało: / Sugestie dotyczące gry w golfa mile widziane! Wypróbuj online!

Edycja: -4 bajty od zmiany sposobu budowania wyniku na nową liczbę.

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 bajtów

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

Nie golfowany:

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

gdzie% oznacza poprzednią wydajność

{{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 bajtów

Nie jest to już najdłuższa odpowiedź (dzięki, Rakieta), a w rzeczywistości krótsza niż rozwiązanie Python (rzadka uczta)! Anonimowa funkcja, która przyjmuje dwie liczby całkowite jako dane wejściowe.

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

Oto jak to działa.

Mnożenie zamka błyskawicznego polega na dzieleniu liczb wejściowych na ich cyfry składowe. Bierzemy wartość bezwzględną liczby i wykonujemy modulo dla malejących mocy 10:

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

Więc bierzemy jedną liczbę xi stosujemy modulo z 99 innymi liczbami ( 10^99przez 10^1). R domyślnie powtarza się x99 razy, zwracając wektor (listę) z 99 elementami. ( x %% 10^99, x %% 10^98,x %% 10^97 Etc.)

Używamy 10^99przez 10^1. Bardziej wydajna implementacja wykorzystałaby wartość liczby cyfr w najdłuższej liczbie (sprawdź historię edycji tego postu; poprzednie wersje to zrobiły), ale po prostu biorąc99..1 mniej bajtów.

Za x = 1276to daje nam

1276 1276 1276 ... 1276 276 76 6

Następnie używamy dzielenia liczb całkowitych, zmniejszając moc 10, aby zaokrąglić liczby:

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

To daje

0 0 0 ... 1 2 7 6

która jest dokładnie taką reprezentacją, jakiej chcemy. W kodzie chcemy 10^(98:0)później użyć ponownie, więc przypisujemy go do zmiennej:

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

(Zawijanie wyrażenia w nawiasach w R zazwyczaj ocenia to wyrażenie (w tym przypadku przypisując wartość 10^(98:0)doe ), a następnie zwraca wynik wyrażenia, co pozwala nam osadzać przypisania zmiennych w innych obliczeniach.)

Następnie wykonujemy mnożenie par cyfr na wejściu. Dane wyjściowe są następnie dopełniane do dwóch cyfr i łączone. Dopełnianie do dwóch cyfr i łączenie jest równoznaczne z pomnożeniem każdej liczby przez 10^n, gdzie njest odległość od prawej krawędzi, a następnie zsumowaniem wszystkich liczb.

 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

Warto zauważyć, że ponieważ mnożenie jest przemienne, możemy wykonać mnożenie przez 10^n przed mnożymy A przez B . Tak więc bierzemy nasze wcześniejsze obliczenia i mnożymy przez 10^(98:0):

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

co jest równoważne z

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

Po zastosowaniu tego do A , to my wtedy chcą powtórzyć całą operację na B . Ale to zajmuje cenne bajty, więc definiujemy funkcję, więc musimy ją zapisać tylko raz:

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

Robimy naszą sztuczkę osadzania w nawiasach, aby umożliwić nam zdefiniowanie i zastosowanie funkcji w tym samym czasie, wywołanie tej funkcji na A i B i pomnożenie ich razem. (Moglibyśmy zdefiniować to w osobnej linii, ale ponieważ ostatecznie zamierzamy umieścić to wszystko w anonimowej funkcji, jeśli mamy więcej niż jedną linię kodu, wszystko musi być owinięte w nawiasy klamrowe, co kosztuje cenne bajtów).

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

I bierzemy sumę tego wszystkiego i jesteśmy prawie skończeni:

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

Jedyne, co należy teraz rozważyć, to znak danych wejściowych. Chcemy przestrzegać regularnych zasad mnożenia, więc jeśli jeden i tylko jeden z A i B jest ujemny, wynik jest ujemny. Używamy funkcji, signktóra zwraca, 1gdy otrzyma liczbę dodatnią i -1gdy otrzyma liczbę ujemną, w celu uzyskania współczynnika, który mnożymy przez całe nasze obliczenia przez:

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

Wreszcie, całość jest zapakowana w anonimową funkcję, która przyjmuje ai bjako dane wejściowe:

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

Usuń biały znak i jego 86 bajtów.


Będzie wspaniale, gdybyś mógł dostarczyć nieokreśloną, objaśnioną wersję z korzyścią dla wszystkich.
rnso

Zaktualizowałem post z wyjaśnieniem.
rturnbull

Dobra robota. Zastosowano bardzo sprytną metodę.
rnso

1

Python 3 , 92 bajty , 119 bajtów

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

Wypróbuj online!

Poprawka do obsługi liczb ujemnych kosztuje 29 bajtów: /


Niezła odpowiedź! Myślę, że możesz wymienić lstripczęść, pakując wszystko do środka int()i zwracając liczbę.
ArBo

Masz rację. Potem miałem ochotę zachować spójny interfejs. Przyjmowanie ciągów jako argumentów zamiast int, a następnie zwracanie int wygląda mi dziwnie;) Miałem raczej nadzieję zmienić pętlę zip + for dla wywołania mapy, ale to nie zadziałałoby: /
movatica

Nie martwiłbym się zbytnio konsekwencją w golfie kodowym, ale to zależy od ciebie :). Mapowanie zwykle nie jest zbyt golfowe w Pythonie, jeśli potrzebujesz dodatkowej lambdy, aby to zrobić.
ArBo

Ta funkcja wydaje się nie działać dla negatywnych danych wejściowych
ArBo

Masz rację: / Poprawka jest dość droga, może jest większy potencjał do gry w golfa.
movatica


0

PHP, 84 bajty

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

nieco dłużej z konkatenacją łańcuchów (86 bajtów):

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

0

Rakieta 325 bajtów

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

Nie golfowany:

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

Testowanie:

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

Wynik:

3001424
0
0
1203021800
-1000420803

0

PowerShell , 153 151 bajtów

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

Wypróbuj online!

Mniej golfa:

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 bajtów

@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

Wypróbuj online!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.