지퍼 곱셈


20

소개

지퍼 곱셈 이라고하는 새로운 산술 연산을 정의 해 봅시다 . 음수가 아닌 두 정수를 지퍼로 곱하려면 앞에 0을 추가하여 길이를 일치시키고 숫자의 해당 10 자릿수를 곱하고 결과에 선행 0을 추가하여 2 자리 숫자를 얻고 연결 한 다음 마지막으로 0을 떨어 뜨립니다.

다음은 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으로 변환"기술을 구현하는 간단한 방법입니다. 여기서 다른 미묘한 것은 반전입니다. 우리는 숫자의 시작 부분에 0을 채우고 싶지만 Jelly의 z명령 패드는 끝 부분에 있으므로 목록을 되 돌리면 z올바르게 채워집니다.


3
당신은 대체 할 수 b⁵D10 바이트를 얻을 수 있습니다. : P
PurkkaKoodari

4

파이썬 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

음수 입력의 경우 부호를 설명하기 위해 많은 바이트가 있습니다. 파이썬에서는 양수가 1n%d 이면 항상 음수가 아닙니다 . 내 의견으로는 이것은 일반적으로 바람직하지만 여기서 불편한 것 같습니다. 호출을 제거 하면 위의 코드가 손상됩니다. 한편 "장소 값"(1, 수백 등)을 추적하고 원하는 출력 부호를 기억합니다.dabsp

코드에서 기본적으로 대칭 ab에서 제외 while조건 : 우리가 계속 될 때까지 a제로이고, 그 시간에 종료합니다. 물론 b0이 먼저이면 0이 될 때까지 잠시 동안 0을 추가하게됩니다 a.


1 예를 들어,를 (-33)%10반환 7하고 정수 몫은 (-33)/10입니다 -4. 때문에 그렇습니다 (-4)*10 + 7 = -33. 그러나 (-33)with 의 지퍼 제품은 대신에 33끝나야합니다 .3*3 = 097*3 = 21


3

자바 스크립트 (ES6), 44 바이트

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

편리하게 이것은 음수에 자동으로 작동합니다.


@Jakube 적어도 f=바이트 수에 포함했지만 항상 그렇게하고 있습니다. 또한 |0정수 나눗셈이 필요하기 때문에 이것이 없으면 올바른 답변을 얻는 방법을 모르겠습니다.
Neil

아, 말이 되네요. 이제 제거 할 때 잘못된 답변을 얻습니다 |0. 어쩌면 새 함수를 f에 다시 할당해도 작동하지 않았고 여전히 이전 버전을로 테스트했습니다 |0.
Jakube

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마지막 자리 multiplicating 제로 킵하지 %10t축적가. 이어서 마지막 자리의 erease ab( /=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 바이트

입력은 두 개의 문자열로 간주됩니다. 또한 ais523이 젤리 답변 에서처럼 기본 100에서 변환하려고 시도하는 것은 실제로 그렇게 잘 작동하지 않습니다. 작동하면 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

매스 매 티카 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 바이트

더 이상 가장 긴 답변 (감사, 라켓)이 아니며 실제로 파이썬 솔루션보다 짧습니다 (드문 취급)! 두 개의 정수를 입력으로 사용하는 익명 함수입니다.

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)

그래서 여기에 우리는 하나 개의 숫자를 복용하고 x, 99 개 다른 숫자 (과 모듈을 적용 10^99을 통해 10^1). R은 암시 적으로 x99 번 반복 되어 99 개의 요소가있는 벡터 (목록)를 반환합니다. ( x %% 10^99, x %% 10^98, x %% 10^97등)

우리는를 10^99통해 사용 합니다 10^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)to 값을 할당 e) 표현식의 출력을 반환하여 다른 계산에 변수 할당을 포함시킬 수 있습니다.)

다음으로 입력의 숫자를 쌍으로 곱합니다. 그런 다음 출력은 두 자리 숫자로 채워지고 연결됩니다. 두 자리와 접합하는 패딩에 의해 각각 승산 수가 동등 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

우리는 괄호 안에 포함하는 트릭을 사용하여 함수를 정의하고 동시에 적용하고 AB 에서이 함수를 호출 하고 함께 곱할 수 있습니다. (우리는 별도의 줄에 정의 할 수 있었지만 결국에는이 모든 것을 익명 함수에 넣을 것이므로 둘 이상의 코드 줄이 있으면 모든 것을 중괄호로 묶어야합니다. 바이트)

(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 중 하나만 음수이면 출력은 음수입니다. 양수와 음수가 주어 졌을 때 sign반환 하는 함수 를 사용하여 전체 계산에 곱하는 계수를 출력합니다.1-1

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

마지막으로, 모든 일이 소요 익명 함수에 싸여 ab입력으로 :

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

잘 했어. 매우 영리한 방법이 사용되었습니다.
rnso

1

파이썬 3 , 92 바이트 , 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를 반환하는 것은 나에게 이상한 모양) 차라리지도 호출을위한 루프 우편 +를 변경하기를 희망하지만이 작동하지 않을 것입니다 : /
movatica

코드 골프의 일관성에 대해 너무 걱정하지 않지만 그것은 당신에게 달려 있습니다 :). 파이썬에서 람다를 추가로 만들어야 할 경우 매핑은 일반적으로 골치 거리가 아닙니다.
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

PowerShell , 153151 바이트

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.