Skip to content

Instantly share code, notes, and snippets.

@YoshiTheChinchilla
Last active January 14, 2021 05:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save YoshiTheChinchilla/fec3e7d3f77b2cfb8641bf2f86c91d0c to your computer and use it in GitHub Desktop.
Save YoshiTheChinchilla/fec3e7d3f77b2cfb8641bf2f86c91d0c to your computer and use it in GitHub Desktop.
A Kiyoshi Hikawa's Zundoko Bushi script written in Rust
[package]
name = "zundoko"
version = "0.1.0"
authors = ["Takashi Yoshimura"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "zundoko"
path = "lib.rs"
[dependencies]
rand = "0.8.2"
#![feature(test)]
#![feature(variant_count)]
extern crate test;
// cargo add zundoko --git https://gist.github.com/YoshiTheChinchilla/fec3e7d3f77b2cfb8641bf2f86c91d0c
// Or use this text of a dependency: `zundoko = { git = "https://gist.github.com/YoshiTheChinchilla/fec3e7d3f77b2cfb8641bf2f86c91d0c" }`
// Rust Playground URL: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=dc83ac03bf9502bf4c5e26018d46420d
use std::fmt::{self, Display, Formatter};
use std::borrow::Borrow;
use std::mem::variant_count;
// cargo add rand
use rand::{Rng, distributions::{Distribution, Standard}};
use Lyric::*;
/// enum Dun or Doko of Kiyoshi Hikawa's Zundoko Bushi
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Lyric {
Zun,
Doko,
}
/// implements [`Borrow<str>`](https://doc.rust-lang.org/std/borrow/trait.Borrow.html) to use [`[T]::join`](https://doc.rust-lang.org/std/slice/trait.Join.html) method
impl Borrow<str> for Lyric {
#[inline]
fn borrow(&self) -> &str {
match self {
Zun => "ズン",
Doko => "ドコ",
}
}
}
impl Display for Lyric {
#[inline]
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.borrow() as &str)
}
}
impl Distribution<Lyric> for Standard {
#[inline]
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Lyric {
if rng.gen() {
Zun
} else {
Doko
}
}
}
/// New type of Vec<Lyric>
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Zundoko(Vec<Lyric>);
impl Zundoko {
/// returns Zundoko struct
#[inline]
pub fn new() -> Self {
Self(Vec::new())
}
/// returns Zundoko struct with perfect lyrics of Zundoko Bushi
#[inline]
pub fn perfect() -> Self {
Self(vec![Zun, Zun, Zun, Zun, Doko])
}
/// returns Zundoko struct that ends with `&[Lyric]`
#[inline]
pub fn new_until_complete(complete: &[Lyric]) -> Self {
let mut rng = rand::thread_rng();
let mut v = Vec::with_capacity(variant_count::<Lyric>().pow(complete.len() as u32));
while !v.ends_with(complete) {
v.push(rng.gen());
}
v.shrink_to_fit();
Zundoko(v)
}
/// formats the lyrics with the tail (キ・ヨ・シ!) and returns the formatted String
#[inline]
pub fn format(&self) -> String {
format!("{} キ・ヨ・シ!", self.0.join(" "))
}
/// prints all lyrics of Zundoko Bushi
#[inline]
pub fn sing(&self) {
println!("{}", self.format());
}
}
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[test]
fn test_zundoko() {
let complete = Zundoko::perfect();
let zundoko = Zundoko::new_until_complete(&complete.0);
let zundoko_str = zundoko.format();
let tail = "ズン ズン ズン ズン ドコ キ・ヨ・シ!";
let tail_count = tail.chars().count();
let count = zundoko.0.len();
assert!(zundoko_str.chars().count() >= tail_count);
assert!(zundoko_str.ends_with(tail));
assert_eq!(zundoko_str.chars().count(), count * 2 + count + "キ・ヨ・シ!".chars().count());
}
#[bench]
fn bench_zundoko(b: &mut Bencher) {
b.iter(|| test_zundoko());
// use std::time::Instant;
// use std::sync::Arc;
// let now = Instant::now();
// let num_threads = num_cpus::get();
// println!("Using {} CPU threads.", num_threads);
// let complete = Arc::new([Zun, Zun, Zun, Zun, Doko]);
// (0..num_threads)
// .map(|_| {
// let complete = complete.clone();
// std::thread::spawn(move || ZunDoko::new_until_complete(complete.as_ref()))
// })
// .for_each(|h| {h.join().map(|zundoko| zundoko.sing());});
// println!("{}", now.elapsed().as_millis());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment