markov_namegen 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/markov_namegen.rb +88 -0
  3. metadata +43 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2dec254a68e0493aa04c93b7dad2e00b9d9474c65304e66df20fae6993d6c139
4
+ data.tar.gz: 765c7b003a772fc3ce40ca1db7803b3b7cd3320f86f4c33c30e33c59a4a6ac13
5
+ SHA512:
6
+ metadata.gz: 527030aa7309fe90b4a31a73f823daa8433f023d54ba1e30cb9b6b649af5a4e0dcaa727dd88c3a11580a553f241c20702822a317931798ef0dc9b4f2fce3d830
7
+ data.tar.gz: 9530192c4a57b2a0aba69128e811dd891292292678c59a724a8e16f6c020a3ae6f030d61573e687f2683bb2a6a2261261f80c482df21411edb5a5769b520bd12
@@ -0,0 +1,88 @@
1
+ # frozen-string-literal: false
2
+
3
+ # Creates a dictionary with prefixes as keys, and an array of possible suffixes
4
+ # as values, to be used by MarkovNameGen class
5
+ class MarkovDict
6
+ def initialize
7
+ @dict = {}
8
+ end
9
+
10
+ def add_key(prefix, suffix)
11
+ @dict.include?(prefix) ? @dict[prefix].push(suffix) : @dict[prefix] = [suffix]
12
+ end
13
+
14
+ def fetch_suffix(prefix)
15
+ @dict[prefix].sample
16
+ end
17
+ end
18
+
19
+ # Builds a new name by constructing a MarkovDict from an array of namees.
20
+ # New instances take 2 parameters:
21
+ # names(array): list of source names
22
+ # chainlength(num 1-10): determines order of markov chain, defaulted to 2 for best mix of
23
+ # readability and uniqueness. Note: with a small source list, values of 3 or higher
24
+ # return names too similar to input
25
+ #
26
+ # To generate a name after creating an instance of MarkovNameGen, call #new_name/1
27
+ # #new_name(unique:) takes a single boolean parameter, defaulted to true.
28
+ # if true: only output names that are not in the original list
29
+ # if false: will output names even if they match names in original list
30
+ class MarkovNameGen
31
+ CHAIN_ERROR = 'Chain length must be between 1 and 10.'.freeze
32
+ DATA_ERROR = 'Invalid name data.'.freeze
33
+
34
+ def initialize(names, chainlength = 2)
35
+ @mdict = MarkovDict.new
36
+ @source_names = []
37
+ @chainlen = chainlength
38
+ build_dict(names)
39
+ end
40
+
41
+ def build_dict(names)
42
+ raise CHAIN_ERROR unless @chainlen.between?(1, 10)
43
+ raise DATA_ERROR unless names.instance_of? Array
44
+
45
+ names.each do |name|
46
+ name = name.strip
47
+ namelen = name.length
48
+ @source_names.push(name)
49
+ str = ' ' * @chainlen + name
50
+
51
+ add_keys(str, namelen)
52
+ end
53
+ end
54
+
55
+ def add_keys(str, namelen)
56
+ 0.upto(namelen - 1) { |i| @mdict.add_key(str[i..i + @chainlen - 1], str[i + @chainlen]) }
57
+ @mdict.add_key(str[namelen..namelen + @chainlen - 1], "\n")
58
+ end
59
+
60
+ def build_name
61
+ prefix = ' ' * @chainlen
62
+ name = ''
63
+ suffix = ''
64
+
65
+ loop do
66
+ suffix = @mdict.fetch_suffix(prefix)
67
+ return namecase(name) if suffix == "\n" || name.length > 9
68
+
69
+ name += suffix
70
+ prefix = prefix[1..] + suffix
71
+ end
72
+ namecase(name)
73
+ end
74
+
75
+ def new_name(unique: true)
76
+ name = build_name
77
+ return name unless unique
78
+
79
+ @source_names.include?(name) ? new_name : name
80
+ end
81
+
82
+ # Credit: vol7ron @ https://stackoverflow.com/a/28288071/19434324
83
+ def namecase(string)
84
+ string.downcase.split(/(\s)/).map.with_index{ |x, i|
85
+ i.zero? || x.match(/^(?:a|is|of|the|and)$/).nil? ? x.capitalize : x
86
+ }.join
87
+ end
88
+ end
metadata ADDED
@@ -0,0 +1,43 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: markov_namegen
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jack Kellenberger
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-08-03 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Uses Markov chains to generate new, similar names from a array of names.
14
+ email: jackson@kellenberger.io
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/markov_namegen.rb
20
+ homepage: https://rubygems.org/gems/markov_namegen
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubygems_version: 3.3.7
40
+ signing_key:
41
+ specification_version: 4
42
+ summary: A Markov Name Generator
43
+ test_files: []