Balanced ternary: Difference between revisions
Content added Content deleted
m (changed </scala> to </lang>) |
|||
Line 555: | Line 555: | ||
65 : +-++- |
65 : +-++- |
||
-262023 : ----0+--0++0</pre> |
-262023 : ----0+--0++0</pre> |
||
=={{header|C}}== |
|||
{{trans|Perl}} |
|||
<lang c>#include <stdio.h> |
|||
#include <string.h> |
|||
void reverse(char *p) { |
|||
size_t len = strlen(p); |
|||
char *r = p + len - 1; |
|||
while (p < r) { |
|||
*p ^= *r; |
|||
*r ^= *p; |
|||
*p++ ^= *r--; |
|||
} |
|||
} |
|||
void to_bt(int n, char *b) { |
|||
static char d[] = { '0', '+', '-' }; |
|||
static int v[] = { 0, 1, -1 }; |
|||
char *ptr = b; |
|||
*ptr = 0; |
|||
while (n) { |
|||
int r = n % 3; |
|||
if (r < 0) { |
|||
r += 3; |
|||
} |
|||
*ptr = d[r]; |
|||
*(++ptr) = 0; |
|||
n -= v[r]; |
|||
n /= 3; |
|||
} |
|||
reverse(b); |
|||
} |
|||
int from_bt(const char *a) { |
|||
int n = 0; |
|||
while (*a != '\0') { |
|||
n *= 3; |
|||
if (*a == '+') { |
|||
n++; |
|||
} else if (*a == '-') { |
|||
n--; |
|||
} |
|||
a++; |
|||
} |
|||
return n; |
|||
} |
|||
char last_char(char *ptr) { |
|||
char c; |
|||
if (ptr == NULL || *ptr == '\0') { |
|||
return '\0'; |
|||
} |
|||
while (*ptr != '\0') { |
|||
ptr++; |
|||
} |
|||
ptr--; |
|||
c = *ptr; |
|||
*ptr = 0; |
|||
return c; |
|||
} |
|||
void add(const char *b1, const char *b2, char *out) { |
|||
if (*b1 != '\0' && *b2 != '\0') { |
|||
char c1[16]; |
|||
char c2[16]; |
|||
char ob1[16]; |
|||
char ob2[16]; |
|||
char d[3] = { 0, 0, 0 }; |
|||
char L1, L2; |
|||
strcpy(c1, b1); |
|||
strcpy(c2, b2); |
|||
L1 = last_char(c1); |
|||
L2 = last_char(c2); |
|||
if (L2 < L1) { |
|||
L2 ^= L1; |
|||
L1 ^= L2; |
|||
L2 ^= L1; |
|||
} |
|||
if (L1 == '-') { |
|||
if (L2 == '0') { |
|||
d[0] = '-'; |
|||
} |
|||
if (L2 == '-') { |
|||
d[0] = '+'; |
|||
d[1] = '-'; |
|||
} |
|||
} |
|||
if (L1 == '+') { |
|||
if (L2 == '0') { |
|||
d[0] = '+'; |
|||
} |
|||
if (L2 == '-') { |
|||
d[0] = '0'; |
|||
} |
|||
if (L2 == '+') { |
|||
d[0] = '-'; |
|||
d[1] = '+'; |
|||
} |
|||
} |
|||
if (L1 == '0') { |
|||
if (L2 == '0') { |
|||
d[0] = '0'; |
|||
} |
|||
} |
|||
add(c1, &d[1], ob1); |
|||
add(ob1, c2, ob2); |
|||
strcpy(out, ob2); |
|||
d[1] = 0; |
|||
strcat(out, d); |
|||
} else if (*b1 != '\0') { |
|||
strcpy(out, b1); |
|||
} else if (*b2 != '\0') { |
|||
strcpy(out, b2); |
|||
} else { |
|||
*out = '\0'; |
|||
} |
|||
} |
|||
void unary_minus(const char *b, char *out) { |
|||
while (*b != '\0') { |
|||
if (*b == '-') { |
|||
*out++ = '+'; |
|||
b++; |
|||
} else if (*b == '+') { |
|||
*out++ = '-'; |
|||
b++; |
|||
} else { |
|||
*out++ = *b++; |
|||
} |
|||
} |
|||
*out = '\0'; |
|||
} |
|||
void subtract(const char *b1, const char *b2, char *out) { |
|||
char buf[16]; |
|||
unary_minus(b2, buf); |
|||
add(b1, buf, out); |
|||
} |
|||
void mult(const char *b1, const char *b2, char *out) { |
|||
char r[16] = "0"; |
|||
char t[16]; |
|||
char c1[16]; |
|||
char c2[16]; |
|||
char *ptr = c2; |
|||
strcpy(c1, b1); |
|||
strcpy(c2, b2); |
|||
reverse(c2); |
|||
while (*ptr != '\0') { |
|||
if (*ptr == '+') { |
|||
add(r, c1, t); |
|||
strcpy(r, t); |
|||
} |
|||
if (*ptr == '-') { |
|||
subtract(r, c1, t); |
|||
strcpy(r, t); |
|||
} |
|||
strcat(c1, "0"); |
|||
ptr++; |
|||
} |
|||
ptr = r; |
|||
while (*ptr == '0') { |
|||
ptr++; |
|||
} |
|||
strcpy(out, ptr); |
|||
} |
|||
int main() { |
|||
const char *a = "+-0++0+"; |
|||
char b[16]; |
|||
const char *c = "+-++-"; |
|||
char t[16]; |
|||
char d[16]; |
|||
to_bt(-436, b); |
|||
subtract(b, c, t); |
|||
mult(a, t, d); |
|||
printf(" a: %14s %10d\n", a, from_bt(a)); |
|||
printf(" b: %14s %10d\n", b, from_bt(b)); |
|||
printf(" c: %14s %10d\n", c, from_bt(c)); |
|||
printf("a*(b-c): %14s %10d\n", d, from_bt(d)); |
|||
return 0; |
|||
}</lang> |
|||
{{out}} |
|||
<pre> a: +-0++0+ 523 |
|||
b: -++-0-- -436 |
|||
c: +-++- 65 |
|||
a*(b-c): ----0+--0++0 -262023</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
<lang cpp> |
<lang cpp>#include <iostream> |
||
#include <iostream> |
|||
#include <string> |
#include <string> |
||
#include <climits> |
#include <climits> |