Input: sentence Modify: words Output: modified sentence

I am new to Ruby. This is a programming interview question to use any
language. I am trying to do it in Ruby.

Write a program to input a given sentence. Replace each word with the
firstletter/#ofcharactersbetween1st&lastletter/lastletter of the word.
All non-alpha (numbers, punctuation, etc.) should not be changed.

Example input: There are 12 chickens for 2 roosters.

Desired output: T3e a1e 12 c6s f1r 2 r6s.

I generally don’t approve of doing people’s homework for them, but this
one interests me.
I’m not very experienced with code so I bet there’s an easier way to do
this… anyway, here’s my attempt:

puts gets.chomp.split.map { |s|
letters = s.gsub(/\W/,’’)
if [0,1,2].include? letters.length || s !~ /[A-Z]/i
s
else
s[/^[^A-Z][A-Z]/i] + ( letters.length - 2 ).to_s +
s[/[A-Z][^A-Z]
$/i]
end
}.join(’ ')

On Fri, Apr 19, 2013 at 1:36 PM, Joel P. [email protected]
wrote:

s[/^[^A-Z]*[A-Z]/i] + ( letters.length - 2 ).to_s +

s[/[A-Z][^A-Z]*$/i]
end
}.join(’ ')

Curious how you’d handle contractions :slight_smile:

Joel P. wrote in post #1106334:

I generally don’t approve of doing people’s homework for them, but this
one interests me.
I’m not very experienced with code so I bet there’s an easier way to do
this… anyway, here’s my attempt:

puts gets.chomp.split.map { |s|
letters = s.gsub(/\W/,’’)
if [0,1,2].include? letters.length || s !~ /[A-Z]/i
s
else
s[/^[^A-Z][A-Z]/i] + ( letters.length - 2 ).to_s +
s[/[A-Z][^A-Z]
$/i]
end
}.join(’ ')

Or there’s:

puts gets.chomp.gsub(/\b([a-z])([a-z]+)([a-z])\b/i){
“#$1#{$2.length}#$3”
}

: There are 12 chickens for 2 roosters.
T3e a1e 12 c6s f1r 2 r6s.
: It’s a gosh-darned shame, really. Isn’t it?
It’s a g2h-d4d s3e, r4y. I1n’t it?

It doesn’t like “words” with underscores or numbers in. :wink: You can
remove the \b markers to change that.

Thank you all! You are helping me to understand more complicated
expressions. I actually did get it to work with my simple logic:

#Limitations: assumes no internal punctuation (i.e. hyphens, commas,
periods on abbreviations, quotes, apostrophes, etc.)
#Known outputs: will return unmodified alphanumeric instances, for
example “3rd”.

s=“There are 12 chickens for 2 roosters.”
#get punctuation from end of sentence
p=s[-1].chr
#create array without end punctuation
anop = s.split§
#create the sentence no end punctuation
snop = anop.join
#Make initial word array equal to working output array
array = output = snop.split(’ ‘)
#iterate through all words in the array. If digits then return
unchanged, otherwise abbreviate as requested.
$i = 0
$num = a.length
while $i < $num do
if a[$i].match(/\d/)
then output[$i]=a[$i]
else output[$i]=a[$i][0].chr + (a[$i].length-2).to_s + a[$i][-1].chr
end
$i +=1
end
#add punctuation back to last word
output[-1]<<p
#rejoin output array as abbreviated sentence
os = output.join(’ ')
#output abbreviated sentence
puts os

On Apr 20, 2013 4:42 AM, [email protected] wrote:

  • use descriptive variable names, not s', p’, …
s="There are 12 chickens for 2 roosters."

#Make initial word array equal to working output array
array = output = snop.split(’ ')

why 2 arrays? you could just append words to an initially empty output
array

end

output…


https://github.com/stomar/

since we’re sharing, here’s mine:

def numify_w(s)
return s if s.nil? || s.empty? || s.length < 3
s.match(/^([[:punct:]])([-_'[:alpha:]]+)([[:punct:]])$/) do |m|
m[1]+m[2][0]+m[2].length.to_s+m[2][-1]+m[3]
end or s
end

def numify(s)
return s if s.nil? || s.empty?
s.split.map{|m| numify_w m}.join(" ")
end

handles some intraword punctuation

Am 20.04.2013 04:46, schrieb Philip Parker:

Thank you all! You are helping me to understand more complicated
expressions. I actually did get it to work with my simple logic:

The below code doesn’t look “rubyish” at all.
A few suggestions:

  • use descriptive variable names, not s',p’, …
    (then you can get rid of most of the comments)
  • do not use while' loop, useeach’ !!!
  • do not use global variables

#Limitations: assumes no internal punctuation (i.e. hyphens, commas,
periods on abbreviations, quotes, apostrophes, etc.)
#Known outputs: will return unmodified alphanumeric instances, for
example “3rd”.

s="There are 12 chickens for 2 roosters."

#get punctuation from end of sentence
p=s[-1].chr

chr is not needed, s[-1] already is a string with length 1

#create array without end punctuation
anop = s.split§

s[0…-1], split is not needed here

#create the sentence no end punctuation
snop = anop.join

not needed when you don’t split

#Make initial word array equal to working output array
array = output = snop.split(’ ')

why 2 arrays? you could just append words to an initially empty output
array

end

  1. iteration: use each and append to an initially empty output array
  2. if: `then’ is not needed; bad indentation:

if …
output…
else
output…
end

tamouse mailing lists wrote in post #1106350:

On Fri, Apr 19, 2013 at 1:36 PM, Joel P. [email protected]
wrote:

s[/^[^A-Z]*[A-Z]/i] + ( letters.length - 2 ).to_s +

s[/[A-Z][^A-Z]*$/i]
end
}.join(’ ')

Curious how you’d handle contractions :slight_smile:

“don’t” should be d2t according to my logic, as I’m only counting
letters. It depends what your real-life usage would be, but I decided to
deal with numbers, letters, and punctuation separately.

What would be the output for this?

“There won’t be a cul-de-sac on 2nd St. until April 3, 2015. But, we’ll
be
waiting.”

Harry

Building on what Matthew and tamouse demonstrated (I didn’t know about
the block form before), I’ve come up with this:

code:


puts gets.chomp.gsub(
/\b([[:alpha:]’-&&[^\d]])([[:alpha:]’-&&[^\d]]{1,})([[:alpha:]’-&&[^\d]])\b/
) { “#{ $1 }#{ $2.length }#{ $3 }” }


input:

“There won’t be a cul-de-sac on 2nd St. until April 3, 2015. But, we’ll
be waiting.”

output:

“T3e w3t be a c8c on 2nd St. u3l A3l 3, 2015. B1t, w3l be w5g.”

We could go on refining this forever with unusual use cases :stuck_out_tongue:

On Sat, Apr 20, 2013 at 8:49 AM, Joel P. [email protected]
wrote:

input:

“There won’t be a cul-de-sac on 2nd St. until April 3, 2015. But, we’ll
be waiting.”

output:

“T3e w3t be a c8c on 2nd St. u3l A3l 3, 2015. B1t, w3l be w5g.”

We could go on refining this forever with unusual use cases :stuck_out_tongue:

These little exercises are great for playing around with things.