1 // The Computer Language Benchmarks Game
2 // http://benchmarksgame.alioth.debian.org/
4 // contributed by the Rust Project Developers
6 // Copyright (c) 2012-2014 The Rust Project Developers
8 // All rights reserved.
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions
14 // - Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
17 // - Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in
19 // the documentation and/or other materials provided with the
22 // - Neither the name of "The Computer Language Benchmarks Game" nor
23 // the name of "The Computer Language Shootout Benchmarks" nor the
24 // names of its contributors may be used to endorse or promote
25 // products derived from this software without specific prior
26 // written permission.
28 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39 // OF THE POSSIBILITY OF SUCH DAMAGE.
43 use self::Color::{Red, Yellow, Blue};
44 use std::sync::mpsc::{channel, Sender, Receiver};
46 use std::thread::Thread;
48 fn print_complements() {
49 let all = [Blue, Red, Yellow];
50 for aa in all.iter() {
51 for bb in all.iter() {
52 println!("{} + {} -> {}", *aa, *bb, transform(*aa, *bb));
63 impl Copy for Color {}
65 impl fmt::Show for Color {
66 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67 let str = match *self {
81 impl Copy for CreatureInfo {}
83 fn show_color_list(set: Vec<Color>) -> String {
84 let mut out = String::new();
85 for col in set.iter() {
87 out.push_str(col.to_string().as_slice());
92 fn show_digit(nn: uint) -> &'static str {
104 _ => {panic!("expected digits from 0 to 9...")}
109 impl fmt::Show for Number {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111 let mut out = vec![];
112 let Number(mut num) = *self;
113 if num == 0 { out.push(show_digit(0)) };
118 let s = show_digit(dig);
122 for s in out.iter().rev() {
123 try!(write!(f, "{}", s))
129 fn transform(aa: Color, bb: Color) -> Color {
131 (Red, Red ) => { Red }
132 (Red, Yellow) => { Blue }
133 (Red, Blue ) => { Yellow }
134 (Yellow, Red ) => { Blue }
135 (Yellow, Yellow) => { Yellow }
136 (Yellow, Blue ) => { Red }
137 (Blue, Red ) => { Yellow }
138 (Blue, Yellow) => { Red }
139 (Blue, Blue ) => { Blue }
146 from_rendezvous: Receiver<CreatureInfo>,
147 to_rendezvous: Sender<CreatureInfo>,
148 to_rendezvous_log: Sender<String>
150 let mut creatures_met = 0i32;
151 let mut evil_clones_met = 0;
152 let mut rendezvous = from_rendezvous.iter();
156 to_rendezvous.send(CreatureInfo {name: name, color: color}).unwrap();
158 // log and change, or quit
159 match rendezvous.next() {
160 Some(other_creature) => {
161 color = transform(color, other_creature.color);
163 // track some statistics
165 if other_creature.name == name {
166 evil_clones_met += 1;
172 // log creatures met and evil clones of self
173 let report = format!("{}{}", creatures_met, Number(evil_clones_met));
174 to_rendezvous_log.send(report).unwrap();
177 fn rendezvous(nn: uint, set: Vec<Color>) {
178 // these ports will allow us to hear from the creatures
179 let (to_rendezvous, from_creatures) = channel::<CreatureInfo>();
181 // these channels will be passed to the creatures so they can talk to us
182 let (to_rendezvous_log, from_creatures_log) = channel::<String>();
184 // these channels will allow us to talk to each creature by 'name'/index
185 let mut to_creature: Vec<Sender<CreatureInfo>> =
186 set.iter().enumerate().map(|(ii, &col)| {
187 // create each creature as a listener with a port, and
188 // give us a channel to talk to each
189 let to_rendezvous = to_rendezvous.clone();
190 let to_rendezvous_log = to_rendezvous_log.clone();
191 let (to_creature, from_rendezvous) = channel();
192 Thread::spawn(move|| {
202 let mut creatures_met = 0;
204 // set up meetings...
205 for _ in range(0, nn) {
206 let fst_creature = from_creatures.recv().unwrap();
207 let snd_creature = from_creatures.recv().unwrap();
211 to_creature[fst_creature.name].send(snd_creature).unwrap();
212 to_creature[snd_creature.name].send(fst_creature).unwrap();
215 // tell each creature to stop
218 // print each color in the set
219 println!("{}", show_color_list(set));
221 // print each creature's stats
222 drop(to_rendezvous_log);
223 for rep in from_creatures_log.iter() {
227 // print the total number of creatures met
228 println!("{}\n", Number(creatures_met));
232 let nn = if std::os::getenv("RUST_BENCH").is_some() {
235 std::os::args().as_slice()
237 .and_then(|arg| arg.parse())
244 rendezvous(nn, vec!(Blue, Red, Yellow));
247 vec!(Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue));