ジッパー掛け算


20

前書き

新しい算術演算を定義しましょう。これをジッパー乗算と呼びます。。2つの非負整数をジッパー乗算するには、長さを一致させるために先行ゼロを追加し、対応する10桁の数字を乗算し、結果に先行ゼロを追加して2桁の数字を取得し、それらを連結し、最後に先行ゼロをドロップします。

A = 1276および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

演算は、通常の符号規則を使用してすべての整数に拡張されます。正の時間の負は負、負の時間の負は正などとなります。

タスク

入力は2つの整数であり、出力はジッパー乗算です。任意の大きな入力を処理できる必要があります。入力および/または出力は文字列形式にすることができます(言語が任意の大きな整数をサポートしていない場合、実際にそうでなければなりません)。ご了承ください-0は有効な入力または出力はない。

ルールとスコアリング

あなたは完全なプログラムまたは関数を書くことができ、最も低いバイト数が勝ちます。

テストケース

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

回答:


8

ゼリー11 10バイト

ƓDUz0P€Uḅ³

オンラインでお試しください!

私はこれを自分で10バイトに減らすことはできませんでしたが、@ Pietu1998は私が見逃した原子を指し示し、この10バイトの解決策を与えました。Jellyにとっては珍しいことですが、これ1276,933024はコマンドラインからではなく、標準入力(フォーム)から入力を取得します(これにより³、コマンドライン引数を返すコマンドの使用が可能になります。デフォルトは100です)。

説明:

Ɠ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

ベース100の使用は、「2桁にパッドしてからベース10に変換する」技術を実装する簡単な方法です。ここでの唯一の他の微妙なことは逆転です。数字の先頭にゼロを埋め込みますが、Jellyのzコマンドは末尾に埋め込みますz。リストを逆にすると、正しく埋め込みが行われます。


3
で置き換えb⁵D、10バイトを取得できます。:P
PurkkaKoodari 16

4

Python 2、99バイト

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

多くのバイトは、負の入力の場合に符号を説明するためにあります。Pythonでは、n%dd正の場合、常に負ではありません1。私の意見では、これは一般的に望ましいことですが、ここでは不便に思われabsます。一方p、「場所の値」(1、100など)を追跡し、出力の目的の符号も記憶します。

コードは基本的に対称でaありbwhile条件を除きます。aゼロになるまで続け、その時点で終了します。もちろん、bが最初にゼロである場合、ゼロになるまでしばらくゼロを追加することになりaます。


1たとえば、(-33)%10はを返し7、整数の商は(-33)/10です-4。これは正しいため(-4)*10 + 7 = -33です。しかし、のジッパー製品(-33)では、33内終わらなければならない3*3 = 09のではなく7*3 = 21


3

JavaScript(ES6)、44バイト

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

便利なことに、これは負の数に対して自動的に機能します。


@Jakube少なくともそれをf=バイトカウントに含めましたが、私は常にそれを行っています。また、|0整数除算が必要だからです。整数除算がなければ正しい答えが得られるとは思いません。
ニール

ああ、それは理にかなっています。今、私は削除するときに間違った答えを得る|0。たぶん、新しい関数のfへの再割り当ては機能しなかったので、古いバージョンをまだテストしました|0
寂部16

2

C、77バイト

冗長な中括弧を削除するための-2バイト(*結合的)。

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、...はパディングに使用されます。aまたはbがゼロでない限り、最後の数字%10を乗算し続けtます。次に、aand b/=10)の最後の桁を消去し、t2桁シフトします(*=100)。

ゴルフをしないと使用法:

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/=10代わりにr=0;while(a|b)r+=t*(a%10)*(b%10),a/=10,b/=10,t*=100
ceilingcat

1

実際には23 19バイト

入力は2つの文字列として取得されます。また、ais523がJellyの回答で行っているように、明らかにベース100から変換しようとしても、Actuallyではうまく機能しません。うまくいけば9バイトも節約できただろう:/ゴルフの提案を歓迎します!オンラインでお試しください!

編集:結果が新しい数値にどのように構築されるかを変更することから-4バイト。

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

アンゴルフ

          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バイト

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

ゴルフをしていない:

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

ここで、%は前の出力がもたらすことを意味します

{{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バイト

最長の回答ではなく(ありがとう、Racket)、実際にはPythonソリューションよりも短い(珍しい御)走)!入力として2つの整数を取る匿名関数。

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

仕組みは次のとおりです。

ジッパー乗算では、入力数値を構成桁に分割します。数値の絶対値を取得し、10の累乗の降順でモジュロを実行します。

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

したがって、ここでは、1つの数値、xおよび99の他の数値(10^9910^1)にモジュロを適用しています。Rは暗黙的にx99回繰り返し、99要素のベクトル(リスト)を返します。(x %% 10^99x %% 10^98x %% 10^97、等)

使用し10^9910^1ます。より効率的な実装では、最も長い数字の桁数の値を使用します(この投稿の編集履歴を確認します。以前のバージョンではこれを行いました)が、単に99..1使用するバイト数が少なくなります。

以下のためにx = 1276これは私たちを与えます

1276 1276 1276 ... 1276 276 76 6

次に、10の累乗を降順にする整数除算を使用して、数値を切り上げます。

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

これにより

0 0 0 ... 1 2 7 6

これはまさに私たちが望む表現です。コードでは、10^(98:0)後で再び使用したいので、変数に割り当てます。

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

(Rの括弧で式をラップすると、一般的に式が評価され(この場合、値にが割り当て10^(98:0)られますe)、式の出力も返されるため、他の計算に変数の割り当てを埋め込むことができます。)

次に、入力の桁のペアワイズ乗算を実行します。次に、出力は2桁に埋め込まれ、連結されます。2桁のパディングと連結は10^n、各数値にを乗算することと同等です。ここでnは右端からの距離であり、すべての数値を合計します。

 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

特に、乗算は可換であるため、ABを乗算する10^n に乗算を実行できます。したがって、以前の計算を使用して乗算します。10^(98:0)

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

これは

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

これをAに適用した後、この操作全体をBで繰り返します。しかし、それは貴重なバイトを必要とするため、関数を定義するので、一度書くだけで済みます。

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

括弧内埋め込みのトリックを実行して、関数を同時に定義および適用し、AおよびBでこの関数を呼び出して、それらを一緒に乗算できるようにします。(別の行で定義することもできますが、最終的にはこれらすべてを匿名関数に入れるため、複数行のコードがある場合は、すべてを中括弧で囲む必要があります。バイト。)

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

そして、これらすべての合計を取得し、ほぼ終了しました。

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

今考慮すべき唯一のことは、入力の符号です。通常の乗算​​規則に従う必要があるため、ABのいずれか1つだけが負の場合、出力は負になります。正の数と負の数が与えられたときにsign戻る関数を使用して、計算全体に次の値を乗算する係数を出力します。1-1

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

最後に、全体のことを取る匿名関数にラップされaかつb入力として:

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

空白を削除すると、86バイトになります。


皆の利益のために、説明のないバージョンを提供できれば素晴らしいことです。
rnso

説明付きで投稿を更新しました。
rturnbull 16

よくやった。非常に巧妙な方法が使用されます。
rnso 16

1

Pythonの392バイト、119のバイト

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

オンラインでお試しください!

負の数を処理するための修正は29バイトかかります:/


いい答えだ!lstripすべてを内側にラップしてint()数値を返すことで、部品を交換できると思います。
ArBo

あなたが正しい。それから、一貫したインターフェースを維持したい気がしました。intの代わりに文字列を引数に取り、intを返すのは奇妙に見えます;)むしろ、map呼び出しのzip + forループを変更したいのですが、
うまくいき

コードゴルフの一貫性についてはあまり心配しませんが、それはあなた次第です:)。マッピングは、通常、追加のラムダを作成する必要がある場合、Pythonではそれほど難しくありません。
ArBo

この関数は、負の入力に対して失敗するようです
ArBo

あなたの言うとおりです:/修正は非常に高価です。おそらくそれをゴルフで打ち落とす可能性がもっとあります。
movatica


0

PHP、84バイト

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

文字列の連結でわずかに長い(86バイト):

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

0

ラケット325バイト

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

ゴルフをしていない:

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

テスト:

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

出力:

3001424
0
0
1203021800
-1000420803

0

PowerShell153 151バイト

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

オンラインでお試しください!

少ないゴルフ:

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.