Sync
This commit is contained in:
parent
6f050a029e
commit
776bba907c
3887 changed files with 59894 additions and 7280 deletions
211
Task/Balanced-ternary/Java/balanced-ternary.java
Normal file
211
Task/Balanced-ternary/Java/balanced-ternary.java
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* Test case
|
||||
* With balanced ternaries a from string "+-0++0+", b from native integer -436, c "+-++-":
|
||||
* Write out a, b and c in decimal notation;
|
||||
* Calculate a × (b − c), write out the result in both ternary and decimal notations.
|
||||
*/
|
||||
public class BalancedTernary
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
BTernary a=new BTernary("+-0++0+");
|
||||
BTernary b=new BTernary(-436);
|
||||
BTernary c=new BTernary("+-++-");
|
||||
|
||||
System.out.println("a="+a.intValue());
|
||||
System.out.println("b="+b.intValue());
|
||||
System.out.println("c="+c.intValue());
|
||||
System.out.println();
|
||||
|
||||
//result=a*(b-c)
|
||||
BTernary result=a.mul(b.sub(c));
|
||||
|
||||
System.out.println("result= "+result+" "+result.intValue());
|
||||
}
|
||||
|
||||
|
||||
public static class BTernary
|
||||
{
|
||||
String value;
|
||||
public BTernary(String s)
|
||||
{
|
||||
int i=0;
|
||||
while(s.charAt(i)=='0')
|
||||
i++;
|
||||
this.value=s.substring(i);
|
||||
}
|
||||
public BTernary(int v)
|
||||
{
|
||||
this.value="";
|
||||
this.value=convertToBT(v);
|
||||
}
|
||||
|
||||
private String convertToBT(int v)
|
||||
{
|
||||
if(v<0)
|
||||
return flip(convertToBT(-v));
|
||||
if(v==0)
|
||||
return "";
|
||||
int rem=mod3(v);
|
||||
if(rem==0)
|
||||
return convertToBT(v/3)+"0";
|
||||
if(rem==1)
|
||||
return convertToBT(v/3)+"+";
|
||||
if(rem==2)
|
||||
return convertToBT((v+1)/3)+"-";
|
||||
return "You can't see me";
|
||||
}
|
||||
private String flip(String s)
|
||||
{
|
||||
String flip="";
|
||||
for(int i=0;i<s.length();i++)
|
||||
{
|
||||
if(s.charAt(i)=='+')
|
||||
flip+='-';
|
||||
else if(s.charAt(i)=='-')
|
||||
flip+='+';
|
||||
else
|
||||
flip+='0';
|
||||
}
|
||||
return flip;
|
||||
}
|
||||
private int mod3(int v)
|
||||
{
|
||||
if(v>0)
|
||||
return v%3;
|
||||
v=v%3;
|
||||
return (v+3)%3;
|
||||
}
|
||||
|
||||
public int intValue()
|
||||
{
|
||||
int sum=0;
|
||||
String s=this.value;
|
||||
for(int i=0;i<s.length();i++)
|
||||
{
|
||||
char c=s.charAt(s.length()-i-1);
|
||||
int dig=0;
|
||||
if(c=='+')
|
||||
dig=1;
|
||||
else if(c=='-')
|
||||
dig=-1;
|
||||
sum+=dig*Math.pow(3, i);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
public BTernary add(BTernary that)
|
||||
{
|
||||
String a=this.value;
|
||||
String b=that.value;
|
||||
|
||||
String longer=a.length()>b.length()?a:b;
|
||||
String shorter=a.length()>b.length()?b:a;
|
||||
|
||||
while(shorter.length()<longer.length())
|
||||
shorter=0+shorter;
|
||||
|
||||
a=longer;
|
||||
b=shorter;
|
||||
|
||||
char carry='0';
|
||||
String sum="";
|
||||
for(int i=0;i<a.length();i++)
|
||||
{
|
||||
int place=a.length()-i-1;
|
||||
String digisum=addDigits(a.charAt(place),b.charAt(place),carry);
|
||||
if(digisum.length()!=1)
|
||||
carry=digisum.charAt(0);
|
||||
else
|
||||
carry='0';
|
||||
sum=digisum.charAt(digisum.length()-1)+sum;
|
||||
}
|
||||
sum=carry+sum;
|
||||
|
||||
return new BTernary(sum);
|
||||
}
|
||||
private String addDigits(char a,char b,char carry)
|
||||
{
|
||||
String sum1=addDigits(a,b);
|
||||
String sum2=addDigits(sum1.charAt(sum1.length()-1),carry);
|
||||
//System.out.println(carry+" "+sum1+" "+sum2);
|
||||
if(sum1.length()==1)
|
||||
return sum2;
|
||||
if(sum2.length()==1)
|
||||
return sum1.charAt(0)+sum2;
|
||||
return sum1.charAt(0)+"";
|
||||
}
|
||||
private String addDigits(char a,char b)
|
||||
{
|
||||
String sum="";
|
||||
if(a=='0')
|
||||
sum=b+"";
|
||||
else if (b=='0')
|
||||
sum=a+"";
|
||||
else if(a=='+')
|
||||
{
|
||||
if(b=='+')
|
||||
sum="+-";
|
||||
else
|
||||
sum="0";
|
||||
}
|
||||
else
|
||||
{
|
||||
if(b=='+')
|
||||
sum="0";
|
||||
else
|
||||
sum="-+";
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public BTernary neg()
|
||||
{
|
||||
return new BTernary(flip(this.value));
|
||||
}
|
||||
|
||||
public BTernary sub(BTernary that)
|
||||
{
|
||||
return this.add(that.neg());
|
||||
}
|
||||
|
||||
public BTernary mul(BTernary that)
|
||||
{
|
||||
BTernary one=new BTernary(1);
|
||||
BTernary zero=new BTernary(0);
|
||||
BTernary mul=new BTernary(0);
|
||||
|
||||
int flipflag=0;
|
||||
if(that.compareTo(zero)==-1)
|
||||
{
|
||||
that=that.neg();
|
||||
flipflag=1;
|
||||
}
|
||||
for(BTernary i=new BTernary(1);i.compareTo(that)<1;i=i.add(one))
|
||||
mul=mul.add(this);
|
||||
|
||||
if(flipflag==1)
|
||||
mul=mul.neg();
|
||||
return mul;
|
||||
}
|
||||
|
||||
public boolean equals(BTernary that)
|
||||
{
|
||||
return this.value.equals(that.value);
|
||||
}
|
||||
public int compareTo(BTernary that)
|
||||
{
|
||||
if(this.intValue()>that.intValue())
|
||||
return 1;
|
||||
else if(this.equals(that))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Task/Balanced-ternary/Racket/balanced-ternary.rkt
Normal file
75
Task/Balanced-ternary/Racket/balanced-ternary.rkt
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#lang racket
|
||||
|
||||
;; Represent a balanced-ternary number as a list of 0's, 1's and -1's.
|
||||
;;
|
||||
;; e.g. 11 = 3^2 + 3^1 - 3^0 ~ "++-" ~ '(-1 1 1)
|
||||
;; 6 = 3^2 - 3^1 ~ "+-0" ~ '(0 -1 1)
|
||||
;;
|
||||
;; Note: the list-rep starts with the least signifcant tert, while
|
||||
;; the string-rep starts with the most significsnt tert.
|
||||
|
||||
(define (bt->integer t)
|
||||
(if (null? t)
|
||||
0
|
||||
(+ (first t) (* 3 (bt->integer (rest t))))))
|
||||
|
||||
(define (integer->bt n)
|
||||
(letrec ([recur (λ (b r) (cons b (convert (floor (/ r 3)))))]
|
||||
[convert (λ (n) (if (zero? n) null
|
||||
(case (modulo n 3)
|
||||
[(0) (recur 0 n)]
|
||||
[(1) (recur 1 n)]
|
||||
[(2) (recur -1 (add1 n))])))])
|
||||
(convert n)))
|
||||
|
||||
(define (bt->string t)
|
||||
(define (strip-leading-zeroes a)
|
||||
(if (or (null? a) (not (= (first a) 0))) a (strip-leading-zeroes (rest a))))
|
||||
(string-join (map (λ (u)
|
||||
(case u
|
||||
[(1) "+"]
|
||||
[(-1) "-"]
|
||||
[(0) "0"]))
|
||||
(strip-leading-zeroes (reverse t))) ""))
|
||||
|
||||
(define (string->bt s)
|
||||
(reverse
|
||||
(map (λ (c)
|
||||
(case c
|
||||
[(#\+) 1]
|
||||
[(#\-) -1]
|
||||
[(#\0) 0]))
|
||||
(string->list s))))
|
||||
|
||||
(define (bt-negate t)
|
||||
(map (λ (u) (- u)) t))
|
||||
|
||||
(define (bt-add a b [c 0])
|
||||
(cond [(and (null? a) (null? b)) (if (zero? c) null (list c))]
|
||||
[(null? b) (if (zero? c) a (bt-add a (list c)))]
|
||||
[(null? a) (bt-add b a c)]
|
||||
[else (let* ([t (+ (first a) (first b) c)]
|
||||
[carry (if (> (abs t) 1) (sgn t) 0)]
|
||||
[v (case (abs t)
|
||||
[(3) 0]
|
||||
[(2) (- (sgn t))]
|
||||
[else t])])
|
||||
(cons v (bt-add (rest a) (rest b) carry)))]))
|
||||
|
||||
(define (bt-multiply a b)
|
||||
(cond [(null? a) null]
|
||||
[(null? b) null]
|
||||
[else (bt-add (case (first a)
|
||||
[(-1) (bt-negate b)]
|
||||
[(0) null]
|
||||
[(1) b])
|
||||
(cons 0 (bt-multiply (rest a) b)))]))
|
||||
|
||||
; test case
|
||||
(let* ([a (string->bt "+-0++0+")]
|
||||
[b (integer->bt -436)]
|
||||
[c (string->bt "+-++-")]
|
||||
[d (bt-multiply a (bt-add b (bt-negate c)))])
|
||||
(for ([bt (list a b c d)]
|
||||
[description (list 'a 'b 'c "a×(b−c)")])
|
||||
(printf "~a = ~a or ~a\n" description (bt->integer bt) (bt->string bt))))
|
||||
|
|
@ -1,67 +1,62 @@
|
|||
class BalancedTernary
|
||||
include Comparable
|
||||
def initialize(str = "")
|
||||
if str !~ /^[-+0]+$/
|
||||
if str =~ /[^-+0]+/
|
||||
raise ArgumentError, "invalid BalancedTernary number: #{str}"
|
||||
end
|
||||
@digits = trim0(str)
|
||||
end
|
||||
|
||||
I2BT = {0 => ["0",0], 1 => ["+",0], 2 => ["-",1]}
|
||||
def self.from_int(value)
|
||||
n = value
|
||||
n = value.to_i
|
||||
digits = ""
|
||||
while n != 0
|
||||
quo, rem = n.divmod(3)
|
||||
case rem
|
||||
when 0
|
||||
digits = "0" + digits
|
||||
n = quo
|
||||
when 1
|
||||
digits = "+" + digits
|
||||
n = quo
|
||||
when 2
|
||||
digits = "-" + digits
|
||||
n = quo + 1
|
||||
end
|
||||
bt, carry = I2BT[rem]
|
||||
digits = bt + digits
|
||||
n = quo + carry
|
||||
end
|
||||
new(digits)
|
||||
end
|
||||
|
||||
BT2I = {"-" => -1, "0" => 0, "+" => 1}
|
||||
def to_int
|
||||
@digits.chars.inject(0) do |sum, char|
|
||||
sum *= 3
|
||||
case char
|
||||
when "+"
|
||||
sum += 1
|
||||
when "-"
|
||||
sum -= 1
|
||||
end
|
||||
sum
|
||||
sum = 3 * sum + BT2I[char]
|
||||
end
|
||||
end
|
||||
alias :to_i :to_int
|
||||
|
||||
def to_s
|
||||
@digits
|
||||
@digits.dup # String is mutable
|
||||
end
|
||||
alias :inspect :to_s
|
||||
|
||||
def <=>(other)
|
||||
to_i <=> other.to_i
|
||||
end
|
||||
|
||||
ADDITION_TABLE = {
|
||||
"-" => {"-" => ["-","+"], "0" => ["0","-"], "+" => ["0","0"]},
|
||||
"0" => {"-" => ["0","-"], "0" => ["0","0"], "+" => ["0","+"]},
|
||||
"+" => {"-" => ["0","0"], "0" => ["0","+"], "+" => ["+","-"]},
|
||||
"---" => ["-","0"], "--0" => ["-","+"], "--+" => ["0","-"],
|
||||
"-0-" => ["-","+"], "-00" => ["0","-"], "-0+" => ["0","0"],
|
||||
"-+-" => ["0","-"], "-+0" => ["0","0"], "-++" => ["0","+"],
|
||||
"0--" => ["-","+"], "0-0" => ["0","-"], "0-+" => ["0","0"],
|
||||
"00-" => ["0","-"], "000" => ["0","0"], "00+" => ["0","+"],
|
||||
"0+-" => ["0","0"], "0+0" => ["0","+"], "0++" => ["+","-"],
|
||||
"+--" => ["0","-"], "+-0" => ["0","0"], "+-+" => ["0","+"],
|
||||
"+0-" => ["0","0"], "+00" => ["0","+"], "+0+" => ["+","-"],
|
||||
"++-" => ["0","+"], "++0" => ["+","-"], "+++" => ["+","0"],
|
||||
}
|
||||
|
||||
def +(other)
|
||||
maxl = [to_s, other.to_s].collect {|s| s.length}.max
|
||||
a = pad0(to_s, maxl)
|
||||
b = pad0(other.to_s, maxl)
|
||||
maxl = [to_s.length, other.to_s.length].max
|
||||
a = pad0_reverse(to_s, maxl)
|
||||
b = pad0_reverse(other.to_s, maxl)
|
||||
carry = "0"
|
||||
sum = a.reverse.chars.zip( b.reverse.chars ).inject("") do |sum, (c1, c2)|
|
||||
carry1, digit1 = ADDITION_TABLE[c1][c2]
|
||||
carry2, digit2 = ADDITION_TABLE[carry][digit1]
|
||||
sum = digit2 + sum
|
||||
carry = ADDITION_TABLE[carry1][carry2][1]
|
||||
sum
|
||||
sum = a.zip( b ).inject("") do |sum, (c1, c2)|
|
||||
carry, digit = ADDITION_TABLE[carry + c1 + c2]
|
||||
sum = digit + sum
|
||||
end
|
||||
self.class.new(carry + sum)
|
||||
end
|
||||
|
|
@ -73,7 +68,7 @@ class BalancedTernary
|
|||
}
|
||||
|
||||
def *(other)
|
||||
product = self.class.new("0")
|
||||
product = self.class.new
|
||||
other.to_s.each_char do |bdigit|
|
||||
row = to_s.tr("-0+", MULTIPLICATION_TABLE[bdigit])
|
||||
product += self.class.new(row)
|
||||
|
|
@ -84,7 +79,7 @@ class BalancedTernary
|
|||
|
||||
# negation
|
||||
def -@()
|
||||
self * BalancedTernary.new("-")
|
||||
self.class.new(@digits.tr('-+','+-'))
|
||||
end
|
||||
|
||||
# subtraction
|
||||
|
|
@ -113,16 +108,16 @@ class BalancedTernary
|
|||
str
|
||||
end
|
||||
|
||||
def pad0(str, len)
|
||||
str.rjust(len, "0")
|
||||
def pad0_reverse(str, len)
|
||||
str.rjust(len, "0").reverse.chars
|
||||
end
|
||||
end
|
||||
|
||||
a = BalancedTernary.new("+-0++0+")
|
||||
b = BalancedTernary.from_int(-436)
|
||||
c = BalancedTernary.new("+-++-")
|
||||
calc = a * (b - c)
|
||||
puts "%s\t%d\t%s\n" % ['a', a.to_i, a]
|
||||
puts "%s\t%d\t%s\n" % ['b', b.to_i, b]
|
||||
puts "%s\t%d\t%s\n" % ['c', c.to_i, c]
|
||||
puts "%s\t%d\t%s\n" % ['a*(b-c)', calc.to_i, calc]
|
||||
|
||||
%w[a b c a*(b-c)].each do |exp|
|
||||
val = eval(exp)
|
||||
puts "%8s :%13s,%8d" % [exp, val, val.to_i]
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue