Ruby - Generate All Two Letter Words

Ruby - Generate all two letter words

As steenslag points out, the quickest way is

('aa'..'zz').to_a

If your alphabet isn't 'a' through 'z', though, you can use Array#repeated_combination:

alphabet = %w[А Б В Г Д Е Ё Ж З И Й К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Ъ Ы Ь Э Ю Я]
alphabet.repeated_combination(2).map(&:join) # => ["AA", "AБ", ...]

Or, as Mladen points out:

alphabet.product(alphabet).map(&:join)

Note: repeated_combination is available in Ruby 1.9.2 or with require 'backports/1.9.2/array/repeated_combination' from my backports gem.

Generate array of all letters and digits

[*('a'..'z'), *('0'..'9')] # doesn't work in Ruby 1.8

or

('a'..'z').to_a + ('0'..'9').to_a

or

(0...36).map{ |i| i.to_s 36 }

(the Integer#to_s method converts a number to a string representing it in a desired numeral system)

ruby - how to generate the possible sequential combination of letters from an array of strings?

This is what you need:

a = ["ABC","DEF", "GHI"]
a.map(&:chars).reduce(&:product).map(&:join)

By the way, you made some errors in your example output, there should never be strings starting with an E or an F according to your specification. So I suppose instead of "ECH", "ECI", "FCG", "FCH", "FCI" you meant "CEH", "CEI", "CFG", "CFH", "CFI".

Edit:

chars returns an Enumerator, not an array, and in Ruby versions before 2.0 those don't have a product method. So in those versions, just use a to_a like this:

a.map(&:chars).map(&:to_a).reduce(&:product).map(&:join)

ruby - How can I generate an array of every combination of letters and numbers of a given length?

alphanum = [*?a..?z, *?0..?9]
length.times.flat_map { |l|
alphanum.repeated_permutation(l + 1).map(&:join)
}

Note that length > 3 will give you a lot of results.

EDIT: As meagar says, this is very memory-intensive. An Enumerator-based answer (not as pretty, but won't kill your memory):

e = Enumerator.new do |y|
length.times do |l|
alphanum.repeated_permutation(l + 1).each do |p|
y << p.join
end
end
end

Get all possible letter combinations with more than 5 letters

You are indeed limited by hardware. In oversimplified terms, there are two limitation that you are facing here - processing power and memory capacity.

The "k-permutations of n" formula will tell us that you are trying to generate and process 26**6 = 308_915_776 elements.

(x..y) creates a Range, which knows how to generate all of its elements, but doesn't eagerly do so. When you call Range#to_a however, your processor tries to generate all those elements. After some time, the process runs out of memory and dies.

To avoid the memory restriction, you could instead take advantage of the fact that Range is also Enumerable. For example:

('aaaaaaa'..'zzzzzzz').each { |seven_letter_word| puts seven_letter_word }

will instantly start printing strings. Eventually (after a lot of waiting) it will loop through all of them.

However, note that this will let you bypass the memory restriction, but not the processing one. For that there are no shortcuts other than understand the specifics of the problem at hand.

Ruby permutations

How about going the other way? Checking every word to make sure it only uses the allowed letters?
I tried this with the 3000 most common words and it worked plenty fast.

words = [..]
letters = [ "m", "o", "r" ]
words.each do |word|
all_letters_valid = true
word.chars.each do |char|
unless letters.include?(char)
all_letters_valid = false
break
end
end
if all_letters_valid
puts word
end
end

If letters can repeat there isn't a finite number of permutations so that approach doesn't make sense.

Assumption: English ascii characters only

Regular expression for only 2 letters

You can add the anchors like this:

my_reg_exp = /^[a-z]{2}$/i

Test:

my_reg_exp.match('aaa')
#=> nil
my_reg_exp.match('aa')
#=> #<MatchData "aa">

Find all occurrences of 1 or 2 letters in a string using ruby

I think this should do it (haven't tested yet):

def find_letter_combinations(str)
return [[]] if str.empty?
combinations = []
find_letter_combinations(str[1..-1]).each do |c|
combinations << c.unshift(str[0])
end
return combinations if str.length == 1
find_letter_combinations(str[2..-1]).each do |c|
combinations << c.unshift(str[0..1])
end
combinations
end

Unable to combine English words from letters by Ruby

[Assuming you can reuse the source letters within one word]: For each word in your dictionary list, construct two arrays of letters - one for the candidate word and one for the input string. Subtract the input array-of-letters from the word array-of-letters and if there weren't any letters left over, you've got a match. Code to do that looks like this:

def findWordsWithReplacement(sentence)
out=[]
splitArray=sentence.downcase.split(//)
`cat /usr/share/dict/words`.each{|word|
if (word.strip!.downcase.split(//) - splitArray).empty?
out.push word
end
}
return out
end

You can call that function from the irb debugger like so:

output=findWordsWithReplacement("some input string"); puts output.join(" ")

...or here's a wrapper you could use to call the function interactively from a script:

puts "enter the text."
ARGF.each {|line|
puts "working..."
out=findWordsWithReplacement(line)
puts out.join(" ")
puts "there were #{out.size} words."
}

When running this on a Mac, the output looks like this:

$ ./findwords.rb

enter the text.

Ziegler's Giant Bar

working...

A a aa
aal aalii Aani Ab aba abaiser
abalienate Abantes Abaris abas abase
abaser Abasgi abasia Abassin abatable
abate abater abatis abaze abb Abba
abbas abbasi abbassi abbatial abbess
Abbie Abe abear Abel abele Abelia
Abelian Abelite abelite abeltree
Aberia aberrant aberrate abet abettal
Abie Abies abietate abietene abietin
Abietineae Abiezer Abigail abigail
abigeat abilla abintestate

[....]

Z z
za Zabaean zabeta Zabian zabra zabti
zabtie zag zain Zan zanella zant zante
Zanzalian zanze Zanzibari zar zaratite
zareba zat zati zattare Zea zeal
zealless zeallessness zebra zebrass
Zebrina zebrine zee zein zeist zel
Zelanian Zeltinger Zen Zenaga zenana
zer zest zeta ziara ziarat zibeline
zibet ziega zieger zig zigzag
zigzagger Zilla zing zingel Zingiber
zingiberene Zinnia zinsang Zinzar zira
zirai Zirbanit Zirian Zirianian
Zizania Zizia zizz

there were 6725 words.

That is well over 4500 words, but that's because the Mac word dictionary is pretty large. If you want to reproduce Knuth's results exactly, download and unzip Knuth's dictionary from here: http://www.packetstormsecurity.org/Crackers/wordlists/dictionaries/knuth_words.gz and replace "/usr/share/dict/words" with the path to wherever you've unpacked the substitute directory. If you did it right you'll get 4514 words, ending in this collection:

zanier zanies zaniness Zanzibar zazen
zeal zebra zebras Zeiss zeitgeist Zen
Zennist zest zestier zeta Ziegler zig
zigging zigzag zigzagging zigzags zing
zingier zings zinnia

I believe that answers the original question.

Alternatively, the questioner/reader might have wanted to list all the words one can construct from a string without reusing any of the input letters. My suggested code to accomplish that works as follows: Copy the candidate word, then for each letter in the input string, destructively remove the first instance of that letter from the copy (using "slice!"). If this process absorbs all the letters, accept that word.

def findWordsNoReplacement(sentence)
out=[]
splitInput=sentence.downcase.split(//)
`cat /usr/share/dict/words`.each{|word|
copy=word.strip!.downcase
splitInput.each {|o| copy.slice!(o) }
out.push word if copy==""
}
return out
end


Related Topics



Leave a reply



Submit