Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- int isZero(int* a)
- {
- if (a[0] == 0)
- return 1;
- int i = 1;
- for (; i<=a[0]; i++)
- if (a[i] != 0)
- return 0;
- return 1;
- }
- long long int arr2long (int* a)
- {
- if (a[0] == 0)
- return 0;
- long long int p2 = 1;
- p2 <<= (a[0]-1); // a[0] <= 30
- long long int res = 0;
- int i;
- for (i=1; i<=a[0]; i+=1, p2>>=1)
- res += (long long int)a[i]*p2;
- return res;
- }
- int* long2arr (long long int a)
- {
- int* res = (int*) malloc(260);
- int i;
- for (i = 64; a > 0; i--)
- {
- res[i] = a & 1;
- a = a >> 1;
- }
- res[i] = 64 - i;
- res = res + i;
- return res;
- }
- int* prepend(int* bin, int n)
- {
- int i = 1;
- int* res = (int*) malloc((n+bin[0]+1) << 2);
- res[0] = bin[0]+n;
- for (; i<=n; i++)
- res[i] = 0;
- for (i=1; i<=bin[0]; i++)
- res[n+i] = bin[i];
- return res;
- }
- void bin2hex(int* bin) {
- int i;
- int r = bin[0] & 3;
- if (r)
- bin = prepend(bin, 4-r);
- for (i = 1; i < bin[0]; i += 4) {
- int j;
- int n = 0;
- for (j = 0; j < 4; j++)
- n = n * 2 + bin[i + j];
- if( n < 10 )
- putchar(n+48);
- else
- putchar(n+55);
- }
- }
- int* add(int* a, int* b) {
- if (a[0] < b[0])
- return add(b, a);
- else if (a[0] > b[0])
- return add(a, prepend(b,a[0]-b[0]));
- int n = a[0];
- int *ans = (int *) malloc((n + 2) << 2);
- ans[0] = n + 1;
- int i, carry = 0;
- for (i = n + 1; i > 1; i--) {
- ans[i] = a[i - 1] + b[i - 1] + carry;
- carry = ans[i] >> 1;
- ans[i] = ans[i] & 1;
- }
- ans[1] = carry;
- return ans; // length n+1
- }
- void print(int* a) {
- int i, n = a[0];
- for (i = 1; i <= n; i++)
- printf("%d", a[i]);
- printf("\n");
- }
- int* sub(int* a, int* b) {
- if (a[0] > b[0])
- return sub(a, prepend(b,a[0]-b[0]));
- int n = a[0];
- int *ans = (int *) malloc((n + 1) << 2);
- ans[0] = n;
- int i, borrow = 0;
- for (i = n; i > 0; i--) {
- ans[i] = a[i] - b[i] - borrow;
- borrow = 0;
- if( ans[i] < 0 ) {
- borrow = 1;
- ans[i] &= 1;
- }
- }
- return ans; // length n+1
- }
- int* mul2(int* a) {
- int *res = (int *) malloc((a[0] + 2) << 2);
- int i;
- res[0] = a[0] + 1;
- for (i = 1; i <= a[0]; i++)
- res[i] = a[i];
- res[i] = 0;
- return res; // length n+1
- }
- void chunkify(int *a, int *A[2]) {
- int n1, n2;
- n1 = a[0]/2;
- n2 = a[0] - n1;
- A[0] = (int*) malloc((n1+1) << 2);
- A[1] = (int*) malloc((n2+1) << 2);
- A[0][0] = n1;
- A[1][0] = n2;
- int i, j;
- for(i = 1; i <= n1; ++i)
- A[0][i] = a[i];
- for(j = 1; j <= n2; ++i, ++j)
- A[1][j] = a[i];
- }
- int* shiftAndAdd(int* a, int* b, int* c, int x)
- { // assumption: a is the least significant chunk
- int i;
- for (i=0; i<x; i++)
- b = mul2(b);
- for (i=0; i<2*x; i++)
- c = mul2(c);
- int* res = add(add(a,b),c);
- return res;
- }
- int* karatsuba(int* a, int* b) {
- if(isZero(a) || isZero(b)) {
- int* r = malloc(4);
- *r = 0;
- return r;
- }
- if(a[0] < b[0])
- return karatsuba(prepend(a,b[0]-a[0]), b);
- if(a[0] > b[0])
- return karatsuba(a, prepend(b, a[0]-b[0]));
- if(a[0] <= 30) {
- long long int A = arr2long(a), B = arr2long(b), C;
- C = A*B;
- return long2arr(C);
- }
- int *A[2], *B[2];
- chunkify(a,A);
- chunkify(b,B);
- if(isZero(A[0]) && isZero(B[0])) {
- return karatsuba(A[1],B[1]);
- }
- int x = A[1][0];
- int* z2 = karatsuba(A[0], B[0]);
- int* z0 = karatsuba(A[1], B[1]);
- int* z1 = sub(sub(karatsuba(add(A[1],A[0]),add(B[1],B[0])),z0),z2);
- int* r = shiftAndAdd(z0, z1, z2, x);
- return r;
- }
- void hex2bin(int* a, char* s) {
- int i;
- for(i = 0; s[i] != '\0'; ++i) {
- int j = i << 2;
- switch(s[i]) {
- case 48: a[j+1] = 0;
- a[j+2] = 0;
- a[j+3] = 0;
- a[j+4] = 0;
- break;
- case 49: a[j+1] = 0;
- a[j+2] = 0;
- a[j+3] = 0;
- a[j+4] = 1;
- break;
- case 50: a[j+1] = 0;
- a[j+2] = 0;
- a[j+3] = 1;
- a[j+4] = 0;
- break;
- case 51: a[j+1] = 0;
- a[j+2] = 0;
- a[j+3] = 1;
- a[j+4] = 1;
- break;
- case 52: a[j+1] = 0;
- a[j+2] = 1;
- a[j+3] = 0;
- a[j+4] = 0;
- break;
- case 53: a[j+1] = 0;
- a[j+2] = 1;
- a[j+3] = 0;
- a[j+4] = 1;
- break;
- case 54: a[j+1] = 0;
- a[j+2] = 1;
- a[j+3] = 1;
- a[j+4] = 0;
- break;
- case 55: a[j+1] = 0;
- a[j+2] = 1;
- a[j+3] = 1;
- a[j+4] = 1;
- break;
- case 56: a[j+1] = 1;
- a[j+2] = 0;
- a[j+3] = 0;
- a[j+4] = 0;
- break;
- case 57: a[j+1] = 1;
- a[j+2] = 0;
- a[j+3] = 0;
- a[j+4] = 1;
- break;
- case 97:
- case 65: a[j+1] = 1;
- a[j+2] = 0;
- a[j+3] = 1;
- a[j+4] = 0;
- break;
- case 98:
- case 66: a[j+1] = 1;
- a[j+2] = 0;
- a[j+3] = 1;
- a[j+4] = 1;
- break;
- case 99:
- case 67: a[j+1] = 1;
- a[j+2] = 1;
- a[j+3] = 0;
- a[j+4] = 0;
- break;
- case 100:
- case 68: a[j+1] = 1;
- a[j+2] = 1;
- a[j+3] = 0;
- a[j+4] = 1;
- break;
- case 101:
- case 69: a[j+1] = 1;
- a[j+2] = 1;
- a[j+3] = 1;
- a[j+4] = 0;
- break;
- case 102:
- case 70: a[j+1] = 1;
- a[j+2] = 1;
- a[j+3] = 1;
- a[j+4] = 1;
- break;
- }
- }
- a[0] = i << 2;
- }
- void main(void) {
- int a[1024], b[1024];
- char s1[256], s2[256];
- scanf("%s\n%s", s1, s2);
- hex2bin(a,s1);
- hex2bin(b,s2);
- int *c;
- c = karatsuba(a,b);
- bin2hex(c);
- printf("\n");
- }
Add Comment
Please, Sign In to add comment