2012-12-10 19:32:48 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-07-06 20:20:36 -05:00
|
|
|
// chameneos
|
|
|
|
|
2013-05-24 21:35:29 -05:00
|
|
|
use std::option;
|
|
|
|
use std::os;
|
2014-04-02 18:54:22 -05:00
|
|
|
use std::strbuf::StrBuf;
|
2013-05-24 21:35:29 -05:00
|
|
|
use std::task;
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
fn print_complements() {
|
2013-06-17 15:37:11 -05:00
|
|
|
let all = [Blue, Red, Yellow];
|
2013-08-03 11:45:23 -05:00
|
|
|
for aa in all.iter() {
|
|
|
|
for bb in all.iter() {
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("{} + {} -> {}", show_color(*aa), show_color(*bb),
|
|
|
|
show_color(transform(*aa, *bb)));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-07 23:43:12 -05:00
|
|
|
enum color { Red, Yellow, Blue }
|
2012-07-06 20:20:36 -05:00
|
|
|
|
2013-01-28 20:55:44 -06:00
|
|
|
struct CreatureInfo {
|
|
|
|
name: uint,
|
|
|
|
color: color
|
|
|
|
}
|
2012-07-06 20:20:36 -05:00
|
|
|
|
2014-04-10 05:55:34 -05:00
|
|
|
fn show_color(cc: color) -> &'static str {
|
2014-01-19 02:21:14 -06:00
|
|
|
match cc {
|
2014-04-10 05:55:34 -05:00
|
|
|
Red => "red",
|
|
|
|
Yellow => "yellow",
|
|
|
|
Blue => "blue"
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-10 05:55:34 -05:00
|
|
|
fn show_color_list(set: Vec<color>) -> StrBuf {
|
2014-04-02 18:54:22 -05:00
|
|
|
let mut out = StrBuf::new();
|
2013-08-03 11:45:23 -05:00
|
|
|
for col in set.iter() {
|
2013-06-11 21:13:42 -05:00
|
|
|
out.push_char(' ');
|
|
|
|
out.push_str(show_color(*col));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
2014-04-10 05:55:34 -05:00
|
|
|
out
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
2014-04-10 05:55:34 -05:00
|
|
|
fn show_digit(nn: uint) -> &'static str {
|
2014-01-19 02:21:14 -06:00
|
|
|
match nn {
|
2014-04-10 05:55:34 -05:00
|
|
|
0 => {"zero"}
|
|
|
|
1 => {"one"}
|
|
|
|
2 => {"two"}
|
|
|
|
3 => {"three"}
|
|
|
|
4 => {"four"}
|
|
|
|
5 => {"five"}
|
|
|
|
6 => {"six"}
|
|
|
|
7 => {"seven"}
|
|
|
|
8 => {"eight"}
|
|
|
|
9 => {"nine"}
|
2013-10-21 15:08:31 -05:00
|
|
|
_ => {fail!("expected digits from 0 to 9...")}
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-10 05:55:34 -05:00
|
|
|
fn show_number(nn: uint) -> StrBuf {
|
|
|
|
let mut out = vec![];
|
2012-07-06 20:20:36 -05:00
|
|
|
let mut num = nn;
|
|
|
|
let mut dig;
|
2014-04-10 05:55:34 -05:00
|
|
|
let mut len = 0;
|
|
|
|
if num == 0 { out.push(show_digit(0)) };
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
while num != 0 {
|
|
|
|
dig = num % 10;
|
|
|
|
num = num / 10;
|
2014-04-10 05:55:34 -05:00
|
|
|
out.push(" ");
|
|
|
|
let s = show_digit(dig);
|
|
|
|
out.push(s);
|
|
|
|
len += 1 + s.len();
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
2014-04-10 05:55:34 -05:00
|
|
|
len += 1;
|
|
|
|
out.push(" ");
|
2012-07-06 20:20:36 -05:00
|
|
|
|
2014-04-10 05:55:34 -05:00
|
|
|
let mut ret = StrBuf::with_capacity(len);
|
|
|
|
for s in out.iter().rev() {
|
|
|
|
ret.push_str(*s);
|
|
|
|
}
|
|
|
|
ret
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
fn transform(aa: color, bb: color) -> color {
|
2012-08-06 14:34:08 -05:00
|
|
|
match (aa, bb) {
|
2012-08-03 21:59:04 -05:00
|
|
|
(Red, Red ) => { Red }
|
|
|
|
(Red, Yellow) => { Blue }
|
|
|
|
(Red, Blue ) => { Yellow }
|
|
|
|
(Yellow, Red ) => { Blue }
|
|
|
|
(Yellow, Yellow) => { Yellow }
|
|
|
|
(Yellow, Blue ) => { Red }
|
|
|
|
(Blue, Red ) => { Yellow }
|
|
|
|
(Blue, Yellow) => { Red }
|
|
|
|
(Blue, Blue ) => { Blue }
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn creature(
|
|
|
|
name: uint,
|
|
|
|
color: color,
|
2014-03-09 16:58:32 -05:00
|
|
|
from_rendezvous: Receiver<Option<CreatureInfo>>,
|
|
|
|
to_rendezvous: Sender<CreatureInfo>,
|
|
|
|
to_rendezvous_log: Sender<~str>
|
2012-07-06 20:20:36 -05:00
|
|
|
) {
|
|
|
|
let mut color = color;
|
|
|
|
let mut creatures_met = 0;
|
|
|
|
let mut evil_clones_met = 0;
|
|
|
|
|
|
|
|
loop {
|
|
|
|
// ask for a pairing
|
2013-01-29 01:54:39 -06:00
|
|
|
to_rendezvous.send(CreatureInfo {name: name, color: color});
|
|
|
|
let resp = from_rendezvous.recv();
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
// log and change, or print and quit
|
2012-08-06 14:34:08 -05:00
|
|
|
match resp {
|
2012-08-20 14:23:37 -05:00
|
|
|
option::Some(other_creature) => {
|
2012-07-06 20:20:36 -05:00
|
|
|
color = transform(color, other_creature.color);
|
|
|
|
|
|
|
|
// track some statistics
|
|
|
|
creatures_met += 1;
|
|
|
|
if other_creature.name == name {
|
|
|
|
evil_clones_met += 1;
|
|
|
|
}
|
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
option::None => {
|
2012-07-06 20:20:36 -05:00
|
|
|
// log creatures met and evil clones of self
|
2013-09-30 01:13:47 -05:00
|
|
|
let report = format!("{} {}",
|
2014-04-10 05:55:34 -05:00
|
|
|
creatures_met, show_number(evil_clones_met).as_slice());
|
2013-01-29 01:54:39 -06:00
|
|
|
to_rendezvous_log.send(report);
|
2012-07-06 20:20:36 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-05 17:28:08 -06:00
|
|
|
fn rendezvous(nn: uint, set: Vec<color>) {
|
2012-12-12 21:17:31 -06:00
|
|
|
|
2012-07-07 23:43:12 -05:00
|
|
|
// these ports will allow us to hear from the creatures
|
2014-03-09 16:58:32 -05:00
|
|
|
let (to_rendezvous, from_creatures) = channel::<CreatureInfo>();
|
|
|
|
let (to_rendezvous_log, from_creatures_log) = channel::<~str>();
|
2012-07-07 23:43:12 -05:00
|
|
|
|
|
|
|
// these channels will be passed to the creatures so they can talk to us
|
|
|
|
|
|
|
|
// these channels will allow us to talk to each creature by 'name'/index
|
2014-03-05 17:28:08 -06:00
|
|
|
let mut to_creature: Vec<Sender<Option<CreatureInfo>>> =
|
2013-08-09 22:09:47 -05:00
|
|
|
set.iter().enumerate().map(|(ii, col)| {
|
2012-09-21 20:43:30 -05:00
|
|
|
// create each creature as a listener with a port, and
|
|
|
|
// give us a channel to talk to each
|
|
|
|
let ii = ii;
|
|
|
|
let col = *col;
|
2013-01-29 01:54:39 -06:00
|
|
|
let to_rendezvous = to_rendezvous.clone();
|
|
|
|
let to_rendezvous_log = to_rendezvous_log.clone();
|
2014-03-09 16:58:32 -05:00
|
|
|
let (to_creature, from_rendezvous) = channel();
|
2014-01-27 17:29:50 -06:00
|
|
|
task::spawn(proc() {
|
2013-12-03 18:44:16 -06:00
|
|
|
creature(ii,
|
|
|
|
col,
|
|
|
|
from_rendezvous,
|
|
|
|
to_rendezvous.clone(),
|
2013-01-29 01:54:39 -06:00
|
|
|
to_rendezvous_log.clone());
|
2014-01-27 17:29:50 -06:00
|
|
|
});
|
2013-01-29 01:54:39 -06:00
|
|
|
to_creature
|
2013-06-29 00:05:50 -05:00
|
|
|
}).collect();
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
let mut creatures_met = 0;
|
|
|
|
|
|
|
|
// set up meetings...
|
2013-08-05 22:43:06 -05:00
|
|
|
for _ in range(0, nn) {
|
2014-03-05 17:28:08 -06:00
|
|
|
let mut fst_creature: CreatureInfo = from_creatures.recv();
|
|
|
|
let mut snd_creature: CreatureInfo = from_creatures.recv();
|
2012-07-07 23:43:12 -05:00
|
|
|
|
|
|
|
creatures_met += 2;
|
|
|
|
|
2014-03-05 17:28:08 -06:00
|
|
|
to_creature.get_mut(fst_creature.name).send(Some(snd_creature));
|
|
|
|
to_creature.get_mut(snd_creature.name).send(Some(fst_creature));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// tell each creature to stop
|
2013-08-03 11:45:23 -05:00
|
|
|
for to_one in to_creature.iter() {
|
2013-01-29 01:54:39 -06:00
|
|
|
to_one.send(None);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// save each creature's meeting stats
|
2014-03-05 16:02:44 -06:00
|
|
|
let mut report = Vec::new();
|
2013-08-03 11:45:23 -05:00
|
|
|
for _to_one in to_creature.iter() {
|
2013-01-29 01:54:39 -06:00
|
|
|
report.push(from_creatures_log.recv());
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// print each color in the set
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("{}", show_color_list(set));
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
// print each creature's stats
|
2013-08-03 11:45:23 -05:00
|
|
|
for rep in report.iter() {
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("{}", *rep);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// print the total number of creatures met
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("{}", show_number(creatures_met));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
2012-10-03 21:16:27 -05:00
|
|
|
fn main() {
|
|
|
|
let args = os::args();
|
2013-07-17 14:31:20 -05:00
|
|
|
let args = if os::getenv("RUST_BENCH").is_some() {
|
2014-04-15 20:17:48 -05:00
|
|
|
vec!("".to_owned(), "200000".to_owned())
|
2012-07-08 00:39:23 -05:00
|
|
|
} else if args.len() <= 1u {
|
2014-04-15 20:17:48 -05:00
|
|
|
vec!("".to_owned(), "600".to_owned())
|
2012-07-06 20:20:36 -05:00
|
|
|
} else {
|
2014-03-05 17:28:08 -06:00
|
|
|
args.move_iter().collect()
|
2012-07-06 20:20:36 -05:00
|
|
|
};
|
|
|
|
|
2014-03-05 17:28:08 -06:00
|
|
|
let nn = from_str::<uint>(*args.get(1)).unwrap();
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
print_complements();
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("");
|
2012-07-06 20:20:36 -05:00
|
|
|
|
2014-03-05 16:02:44 -06:00
|
|
|
rendezvous(nn, vec!(Blue, Red, Yellow));
|
2014-01-09 04:06:55 -06:00
|
|
|
println!("");
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
rendezvous(nn,
|
2014-03-05 16:02:44 -06:00
|
|
|
vec!(Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|