Shortened words

My cell phone carrier charges a cent per character in a text! I need a program to shorten the words for me, while still being understandable. I will be texting this program to my friends, so it needs to be as short as possible.

Your program will take a String (a word is separated by a non-alphanumeric character) of words from STDIN (or closest alternative) reduce any similar (a and A are similar, b and a are not, 1 is similar only to itself) consecutive alphanumeric characters down to one character, and remove all the vowels (aeiou), and print it to STDOUT (or closest alternative), only letters, numbers, and spaces are kept: everything else is removed at the end. The first character of a word must remain the same, and only shorten the word if the resulting shortened word is 4 or more characters long. Examples:

homework -> hmwrk
llamas -> llamas (lms<4 characters)
botany -> btny
y3333llow -> y3lw
shorten -> shrtn
aabcddde -> abcd
abb'bbc -> abbbbc (abb -> abb and bbc -> bbc = abb'bbc --(remove non-alphanumeric-space characters)-> abbbbc)
SHARRRKnado -> shrknd (or with capitalization bonus: SHrKnd)
everything is awesome! -> evrythng is awsm
you can't break what is already broken -> you cant break what is alrdy brkn
the person's cat's bed's blanket's poka-dots are orangy-yellow -> the prsns cats beds blnkts pokadots are orngyyellow


-5% bonus if kept a i o or u at end of word

sharknado -> shrkndo


-10% bonus if kept capitalization of non-consecutive characters

aAbCDdDE -> abCd


This is so the shortest program in bytes wins.

• What characters can the string contain? (Ex. can it contain spaces?) Why the restriction to STDIN/STDOUT instead of allowing, say, a function? Is y a vowel? – Doorknob Nov 19 '15 at 2:52
• If the input can contain multiple words, you should include some test cases that demonstrate this. Also, you still don't seem to allow functions that take input via arguments and output via return values; this is typically frowned upon as it's simply an unnecessary restriction. – Doorknob Nov 19 '15 at 3:02
• All your non-bonus examples have words consisting solely of lowercase letters. Can we expect the input to be like this? – Dennis Nov 19 '15 at 3:03
• @helix it seems the bonus only applies to non-repeated letters. – Martin Ender Nov 19 '15 at 7:15
• @CᴏɴᴏʀO'Bʀɪᴇɴ The o was deleted by legion in an edit, and hyphens act as a word separator, until the end, where it is removed, as a hyphen is not alphanumeric or a space. – Grant Davis Nov 19 '15 at 15:47

CJam, 54 bytes

qelS/" ,"*__eu&S-A,s-NerN%{_(\"aeiou"-+e1f=_S-Z>\@?}/


Try this fiddle or this test suite in the CJam interpreter.

How it works

qel        e# Read all input and cast to lowercase.
S/" ,"*    e# Replace spaces with " ,". This way, we don't have to consider
e# spaces word delimiters, which will make them easier to preserve.
__eu       e# Push two copies and convert the second one to uppercase.
&          e# Intersect the copies. This will keep only non-letters.
S-A,s-     e# Remove spaces and digits from the non-letters.
Ner        e# Replace their occurrences in the input with linefeeds.
N%         e# Split at linefeeds.
{          e# For each resulting chunk:
_(\      e#   Push a copy and shift out the first character.
"aeiou"- e#   Remove all vowels from the tail.
+        e#   Concatenate the result with the first character.
e       e#   Perform run-length encoding.
1f=      e#   Select all characters.
_S-      e#   Push a copy and remove spaces.
e#   This is for the length check; spaces don't actually form part
e#   of the word.
Z>       e#   Discard the first three characters.
\@?      e#   If there are characters left, pick the modified word; else
e#   pick the unmodified one.
}/         e#


Japt, 57 bytes 58 80 88 90 95 98

Saved 6 bytes thanks to @ETHproductions

Japt is a shortened version of JavaScript. Interpreter

Uv qS m@(A=Xg0 +Xs1 r"(.)\\1+",@Y r"[aeiou]",P)g3 ?A:X)qS


Uses RegExp to do most of the work.

Try it online

Explanation

This explanation is old but the method used is still generally the same.

UqS       // Splits input
m@     // Loops through words
Xr"(.)\\1+","$1" // Removes consecutive sequences r"[aeiouAEIOU]",P // Removes vowels m@ // Loops again Xl >3? // If length of word is greater than 3 X[0]==UqS [Y][0]? // If first letter is right, keep it X :UqS [Y][0]+X // Otherwise, use the correct first letter :UqS [Y] qS v // Otherwise return the original word  • Hey, my language is in use :D BTW, two spaces in a row can be replaced with a right-paren. I may have some more golfing tips tomorrow, but right now I'm tired and need some rest... – ETHproductions Nov 19 '15 at 4:47 • In response to your other question, you could use A-J (predefined to different numbers), since you aren't using them anywhere else. – ETHproductions Nov 19 '15 at 4:53 • Let's see... you can replace [Y] and the following space with gY). There is also a string remove function k, but it currently only removes the first occurance, and doesn't do regex anyway. I think "$1" could be replaced with @Y, too. – ETHproductions Nov 19 '15 at 13:32
• There's not much room for golfing that I can see, but I think l >3? could be replaced with [3]?. – ETHproductions Nov 20 '15 at 1:58
• Yep, it functions identically, except that you can't do Ug3 =7. It is usually the same length as well, unless you have another space afterward that you can combine into a right-paren. I think that for v0.2, <array><number> should compile to <array>[<number>]. This will save 1 byte in most scenarios, and even 2 in some. – ETHproductions Nov 20 '15 at 2:17

TeaScript, 60 bytes64 58 63 70

xL¡l»(b=l0+lS(1)g(/(.)\1+/,"$1")g[aeiou])n>3?b:l,ø)Oa-z   I should be able to use the unique function to get rid of repeated characters but for now I'm using a regex. I believe this should work fine. I'll be heading off to sleep so notify me if anything is wrong and I'll address it next morning. Ungolfed xL()l(#(b=l0+lS(1)g(/(.)\1+/,"$1")g[aeiou])n>3?b:l, )Oa-z

• @Dennis Pretty sure it's all good now, I've tested with the test cases and it seems to work. – Downgoat Nov 19 '15 at 5:42
• The last test case should print pokadots and probably orngyyellow. – Dennis Nov 19 '15 at 5:47
• Doesn't seem to work with y3333llow. I think you need to add 0-9 at the O function. – Mama Fun Roll Nov 20 '15 at 1:04

C# - 404 bytes

using System;using System.Text;using System.Text.RegularExpressions;class j{static bool v(char l){return l=='e'||l=='a'||l=='o'||l=='i'||l=='u';}static void Main(){string a=Console.ReadLine();string z=Regex.Replace(a,"[^a-zA-Z ]","");string[]b=z.Split(' ');string c="";foreach(string d in b)    {if(d.Length>4){foreach(char e in d.ToCharArray()){if(!v(e))c+=e;}}else{c+=d;}c+=' ';}Console.WriteLine(c);}}


It takes input from Console.ReadLine(). I used a regex to find the non alphanumeric characters and spaces and I calculated if the size is less than 4. I tested using the final example.

C# - 279 bytes (from LegionMammal798)

using C=System.Console;class j{static void Main(){var c="";foreach(var d in System.Text.RegularExpressions.Regex.Replace(C.ReadLine(),"[^a-zA-Z0-9 ]",c).Split(' ')){if(d.Length>4){foreach(var e in d)if(!"aeiou".Contains(e.ToString()))c+=e;}else c+=d;c+=' ';}C.Write(c);}}


Thank you for the golfing tips!

• Various golfs – LegionMammal978 Nov 19 '15 at 12:42
• Thank you! Is it alright if I edit my post with one of those golfs? – Admin3X Nov 19 '15 at 14:05
• Hmm. This can be colfed by using C# 6.0. You can just do: static bool v(char l)=>... . No return statements have to be written – Yytsi Nov 19 '15 at 15:46
• @Admin3X Sure, was providing suggestions. – LegionMammal978 Nov 19 '15 at 21:57

𝔼𝕊𝕄𝕚𝕟, 57 chars / 97 bytes (noncompetitive)

Ɱ(ï,↪(a=$ù⬮ċ/⊙\1+⌿,⑴”ċ/[ᶌ]⌿,⬯⸩Ꝉ>3?a⎖0≔$⎖0?a:$⎖0+a:$,⬭,⬭)


Try it here (Firefox only).

Uses regex aliasing and other syntax made after the challenge was posted.

Adhering to written description, not given examples:

import Data.List
import Data.Char
f=filter
d w@(_:_:_:_)=map head\$groupBy(\a b->toLower a==toLower b)w
d w=w
s=unwords.map(f isAlphaNum.d.(\(h:t)->h:f(notElem"aeiou")t)).words


Call s`.

Improved late after vote reminded me of its existence.