블라인드 이진 가산기


10

두 개의 상자가 B(x)있고 B(y)각각에 알 수없는 비트 -0 또는 1 F이 포함되어 있고 X-ray를 수행하고 B(x^y)( xor )에 대한 세 번째 상자를 생성 할 수 있는 기계가 있다고 가정합니다 . ( )를 F계산할 수도 있습니다 . 실제로, 이는 기계가 각각 내부 제품을 수행 할 수있는 단일 작업의 특수한 경우입니다 ( 아래 표시) .B(x*y)F()

동일한 길이의 배열 2 개

[B(x[0]), B(x[1]), ..., B(x[n-1])]
[B(y[0]), B(y[1]), ..., B(y[n-1])]

내부 제품 은 다음과 같이 정의됩니다

B(x[0]*y[0] ^ x[1]*y[1] ^ ... ^ x[n-1]*y[n-1])

" "수단 F()의 여러 쌍을 처리 할 수있는 x[], y[]한 번에. x[]y[]한 쌍의 동일한 길이이어야한다; 서로 다른 쌍의 x[]-s와 y[]-s는 반드시 필요한 것은 아닙니다.

상자는 고유 한 정수 ID로 표시됩니다.

JavaScript 로 된 내부 제품 의 구현은 다음과 같습니다.

var H=[0,1];          // hidden values, indexed by boxId
function B(x) {       // seal x in a new box and return the box id
  return H.push(x)-1;
}
function F(pairs) {   // "inner product each"
  return pairs.map(function (pair) {
    var r = 0, x = pair[0], y = pair[1];
    for (var i = 0; i < x.length; i++) r ^= H[x[i]] * H[y[i]];
    return B(r);
  })
}

(위의 언어를 원하는 언어로 번역하십시오.)

에 대한 접근을 감안할 때 F()해당 언어에 맞게 구현 (그러나 액세스 할 수 없음 H또는 B()16 비트 두 정수의 이진 표현을 구성하는 박스 ID의 두 배열)와 부여 a하고 b, 당신의 작업에 대한 생산 상자 ID에있는 이진 표현을 16 비트는 의 a+b최소 번호 (폐기 오버 플로우) F()를 호출합니다.

F()가장 적은 시간 을 호출 하는 솔루션이 이깁니다. 호출 된 전체 x[],y[]페어 수를 세면 연결이 끊어집니다 F(). 더 적은 것이 좋습니다. 여전히 묶여 있으면 코드의 크기 (구현 자 F()와 도우미를 제외한 )는 기존 코드 골프 방식으로 우승자를 결정합니다. 답에 "MyLang, 123 통화, 456 쌍, 789 바이트"와 같은 제목을 사용하십시오.

함수 나 완전한 프로그램을 작성하십시오. 입력 / 출력 / 인수 / 결과는 적절한 형식의 int 배열입니다. 이진 표현은 리틀 또는 빅 엔디안 일 수 있습니다. 하나를 선택하십시오.


부록 1 : 챌린지를 조금 더 쉽게하기 위해, ID가 0과 1 인 상자에 값 0과 1이 포함되어 있다고 가정 할 수 있습니다. 이는 부정에 유용한 상수를 제공합니다 ( x^1"not"). 물론 상수가 부족한 방법이 있었지만 나머지 과제는 어려우므로이 혼란을 제거합시다.


부록 2 : 현상금을 받으려면 다음 중 하나를 수행해야합니다.

  • 마감일 전에 점수 (전화, 쌍, 바이트) 및 코드를 게시하십시오.

  • 마감일 전에 점수와 코드의 sha256 해시를 게시하십시오. 마감일 후 23 시간 이내에 실제 코드를 게시하십시오.


이 언어를 선택한 언어 (Haskell)로 번역하면 값 재귀를 사용하고 F한 번만 호출 할 수 있습니다 . 그것은 부정 행위 일 것이지만, 부정 행위가 좋은지, 부정 행위인지는 확실하지 않습니다.
Christian Sievers

나는 Haskell에서 글로벌 상태가 환영받지 못한다는 것을 알고 있지만 이것을 생각 실험으로 물어 보도록하겠습니다. F 구현에서 글로벌 카운터를 늘리면 결국 얼마나 커질까요? - "전화 수"에 대한 나의 이해입니다.
ngn

정확히 그렇게 할 수 있고 1이라고 말할 수 있지만 코드를 사용하여 JavaScript로 다시 번역 할 수는 없습니다. 기본적으로 내가 말하고 싶지만 y=f(x)및하자 x에 달려있다 y.
Christian Sievers

어떻게 작동하는지 이해할 수 없습니다. 샘플 코드를 보여 주시겠습니까? 내 Haskell은 가난하지만 코드로 재생할 수 있는지 알아낼 수 있습니다.
ngn

아마도 다음 유형을 사용하여이 문제를 모델링 할 수 있습니까? data Box = B Int deriving (Show); f :: [[[Box]]] -> [Box]구현 방법을 알아내는 데 더 많은 시간이 필요합니다 f(여기서는 Haskell Force 소문자). 내일 시험해 볼 것입니다.
ngn

답변:


6

파이썬 3 , 5 호출, 92 쌍, 922 바이트

Python 3 , 5 호출, 134 쌍, 3120 바이트

Python 3 , 6 호출, 106 쌍, 2405 바이트

[자바 스크립트 (Node.js)], 9 건, 91 쌍, 1405 바이트

자바 스크립트 (Node.js), 16 개의 호출, 31 쌍, 378 바이트

def add(F,a,b):r=[];p=lambda x:(x,x);q=lambda u,v,t:([u,v]+t[0],[u,v]+t[1]);s=lambda c,k,n:([e[j][n]for j in range(k,-1,-1)]+[f[n]],[c]+f[n-k:n+1]);t=lambda c,k,n:q(a[n],b[n],s(c,k,n-1));z=F([p([a[i],b[i]])for i in range(16)]+[([a[i]],[b[i]])for i in range(16)]);e=[z[0:16]];f=z[16:32];r+=[e[0][0]];c=f[0];z=F([p([a[1],b[1],c]),([e[0][1],f[1]],[c,f[1]])]+[([e[0][i]],[e[0][i-1]])for i in range(3,16)]);r+=[z[0]];c=z[1];e+=[[0]*3+z[2:15]];z=F([p([a[2],b[2],c]),t(c,0,3),s(c,1,3)]+[([e[j][i]],[e[1][i-j-1]])for j in range(2)for i in range(6+j,16)]);r+=z[0:2];c=z[2];e+=u(2,4,z[3:]);z=F([p([a[4],b[4],c])]+[t(c,i,i+5)for i in range(0,3)]+[s(c,3,7)]+[([e[j][i]],[e[3][i-j-1]])for j in range(4)for i in range(12+j,16)]);r+=z[0:4];c=z[4];e+=u(4,8,z[5:]);z=F([p([a[8],b[8],c])]+[t(c,i,i+9) for i in range(0,7)]);return r+z
def u(b,e,z):
	j=0;w=[0]*(e-b)
	for i in range(b,e):w[i-b]=[0]*(i+e)+z[j:j+16-(i+e)];j+=16-(i+e)
	return w

온라인으로 사용해보십시오!

첫 번째 버전 좋아. 골프는 아니야. 그것은 단지 @ngn의 코드의 적응 일뿐입니다.

여기서 유일한 아이디어는 오버플로를 버린 이후 마지막 캐리를 계산할 필요가 없다는 것입니다. 또한 통화는 F2 개로 그룹화됩니다. 어쩌면 그것들은 다른 방식으로 그룹화 될 수도 있지만 기본 추가 알고리즘의 특성으로 인해 쌍 수를 크게 줄일 수는 없을 것입니다.

편집 : 여전히 골프하지 않습니다. 쌍 수는 확실히 줄어들 수 있으며 아마도 전화 수도 줄어들 수 있습니다. sympy가있는 "증거"에 대해서는 https://gist.github.com/jferard/864f4be6e4b63979da176bff380e6c62 를 참조 하십시오 .

편집 2 더 읽기 쉽기 때문에 Python으로 전환했습니다. 이제 나는 일반 공식을 얻었습니다 .5 (아마도 4) 통화 한도에 도달 할 수 있다고 생각합니다.

편집 3 기본 벽돌은 다음과 같습니다.

alpha[i] = a[i] ^ b[i]
beta[i] = a[i] * b[i]
c[0] = beta[0]
r[0] = alpha[0]

일반적인 공식은 다음과 같습니다.

c[i] = alpha[i]*c[i-1] ^ beta[i]
r[i] = a[i] ^ b[i] ^ c[i-1]

확장 된 버전은 다음과 같습니다.

c[0] = beta[0]
c[1] = alpha[1]*beta[0] ^ beta[1]
c[2] = alpha[2]*alpha[1]*beta[0] ^ alpha[2]*beta[1] ^ beta[2]
c[3] = alpha[3]*alpha[2]*alpha[1]*beta[0] ^ alpha[3]*alpha[2]*beta[1] ^ alpha[3]*beta[2] ^ beta[3]
...
c[i] = alpha[i]*...*alpha[1]*beta[0] ^ alpha[i]*...*alpha[2]*beta[1] ^ .... ^ alpha[i]*beta[i-1] ^ beta[i]

5 번의 전화는 저에게 한계 인 것 같습니다. 이제 쌍을 제거하고 골프를 치기 위해 약간의 작업이 있습니다!

편집 4 나는 이것을 골프했다.

언 골프 버전 :

def add(F, a, b):
    r=[]
    # p is a convenient way to express x1^x2^...x^n
    p = lambda x:(x,x)
    # q is a convenient way to express a[i]^b[i]^carry[i-1]
    q = lambda u,v,t:([u,v]+t[0],[u,v]+t[1])

    # step1: the basic bricks
    z=F([p([a[i],b[i]]) for i in range(16)]+[([a[i]],[b[i]]) for i in range(16)])
    alpha=z[0:16];beta=z[16:32]
    r.append(alpha[0])
    c = beta[0]

    # step 2
    z=F([
        p([a[1],b[1],c]),
        ([alpha[1],beta[1]],[c,beta[1]])
        ]+[([alpha[i]],[alpha[i-1]]) for i in range(3,16)])
    r.append(z[0])
    c = z[1] # c[1]
    alpha2=[0]*3+z[2:15]
    assert len(z)==15, len(z)

    # step 3
    t0=([alpha[2],beta[2]],[c,beta[2]])
    t1=([alpha2[3],alpha[3],beta[3]],[c,beta[2],beta[3]])
    z=F([
        p([a[2],b[2],c]),
        q(a[3],b[3],t0),
        t1]+
        [([alpha[i]],[alpha2[i-1]]) for i in range(6,16)]+
        [([alpha2[i]],[alpha2[i-2]]) for i in range(7,16)])
    r.extend(z[0:2])
    c = z[2] # c[3]
    alpha3=[0]*6+z[3:13]
    alpha4=[0]*7+z[13:22]
    assert len(z)==22, len(z)

    # step 4
    t0=([alpha[4],beta[4]],[c,beta[4]])
    t1=([alpha2[5],alpha[5],beta[5]],[c,beta[4],beta[5]])
    t2=([alpha3[6],alpha2[6],alpha[6],beta[6]],[c,beta[4],beta[5],beta[6]])
    t3=([alpha4[7],alpha3[7],alpha2[7],alpha[7],beta[7]],[c,beta[4],beta[5],beta[6],beta[7]])
    z=F([
        p([a[4],b[4],c]),
        q(a[5],b[5],t0),
        q(a[6],b[6],t1),
        q(a[7],b[7],t2),
        t3]+
        [([alpha[i]],[alpha4[i-1]]) for i in range(12,16)]+
        [([alpha2[i]],[alpha4[i-2]]) for i in range(13,16)]+
        [([alpha3[i]],[alpha4[i-3]]) for i in range(14,16)]+
        [([alpha4[i]],[alpha4[i-4]]) for i in range(15,16)])
    r.extend(z[0:4])
    c = z[4] # c[7]
    alpha5 = [0]*12+z[5:9]
    alpha6 = [0]*13+z[9:12]
    alpha7 = [0]*14+z[12:14]
    alpha8 = [0]*15+z[14:15]
    assert len(z) == 15, len(z)

    # step 5
    t0=([alpha[8],beta[8]],[c,beta[8]])
    t1=([alpha2[9],alpha[9],beta[9]],[c,beta[8],beta[9]])
    t2=([alpha3[10],alpha2[10],alpha[10],beta[10]],[c,beta[8],beta[9],beta[10]])
    t3=([alpha4[11],alpha3[11],alpha2[11],alpha[11],beta[11]],[c,beta[8],beta[9],beta[10],beta[11]])
    t4=([alpha5[12],alpha4[12],alpha3[12],alpha2[12],alpha[12],beta[12]],[c,beta[8],beta[9],beta[10],beta[11],beta[12]])
    t5=([alpha6[13],alpha5[13],alpha4[13],alpha3[13],alpha2[13],alpha[13],beta[13]],[c,beta[8],beta[9],beta[10],beta[11],beta[12],beta[13]])
    t6=([alpha7[14],alpha6[14],alpha5[14],alpha4[14],alpha3[14],alpha2[14],alpha[14],beta[14]],[c,beta[8],beta[9],beta[10],beta[11],beta[12],beta[13],beta[14]])
    t7=([alpha8[15],alpha7[15],alpha6[15],alpha5[15],alpha4[15],alpha3[15],alpha2[15],alpha[15],beta[15]],[c,beta[8],beta[9],beta[10],beta[11],beta[12],beta[13],beta[14],beta[15]])

    z=F([
        p([a[8],b[8],c]),
        q(a[9],b[9],t0),
        q(a[10],b[10],t1),
        q(a[11],b[11],t2),
        q(a[12],b[12],t3),
        q(a[13],b[13],t4),
        q(a[14],b[14],t5),
        q(a[15],b[15],t6)
    ])
    r.extend(z)
    return r

온라인으로 사용해보십시오!


아주 좋은 :) 당신은 내가 의도적으로 생략 한 두 가지 쉬운 최적화를 발견했습니다. "페어 수를 대폭 줄일 수 있을지 의심됩니다"-우승의 첫 번째 기준은에 대한 전화 수 F()입니다. 나는 그것들을 크게 줄일 수있는 방법이 있음을 보증하고 (이 도전의 가장 어려운 부분), 쌍 수를 최적화하고, 결국 코드를 ​​골프로 칠 수있는 여지가있을 것입니다 (그러나 그것은 가장 중요한 기준입니다).
ngn

알았어! 조만간, 당신은 다음과 같은 것을 얻었습니다 : ... + x * y * z + .... 우리는 F그것을 평가하는 데 사용할 수 없지만 x * y이전 F호출로 계산했다면 ... + (x * y) * z + ...다음과 같이하면됩니다 (의 형식과 일치 F). sympy와 함께 연주하면서 통화를 절약 할 수있었습니다 (1 단계 : r0, c0, r1 계산; 2 단계 : c1 및 일부 aux 값 계산; 3 단계 : r2, c2, r3, c3 계산). 해결책.
jferard

다시 말하면, 출력 비트는 입력 비트에서 2보다 큰 차수의 다항식입니다. 내부 제품은 m도 및 n도 다항식을 최대 (m + n)도 다항식으로 결합 할 수 있습니다. 서두르지 마십시오-몇 시간 안에 현상금을 설정할 수 있습니다 :)
ngn

위의 부록 2를 활용하는 것이 좋습니다. 그렇지 않으면 : 누군가가 코드를 복사하고 공간을 제거한 다음 다시 게시하면 기술적으로 보너스를 부여해야합니다.
ngn

2
레코드에는 32도 다항식이 필요하므로 5 개 미만의 호출을 사용하는 것은 불가능합니다. (입력 비트의 모든 기능에 해당하는 다항식은 고유합니다.)
Nitrodon

2

Haskell, 1 개의 호출 (부정 행위 ???), 32 쌍 (향상 될 수 있음), 283 바이트 (동일)

나에게 화 내지 말고, 이기고 싶지 않지만, 내가 말하고있는 것을 설명하는 도전에 대한 발언에서 격려를 받았다.

상태 모나드를 사용하여 상자 추가 및 통화 및 쌍 계산을 처리하려고 시도했지만 효과가 있었지만 해당 설정에서 솔루션을 작동시키지 못했습니다. 그래서 의견에서 제안 된 것을했습니다. 데이터 생성자 뒤에 데이터를 숨기고 들여다 보지 마십시오. (깨끗한 방법은 별도의 모듈을 사용하고 생성자를 내 보내지 않는 것입니다.)이 버전은 훨씬 단순하다는 장점이 있습니다.

비트 박스에 대해 이야기하고 있기 때문에 Bool값을 넣습니다. 나는 zero0 비트가있는 주어진 상자로 정의 합니다-a one는 필요하지 않습니다.

import Debug.Trace

data B = B { unB :: Bool }

zero :: B
zero = B False

f :: [([B],[B])] -> [B]
f pairs =  trace ("f was called with " ++ show (length pairs) ++ " pairs") $
           let (B i) &&& (B j) = i && j
           in map (\(x,y) ->  B ( foldl1 (/=) (zipWith (&&&) x y))) pairs

우리는 디버깅 함수 trace를 사용하여 얼마나 자주 f호출되었고 얼마나 많은 쌍을 가지고 있는지 확인합니다. &&&패턴 일치로 상자를 살펴보면 값에 /= 사용되는 부등식 Boolxor입니다.

bits :: Int -> [Bool]
bits n = bitsh n 16
  where bitsh _ 0 = []
        bitsh n k = odd n : bitsh (n `div` 2) (k-1)

test :: ( [B] -> [B] -> [B] ) -> Int -> Int -> Bool
test bba n m = let x = map B (bits n)
                   y = map B (bits m)
                   r = bba x y
                   res = map unB r
               in res==bits(n+m)

test함수는 블라인드 이진 가산기를 첫 번째 인수로 사용한 다음 추가를 테스트 할 두 개의 숫자를 사용합니다. Bool테스트 성공 여부를 나타내는 표시를 리턴합니다 . 먼저 입력 상자가 생성 된 다음 가산기가 호출되고 결과가 상자가 풀리고 (로 unB) 예상 결과와 비교됩니다.

샘플 솔루션이라는 두 개의 가산기를 구현 simple하여 디버그 출력이 올바르게 작동하고 값 재귀를 사용하는 솔루션을 볼 수 있습니다 valrec.

simple a b = let [r0] = f [([a!!0,b!!0],[a!!0,b!!0])]
                 [c]  = f [([a!!0],[b!!0])]
             in loop 1 [r0] c
             where loop 16 rs _ = rs
                   loop i  rs c = let [ri] = f [([a!!i,b!!i,c],[a!!i,b!!i,c])]
                                      [c'] = f [([a!!i,b!!i,c],[b!!i,c,a!!i])]
                                  in loop (i+1) (rs++[ri]) c'

valrec a b =
    let res = f (pairs res a b)
    in [ res!!i | i<-[0,2..30] ]
  where pairs res a b =
           let ts = zipWith3 (\x y z -> [x,y,z])
                             a b (zero : [ res!!i | i<-[1,3..29] ]) in
           [ p | t@(h:r) <- ts, p <- [ (t,t), (t,r++[h]) ] ]

res그 자체로 어떻게 정의하는지 봅니까? 그것은 매듭묶는 것으로 알려져 있습니다.

이제 f한 번만 호출되는 방법을 볼 수 있습니다 .

*Main> test valrec 123 456
f was called with 32 pairs
True

또는 교체 valrecsimplef32 번 호출된다.

온라인으로 사용해보십시오! (추적 출력은 "디버그"아래에 나타납니다)


여기에 분노가 없습니다 :), 내가 올바르게 이해한다면,에 대한 논쟁 f은 당신이 그것을 반복 할 때 구체화되는 게으르고 잠재적으로 무한한 목록입니까? 나는 그것이 도전의 정신에 위배된다는 것을 두려워합니다.-에 해당하는 결과를 얻은 후에i+1 까지 -st 인수 로 무엇을 전달할지에 대한 결정을 연기 할 수 있습니다 . 완전히 구체화되고 불변 인 인수로 얼마나 많은 호출 이 필요한지 알아내는 것이 훨씬 더 흥미 롭습니다. :)if
ngn

동의한다. @jferard는 그러한 트릭으로 무효화해서는 안되는 놀라운 작업을 수행했습니다. f무한 입력을 할 수는 있지만 (무한 비트 스트림을 추가하십시오!)! 아, 실제로 trace메시지는 길이가 유한하고 처음에 알려 졌음을 보장합니다. 또한, 나는 연기 된 결정이 있다고 말하지 않을 것입니다. 요구에 따라 모든 것이 맹목적으로 셔플 박스입니다. 그리고 그것은 논쟁의 순서가 아니라는 것을 주목하십시오 : 나는 res먼저 결과와 캐리 비트 를 포함 하도록 그것을 바꿀 수 있습니다 .
Christian Sievers

"나는 단지 맹목적으로 상자를 섞고있다"-전화를 통해 상자를 얻었다 고 가정하자 f. 동일한 호출 에서 해당 상자를 다른 인수 로 피드백 f합니까?
ngn

네 저도 그렇습니다. 이것이 바로 가치 재귀입니다. 당신은 그 권리를 가지고 있습니다 : 그것은 게으름을 사용하고 있으며 완전히 구체화 되지 않은 인수를 사용할 수 있다는 사실입니다 (나는 그 설명을 좋아합니다). 도전의 분명한 정신을 감안할 때, 그것은 발표 된대로 분명히 부정 행위입니다. 그것이 독창적이거나 주목할 만하다고 생각한다면, 좋은 속임수라고 주장 할 수 있습니다.
Christian Sievers

그것은 분명히 좋은 종류입니다-분명히 당신은 여기에 속일 의도가 없습니다. 함수형 프로그래밍의 게으름은 아름다운 개념이며 올바른 용도로 사용됩니다. 몇 년 전에 하스켈을 배우려고했을 때, 피보나치 수를 위해 "매듭을 묶는"한 줄짜리 라이너에 깊은 인상을 받았던 것을 기억합니다.
ngn

0

자바 스크립트, 32 개의 호출, 32 쌍, 388 바이트

Dyalog APL, 32 개의 호출, 32 쌍, 270 바이트

템플릿으로 사용할 수있는 순진한 샘플 솔루션입니다.

바이트 수에는 "BEGIN / END SOLUTION"으로 둘러싸인 섹션 만 포함되어야합니다.

설명:

리틀 엔디안 비트 순서를 선택했습니다 ( x[0]가장 중요한 비트입니다).

단일 비트 덧셈 mod 2는 F([[[x,y],[x,y]]])(즉 x*x ^ y*y, 곱셈 mod 2는 ent 등원)으로, 이진 곱셈 은으로 실현 될 수 있습니다 F([[[x],[y]]]).

우리는 비트를 최하위에서 최하위로 트래버스하고 각 단계에서 결과 비트와 캐리를 계산합니다.

#!/usr/bin/env node
'use strict'
let H=[0,1]
,B=x=>H.push(x)-1
,nCalls=0
,nPairs=0
,F=pairs=>{
  nCalls++;nPairs+=pairs.length
  return pairs.map(([x,y])=>{let s=0;for(let i=0;i<x.length;i++)s^=H[x[i]]*H[y[i]];return B(s)})
}

// -----BEGIN SOLUTION-----
var f=(a,b)=>{
  var r=[], c // r:result bits (as box ids), c:carry (as a box id)
  r[0]=F([[[a[0],b[0]],[a[0],b[0]]]])          // r0 = a0 ^ b0
  c=F([[[a[0]],[b[0]]]])                       // c = a0*b0
  for(var i=1;i<16;i++){
    r.push(F([[[a[i],b[i],c],[a[i],b[i],c]]])) // ri = ai ^ bi ^ c
    c=F([[[a[i],b[i],c],[b[i],c,a[i]]]])       // c = ai*bi ^ bi*c ^ c*ai
  }
  return r
}
// -----END SOLUTION-----

// tests
let bits=x=>{let r=[];for(let i=0;i<16;i++){r.push(x&1);x>>=1}return r}
,test=(a,b)=>{
  console.info(bits(a))
  console.info(bits(b))
  nCalls=nPairs=0
  let r=f(bits(a).map(B),bits(b).map(B))
  console.info(r.map(x=>H[x]))
  console.info('calls:'+nCalls+',pairs:'+nPairs)
  console.assert(bits(a+b).every((x,i)=>x===H[r[i]]))
}

test(12345,6789)
test(12,3)
test(35342,36789)

Dyalog APL에서도 동일하지만 무작위 상자 ID를 사용합니다.

⎕io←0⋄K←(V←⍳2),2+?⍨1e6⋄B←{(V,←⍵)⊢K[≢V]}⋄S←0⋄F←{S+←1,≢⍵⋄B¨2|+/×/V[K⍳↑⍉∘↑¨⍵]}
⍝ -----BEGIN SOLUTION-----
f←{
  r←F,⊂2⍴⊂⊃¨⍺⍵        ⍝ r0 = a0 ^ b0
  c←⊃F,⊂,¨⊃¨⍺⍵        ⍝ c = a0*b0
  r,⊃{
    ri←⊃F,⊂2⍴⊂⍺⍵c     ⍝ ri = ai ^ bi ^ c
    c⊢←⊃F,⊂(⍺⍵c)(⍵c⍺) ⍝ c = ai*bi ^ bi*c ^ c*ai
    ri
  }¨/1↓¨⍺⍵
}
⍝ -----END SOLUTION-----
bits←{⌽(16⍴2)⊤⍵}
test←{S⊢←0⋄r←⊃f/B¨¨bits¨⍺⍵
      ⎕←(↑bits¨⍺⍵)⍪V[K⍳r]⋄⎕←'calls:' 'pairs:',¨S
      (bits⍺+⍵)≢V[K⍳r]:⎕←'wrong!'}
test/¨(12345 6789)(12 3)(35342 36789)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.