# Trying to make make an array of all different combinations of a string and running into fibonacci

I am trying to make an array of all different combinations of a string.
The minimum amount of chars in the output string must be two.

``````# Example string.  But what if string is n chars long though?
s = "string"
``````

What I tried:

``````new_array = s.size.times.map{|i| s.split("",i)}.map do |a|
if a.size == 1
a
elsif a.size != s.size and a.size > 2
[a[0..-2].join(''),a[-1]]
end
end
``````

new_array.compact.sort_by{|a| a.first.size }

Expected output:

``````[['st', 'ring',],['str', 'ing'],['stri', 'ng']['string'], ['st',
``````

‘ri’, ‘ng’]]

The code above works until I get to: s.length > 5.

I only need the consecutive forward groups of chars output. Each
subarray should contain all the letters of `s` broken in different ways.
I don’t need `['gnirts']`, `['gn', irts']`, or something mixed up like
`['stngri']`. When it’s over seven chars, it is tricky. Here’s a map of
the different combinations, assuming the string `s` is a minimum length
of two:

``````For a 2-letter string: ['first 2 letters']
3-letter string: ['first 3 letters']
4-letter string: [['first 2', 'third and fourth'], ['first four']]
5-letter string: [['first 2, 'thrid fourth and fifth'],['first 3,
``````

fourth and fifth’],[‘all five’]]

``````and etc.
``````

I’m wondering if what I’m asking is possible.

There is a Fibonacci sequence in here. There is only 1 solution for 2
or 3- letter strings. 2 solutions for 4-char. 3 for 5-char. 5 for
6-char, and 8 for 7-char.

On Sat, Dec 21, 2013 at 8:56 AM, Jim W. [email protected]
wrote:

I am trying to make an array of all different combinations of a string.
The minimum amount of chars in the output string must be two.

``````# Example string.  But what if string is n chars long though?
s = "string"
``````

I would strongly suggest that this is an excellent opportunity to get
in the habit of writing tests that describe the behavior you want and
using those to drive discovery of the solution

However, just one possibility:

require ‘active_support/core_ext/array’ # small cheat

s = “antidisestablishmentarianism”
result = []
(s.length - 1).times do |i|
result << s.split(//).in_groups_of(i+1).map(&:compact).map(&:join)
end
puts result.flatten.uniq.reject{ |str| str.length == 1 }

FWIW,

Hassan S. wrote in post #1131369:

On Sat, Dec 21, 2013 at 8:56 AM, Jim W. [email protected]
wrote:

I am trying to make an array of all different combinations of a string.
The minimum amount of chars in the output string must be two.

``````# Example string.  But what if string is n chars long though?
s = "string"
``````

I would strongly suggest that this is an excellent opportunity to get
in the habit of writing tests that describe the behavior you want and
using those to drive discovery of the solution

However, just one possibility:

require ‘active_support/core_ext/array’ # small cheat

s = “antidisestablishmentarianism”
result = []
(s.length - 1).times do |i|
result << s.split(//).in_groups_of(i+1).map(&:compact).map(&:join)
end
puts result.flatten.uniq.reject{ |str| str.length == 1 }

``````#=> ["st", "ri", "ng", "str", "ing", "stri", "strin"]
``````

This is what I got for output running your equation. Not quite there
but thanks for the ideas. Also can you elaborate on the “habit of
writing tests” bit you mentioned? Thanks

On Sat, Dec 21, 2013 at 1:29 PM, Jim W. [email protected]
wrote:

“habit of writing tests”

Dear Jim W.,

I just modified the method that I wrote in a previous answer.

I’ve put a … return [] if str.size < 2
and a … 1.upto(str.size-2) (instead of 0.upto(str.size-2))

… and I think it now meet your criterias.

def partitions(str)
return [] if str.size < 2
ary = [[str]]
1.upto(str.size-2) do |first_slice_index| # don’t recurse at the
last element (so size-2)
first_slice = str[0…first_slice_index]
second_slice = str[(first_slice_index+1)…-1]
other_slices = partitions(second_slice) # recursively
other_slices.each do |slice|
candidate = [first_slice] + slice
ary.push candidate
end
end
ary
end

1.upto(7) do |size|
str = (1…size).map(&:to_s).join
pts = partitions(str)
puts “#{size} - #{pts.size} - #{pts}”
end

1 - 0 - []
2 - 1 - [[“12”]]
3 - 1 - [[“123”]]
4 - 2 - [[“1234”], [“12”, “34”]]
5 - 3 - [[“12345”], [“12”, “345”], [“123”, “45”]]
6 - 5 - [[“123456”], [“12”, “3456”], [“12”, “34”, “56”], [“123”,
“456”], [“1234”, “56”]]
7 - 8 - [[“1234567”], [“12”, “34567”], [“12”, “34”, “567”], [“12”,
“345”, “67”], [“123”, “4567”], [“123”, “45”, “67”], [“1234”, “567”],
[“12345”, “67”]]
8 - 13 - [[“12345678”], [“12”, “345678”], [“12”, “34”, “5678”], [“12”,
“34”, “56”, “78”], [“12”, “345”, “678”], [“12”, “3456”, “78”], [“123”,
“45678”], [“123”, “45”, “678”], [“123”, “456”, “78”], [“1234”,
“5678”], [“1234”, “56”, “78”], [“12345”, “678”], [“123456”, “78”]]

So… If this is the results you are expecting, let us know.

I agree with the others. It would be easier if you’ve had written a
simple test with the arguments and the expected results. But, you
still may do it!
I can help you to write a simple test so that somebody can come up
with a better approach than mine.

Best regards,
Abinoam Jr.

On Sat, Dec 21, 2013 at 9:00 PM, Hassan S.

cool solution, Jr. !

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.