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
Zgarb
źródło

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.


źródło
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.

Mathmandan
źródło
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.

Neil
źródło
@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));
}
Karl Napf
źródło
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.
Sherlock9
źródło
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
Kelly Lowder
źródło
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.

rturnbull
źródło
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: /

movatica
źródło
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;
Tytus
źródło
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
rnso
źródło
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
mazzy
źródło
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!

Xcali
źródło