34
\$\begingroup\$

This is a relatively quick one, but I'm sure you'll like it.

Codegolf a program that will take input in the form of a sentence and then provide the output with the first letter capitalized in each word.

Rules:

  1. Submissions may not be in the form of a function. So no:

    function x(y){z=some_kind_of_magic(y);return z;} as your final answer... Your code must show that it takes input, and provides output.

  2. The code must preserve any other capital letters the input has. So

    eCommerce and eBusiness are cool, don't you agree, Richard III?
    

    will be rendered as

    ECommerce And EBusiness Are Cool, Don't You Agree, Richard III?
    
  3. Some of you may be thinking, "Easy, I'll just use regex!" and so using the native regex in your chosen golfing language will incur a 30 character penalty which will be applied to your final code count. Evil laugh

  4. A "word" in this case is anything separated by a space. Therefore palate cleanser is two words, whereas pigeon-toed is considered one word. if_you_love_her_then_you_should_put_a_ring_on_it is considered one word. If a word starts with a non-alphabetical character, the word is preserved, so _this after rendering remains as _this. (Kudos to Martin Buttner for pointing this test case out).

    • 4b. There is no guarantee that words in the input phrase will be separated by a single space.
  5. Test Case, (please use to test your code):

    Input:

    eCommerce rocks. crazyCamelCase stuff. _those  pigeon-toed shennanigans. Fiery trailblazing 345 thirty-two Roger. The quick brown fox jumped over the lazy dogs. Clancy Brown would have been cool as Lex Luthor. good_bye
    

    Output:

    ECommerce Rocks. CrazyCamelCase Stuff. _those  Pigeon-toed Shennanigans. Fiery Trailblazing 345 Thirty-two Roger. The Quick Brown Fox Jumped Over The Lazy Dogs. Clancy Brown Would Have Been Cool As Lex Luthor. Good_bye
    
  6. This is code golf, shortest code wins...

Good luck...

\$\endgroup\$
14
  • 1
    \$\begingroup\$ What about spaces at the end of the line? Do we have to preserve them? Can we add one if it serves our needs? \$\endgroup\$
    – Dennis
    Commented May 11, 2015 at 0:48
  • 2
    \$\begingroup\$ Dennis, please preserve spaces from the input... \$\endgroup\$ Commented May 11, 2015 at 1:04
  • 3
    \$\begingroup\$ != TitleCase dam it! c# loses AGAIN! \$\endgroup\$
    – Ewan
    Commented May 11, 2015 at 11:07
  • 1
    \$\begingroup\$ @Tim The double space before Pigeon-toed is correct. He said to preserve spacing. \$\endgroup\$
    – mbomb007
    Commented May 11, 2015 at 17:04
  • 2
    \$\begingroup\$ What separates the words? Any whitespace (tabs, newlines, etc) or just spaces? \$\endgroup\$ Commented May 11, 2015 at 18:22

69 Answers 69

2
\$\begingroup\$

C#, 133 131

using C=System.Console;class P{static void Main(){var s=2>1;foreach(var c in C.ReadLine()){C.Write(s?char.ToUpper(c):c);s=c==32;}}}
\$\endgroup\$
3
  • \$\begingroup\$ Do you need &&c!=32? I'm not too fluent in C#, but I would guess that converting a space to uppercase results in a space. \$\endgroup\$
    – DLosc
    Commented May 11, 2015 at 4:01
  • \$\begingroup\$ Whoops, thanks - that was from before I made some other changes, I think. You're correct it's not needed. \$\endgroup\$
    – Blorgbeard
    Commented May 11, 2015 at 4:25
  • \$\begingroup\$ try "using C=System.Console;" instead of using system \$\endgroup\$
    – Ewan
    Commented May 11, 2015 at 11:38
2
\$\begingroup\$

Mathematica, 66 bytes

Print@StringReplace[InputString[],WordBoundary~~a_:>ToUpperCase@a]

I would use ToCamelCase, but it doesn't preserve spacing.

\$\endgroup\$
2
\$\begingroup\$

R, 139 105 bytes

for(i in 1:length(p<-strsplit(readline(),"")[[1]])){if(i<2||p[i-1]==" ")p[i]=toupper(p[i])};cat(p,sep="")

Ungolfed + explanation:

# Assign p to be a vector of the input read from stdin, split into characters

for(i in 1:length(p <- strsplit(readline(), "")[[1]])) {

    # If we're at the first iteration or the previous character was a space

    if (i < 2 || p[i-1] == " ") {

        # Convert the current character to its uppercase equivalent

        p[i] <- toupper(p[i])
    }
}

# Join the vector elements into a single string and print it to stdout
cat(p, sep = "")

R with regex, 49 41 + 30 = 71 bytes

I'm really bummed; this actually has a better score using regular expressions with the penalty.

gsub("(^.| +.)","\\U\\1",readline(),pe=T)

This matches any single character at the beginning of the string or following any number of spaces and replaces it with an uppercase version of the capture. Note that applying \\U is legit and has no effect for non-letters. pe=T is interpreted as perl = TRUE since it takes advantage of R's partial matching of function parameters and the synonym for TRUE. For whatever reason, R doesn't use Perl-style regular expression by default.

Thanks to MickyT for helping save 8 bytes on the regex approach!

\$\endgroup\$
2
  • \$\begingroup\$ With your regex the matching string could be (^.| +.). Uppercasing anything is OK. \$\endgroup\$
    – MickyT
    Commented May 11, 2015 at 20:49
  • \$\begingroup\$ @MickyT: Good idea, thanks! Edited to use your suggestion. \$\endgroup\$
    – Alex A.
    Commented May 11, 2015 at 20:54
2
\$\begingroup\$

Java, 201 178 174 bytes

class C{public static void main(String[]a){for(String s:a[0].split(" ")){int c=s.length()>0?s.charAt(0):0;System.out.print((c>96&c<123?(char)(c-32)+s.substring(1):s)+" ");}}}

I'm back after realizing that my previous program did not preserve spaces.

First time I've had to submit an entire class before. Pass in the string as a command-line argument wrapped in quotes. (I never thought I could get it this short!)

\$\endgroup\$
1
2
\$\begingroup\$

Python 2, 64 59 63

Try it here

This iterates through each word, converting the first character of each to uppercase, then printing it with a space after. I have to check if the split substring is not empty, which refers to multiple spaces in a row.

for w in raw_input().split(" "):print w and w[0].upper()+w[1:],
\$\endgroup\$
3
  • \$\begingroup\$ @StevenRumbalski Fixed. \$\endgroup\$
    – mbomb007
    Commented May 11, 2015 at 20:41
  • \$\begingroup\$ I think you can do w and w[0].upper()+w[1:]. Not sure about the input format though. \$\endgroup\$
    – Sp3000
    Commented May 11, 2015 at 23:56
  • \$\begingroup\$ @StevenRumbalski Fixed \$\endgroup\$
    – mbomb007
    Commented May 12, 2015 at 16:44
2
\$\begingroup\$

Python 3, 58 63 59 chars

print(*(c and c[0].upper()+c[1:] for c in input().split(" ")))

I have to add 5 characters because of bugfix

\$\endgroup\$
1
  • 3
    \$\begingroup\$ This not preserves multiple whitespaces. \$\endgroup\$
    – manatwork
    Commented May 12, 2015 at 8:03
2
\$\begingroup\$

Python 3, 101 bytes

x=list(' '+input())
for i in range(len(x)-1):
 if x[i-1]==' ':x[i]=x[i].title()
print(''.join(x[1:]))
\$\endgroup\$
2
\$\begingroup\$

Rebol - 56 51

print map-each n split input" "[uppercase/part n 1]

The above works correctly with the test case and also with multiple whitespace input.

An interesting (but longer!) alternative version would to use the parse dialect (not a regex!) which when golfed would come down to 65 chars:

parse s: input [any [x: thru [" " | end] (uppercase/part x 1)]] print s
\$\endgroup\$
2
\$\begingroup\$

R, 96 93

A different approach than Alex A's. I'm not using a loop, rather creating a another vector with a space prepended, then uppercasing any character in the original vector that is sitting under a space.

p=(strsplit(readline(),''))[[1]];s=c(' ',p);p[e]=toupper(p[e<-s==' ']);cat(head(p,-1),sep='')

Doesn't beat the regexp version though.

Edit I love it when you learn something new. Replace p[-length(p)] with head(p,-1)

\$\endgroup\$
2
\$\begingroup\$

KDB(Q), 30 bytes

{@[x;0,1+where" "=-1_x;upper]}

Explanation

                  -1_x            / handle case where last char is space
       1+where" "=                / find index of space and shift by 1
     0,                           / include the first char
 @[x;                 ;upper]     / apply upper case
{                            }    / lambda

Test

q){@[x;0,1+where" "=-1_x;upper]}t
"ECommerce Rocks. CrazyCamelCase Stuff. _those  Pigeon-toed Shennanigans. Fiery Trailblazing 345 Thirty-two Roger. The Quick Brown Fox Jumped Over The Lazy Dogs. Clancy Brown Would Have Been Cool As Lex Luthor. Good_bye"
\$\endgroup\$
2
\$\begingroup\$

JavaScript (SpiderMonkey 31 (1.8)) 63 70

// first version
// alert([for(c of x=prompt())[x?c.toUpperCase():c,x=c<'!'][0]].join(''))
// new version, thx @nderscore
[for(c of prompt(o=x=''))o+=x=x<'!'?c.toUpperCase():c],alert(o)

\$\endgroup\$
10
  • \$\begingroup\$ Nice method! Here's -3 : [for(c of x=prompt(o=''))(o+=x?c.toUpperCase():c,x=c<'!')],alert(o) \$\endgroup\$
    – nderscore
    Commented May 11, 2015 at 6:03
  • 1
    \$\begingroup\$ I can't sleep... so it's -7 now : [for(c of prompt(o=x=''))o+=x=x<'!'?c.toUpperCase():c];alert(o) \$\endgroup\$
    – nderscore
    Commented May 11, 2015 at 6:37
  • \$\begingroup\$ @nderscore wow your inexhaustible. I'm sorry I never find a way to give back \$\endgroup\$
    – edc65
    Commented May 11, 2015 at 6:46
  • \$\begingroup\$ I'm just happy to aid in the quest for the smallest possible JS solution :) \$\endgroup\$
    – nderscore
    Commented May 11, 2015 at 6:48
  • 1
    \$\begingroup\$ @Chiru agreed. And thanx for giving the exact version. \$\endgroup\$
    – edc65
    Commented Aug 5, 2015 at 17:09
2
\$\begingroup\$

V, 5 (non-competing)

$òBvU

Try it online!

Not too interesting. Just a direct port of my vim answer:

$        #Move to the last character
 ò       #Recursively
  B      #Move back a WORD
   vU    #Capitalize
\$\endgroup\$
2
\$\begingroup\$

Brachylog, 12 bytes

ṇ₁{ụʰ|}ᵐ~ṇ₁w

Try it online!

           w    Print
                the input
ṇ₁              split on spaces
  {   }ᵐ        with every word
    ʰ           having its first letter
   ụ            uppercased
     |          (without failing on empty words)
        ~ṇ₁     and then joined by spaces.

If this was allowed to be a function which would normalize runs of spaces to just one space, it would only be two bytes shorter: ṇ₁{ụʰ}ˢ~ṇ₁. That would be another two bytes shorter if we'd figured out how to parse chained metapredicates (ṇ₁ụʰˢ~ṇ₁), but since handling runs of spaces requires the |, it doesn't actually matter for this challenge.

\$\endgroup\$
2
\$\begingroup\$

Lexurgy, 116 bytes

Simple replacement of lowercase letters at the beginning of a word to uppercase.

This works because of how Lexurgy handles whitespace in the input. The $ symbol denotes a word boundary, which is defined as any sort of whitespace before or after any character. As a result, input like hello world on a single line is considered as 2 words rather than 1 word.

a:
{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}=>{A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z}/$ _
\$\endgroup\$
2
\$\begingroup\$

Python 3, 59 bytes

print(*(w[0].upper()+w[1:]for w in input().split(' ')if w))

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Vyxal s, 7 bytes

ðẆƛḣ$⇧p

Try it Online!

Fixed thanks to lyxal.

ðẆƛ     # Over each word...
   ḣ$ p # To the first character...
     ⇧  # Uppercase it
\$\endgroup\$
2
  • \$\begingroup\$ This doesn't preserve spaces, and doesn't output as a single string as required. Try it Online! to fix it for 7 bytes. \$\endgroup\$
    – lyxal
    Commented Mar 24, 2022 at 8:33
  • \$\begingroup\$ @lyxal We probably need to fix the S flag - this is kinda cursed. Thanks! \$\endgroup\$
    – emanresu A
    Commented Mar 24, 2022 at 18:26
2
\$\begingroup\$

Japt -S, 7 bytes

¸®©hZÎu

Try it

¸®©hZÎu     :Implicit input of string
¸           :Split on spaces
 ®          :Map each Z
  ©         :  Logical AND with
   h        :  Replace first character with
    ZÎ      :    First character of Z
      u     :    Uppercased
            :Implicit output joined with spaces
\$\endgroup\$
2
\$\begingroup\$

Factor, 57 bytes

readln >words [ unclip ch>upper prefix ] map ""join write

Try it online!

Factor has a capitalize word, but for some reason it lowercases the rest of the word, so I couldn't use it.

\$\endgroup\$
2
\$\begingroup\$

C - 85 Bytes

s[99]={32};j;main(i){for(;read(0,&j,1);)putchar(s[i++]=j<97|j>122|s[i-1]-32?j:j-32);}

Thanks to @ceilingcat because I saved 43 bytes with his modification.

Ungolfed

s[99] = {32};
j;

main(i)
{
   for( ; read(0, &j, 1); )
         
   putchar(s[i++] = j < 97 | j > 122 | s[i - 1] - 32 ?j :j - 32);
}

Explanation

A simple program that reads characters from the console and capitalizes each "valid" word and then displays it on the console as well. It was tested in GCC and it generates some warnings.

\$\endgroup\$
0
1
\$\begingroup\$

Ruby: 46 characters

l=0
gets.chars{|c|l&&c.upcase!
l=c==" "
$><<c}

Sample run:

bash-4.3$ ruby -e 'l=0;gets.chars{|c|l&&c.upcase!;l=c==" ";$><<c}' <<< 'eCommerce rocks. crazyCamelCase stuff. _those  pigeon-toed shennanigans. Fiery trailblazing 345 thirty-two Roger. The quick brown fox jumped over the lazy dogs. Clancy Brown would have been cool as Lex Luthor. good_bye'
ECommerce Rocks. CrazyCamelCase Stuff. _those  Pigeon-toed Shennanigans. Fiery Trailblazing 345 Thirty-two Roger. The Quick Brown Fox Jumped Over The Lazy Dogs. Clancy Brown Would Have Been Cool As Lex Luthor. Good_bye
\$\endgroup\$
1
\$\begingroup\$

PHP, 91+30 bytes

Well, all the ideas were used.

I had to resort to drastic measures and build a huge piece of code:

<?=preg_replace_callback('@( |^)([a-z])@',function($a){return$a[1].($a[2]^' ');},$_GET[s]);

The only function it uses is to fetch the small letters, using regex.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Your regular expression has a minor glitch. Should be @( |^)([a-z])@ as currently not processes the first word. \$\endgroup\$
    – manatwork
    Commented May 11, 2015 at 16:08
  • \$\begingroup\$ @manatwork GODDAMN! I deleted the wrong char. Thanks a lot for the tip. I've fixed it now. Initially I had @( |$|^)([a-z])@, which didn't made sense to have the |$ there, but deleted the very important |^ by mistake. \$\endgroup\$ Commented May 11, 2015 at 16:18
  • \$\begingroup\$ Why not ucwords? \$\endgroup\$ Commented May 17, 2017 at 18:30
  • \$\begingroup\$ @JörgHülsermann Because of codegolf.stackexchange.com/a/49980/14732 and because of rule #1. \$\endgroup\$ Commented May 17, 2017 at 18:49
1
\$\begingroup\$

C#, 143 138123 bytes

class G{static void Main(string[]a){var l=' ';foreach(var c in a[0]){System.Console.Write(l==' '?char.ToUpper(c):c);l=c;}}}

Runs as a command line util. Will try and golf it down from here. Comments & critique encouraged!

\$\endgroup\$
1
  • \$\begingroup\$ Instead of using ' ' you can use the ascii integer equivalent - 32 - which will save you two bytes :) \$\endgroup\$
    – ldam
    Commented May 14, 2015 at 13:07
1
\$\begingroup\$

Java, 142

First post here as well, but found that the requirements are a one to one mapping to the way Java handles arguments.

class X{public static void main(String[]s){for(String p:s){System.out.append(p.toUpperCase().charAt(0)).append(p,1,p.length()).append(' ');}}}

Unfortunately, because they are command line arguments, spaces are not preserved, and the offending words (don't) have to be quoted ("don't"). So while I didn't entirely meet all the criteria I just wanted to share a Java solution that's under 200 bytes.

\$\endgroup\$
0
1
\$\begingroup\$

Ruby(55)

gets.chars.inject(' '){|c,d|print c<?!?d.upcase():d;d}

I know that a better ruby solution exits in an old answer, but I like this better.

note:c<?! checks for chars that come before !, which are just control/whitespace.

\$\endgroup\$
0
1
\$\begingroup\$

Groovy - 69

t=args[0];t.eachWithIndex{c,i->print!i|t[i-1]==' '?c.toUpperCase():c}
\$\endgroup\$
1
\$\begingroup\$

GNU sed, 20 + 1 (-r flag) +30 (regex penalty) = 51

s/(^| +)(.)/\1\u\2/g

(thks @manatwork for helping me save 4 bytes)

Usage :

sed 's/\(^\| \)\(.\)/\1\u\2/g' <<< "eCommerce and eBusiness are cool, don't you agree, Richard III?"
\$\endgroup\$
7
  • \$\begingroup\$ You have to add +30 penalty for using regular expression and +1 for the required -r option. By the way, no need to say [a-z] if you consume all spaces first: s/(^| +)(.)/\1\u\2/g \$\endgroup\$
    – manatwork
    Commented May 11, 2015 at 9:56
  • \$\begingroup\$ thanks -- Actually It seems (at last with GNU sed, that it dors not need the -r option) \$\endgroup\$
    – dieter
    Commented May 11, 2015 at 10:06
  • \$\begingroup\$ Grr! I felt something is not optimal there since I first read this. s/^.| +./\U&/g \$\endgroup\$
    – manatwork
    Commented May 11, 2015 at 17:19
  • \$\begingroup\$ Your code has 20 bytes + 1 byte for a required r flag, so 21 without the regex penalty. It's not allowed to change the code when running it, which is what you did when adding all those escape slashes. The -r flag is given just for that purpose. Please correct the title and usage or I will downvote. \$\endgroup\$
    – seshoumara
    Commented Sep 3, 2016 at 10:49
  • 3
    \$\begingroup\$ So I see usage still has a different code. I won't downvote as initially said, sorry for coming too strong at you last time. \$\endgroup\$
    – seshoumara
    Commented Sep 6, 2016 at 19:08
1
\$\begingroup\$

s-lang, 8 bytes + 30 = 38

c![[^ ]*

s-lang

Procedure:

  • Capitalize the first letter of every range matched by the regex.
    • Any number of Every character not in Space.
\$\endgroup\$
1
\$\begingroup\$

VTL-2, 89 bytes

1 B=A
2 A=$
3 A=A-(32*(((B=0)+(B=32))*(A>97)*(A<123
4 $=8*(1-(A=4
5 $=B
6 #=1-(A=4

If I read the challenge right, input seems fairly flexible, so... This operates every time a character is input. Input is terminated by an EOT (CtrlD). Output is one character behind, so every time you input a character, the previous one will be output. This really confused my brain when I was entering the test case.

Line 1 is fairly obvious, it copies the value of B into A. It's fine to start the program from here because uninitialized variables are assumed to be 0. Line 2 takes a single character input from the terminal and assigns A to its ASCII value. Fairly straightforward so far. Line 3 is a bit of a doozy, but it translates to (keeping in mind that B is the previous character entered, and A is the character just entered) IF (B==NULL OR B==" ") AND (96 < A < 123) THEN A=A-32. Because $ echoes, line 4 inserts a backspace character so long as A isn't EOT. Line 5 prints B, and line 6 is akin to IF A!=EOT THEN GOTO 1.

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 59 bytes

n=>n.split` `.map(e=>e[0].toUpperCase()+e.slice(1)).join` `

As I mentioned in some of my other answers, my solutions tend to be extremely boring and unimaginative.

\$\endgroup\$
1
\$\begingroup\$

Ly, 33 bytes

irs[:'`Gf'zG!fpl**[p' -0]p' =spo]

Try it online!

Pretty much a straight-forward application of the rules this time...

irs                               - read input, reverse, stash non-zero "capitalize?" state
   [                            ] - for each codepoint in the input...
    :                             - duplicate current char
     '`G                          - is it >="a"?
        f                         - pull current char forward
         'zG!                     - is it <="z"?
             fp                   - pull current char forward, delete it
               l                  - load "capitalize?" flag
                **                - multiply all three tests values
                  [p   0]p        - if/then, true if we need to capitalize
                    ' -           - sub 32 from codepoint to capitalize
                          ' =     - is the current char a space?
                             s    - save result as "capitalize?" flag
                              p   - delete test result
                               o  - print current codepoint as a char
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.