i made a program and i need to put all the possible characters in an array.
here i create my variable just to read the name
print "write your name: "
name1 = gets.chomp
then i try to put all the character inside the array, for example if your name is John, the array would be: J,Jo,Joh,john
arrayNames = []
number = name1.length
number.times {|i|
arrayNames[i] = name1.slice(0,i)
}
arrayNames << name1
then to read it, i wanted to make a permutation program, i write:
numb = name1.length+ 1
numb2 = anotherVariable.length + 1
numb.times {|j|
numb2.times {|k|
perm = [arrayNames[j],theSecondArray[k]]
p perm
file1.puts
}
}
of course i had the file1 made, and i have the exactly same code for the second array than the arrayNamesbut is not working. it doesnt even show an error. ill put all the code together down below
class Data
def initialize
end
def dataIn
print "write your name: "
$name = gets.chomp
print "write your surname: "
$surname = gets.chomp
end
def dataName
$passwordName = []
numb = $name.length
numb.times {|i|
$passwordName[i] = $name.slice(0,i)
$passwordName << $name
end
def dataSurn
$passwordSur = []
numb = $surname.length
numb.times {|i|
$passwordSur[i] = $surname.slice(0,i)
}
$passwordSur << $surname
end
def alg1
numb = $name.length + 1
numb2 = $surname.length + 1
numb.times {|i|
numb2.times {|j|
perm = [$passwordName[i], $passwordSur[j]].permutation.map {|k|
k.join}
p perm
$archivos.puts perm
}
}
end
end
the code itself is a little bit more complicaded, but my question is the same. the method alg1 doesnt work.then i just call them and create the file
data = Data.new()
datos.dataIn
$archivos = File.new("passwords",'w+')
File.open("passwords")
data.datosName
data.datosSurn
data.alg1
gets()
I'm not sure exactly what you are trying to do, but Ruby's built-in Array methods will make your life much easier:
>> name1 = 'John'
=> "John"
>> names = (0...name1.length).map { |i| name1[0..i] }
=> ["J", "Jo", "Joh", "John"]
>> other = ['dog', 'wolf', 'sheep']
=> ["dog", "wolf", "sheep"]
>> result = names.product(other)
=> [["J", "dog"],
["J", "wolf"],
["J", "sheep"],
["Jo", "dog"],
["Jo", "wolf"],
["Jo", "sheep"],
["Joh", "dog"],
["Joh", "wolf"],
["Joh", "sheep"],
["John", "dog"],
["John", "wolf"],
["John", "sheep"]]
Related
My code:
def wave(str)
ary = []
increase_num = 0
str = str.chars
until increase_num > str.size
ary << str[increase_num].upcase && increase_num += 1
end
end
What it's supposed to do:
wave("hello") => ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
I would really appreciate some help, as you probably know by looking at it I'm relatively new.
str = "hello"
str.size.times.map { |i| str[0,i] << str[i].upcase << str[i+1..] }
#=> ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
I would go about it as follows:
def wave(str)
str = str.downcase # so we can ensure a wave even if the original string had capitalization
str.each_char.with_index.map do |c,idx|
str[0...idx].concat(c.upcase,str[idx.+(1)..-1])
end
end
wave("hello")
#=> ["Hello", "hEllo", "heLlo", "helLo", "hellO"]
str.each_char.with_index.map do |c,idx| - This converts the String into an Enumerator and yields each character and its index to the map block.
str[0...idx] - In the block we slice the string into characters 0 through index (exclusive)
.concat(c.upcase,str[idx.+(1)..-1]) - Then we concatenate that with the current character upcased and the remaining portion of the String (index + 1 through the end of the String)
First 2 passes will look like:
# idx = 0
# c = "h"
# str[0...idx].concat(c.upcase,str[idx.+(1)..-1])
"".concat("H","ello")
# idx = 1
# c = "e"
# str[0...idx].concat(c.upcase,str[idx.+(1)..-1])
"h".concat("E","llo")
I have an Array-1 say
arr1 =['s','a','sd','few','asdw','a','sdfeg']
And a second Array
arr2 = ['s','a','d','f','w']
I want to take arr1 and sort the frequency of letters by inputting arr2 with result
[s=> 4, a=> 2, d => 3] So on and so forth.
As far as I can muddle around.. Nothing below works, Just my thoughts on it?
hashy = Hash.new
print "give me a sentance "
sentance = gets.chomp.downcase.delete!(' ')
bing = sentance.split(//)
#how = sentance.gsub!(/[^a-z)]/, "") #Remove nil result
#chop = how.to_s.split(//).uniq
#hashy << bing.each{|e| how[e] }
#puts how.any? {|e| bing.count(e)}
#puts how, chop
bing.each {|v| hashy.store(v, hashy[v]+1 )}
puts bing
Thank you for your time.
I assumed that you want to count all letters in the sentence you put in, and not array 1. Assuming that, here's my take on it:
hashy = Hash.new()
['s','a','d','f','w'].each {|item| hashy[item.to_sym] = 0}
puts "give me a sentence"
sentence = gets.chomp.downcase.delete!(' ')
sentence_array = []
sentence.each_char do |l|
sentence_array.push(l)
end
hashy.each do |key, value|
puts "this is key: #{key} and value #{hashy[key]}"
sentence_array.each do |letter|
puts "letter: #{letter}"
if letter.to_sym == key
puts "letter #{letter} equals key #{key}"
value = value + 1
hashy[key] = value
puts "value is now #{value}"
end
end
end
puts hashy
I've been trying to solve a simple quiz question to find all the possible permutation of a string using Ruby and recursion.
I have the following Ruby code:
def permutation(string)
return [string] if string.size < 2
chr = string.chars.first
perms = permutation(string[1..-1])
result = []
for perm in perms
for i in (0..perm.size)
result << (perm[0..i] + chr + perm[i..-1])
end
end
return result
end
Whenever I try to test the code with puts permutation("abc") I get the following output:
cacbc
cbabc
cbcac
cbca
cacb
cbab
cba
Theoretically speaking it's supposed to be a very simple and straightforward problem, but I'm sure I'm doing something wrong. Most probably it's something with the ranges of the loops. And I know that Ruby Array class has instance method permutation to do that but I'm trying to solve it for practising.
Please note that the complexity is O(N!) for the current implementation. Is there anyway to enhance the performance further?
To see what the difficulty may be, let's try it with an even simpler example:
string = "ab"
Your desired result is ["ab", "ba"]. Let's see what you get:
string.size #=> 2
so we don't return when
return [string] if string.size < 2
#=> return ["ab"] if "ab".size < 2
is executed.
Next we calculate:
chr = string.chars.first #=> "a"
Notice that a more direct way of making this calculation is as follows:
chr = string[0] #=> "a"
or, better, using String#chr,
chr = string.chr #=> "a"
The latter illustrates why chr is not the best choice for the variable name.
Next
perms = permutation(string[1..-1])
#=> = permutation("b")
I will now indent the return values to emphasize that we are calling permutation a second time. permuation's argument is:
string #=> "b"
Now when we execute:
return [string] if string.size < 2
#=> return ["b"] if "b".size < 2
we return ["b"], so (back to original call to permutation):
perms = ["b"]
to go with chr => "a", calculated earlier. Next:
result = []
for perm in perms
for i in (0..perm.size)
result << (perm[0..i] + chr + perm[i..-1])
end
end
As perms contains only the single element "b", the two for loops simplify to:
for i in (0.."b".size)
result << ("b"[0..i] + "a" + "b"[i..-1])
end
which is:
for i in (0..1)
result << ("b"[0..i] + "a" + "b"[i..-1])
end
Notice that "b"[0..0], "b"[0..1] and "b"[0..-1] all equal "b"[0], which is just "b", and "b"[1..-1] #=> ''. Therefore, when i => 0, we execute:
result << ("b"[0..0] + "a" + "b"[0..-1])
#=> result << ("b" + "a" + "b")
#=> result << "bab"
and when i => 1:
result << ("b"[0..1] + "a" + "b"[1..-1])
#=> result << ("b" + "a" + "")
#=> result << "ba"
so:
result => ["bab" + "ba"]
which clearly is not what you want.
What you need to do is is change the double for loops to:
for perm in perms
result << chr + perm
for i in (1..perm.size-1)
result << (perm[0..i-1] + chr + perm[i..-1])
end
result << perm + chr
end
which could be written more compactly by employing the method String#insert:
for perm in perms
for i in (0..perm.size)
result << perm.dup.insert(i,chr)
end
end
which you would normally see written like this:
perms.each_with_object([]) do |perm, result|
(0..perm.size).each { |i| result << perm.dup.insert(i,chr) }
end
Notice that we have to .dup the string before sending insert, as insert modifies the string.
Doing it like this, you don't need result = []. Neither do you need return result, as parms.each_with_object returns result and if there is no return statement, the method returns the last quantity calculated. Also, you don't need the temporary variable perms (or ch, if desired).
Putting this altogether, we have:
def permutation(string)
return [string] if string.size < 2
ch = string[0]
permutation(string[1..-1]).each_with_object([]) do |perm, result|
(0..perm.size).each { |i| result << perm.dup.insert(i,ch) }
end
end
Let's try it:
permutation("ab")
#=> ["ab", "ba"]
permutation("abc")
#=> ["abc", "bac", "bca", "acb", "cab", "cba"]
permutation("abcd")
#=> ["abcd", "bacd", "bcad", "bcda", "acbd", "cabd",
# "cbad", "cbda", "acdb", "cadb", "cdab", "cdba",
# "abdc", "badc", "bdac", "bdca", "adbc", "dabc",
# "dbac", "dbca", "adcb", "dacb", "dcab", "dcba"]
Eki, which one are you in the picture?
You can use Array#permutation:
def permutation(string)
string.permutation(string.size).to_a
end
permutation('abc'.chars)
# => [["a", "b", "c"], ["a", "c", "b"], ["b", "a", "c"], ["b", "c", "a"],
# ["c", "a", "b"], ["c", "b", "a"]]
UPDATE Without usign Array#permutation:
def permutation(string)
return [''] if string.empty?
chrs = string.chars
(0...string.size).flat_map { |i|
chr, rest = string[i], string[0...i] + string[i+1..-1]
permutation(rest).map { |sub|
chr + sub
}
}
end
permutation('abc')
# => ["abc", "acb", "bac", "bca", "cab", "cba"]
How do I delete the earlier array value if similar values exist? Here's the code I use:
def address_geo
arr = []
arr << do if do
arr << re if re
arr << me if me
arr << fa if fa
arr << so if so
arr << la if la
arr.reject{|y|y==''}.join(' ')
end
Given the following values
do = 'I'
re = 'am'
me = 'a'
fa = 'good'
so = 'good'
la = 'boy'
The above method would yield:
I am a good good boy
How should I write the array merge to reject fa and just take so to yield:
I am a good boy
Many thanks!
You can use Array#uniq
> arr = ['good', 'good']
> arr.uniq
=> ['good']
As per #tokland's suggestion, if you wanted to remove only consecutive duplicates, this would work (and support ruby 1.8). By building a new array using inject we can filter out each string that is either empty?, or the same as the previous string.
> %w(a good good boy).inject([]) do |mem, str|
> mem << str if !str.empty? && mem[-1] != str
> mem
> end
=> ['a', 'good', 'boy']
You you can remove consecutive elements in the array with Enumerable#chunk:
strings = ["hi", "there", "there", "hi", "bye"].select { |x| x && !x.empty? }
strings.chunk { |x| x }.map(&:first).join(" ")
#=> "hi there hi bye"
How would I do this in Ruby?
p "abc".all_possible_permutations
Would return:
[
"abc",
"acb",
"bca",
"bac",
"cba",
"cab",
]
Edit
Thanks to Jakub Hampl:
class String
def all_possible_permutations
self.chars.to_a.permutation.map(&:join)
end
end
%w[a b c].permutation.map &:join
If someone doesnt want to use inbuilt function :
def permute(result,input)
if(input.length == 0)
return
end
if(input.length == 1)
puts result + input[0]
return
end
if(input.length == 2)
puts result + input[0] + input[1]
puts result + input[1] + input[0]
return
end
(0...input.length).step(1).each do |i|
firstpart = result+input[i]
secondpart = (i > 0 ? input[0..(i-1)] : '') + (input[(i+1)..-1] || '')
permute(firstpart,secondpart)
end
end
permute('',gets.chomp)
One line:
p "abc".chars.permutation.map &:join
Sample output:
["abc", "acb", "bac", "bca", "cab", "cba"]
p is optional
string could be a variable instead
chars is pretty quick, it separates the string into an array of single characters
map has tons of cool applications,it takes a object, and returns it after the block is done, in this case the operation join
&:join could be replaced with { |i| i.join } like this:
p "abc".chars.permutation.map{ |i| i.join }
If anyone wants to have the code for this using basic algorithms, here is how you do it-
$count = 0
def permute(permuted_string, original_string, done_array)
if permuted_string.length == original_string.length
$count = $count+1
puts "#{$count} #{permuted_string}"
else
(0..original_string.length-1).each do |i|
if !done_array[i]
done_array[i] = true
permute(permuted_string+original_string[i], original_string, done_array)
done_array[i] = false
end
end
end
end
puts "Please enter the string for permutations"
input = gets.chomp
done_array = Array.new(input.length, false)
permute("", input, done_array)