13
\$\begingroup\$

Create a program with the lowest amount of characters to reverse each word in a string while keeping the order of the words, as well as punctuation and capital letters, in their initial place.

By "Order of the words," I mean that each word is split by a empty space (" "), so contractions and such will be treated as one word. The apostrophe in contractions should stay in the same place. ("Don't" => "Tno'd").

(Punctuation means any characters that are not a-z, A-Z or whitespace*).

  • Numbers were removed from this list due to the fact that you cannot have capital numbers. Numbers are now treated as punctuation.

For example, for the input:

Hello, I am a fish.

it should output:

Olleh, I ma a hsif.

Notice that O, which is the first letter in the first word, is now capital, since H was capital before in the same location.

The comma and the period are also in the same place.

More examples:

This; Is Some Text!

would output

Siht; Si Emos Txet!

Any language can be used. The program with the lowest amount of characters wins.

DJMcMayhem
60.1k18 gold badges203 silver badges352 bronze badges
asked Apr 7, 2013 at 3:21
\$\endgroup\$
18
  • 3
    \$\begingroup\$ How should contractions be treated? That is does Don't touch that! map to t'noD hcuot taht! or to noD't hcuot taht!? \$\endgroup\$ Commented Apr 7, 2013 at 4:39
  • 2
    \$\begingroup\$ @dmckee "(Punctuation means any characters that are not a-z, A-Z, 1-9 or whitespace)" \$\endgroup\$ Commented Apr 7, 2013 at 4:46
  • 1
    \$\begingroup\$ @dmckee so it should map to Nod't hcuot tath! \$\endgroup\$ Commented Apr 7, 2013 at 4:49
  • 3
    \$\begingroup\$ Reversing each word is easy. Reversing each word and keeping capitalisation is not. \$\endgroup\$ Commented Apr 7, 2013 at 4:53
  • 1
    \$\begingroup\$ Yup, that's the challenge ;) just simply reversing them would be too simple and would likely come down to the language used. This is meant to make you think. \$\endgroup\$ Commented Apr 7, 2013 at 4:56

7 Answers 7

7
\$\begingroup\$

GolfScript, (削除) 58 (削除ここまで) (削除) 54 (削除ここまで) 48 characters

" "/{.{65- 223&26<}:A,\{.A{96&\)31&@+}*}%+}%" "*

This is a GolfScript solution which became rather long. Lots of the code is actually finding out if a character is in a-zA-Z. Maybe someone can find an even shorter way of testing it.

You can try the code online. Examples:

> Hello, I am fish.
Olleh, I ma hsif.
> This; Is Some Text!
Siht; Si Emos Txet!
> Don't try this at home.
Tno'd yrt siht ta emoh.
answered Apr 7, 2013 at 6:42
\$\endgroup\$
2
  • \$\begingroup\$ That online golfscript editor looks useful. Bookmarking, thanks \$\endgroup\$ Commented Apr 7, 2013 at 11:00
  • \$\begingroup\$ You can pull the final " " inside the % to save one. I've found other ways of testing a-zA-Z for 11 chars, but none yet for 10. \$\endgroup\$ Commented Apr 10, 2013 at 7:08
5
\$\begingroup\$

Coffeescript, (削除) 134 (削除ここまで) 133 characters

alert prompt().replace /\S+/g,(x)->c=x.match r=/[a-z]/gi;return x.replace r,(y)->return c.pop()[`(y<"a"?"toUpp":"toLow")`+"erCase"]()

Coffeescript is (for the purposes of code golf) a slightly denser version of javascript. It doesn't have the ternary operator, but it has an escape to javascript.

Here's the javascript version:

Javascript, (削除) 152 (削除ここまで) 151 characters

alert(prompt().replace(/\S+/g,function(x){c=x.match(r=/[a-z]/gi);return x.replace(r,function(y){return c.pop()[(y<"a"?"toUpp":"toLow")+"erCase"]()})}))

Indented:

alert(prompt().replace(/\S+/g,function(x){
 c=x.match(r=/[a-z]/gi);
 return x.replace(r, function(y){
 return c.pop()[(y<"a"?"toUpp":"toLow")+"erCase"]()
 })
}))
answered Apr 7, 2013 at 6:58
\$\endgroup\$
4
\$\begingroup\$

APL 69

Takes screen input via: t←⍞

⎕av[1↓∊(↑ ̈v), ̈(( ×ばつ⌽ ̈z)+z← ×ばつ~1↓ ̈v>97)+ ̈⌽ ̈1↓ ̈v←(+\v<66)⊂v←0,⎕av⍳t←⍞]
answered Apr 7, 2013 at 9:51
\$\endgroup\$
2
  • \$\begingroup\$ Shouldn't APL be counted in UTF-8 bytes? :-) \$\endgroup\$ Commented Apr 7, 2013 at 10:40
  • \$\begingroup\$ @JanDvorak The APL+Win V5 character set is single byte. I have to convert to UTF-8 to post here in order for the characters to render correctly. ⎕av⍳t above returns an index into the character set from 0-255 for the characters in the vector t. \$\endgroup\$ Commented Apr 7, 2013 at 10:50
2
\$\begingroup\$

Ruby: 89 characters (including 1 for the -p switch)

Not copied Jan Dvorak's CoffeeScript solution, but after many attempts my code ended looking like an exact copy. A subconscious voice probably kept whispering "follow (削除) the white rabbit (削除ここまで) Jan Dvorak". So upvotes for the algorithm should go to his answer.

$_.gsub!(/\S+/){|m|l=m.scan r=/[a-z]/i;m.gsub(r){|c|l.pop.send c<?a?:upcase: :downcase}}

Sample run:

bash-4.2$ ruby -p reverse-word.rb <<< "Hello, I am a fish.
This; Is Some Text!
Don't touch that!
S'm00ch1e"
Olleh, I ma a hsif.
Siht; Si Emos Txet!
Tno'd hcuot taht!
E'h00cm1s
answered Apr 8, 2013 at 10:05
\$\endgroup\$
0
\$\begingroup\$

Lua, 143

print(((io.read"*l"):gsub("%w+",function(s)local r=""for i=1,#s do r=("")[s:byte(-i)>96 and"lower"or"upper"](s:sub(i,i))..r end return r end)))
answered Apr 7, 2013 at 16:33
\$\endgroup\$
2
  • \$\begingroup\$ Nice try, but it should also keep punctuation in place: pastebin.com/X8QLf6fW \$\endgroup\$ Commented Apr 8, 2013 at 10:08
  • \$\begingroup\$ EDIT: oh i see now \$\endgroup\$ Commented Apr 8, 2013 at 19:24
-1
\$\begingroup\$

EcmaScript 6 (112 characters)

The input is provided in s.

alert(s.replace(/\S+/g,x=>(_=x.match(X=/[a-z]/gi),x.replace(X,a=>_.pop()[(a<"a"?"toUpp":"toLow")+"erCase"]()))))

Based on @Jan Dorvak's answer.

answered Jan 29, 2014 at 20:46
\$\endgroup\$
-2
\$\begingroup\$

C# (375)

 public static string rev(string s)
 {
 var r = new Regex("[^A-za-z]");
 var result = "";
 var token = "";
 foreach (var c in s)
 {
 if (!r.IsMatch(c + ""))
 {
 token += c;
 }
 else
 {
 result += new string(token.Reverse().ToArray());
 result += c;
 token = "";
 }
 }
 var arr = result.ToArray();
 int i = 0;
 foreach (var c in s)
 {
 arr[i] = char.IsUpper(c) ? char.ToUpper(arr[i]) : char.ToLower(arr[i]);
 i++;
 }
 result = new string(arr);
 return result;
 }

Minified

public static string rev(string s){var r=new Regex("[^A-za-z]");var result="";var token="";foreach(var c in s){if(!r.IsMatch(c+"")){token+=c;}else{result+=new string(token.Reverse().ToArray());result+=c;token="";}}var arr=result.ToArray();int i=0;foreach(var c in s){arr[i]=char.IsUpper(c)?char.ToUpper(arr[i]):char.ToLower(arr[i]);i++;}result=new string(arr);return result;}
answered Jan 29, 2014 at 21:31
\$\endgroup\$
3
  • \$\begingroup\$ Shouldn't it be A-Za-z? \$\endgroup\$ Commented Feb 27, 2016 at 20:30
  • \$\begingroup\$ @Cyoce A little detail: [A-z] is not [A-Za-z]. The first one is a common (?) mistake, 'cause it contains non-alphabetic characters. \$\endgroup\$ Commented Apr 26, 2016 at 18:06
  • 1
    \$\begingroup\$ Also shouldn't this be, erm, golfed? \$\endgroup\$ Commented Apr 28, 2016 at 22:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.