Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

224 lines (187 sloc) 6.087 kb
// 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.
// chameneos
extern mod std;
use std::oldmap;
use std::oldmap::HashMap;
use std::sort;
use std::cell::Cell;
use core::pipes::*;
fn print_complements() {
let all = ~[Blue, Red, Yellow];
for vec::each(all) |aa| {
for vec::each(all) |bb| {
io::println(show_color(*aa) + ~" + " + show_color(*bb) +
~" -> " + show_color(transform(*aa, *bb)));
}
}
}
enum color { Red, Yellow, Blue }
struct CreatureInfo {
name: uint,
color: color
}
fn show_color(cc: color) -> ~str {
match (cc) {
Red => {~"red"}
Yellow => {~"yellow"}
Blue => {~"blue"}
}
}
fn show_color_list(set: ~[color]) -> ~str {
let mut out = ~"";
for vec::eachi(set) |_ii, col| {
out += ~" ";
out += show_color(*col);
}
return out;
}
fn show_digit(nn: uint) -> ~str {
match (nn) {
0 => {~"zero"}
1 => {~"one"}
2 => {~"two"}
3 => {~"three"}
4 => {~"four"}
5 => {~"five"}
6 => {~"six"}
7 => {~"seven"}
8 => {~"eight"}
9 => {~"nine"}
_ => {die!(~"expected digits from 0 to 9...")}
}
}
fn show_number(nn: uint) -> ~str {
let mut out = ~"";
let mut num = nn;
let mut dig;
if num == 0 { out = show_digit(0) };
while num != 0 {
dig = num % 10;
num = num / 10;
out = show_digit(dig) + ~" " + out;
}
return out;
}
fn transform(aa: color, bb: color) -> color {
match (aa, bb) {
(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 }
}
}
fn creature(
name: uint,
color: color,
from_rendezvous: Port<Option<CreatureInfo>>,
to_rendezvous: SharedChan<CreatureInfo>,
to_rendezvous_log: SharedChan<~str>
) {
let mut color = color;
let mut creatures_met = 0;
let mut evil_clones_met = 0;
loop {
// ask for a pairing
to_rendezvous.send(CreatureInfo {name: name, color: color});
let resp = from_rendezvous.recv();
// log and change, or print and quit
match resp {
option::Some(other_creature) => {
color = transform(color, other_creature.color);
// track some statistics
creatures_met += 1;
if other_creature.name == name {
evil_clones_met += 1;
}
}
option::None => {
// log creatures met and evil clones of self
let report = fmt!("%u", creatures_met) + ~" " +
show_number(evil_clones_met);
to_rendezvous_log.send(report);
break;
}
}
}
}
fn rendezvous(nn: uint, set: ~[color]) {
// these ports will allow us to hear from the creatures
let (from_creatures, to_rendezvous) = stream::<CreatureInfo>();
let to_rendezvous = SharedChan(to_rendezvous);
let (from_creatures_log, to_rendezvous_log) = stream::<~str>();
let to_rendezvous_log = SharedChan(to_rendezvous_log);
// 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
let to_creature: ~[Chan<Option<CreatureInfo>>] =
vec::mapi(set, |ii, col| {
// create each creature as a listener with a port, and
// give us a channel to talk to each
let ii = ii;
let col = *col;
let to_rendezvous = to_rendezvous.clone();
let to_rendezvous_log = to_rendezvous_log.clone();
let (from_rendezvous, to_creature) = stream();
let from_rendezvous = Cell(from_rendezvous);
do task::spawn |move ii, move col| {
creature(ii, col, from_rendezvous.take(), to_rendezvous.clone(),
to_rendezvous_log.clone());
}
to_creature
});
let mut creatures_met = 0;
// set up meetings...
for nn.times {
let fst_creature: CreatureInfo = from_creatures.recv();
let snd_creature: CreatureInfo = from_creatures.recv();
creatures_met += 2;
to_creature[fst_creature.name].send(Some(snd_creature));
to_creature[snd_creature.name].send(Some(fst_creature));
}
// tell each creature to stop
for vec::eachi(to_creature) |_ii, to_one| {
to_one.send(None);
}
// save each creature's meeting stats
let mut report = ~[];
for vec::each(to_creature) |_to_one| {
report.push(from_creatures_log.recv());
}
// print each color in the set
io::println(show_color_list(set));
// print each creature's stats
for vec::each(report) |rep| {
io::println(*rep);
}
// print the total number of creatures met
io::println(show_number(creatures_met));
}
fn main() {
let args = os::args();
let args = if os::getenv(~"RUST_BENCH").is_some() {
~[~"", ~"200000"]
} else if args.len() <= 1u {
~[~"", ~"600"]
} else {
args
};
let nn = uint::from_str(args[1]).get();
print_complements();
io::println(~"");
rendezvous(nn, ~[Blue, Red, Yellow]);
io::println(~"");
rendezvous(nn,
~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
}
Jump to Line
Something went wrong with that request. Please try again.