Compare commits
2 Commits
1fb0b63bcc
...
69a5ac4d51
Author | SHA1 | Date | |
---|---|---|---|
69a5ac4d51 | |||
a70a0828b6 |
221
src/main.rs
221
src/main.rs
@ -20,6 +20,9 @@ use std::io::{self, BufReader};
|
|||||||
|
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
|
|
||||||
|
mod suffix;
|
||||||
|
use crate::suffix::{AlphabeticSuffixGenerator, NumericSuffixGenerator};
|
||||||
|
|
||||||
#[derive(FromArgs)]
|
#[derive(FromArgs)]
|
||||||
#[argh(description = "\
|
#[argh(description = "\
|
||||||
chop off bits of file\n\n\
|
chop off bits of file\n\n\
|
||||||
@ -51,85 +54,6 @@ struct Options {
|
|||||||
filename: String,
|
filename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AlphabeticSuffixGenerator {
|
|
||||||
suffix: Vec<u8>,
|
|
||||||
remaining: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AlphabeticSuffixGenerator {
|
|
||||||
fn new(count: usize) -> AlphabeticSuffixGenerator {
|
|
||||||
let suffix_length = AlphabeticSuffixGenerator::calculate_suffix_length(count);
|
|
||||||
let mut suffix = vec![b'a'; suffix_length];
|
|
||||||
suffix[suffix_length - 1] -= 1;
|
|
||||||
|
|
||||||
AlphabeticSuffixGenerator {
|
|
||||||
suffix,
|
|
||||||
remaining: count,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn calculate_suffix_length(count: usize) -> usize {
|
|
||||||
let mut suffix_length = 1;
|
|
||||||
let mut remainder = count as f64;
|
|
||||||
loop {
|
|
||||||
if remainder <= 26.0 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
suffix_length += 1;
|
|
||||||
remainder /= 26.0;
|
|
||||||
}
|
|
||||||
suffix_length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for AlphabeticSuffixGenerator {
|
|
||||||
type Item = String;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<String> {
|
|
||||||
if self.remaining == 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
for idx in (0..self.suffix.len()).rev() {
|
|
||||||
if self.suffix[idx] < b'z' {
|
|
||||||
self.suffix[idx] += 1;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
self.suffix[idx] = b'a';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.remaining -= 1;
|
|
||||||
Some(String::from_utf8(self.suffix.to_vec()).expect("invalid suffix generated"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NumericSuffixGenerator {
|
|
||||||
current: usize,
|
|
||||||
last: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NumericSuffixGenerator {
|
|
||||||
fn new(start: usize, count: usize) -> NumericSuffixGenerator {
|
|
||||||
NumericSuffixGenerator {
|
|
||||||
current: start,
|
|
||||||
last: (start + count),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Iterator for NumericSuffixGenerator {
|
|
||||||
type Item = String;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<String> {
|
|
||||||
if self.current == self.last {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let next = self.current.to_string();
|
|
||||||
self.current += 1;
|
|
||||||
Some(next)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_main() -> Result<(), Box<dyn Error>> {
|
fn try_main() -> Result<(), Box<dyn Error>> {
|
||||||
let opts: Options = argh::from_env();
|
let opts: Options = argh::from_env();
|
||||||
|
|
||||||
@ -170,7 +94,8 @@ fn try_main() -> Result<(), Box<dyn Error>> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let mut out_file = File::create(format!("{}{}", prefix, suffix))?;
|
let mut out_file = File::create(format!("{}{}", prefix, suffix))?;
|
||||||
for _ in 0..opts.lines {
|
out_file.write_all(line.as_bytes())?;
|
||||||
|
for _ in 1..opts.lines {
|
||||||
line.clear();
|
line.clear();
|
||||||
match reader.read_line(&mut line)? {
|
match reader.read_line(&mut line)? {
|
||||||
0 => {
|
0 => {
|
||||||
@ -181,6 +106,7 @@ fn try_main() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
line.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if there's anything left for the remainder file
|
// see if there's anything left for the remainder file
|
||||||
@ -205,138 +131,3 @@ fn main() {
|
|||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_numeric_suffix_generator_output() {
|
|
||||||
// tuple of start, count
|
|
||||||
let testcases = vec![(0, 10), (5, 20), (0, 200), (10, 5)];
|
|
||||||
|
|
||||||
for (start, count) in testcases {
|
|
||||||
let expected: Vec<String> = (start..(start + count)).map(|i| i.to_string()).collect();
|
|
||||||
let actual: Vec<String> = NumericSuffixGenerator::new(start, count).collect();
|
|
||||||
assert_eq!(actual, expected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_alpha_suffix_generator_min_digits() {
|
|
||||||
// tuple of count => expected min length of suffix
|
|
||||||
let testcases = vec![
|
|
||||||
(1, 1),
|
|
||||||
(10, 1),
|
|
||||||
(26, 1),
|
|
||||||
(27, 2),
|
|
||||||
(30, 2),
|
|
||||||
(700, 3),
|
|
||||||
(50_000, 4),
|
|
||||||
];
|
|
||||||
|
|
||||||
for (count, expected) in testcases {
|
|
||||||
let actual = AlphabeticSuffixGenerator::calculate_suffix_length(count);
|
|
||||||
assert_eq!(
|
|
||||||
actual, expected,
|
|
||||||
"for count {} expected suffix length {} got {}",
|
|
||||||
count, expected, actual
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_alpha_suffix_generator_output() {
|
|
||||||
// tuple of count => expected suffix vector
|
|
||||||
let testcases = vec![
|
|
||||||
(3, vec!["a", "b", "c"]),
|
|
||||||
(
|
|
||||||
30,
|
|
||||||
vec![
|
|
||||||
"aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am",
|
|
||||||
"an", "ao", "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax", "ay", "az",
|
|
||||||
"ba", "bb", "bc", "bd",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
700,
|
|
||||||
vec![
|
|
||||||
"aaa", "aab", "aac", "aad", "aae", "aaf", "aag", "aah", "aai", "aaj", "aak",
|
|
||||||
"aal", "aam", "aan", "aao", "aap", "aaq", "aar", "aas", "aat", "aau", "aav",
|
|
||||||
"aaw", "aax", "aay", "aaz", "aba", "abb", "abc", "abd", "abe", "abf", "abg",
|
|
||||||
"abh", "abi", "abj", "abk", "abl", "abm", "abn", "abo", "abp", "abq", "abr",
|
|
||||||
"abs", "abt", "abu", "abv", "abw", "abx", "aby", "abz", "aca", "acb", "acc",
|
|
||||||
"acd", "ace", "acf", "acg", "ach", "aci", "acj", "ack", "acl", "acm", "acn",
|
|
||||||
"aco", "acp", "acq", "acr", "acs", "act", "acu", "acv", "acw", "acx", "acy",
|
|
||||||
"acz", "ada", "adb", "adc", "add", "ade", "adf", "adg", "adh", "adi", "adj",
|
|
||||||
"adk", "adl", "adm", "adn", "ado", "adp", "adq", "adr", "ads", "adt", "adu",
|
|
||||||
"adv", "adw", "adx", "ady", "adz", "aea", "aeb", "aec", "aed", "aee", "aef",
|
|
||||||
"aeg", "aeh", "aei", "aej", "aek", "ael", "aem", "aen", "aeo", "aep", "aeq",
|
|
||||||
"aer", "aes", "aet", "aeu", "aev", "aew", "aex", "aey", "aez", "afa", "afb",
|
|
||||||
"afc", "afd", "afe", "aff", "afg", "afh", "afi", "afj", "afk", "afl", "afm",
|
|
||||||
"afn", "afo", "afp", "afq", "afr", "afs", "aft", "afu", "afv", "afw", "afx",
|
|
||||||
"afy", "afz", "aga", "agb", "agc", "agd", "age", "agf", "agg", "agh", "agi",
|
|
||||||
"agj", "agk", "agl", "agm", "agn", "ago", "agp", "agq", "agr", "ags", "agt",
|
|
||||||
"agu", "agv", "agw", "agx", "agy", "agz", "aha", "ahb", "ahc", "ahd", "ahe",
|
|
||||||
"ahf", "ahg", "ahh", "ahi", "ahj", "ahk", "ahl", "ahm", "ahn", "aho", "ahp",
|
|
||||||
"ahq", "ahr", "ahs", "aht", "ahu", "ahv", "ahw", "ahx", "ahy", "ahz", "aia",
|
|
||||||
"aib", "aic", "aid", "aie", "aif", "aig", "aih", "aii", "aij", "aik", "ail",
|
|
||||||
"aim", "ain", "aio", "aip", "aiq", "air", "ais", "ait", "aiu", "aiv", "aiw",
|
|
||||||
"aix", "aiy", "aiz", "aja", "ajb", "ajc", "ajd", "aje", "ajf", "ajg", "ajh",
|
|
||||||
"aji", "ajj", "ajk", "ajl", "ajm", "ajn", "ajo", "ajp", "ajq", "ajr", "ajs",
|
|
||||||
"ajt", "aju", "ajv", "ajw", "ajx", "ajy", "ajz", "aka", "akb", "akc", "akd",
|
|
||||||
"ake", "akf", "akg", "akh", "aki", "akj", "akk", "akl", "akm", "akn", "ako",
|
|
||||||
"akp", "akq", "akr", "aks", "akt", "aku", "akv", "akw", "akx", "aky", "akz",
|
|
||||||
"ala", "alb", "alc", "ald", "ale", "alf", "alg", "alh", "ali", "alj", "alk",
|
|
||||||
"all", "alm", "aln", "alo", "alp", "alq", "alr", "als", "alt", "alu", "alv",
|
|
||||||
"alw", "alx", "aly", "alz", "ama", "amb", "amc", "amd", "ame", "amf", "amg",
|
|
||||||
"amh", "ami", "amj", "amk", "aml", "amm", "amn", "amo", "amp", "amq", "amr",
|
|
||||||
"ams", "amt", "amu", "amv", "amw", "amx", "amy", "amz", "ana", "anb", "anc",
|
|
||||||
"and", "ane", "anf", "ang", "anh", "ani", "anj", "ank", "anl", "anm", "ann",
|
|
||||||
"ano", "anp", "anq", "anr", "ans", "ant", "anu", "anv", "anw", "anx", "any",
|
|
||||||
"anz", "aoa", "aob", "aoc", "aod", "aoe", "aof", "aog", "aoh", "aoi", "aoj",
|
|
||||||
"aok", "aol", "aom", "aon", "aoo", "aop", "aoq", "aor", "aos", "aot", "aou",
|
|
||||||
"aov", "aow", "aox", "aoy", "aoz", "apa", "apb", "apc", "apd", "ape", "apf",
|
|
||||||
"apg", "aph", "api", "apj", "apk", "apl", "apm", "apn", "apo", "app", "apq",
|
|
||||||
"apr", "aps", "apt", "apu", "apv", "apw", "apx", "apy", "apz", "aqa", "aqb",
|
|
||||||
"aqc", "aqd", "aqe", "aqf", "aqg", "aqh", "aqi", "aqj", "aqk", "aql", "aqm",
|
|
||||||
"aqn", "aqo", "aqp", "aqq", "aqr", "aqs", "aqt", "aqu", "aqv", "aqw", "aqx",
|
|
||||||
"aqy", "aqz", "ara", "arb", "arc", "ard", "are", "arf", "arg", "arh", "ari",
|
|
||||||
"arj", "ark", "arl", "arm", "arn", "aro", "arp", "arq", "arr", "ars", "art",
|
|
||||||
"aru", "arv", "arw", "arx", "ary", "arz", "asa", "asb", "asc", "asd", "ase",
|
|
||||||
"asf", "asg", "ash", "asi", "asj", "ask", "asl", "asm", "asn", "aso", "asp",
|
|
||||||
"asq", "asr", "ass", "ast", "asu", "asv", "asw", "asx", "asy", "asz", "ata",
|
|
||||||
"atb", "atc", "atd", "ate", "atf", "atg", "ath", "ati", "atj", "atk", "atl",
|
|
||||||
"atm", "atn", "ato", "atp", "atq", "atr", "ats", "att", "atu", "atv", "atw",
|
|
||||||
"atx", "aty", "atz", "aua", "aub", "auc", "aud", "aue", "auf", "aug", "auh",
|
|
||||||
"aui", "auj", "auk", "aul", "aum", "aun", "auo", "aup", "auq", "aur", "aus",
|
|
||||||
"aut", "auu", "auv", "auw", "aux", "auy", "auz", "ava", "avb", "avc", "avd",
|
|
||||||
"ave", "avf", "avg", "avh", "avi", "avj", "avk", "avl", "avm", "avn", "avo",
|
|
||||||
"avp", "avq", "avr", "avs", "avt", "avu", "avv", "avw", "avx", "avy", "avz",
|
|
||||||
"awa", "awb", "awc", "awd", "awe", "awf", "awg", "awh", "awi", "awj", "awk",
|
|
||||||
"awl", "awm", "awn", "awo", "awp", "awq", "awr", "aws", "awt", "awu", "awv",
|
|
||||||
"aww", "awx", "awy", "awz", "axa", "axb", "axc", "axd", "axe", "axf", "axg",
|
|
||||||
"axh", "axi", "axj", "axk", "axl", "axm", "axn", "axo", "axp", "axq", "axr",
|
|
||||||
"axs", "axt", "axu", "axv", "axw", "axx", "axy", "axz", "aya", "ayb", "ayc",
|
|
||||||
"ayd", "aye", "ayf", "ayg", "ayh", "ayi", "ayj", "ayk", "ayl", "aym", "ayn",
|
|
||||||
"ayo", "ayp", "ayq", "ayr", "ays", "ayt", "ayu", "ayv", "ayw", "ayx", "ayy",
|
|
||||||
"ayz", "aza", "azb", "azc", "azd", "aze", "azf", "azg", "azh", "azi", "azj",
|
|
||||||
"azk", "azl", "azm", "azn", "azo", "azp", "azq", "azr", "azs", "azt", "azu",
|
|
||||||
"azv", "azw", "azx", "azy", "azz", "baa", "bab", "bac", "bad", "bae", "baf",
|
|
||||||
"bag", "bah", "bai", "baj", "bak", "bal", "bam", "ban", "bao", "bap", "baq",
|
|
||||||
"bar", "bas", "bat", "bau", "bav", "baw", "bax",
|
|
||||||
],
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
for (count, expected) in testcases {
|
|
||||||
let gen = AlphabeticSuffixGenerator::new(count);
|
|
||||||
let actual: Vec<String> = gen.collect();
|
|
||||||
assert_eq!(
|
|
||||||
actual, expected,
|
|
||||||
"unexpected suffix list for count {}",
|
|
||||||
count
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
213
src/suffix.rs
Normal file
213
src/suffix.rs
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
pub struct AlphabeticSuffixGenerator {
|
||||||
|
suffix: Vec<u8>,
|
||||||
|
remaining: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AlphabeticSuffixGenerator {
|
||||||
|
pub fn new(count: usize) -> AlphabeticSuffixGenerator {
|
||||||
|
let suffix_length = AlphabeticSuffixGenerator::calculate_suffix_length(count);
|
||||||
|
let mut suffix = vec![b'a'; suffix_length];
|
||||||
|
suffix[suffix_length - 1] -= 1;
|
||||||
|
|
||||||
|
AlphabeticSuffixGenerator {
|
||||||
|
suffix,
|
||||||
|
remaining: count,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_suffix_length(count: usize) -> usize {
|
||||||
|
let mut suffix_length = 1;
|
||||||
|
let mut remainder = count as f64;
|
||||||
|
loop {
|
||||||
|
if remainder <= 26.0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
suffix_length += 1;
|
||||||
|
remainder /= 26.0;
|
||||||
|
}
|
||||||
|
suffix_length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for AlphabeticSuffixGenerator {
|
||||||
|
type Item = String;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<String> {
|
||||||
|
if self.remaining == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
for idx in (0..self.suffix.len()).rev() {
|
||||||
|
if self.suffix[idx] < b'z' {
|
||||||
|
self.suffix[idx] += 1;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
self.suffix[idx] = b'a';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.remaining -= 1;
|
||||||
|
Some(String::from_utf8(self.suffix.to_vec()).expect("invalid suffix generated"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NumericSuffixGenerator {
|
||||||
|
current: usize,
|
||||||
|
last: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumericSuffixGenerator {
|
||||||
|
pub fn new(start: usize, count: usize) -> NumericSuffixGenerator {
|
||||||
|
NumericSuffixGenerator {
|
||||||
|
current: start,
|
||||||
|
last: (start + count),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for NumericSuffixGenerator {
|
||||||
|
type Item = String;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<String> {
|
||||||
|
if self.current == self.last {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let next = self.current.to_string();
|
||||||
|
self.current += 1;
|
||||||
|
Some(next)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_numeric_suffix_generator_output() {
|
||||||
|
// tuple of start, count
|
||||||
|
let testcases = vec![(0, 10), (5, 20), (0, 200), (10, 5)];
|
||||||
|
|
||||||
|
for (start, count) in testcases {
|
||||||
|
let expected: Vec<String> = (start..(start + count)).map(|i| i.to_string()).collect();
|
||||||
|
let actual: Vec<String> = NumericSuffixGenerator::new(start, count).collect();
|
||||||
|
assert_eq!(actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_alpha_suffix_generator_min_digits() {
|
||||||
|
// tuple of count => expected min length of suffix
|
||||||
|
let testcases = vec![
|
||||||
|
(1, 1),
|
||||||
|
(10, 1),
|
||||||
|
(26, 1),
|
||||||
|
(27, 2),
|
||||||
|
(30, 2),
|
||||||
|
(700, 3),
|
||||||
|
(50_000, 4),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (count, expected) in testcases {
|
||||||
|
let actual = AlphabeticSuffixGenerator::calculate_suffix_length(count);
|
||||||
|
assert_eq!(
|
||||||
|
actual, expected,
|
||||||
|
"for count {} expected suffix length {} got {}",
|
||||||
|
count, expected, actual
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_alpha_suffix_generator_output() {
|
||||||
|
// tuple of count => expected suffix vector
|
||||||
|
let testcases = vec![
|
||||||
|
(3, vec!["a", "b", "c"]),
|
||||||
|
(
|
||||||
|
30,
|
||||||
|
vec![
|
||||||
|
"aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am",
|
||||||
|
"an", "ao", "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax", "ay", "az",
|
||||||
|
"ba", "bb", "bc", "bd",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
700,
|
||||||
|
vec![
|
||||||
|
"aaa", "aab", "aac", "aad", "aae", "aaf", "aag", "aah", "aai", "aaj", "aak",
|
||||||
|
"aal", "aam", "aan", "aao", "aap", "aaq", "aar", "aas", "aat", "aau", "aav",
|
||||||
|
"aaw", "aax", "aay", "aaz", "aba", "abb", "abc", "abd", "abe", "abf", "abg",
|
||||||
|
"abh", "abi", "abj", "abk", "abl", "abm", "abn", "abo", "abp", "abq", "abr",
|
||||||
|
"abs", "abt", "abu", "abv", "abw", "abx", "aby", "abz", "aca", "acb", "acc",
|
||||||
|
"acd", "ace", "acf", "acg", "ach", "aci", "acj", "ack", "acl", "acm", "acn",
|
||||||
|
"aco", "acp", "acq", "acr", "acs", "act", "acu", "acv", "acw", "acx", "acy",
|
||||||
|
"acz", "ada", "adb", "adc", "add", "ade", "adf", "adg", "adh", "adi", "adj",
|
||||||
|
"adk", "adl", "adm", "adn", "ado", "adp", "adq", "adr", "ads", "adt", "adu",
|
||||||
|
"adv", "adw", "adx", "ady", "adz", "aea", "aeb", "aec", "aed", "aee", "aef",
|
||||||
|
"aeg", "aeh", "aei", "aej", "aek", "ael", "aem", "aen", "aeo", "aep", "aeq",
|
||||||
|
"aer", "aes", "aet", "aeu", "aev", "aew", "aex", "aey", "aez", "afa", "afb",
|
||||||
|
"afc", "afd", "afe", "aff", "afg", "afh", "afi", "afj", "afk", "afl", "afm",
|
||||||
|
"afn", "afo", "afp", "afq", "afr", "afs", "aft", "afu", "afv", "afw", "afx",
|
||||||
|
"afy", "afz", "aga", "agb", "agc", "agd", "age", "agf", "agg", "agh", "agi",
|
||||||
|
"agj", "agk", "agl", "agm", "agn", "ago", "agp", "agq", "agr", "ags", "agt",
|
||||||
|
"agu", "agv", "agw", "agx", "agy", "agz", "aha", "ahb", "ahc", "ahd", "ahe",
|
||||||
|
"ahf", "ahg", "ahh", "ahi", "ahj", "ahk", "ahl", "ahm", "ahn", "aho", "ahp",
|
||||||
|
"ahq", "ahr", "ahs", "aht", "ahu", "ahv", "ahw", "ahx", "ahy", "ahz", "aia",
|
||||||
|
"aib", "aic", "aid", "aie", "aif", "aig", "aih", "aii", "aij", "aik", "ail",
|
||||||
|
"aim", "ain", "aio", "aip", "aiq", "air", "ais", "ait", "aiu", "aiv", "aiw",
|
||||||
|
"aix", "aiy", "aiz", "aja", "ajb", "ajc", "ajd", "aje", "ajf", "ajg", "ajh",
|
||||||
|
"aji", "ajj", "ajk", "ajl", "ajm", "ajn", "ajo", "ajp", "ajq", "ajr", "ajs",
|
||||||
|
"ajt", "aju", "ajv", "ajw", "ajx", "ajy", "ajz", "aka", "akb", "akc", "akd",
|
||||||
|
"ake", "akf", "akg", "akh", "aki", "akj", "akk", "akl", "akm", "akn", "ako",
|
||||||
|
"akp", "akq", "akr", "aks", "akt", "aku", "akv", "akw", "akx", "aky", "akz",
|
||||||
|
"ala", "alb", "alc", "ald", "ale", "alf", "alg", "alh", "ali", "alj", "alk",
|
||||||
|
"all", "alm", "aln", "alo", "alp", "alq", "alr", "als", "alt", "alu", "alv",
|
||||||
|
"alw", "alx", "aly", "alz", "ama", "amb", "amc", "amd", "ame", "amf", "amg",
|
||||||
|
"amh", "ami", "amj", "amk", "aml", "amm", "amn", "amo", "amp", "amq", "amr",
|
||||||
|
"ams", "amt", "amu", "amv", "amw", "amx", "amy", "amz", "ana", "anb", "anc",
|
||||||
|
"and", "ane", "anf", "ang", "anh", "ani", "anj", "ank", "anl", "anm", "ann",
|
||||||
|
"ano", "anp", "anq", "anr", "ans", "ant", "anu", "anv", "anw", "anx", "any",
|
||||||
|
"anz", "aoa", "aob", "aoc", "aod", "aoe", "aof", "aog", "aoh", "aoi", "aoj",
|
||||||
|
"aok", "aol", "aom", "aon", "aoo", "aop", "aoq", "aor", "aos", "aot", "aou",
|
||||||
|
"aov", "aow", "aox", "aoy", "aoz", "apa", "apb", "apc", "apd", "ape", "apf",
|
||||||
|
"apg", "aph", "api", "apj", "apk", "apl", "apm", "apn", "apo", "app", "apq",
|
||||||
|
"apr", "aps", "apt", "apu", "apv", "apw", "apx", "apy", "apz", "aqa", "aqb",
|
||||||
|
"aqc", "aqd", "aqe", "aqf", "aqg", "aqh", "aqi", "aqj", "aqk", "aql", "aqm",
|
||||||
|
"aqn", "aqo", "aqp", "aqq", "aqr", "aqs", "aqt", "aqu", "aqv", "aqw", "aqx",
|
||||||
|
"aqy", "aqz", "ara", "arb", "arc", "ard", "are", "arf", "arg", "arh", "ari",
|
||||||
|
"arj", "ark", "arl", "arm", "arn", "aro", "arp", "arq", "arr", "ars", "art",
|
||||||
|
"aru", "arv", "arw", "arx", "ary", "arz", "asa", "asb", "asc", "asd", "ase",
|
||||||
|
"asf", "asg", "ash", "asi", "asj", "ask", "asl", "asm", "asn", "aso", "asp",
|
||||||
|
"asq", "asr", "ass", "ast", "asu", "asv", "asw", "asx", "asy", "asz", "ata",
|
||||||
|
"atb", "atc", "atd", "ate", "atf", "atg", "ath", "ati", "atj", "atk", "atl",
|
||||||
|
"atm", "atn", "ato", "atp", "atq", "atr", "ats", "att", "atu", "atv", "atw",
|
||||||
|
"atx", "aty", "atz", "aua", "aub", "auc", "aud", "aue", "auf", "aug", "auh",
|
||||||
|
"aui", "auj", "auk", "aul", "aum", "aun", "auo", "aup", "auq", "aur", "aus",
|
||||||
|
"aut", "auu", "auv", "auw", "aux", "auy", "auz", "ava", "avb", "avc", "avd",
|
||||||
|
"ave", "avf", "avg", "avh", "avi", "avj", "avk", "avl", "avm", "avn", "avo",
|
||||||
|
"avp", "avq", "avr", "avs", "avt", "avu", "avv", "avw", "avx", "avy", "avz",
|
||||||
|
"awa", "awb", "awc", "awd", "awe", "awf", "awg", "awh", "awi", "awj", "awk",
|
||||||
|
"awl", "awm", "awn", "awo", "awp", "awq", "awr", "aws", "awt", "awu", "awv",
|
||||||
|
"aww", "awx", "awy", "awz", "axa", "axb", "axc", "axd", "axe", "axf", "axg",
|
||||||
|
"axh", "axi", "axj", "axk", "axl", "axm", "axn", "axo", "axp", "axq", "axr",
|
||||||
|
"axs", "axt", "axu", "axv", "axw", "axx", "axy", "axz", "aya", "ayb", "ayc",
|
||||||
|
"ayd", "aye", "ayf", "ayg", "ayh", "ayi", "ayj", "ayk", "ayl", "aym", "ayn",
|
||||||
|
"ayo", "ayp", "ayq", "ayr", "ays", "ayt", "ayu", "ayv", "ayw", "ayx", "ayy",
|
||||||
|
"ayz", "aza", "azb", "azc", "azd", "aze", "azf", "azg", "azh", "azi", "azj",
|
||||||
|
"azk", "azl", "azm", "azn", "azo", "azp", "azq", "azr", "azs", "azt", "azu",
|
||||||
|
"azv", "azw", "azx", "azy", "azz", "baa", "bab", "bac", "bad", "bae", "baf",
|
||||||
|
"bag", "bah", "bai", "baj", "bak", "bal", "bam", "ban", "bao", "bap", "baq",
|
||||||
|
"bar", "bas", "bat", "bau", "bav", "baw", "bax",
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (count, expected) in testcases {
|
||||||
|
let gen = AlphabeticSuffixGenerator::new(count);
|
||||||
|
let actual: Vec<String> = gen.collect();
|
||||||
|
assert_eq!(
|
||||||
|
actual, expected,
|
||||||
|
"unexpected suffix list for count {}",
|
||||||
|
count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user