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.
7 Answers 7
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.
-
\$\begingroup\$ That online golfscript editor looks useful. Bookmarking, thanks \$\endgroup\$John Dvorak– John Dvorak2013年04月07日 11:00:33 +00:00Commented 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\$Peter Taylor– Peter Taylor2013年04月10日 07:08:09 +00:00Commented Apr 10, 2013 at 7:08
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"]()
})
}))
APL 69
Takes screen input via: t←⍞
⎕av[1↓∊(↑ ̈v), ̈(( ×ばつ⌽ ̈z)+z← ×ばつ~1↓ ̈v>97)+ ̈⌽ ̈1↓ ̈v←(+\v<66)⊂v←0,⎕av⍳t←⍞]
-
\$\begingroup\$ Shouldn't APL be counted in UTF-8 bytes? :-) \$\endgroup\$John Dvorak– John Dvorak2013年04月07日 10:40:48 +00:00Commented 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\$Graham– Graham2013年04月07日 10:50:22 +00:00Commented Apr 7, 2013 at 10:50
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
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)))
-
\$\begingroup\$ Nice try, but it should also keep punctuation in place: pastebin.com/X8QLf6fW \$\endgroup\$manatwork– manatwork2013年04月08日 10:08:50 +00:00Commented Apr 8, 2013 at 10:08
-
\$\begingroup\$ EDIT: oh i see now \$\endgroup\$mniip– mniip2013年04月08日 19:24:24 +00:00Commented Apr 8, 2013 at 19:24
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.
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;}
-
\$\begingroup\$ Shouldn't it be
A-Za-z? \$\endgroup\$Cyoce– Cyoce2016年02月27日 20:30:01 +00:00Commented 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\$Erik the Outgolfer– Erik the Outgolfer2016年04月26日 18:06:23 +00:00Commented Apr 26, 2016 at 18:06 -
1\$\begingroup\$ Also shouldn't this be, erm, golfed? \$\endgroup\$Cyoce– Cyoce2016年04月28日 22:01:11 +00:00Commented Apr 28, 2016 at 22:01
Don't touch that!map tot'noD hcuot taht!or tonoD't hcuot taht!? \$\endgroup\$Nod't hcuot tath!\$\endgroup\$