-
-
Notifications
You must be signed in to change notification settings - Fork 372
/
Rat.pm
93 lines (72 loc) · 2.37 KB
/
Rat.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class Rat {
has $.numerator;
has $.denominator;
my sub gcd(Int $a is copy, Int $b is copy) {
$a = -$a if ($a < 0);
$b = -$b if ($b < 0);
while $a > 0 && $b > 0 {
($a, $b) = ($b, $a) if ($b > $a);
$a %= $b;
}
return $a + $b;
}
multi method new(Int $numerator is copy, Int $denominator is copy) {
if $denominator < 0 {
$numerator = -$numerator;
$denominator = -$denominator;
}
my $gcd = gcd($numerator, $denominator);
$numerator = $numerator div $gcd;
$denominator = $denominator div $gcd;
self.bless(*, :$numerator, :$denominator);
}
multi method perl() { "$!numerator/$!denominator"; }
multi method Num() { $!numerator.Num / $!denominator.Num }
multi method Str() { $.Num.Str; }
multi method nude() { $.numerator, $.denominator; }
}
multi sub infix:<+>(Rat $a, Rat $b) {
Rat.new($a.numerator * $b.denominator + $b.numerator * $a.denominator,
$a.denominator * $b.denominator );
}
multi sub infix:<+>(Rat $a, Int $b) {
Rat.new($a.numerator + $b * $a.denominator, $a.denominator);
}
multi sub infix:<+>(Int $a, Rat $b) {
Rat.new($a * $b.denominator + $b.numerator, $b.denominator);
}
multi sub infix:<->(Rat $a, Rat $b) {
Rat.new($a.numerator * $b.denominator - $b.numerator * $a.denominator,
$a.denominator * $b.denominator );
}
multi sub infix:<->(Rat $a, Int $b) {
Rat.new($a.numerator - $b * $a.denominator, $a.denominator);
}
multi sub infix:<->(Int $a, Rat $b) {
Rat.new($a * $b.denominator - $b.numerator, $b.denominator);
}
multi sub prefix:<->(Rat $a) {
Rat.new(-$a.numerator, $a.denominator);
}
multi sub infix:<*>(Rat $a, Rat $b) {
Rat.new($a.numerator * $b.numerator, $a.denominator * $b.denominator);
}
multi sub infix:<*>(Rat $a, Int $b) {
Rat.new($a.numerator * $b, $a.denominator);
}
multi sub infix:<*>(Int $a, Rat $b) {
Rat.new($a * $b.numerator, $b.denominator);
}
multi sub infix:</>(Rat $a, Rat $b) {
Rat.new($a.numerator * $b.denominator, $a.denominator * $b.numerator);
}
multi sub infix:</>(Rat $a, Int $b) {
Rat.new($a.numerator, $a.denominator * $b);
}
multi sub infix:</>(Int $a, Rat $b) {
Rat.new($b.denominator * $a, $b.numerator);
}
multi sub infix:</>(Int $a, Int $b) {
Rat.new($a, $b);
}
# vim: ft=perl6 sw=4 ts=4 expandtab