1
1
// based on:
2
- // http://shootout.alioth.debian.org/u64q/program.php?test=mandelbrot&lang=python3&id=2
2
+ // http://shootout.alioth.debian.org/
3
+ // u64q/program.php?test=mandelbrot&lang=python3&id=2
3
4
//
4
5
// takes 2 optional numeric args: square image size and yield frequency
5
6
// in the shootout, they use 16000 as image size
@@ -14,130 +15,129 @@ type cmplx = {re: f64, im: f64};
14
15
type line = { i : uint , b : [ u8 ] } ;
15
16
16
17
impl arith for cmplx {
17
- fn * ( x: cmplx) -> cmplx {
18
- { re: self . re* x. re - self . im* x. im, im: self . re* x. im + self . im* x. re }
19
- }
18
+ fn * ( x: cmplx) -> cmplx {
19
+ { re: self . re* x. re - self . im* x. im, im: self . re* x. im + self . im* x. re }
20
+ }
20
21
21
- fn +( x : cmplx ) -> cmplx {
22
- { re: self . re + x. re , im: self . im + x. im }
23
- }
22
+ fn +( x : cmplx ) -> cmplx {
23
+ { re: self . re + x. re , im: self . im + x. im }
24
+ }
24
25
}
25
26
26
27
pure fn cabs ( x : cmplx ) -> f64
27
28
{
28
- x. re * x. re + x. im * x. im
29
+ x. re * x. re + x. im * x. im
29
30
}
30
31
31
32
fn mb ( x : cmplx ) -> bool
32
33
{
33
- let z = { re: 0 . , im: 0 . } ;
34
- let i = 0 ;
35
- let in = true ;
36
- while i < 50 {
37
- z = z* z + x;
38
- if cabs ( z) >= 4. {
39
- in = false ;
40
- break ;
41
- }
42
- i += 1 ;
43
- }
44
- in
34
+ let z = { re: 0 . , im: 0 . } ;
35
+ let i = 0 ;
36
+ let in = true ;
37
+ while i < 50 {
38
+ z = z* z + x;
39
+ if cabs ( z) >= 4. {
40
+ in = false ;
41
+ break ;
42
+ }
43
+ i += 1 ;
44
+ }
45
+ in
45
46
}
46
47
47
48
fn fillbyte ( x : cmplx , incr : f64 ) -> u8 {
48
- let rv = 0_u8 ;
49
- let i = 0_u8 ;
50
- while i < 8_u8 {
51
- let z = { re: x. re + ( i as f64 ) * incr, im: x. im } ;
52
- if mb ( z) {
53
- rv += 1_u8 << ( 7_u8 - i) ;
54
- }
55
- i += 1_u8 ;
56
- }
57
- rv
49
+ let rv = 0_u8 ;
50
+ let i = 0_u8 ;
51
+ while i < 8_u8 {
52
+ let z = { re: x. re + ( i as f64 ) * incr, im: x. im } ;
53
+ if mb ( z) {
54
+ rv += 1_u8 << ( 7_u8 - i) ;
55
+ }
56
+ i += 1_u8 ;
57
+ }
58
+ rv
58
59
}
59
60
60
61
fn chanmb ( i : uint , size : uint , ch : comm:: chan < line > ) -> ( )
61
62
{
62
- let crv = [ ] ;
63
- let incr = 2. /( size as f64 ) ;
64
- let y = incr* ( i as f64 ) - 1. ;
65
- let xincr = 8. * incr;
66
- uint:: range ( 0_ u, size/8_ u) {
67
- |j|
68
- let x = { re: xincr* ( j as f64 ) - 1.5 , im: y} ;
69
- crv += [ fillbyte ( x, incr) ] ;
70
- } ;
71
- comm:: send ( ch, { i: i, b: crv} ) ;
63
+ let crv = [ ] ;
64
+ let incr = 2. /( size as f64 ) ;
65
+ let y = incr* ( i as f64 ) - 1. ;
66
+ let xincr = 8. * incr;
67
+ uint:: range ( 0_ u, size/8_ u) {
68
+ |j|
69
+ let x = { re: xincr* ( j as f64 ) - 1.5 , im: y} ;
70
+ crv += [ fillbyte ( x, incr) ] ;
71
+ } ;
72
+ comm:: send ( ch, { i: i, b: crv} ) ;
72
73
}
73
74
74
75
fn writer ( writech : comm:: chan < comm:: chan < line > > , size : uint )
75
76
{
76
- let p: comm:: port < line > = comm:: port ( ) ;
77
- let ch = comm:: chan ( p) ;
78
- comm:: send ( writech, ch) ;
79
- let cout = std:: io:: stdout ( ) ;
80
- cout. write_line ( "P4" ) ;
81
- cout. write_line ( #fmt ( "%u %u" , size, size) ) ;
82
- let lines = std:: map:: new_uint_hash ( ) ;
83
- let done = 0_ u;
84
- let i = 0_ u;
85
- while i < size {
86
- let aline = comm:: recv ( p) ;
87
- if aline. i == done {
88
- #debug ( "W %u" , aline. i ) ;
89
- cout. write ( aline. b ) ;
90
- done += 1_ u;
91
- let prev = done;
92
- while prev <= i {
93
- if lines. contains_key ( prev) {
94
- #debug ( "WS %u" , prev) ;
95
- cout. write ( lines. get ( prev) ) ;
96
- done += 1_ u;
97
- lines. remove ( prev) ;
98
- prev += 1_ u;
99
- }
100
- else {
101
- break
102
- }
103
- } ;
104
-
105
- }
106
- else {
107
- #debug ( "S %u" , aline. i ) ;
108
- lines. insert ( aline. i , aline. b ) ;
109
- } ;
110
- i += 1_ u;
111
- }
77
+ let p: comm:: port < line > = comm:: port ( ) ;
78
+ let ch = comm:: chan ( p) ;
79
+ comm:: send ( writech, ch) ;
80
+ let cout = std:: io:: stdout ( ) ;
81
+ cout. write_line ( "P4" ) ;
82
+ cout. write_line ( #fmt ( "%u %u" , size, size) ) ;
83
+ let lines = std:: map:: new_uint_hash ( ) ;
84
+ let done = 0_ u;
85
+ let i = 0_ u;
86
+ while i < size {
87
+ let aline = comm:: recv ( p) ;
88
+ if aline. i == done {
89
+ #debug ( "W %u" , aline. i ) ;
90
+ cout. write ( aline. b ) ;
91
+ done += 1_ u;
92
+ let prev = done;
93
+ while prev <= i {
94
+ if lines. contains_key ( prev) {
95
+ #debug ( "WS %u" , prev) ;
96
+ cout. write ( lines. get ( prev) ) ;
97
+ done += 1_ u;
98
+ lines. remove ( prev) ;
99
+ prev += 1_ u;
100
+ }
101
+ else {
102
+ break
103
+ }
104
+ } ;
105
+ }
106
+ else {
107
+ #debug ( "S %u" , aline. i ) ;
108
+ lines. insert ( aline. i , aline. b ) ;
109
+ } ;
110
+ i += 1_ u;
111
+ }
112
112
}
113
113
114
114
fn main ( argv : [ str ] )
115
115
{
116
- let size = if vec:: len ( argv) < 2_ u {
117
- 80 u
118
- }
119
- else {
120
- uint:: from_str ( argv[ 1 ] )
121
- } ;
122
- let yieldevery = if vec:: len ( argv) < 3_ u {
123
- 10_ u
124
- }
125
- else {
126
- uint:: from_str ( argv[ 2 ] )
127
- } ;
128
- let writep = comm:: port ( ) ;
129
- let writech = comm:: chan ( writep) ;
130
- task:: spawn {
131
- || writer ( writech, size) ;
132
- } ;
133
- let ch = comm:: recv ( writep) ;
134
- uint:: range ( 0_ u, size) {
135
- |j| task:: spawn {
136
- || chanmb ( j, size, ch) ;
137
- } ;
138
- if j % yieldevery == 0_ u {
139
- #debug ( "Y %u" , j) ;
140
- task:: yield ( ) ;
141
- } ;
142
- } ;
116
+ let size = if vec:: len ( argv) < 2_ u {
117
+ 80 u
118
+ }
119
+ else {
120
+ uint:: from_str ( argv[ 1 ] )
121
+ } ;
122
+ let yieldevery = if vec:: len ( argv) < 3_ u {
123
+ 10_ u
124
+ }
125
+ else {
126
+ uint:: from_str ( argv[ 2 ] )
127
+ } ;
128
+ let writep = comm:: port ( ) ;
129
+ let writech = comm:: chan ( writep) ;
130
+ task:: spawn {
131
+ || writer ( writech, size) ;
132
+ } ;
133
+ let ch = comm:: recv ( writep) ;
134
+ uint:: range ( 0_ u, size) {
135
+ |j| task:: spawn {
136
+ || chanmb ( j, size, ch) ;
137
+ } ;
138
+ if j % yieldevery == 0_ u {
139
+ #debug ( "Y %u" , j) ;
140
+ task:: yield ( ) ;
141
+ } ;
142
+ } ;
143
143
}
0 commit comments