-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanagram.cr
114 lines (98 loc) · 2.54 KB
/
anagram.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# Program to tell if strings are anagrams, modulo whitespace.
require "option_parser"
# Make lazy sequences sortable, creating a new array.
module Iterator
def sort
to_a.sort!
end
end
# Anagram-related extensions for strings.
class String
# Tells if this is an anagram of another string, ignoring whitespace.
# Uses sorting.
def anagram_by_sort?(other)
each_non_ws_char.sort == other.each_non_ws_char.sort
end
# Tells if this is an anagram of another string, ignoring whitespace.
# Uses hashing.
def anagram_by_hash?(other)
each_non_ws_char.tally == other.each_non_ws_char.tally
end
# Gets a sequence of the non-whitespace characters, with case folding.
protected def each_non_ws_char
each_char.reject(&.whitespace?).map(&.downcase)
end
end
# The strategy used to compare strings to determine if they are anagrams.
enum Strategy
Sort
Hash
def to_s(io)
case self
when Sort
io << "SORTING"
when Hash
io << "HASHING"
else
raise "Internal error: can't give name of unrecognized strategy"
end
end
def call(lhs, rhs)
case self
when Sort
lhs.anagram_by_sort?(rhs)
when Hash
lhs.anagram_by_hash?(rhs)
else
raise "Internal error: can't compare using unrecognized strategy"
end
end
end
# Configuration information obtained from parsing options.
class Configuration
getter strategy = Strategy::Sort
def initialize
failed = false
OptionParser.parse do |parser|
parser.on "-v", "--version", "Show version information and exit" do
puts "anagram, version 0.2"
exit 0
end
parser.on "-h", "--help", "Show this help and exit" do
puts parser
exit 0
end
parser.on "-S", "--sort",
"Use sorting-based anagram comparison (default)" do
@strategy = Strategy::Sort
end
parser.on "-H", "--hash", "Use hashing-based anagram comparison" do
@strategy = Strategy::Hash
end
parser.invalid_option do |option|
STDERR.puts "#{PROGRAM_NAME}: error: invalid option: #{option}"
failed = true
end
end
exit 1 if failed
end
end
def prompt(label)
print "#{label}> "
input = gets
exit 0 unless input
input
end
conf = Configuration.new
puts "Using #{conf.strategy} anagram-comparison strategy."
loop do
puts
puts "Enter two strings, or Ctrl+D to quit."
text1 = prompt(1)
text2 = prompt(2)
if conf.strategy.call(text1, text2)
puts "YES, those ARE anagrams."
else
puts "NO, those are NOT anagrams."
end
end