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
|
|
|
|
|
2012-09-11 19:46:20 -05:00
|
|
|
extern mod std;
|
2012-09-05 14:32:05 -05:00
|
|
|
use std::map;
|
2012-09-10 17:38:28 -05:00
|
|
|
use std::map::HashMap;
|
2012-09-05 14:32:05 -05:00
|
|
|
use std::sort;
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
fn print_complements() {
|
|
|
|
let all = ~[Blue, Red, Yellow];
|
2012-09-18 23:41:13 -05:00
|
|
|
for vec::each(all) |aa| {
|
|
|
|
for vec::each(all) |bb| {
|
2012-09-18 23:41:37 -05:00
|
|
|
io::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
|
|
|
|
|
|
|
type creature_info = { name: uint, color: color };
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn show_color(cc: color) -> ~str {
|
2012-08-06 14:34:08 -05:00
|
|
|
match (cc) {
|
2012-08-03 21:59:04 -05:00
|
|
|
Red => {~"red"}
|
|
|
|
Yellow => {~"yellow"}
|
|
|
|
Blue => {~"blue"}
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn show_color_list(set: ~[color]) -> ~str {
|
|
|
|
let mut out = ~"";
|
2012-07-06 20:20:36 -05:00
|
|
|
for vec::eachi(set) |_ii, col| {
|
2012-07-14 00:57:48 -05:00
|
|
|
out += ~" ";
|
2012-09-21 20:43:30 -05:00
|
|
|
out += show_color(*col);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
2012-08-01 19:30:05 -05:00
|
|
|
return out;
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn show_digit(nn: uint) -> ~str {
|
2012-08-06 14:34:08 -05:00
|
|
|
match (nn) {
|
2012-08-03 21:59:04 -05:00
|
|
|
0 => {~"zero"}
|
|
|
|
1 => {~"one"}
|
|
|
|
2 => {~"two"}
|
|
|
|
3 => {~"three"}
|
|
|
|
4 => {~"four"}
|
|
|
|
5 => {~"five"}
|
|
|
|
6 => {~"six"}
|
|
|
|
7 => {~"seven"}
|
|
|
|
8 => {~"eight"}
|
|
|
|
9 => {~"nine"}
|
|
|
|
_ => {fail ~"expected digits from 0 to 9..."}
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 00:57:48 -05:00
|
|
|
fn show_number(nn: uint) -> ~str {
|
|
|
|
let mut out = ~"";
|
2012-07-06 20:20:36 -05:00
|
|
|
let mut num = nn;
|
|
|
|
let mut dig;
|
|
|
|
|
|
|
|
if num == 0 { out = show_digit(0) };
|
|
|
|
|
|
|
|
while num != 0 {
|
|
|
|
dig = num % 10;
|
|
|
|
num = num / 10;
|
2012-07-14 00:57:48 -05:00
|
|
|
out = show_digit(dig) + ~" " + out;
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
2012-08-01 19:30:05 -05:00
|
|
|
return out;
|
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,
|
2012-12-13 16:18:47 -06:00
|
|
|
from_rendezvous: oldcomm::Port<Option<creature_info>>,
|
|
|
|
to_rendezvous: oldcomm::Chan<creature_info>,
|
|
|
|
to_rendezvous_log: oldcomm::Chan<~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
|
2012-12-13 16:18:47 -06:00
|
|
|
oldcomm::send(to_rendezvous, {name: name, color: color});
|
|
|
|
let resp = oldcomm::recv(from_rendezvous);
|
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
|
2012-08-22 19:24:52 -05:00
|
|
|
let report = fmt!("%u", creatures_met) + ~" " +
|
2012-07-06 20:20:36 -05:00
|
|
|
show_number(evil_clones_met);
|
2012-12-13 16:18:47 -06:00
|
|
|
oldcomm::send(to_rendezvous_log, report);
|
2012-07-06 20:20:36 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn rendezvous(nn: uint, set: ~[color]) {
|
2012-12-12 21:17:31 -06:00
|
|
|
|
2012-12-14 17:57:59 -06:00
|
|
|
pub fn spawn_listener<A: Owned>(+f: fn~(oldcomm::Port<A>)) -> oldcomm::Chan<A> {
|
2012-12-13 16:18:47 -06:00
|
|
|
let setup_po = oldcomm::Port();
|
|
|
|
let setup_ch = oldcomm::Chan(&setup_po);
|
2012-12-12 21:17:31 -06:00
|
|
|
do task::spawn |move f| {
|
2012-12-13 16:18:47 -06:00
|
|
|
let po = oldcomm::Port();
|
|
|
|
let ch = oldcomm::Chan(&po);
|
|
|
|
oldcomm::send(setup_ch, ch);
|
2012-12-12 21:17:31 -06:00
|
|
|
f(move po);
|
|
|
|
}
|
2012-12-13 16:18:47 -06:00
|
|
|
oldcomm::recv(setup_po)
|
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
|
2012-12-13 16:18:47 -06:00
|
|
|
let from_creatures: oldcomm::Port<creature_info> = oldcomm::Port();
|
|
|
|
let from_creatures_log: oldcomm::Port<~str> = oldcomm::Port();
|
2012-07-07 23:43:12 -05:00
|
|
|
|
|
|
|
// these channels will be passed to the creatures so they can talk to us
|
2012-12-13 16:18:47 -06:00
|
|
|
let to_rendezvous = oldcomm::Chan(&from_creatures);
|
|
|
|
let to_rendezvous_log = oldcomm::Chan(&from_creatures_log);
|
2012-07-07 23:43:12 -05:00
|
|
|
|
|
|
|
// these channels will allow us to talk to each creature by 'name'/index
|
2012-12-13 16:18:47 -06:00
|
|
|
let to_creature: ~[oldcomm::Chan<Option<creature_info>>] =
|
2012-09-21 20:43:30 -05:00
|
|
|
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;
|
2012-12-12 21:17:31 -06:00
|
|
|
do spawn_listener |from_rendezvous, move ii, move col| {
|
2012-09-21 20:43:30 -05:00
|
|
|
creature(ii, col, from_rendezvous, to_rendezvous,
|
|
|
|
to_rendezvous_log);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
2012-09-21 20:43:30 -05:00
|
|
|
});
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
let mut creatures_met = 0;
|
|
|
|
|
|
|
|
// set up meetings...
|
2012-07-07 23:43:12 -05:00
|
|
|
for nn.times {
|
2012-12-13 16:18:47 -06:00
|
|
|
let fst_creature: creature_info = oldcomm::recv(from_creatures);
|
|
|
|
let snd_creature: creature_info = oldcomm::recv(from_creatures);
|
2012-07-07 23:43:12 -05:00
|
|
|
|
|
|
|
creatures_met += 2;
|
|
|
|
|
2012-12-13 16:18:47 -06:00
|
|
|
oldcomm::send(to_creature[fst_creature.name], Some(snd_creature));
|
|
|
|
oldcomm::send(to_creature[snd_creature.name], Some(fst_creature));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// tell each creature to stop
|
|
|
|
for vec::eachi(to_creature) |_ii, to_one| {
|
2012-12-13 16:18:47 -06:00
|
|
|
oldcomm::send(*to_one, None);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// save each creature's meeting stats
|
|
|
|
let mut report = ~[];
|
2012-09-18 23:41:13 -05:00
|
|
|
for vec::each(to_creature) |_to_one| {
|
2012-12-13 16:18:47 -06:00
|
|
|
report.push(oldcomm::recv(from_creatures_log));
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// print each color in the set
|
|
|
|
io::println(show_color_list(set));
|
|
|
|
|
|
|
|
// print each creature's stats
|
2012-09-18 23:41:13 -05:00
|
|
|
for vec::each(report) |rep| {
|
2012-09-18 23:41:37 -05:00
|
|
|
io::println(*rep);
|
2012-07-06 20:20:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// print the total number of creatures met
|
|
|
|
io::println(show_number(creatures_met));
|
|
|
|
}
|
|
|
|
|
2012-10-03 21:16:27 -05:00
|
|
|
fn main() {
|
|
|
|
let args = os::args();
|
2012-07-14 00:57:48 -05:00
|
|
|
let args = if os::getenv(~"RUST_BENCH").is_some() {
|
|
|
|
~[~"", ~"200000"]
|
2012-07-08 00:39:23 -05:00
|
|
|
} else if args.len() <= 1u {
|
2012-07-14 00:57:48 -05:00
|
|
|
~[~"", ~"600"]
|
2012-07-06 20:20:36 -05:00
|
|
|
} else {
|
|
|
|
args
|
|
|
|
};
|
|
|
|
|
|
|
|
let nn = uint::from_str(args[1]).get();
|
|
|
|
|
|
|
|
print_complements();
|
2012-07-14 00:57:48 -05:00
|
|
|
io::println(~"");
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
rendezvous(nn, ~[Blue, Red, Yellow]);
|
2012-07-14 00:57:48 -05:00
|
|
|
io::println(~"");
|
2012-07-06 20:20:36 -05:00
|
|
|
|
|
|
|
rendezvous(nn,
|
|
|
|
~[Blue, Red, Yellow, Red, Yellow, Blue, Red, Yellow, Red, Blue]);
|
|
|
|
}
|
|
|
|
|