33
\$\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
    May 11, 2015 at 0:48
  • 2
    \$\begingroup\$ Dennis, please preserve spaces from the input... \$\endgroup\$ May 11, 2015 at 1:04
  • 3
    \$\begingroup\$ != TitleCase dam it! c# loses AGAIN! \$\endgroup\$
    – Ewan
    May 11, 2015 at 11:07
  • 1
    \$\begingroup\$ @Tim The double space before Pigeon-toed is correct. He said to preserve spacing. \$\endgroup\$
    – mbomb007
    May 11, 2015 at 17:04
  • 2
    \$\begingroup\$ What separates the words? Any whitespace (tabs, newlines, etc) or just spaces? \$\endgroup\$ May 11, 2015 at 18:22

66 Answers 66

22
\$\begingroup\$

CJam, 15 13 bytes

Lq{_eu?_S-}/;

Try it online in the CJam interpreter.

Pseudocode

L             e# B := ""
 q            e# Q := input()
  {       }/  e# for C in Q:
   _eu?       e#     C := B ? C : uppercase(C)
       _S-    e#     B := string(C).strip(" ")
            ; e# discard(B)

All modified characters C are left on the stack and, therefore, printed when exiting.

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Damn this is clever. D: \$\endgroup\$ May 11, 2015 at 0:25
  • \$\begingroup\$ I have to agree, outgolfing someone by 4 chars in a codegolf language is a feat in itself... well done. \$\endgroup\$ May 11, 2015 at 1:07
  • 12
    \$\begingroup\$ @WallyWest: Golfing languages can give the impression that they kinda golf themselves, but I assure you that they don't. TMTOWTDI is true for all languages and especially for those with a lot of built-ins. Sometimes you win, sometimes you lose and sometimes you feel like you've been hit by a truck. \$\endgroup\$
    – Dennis
    May 11, 2015 at 1:30
13
\$\begingroup\$

CSS 2.1, 49

:after{content:attr(t);text-transform:capitalize}

Explanation:

  • The attr function takes the input from a t (text) HTML attribute.
  • The input is capitalized by setting text-transform to capitalize.
  • The output is provided as a generated content, using the content property on an ::after pseudo-element.

Runnable snippet:

:after {
    content: attr(t);
    text-transform: capitalize;
}
<div 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"></div>

Note: CSS 2.1 specified the desired behavior: capitalize uppercased the first character of each word. However, CSS3 uppercases first typographic letter unit of each word. So the snippet above won't work properly neither on old IE, which didn't follow CSS 2.1; nor on new compliant browsers which follow CSS3.

\$\endgroup\$
3
  • \$\begingroup\$ Oh, this is clever! \$\endgroup\$
    – IQAndreas
    May 12, 2015 at 6:28
  • 1
    \$\begingroup\$ (too bad about the _those problem on CSS3 browsers, but I'm still upvoting because of the unique way of solving the problem.) \$\endgroup\$
    – IQAndreas
    May 12, 2015 at 6:29
  • \$\begingroup\$ @Oriol, "oh this is clever!" indeed! Sorry IQAndreas, I have to borrow your comment here... this is an ingenious approach to solving the problem... i will have to make use of this approach... \$\endgroup\$ May 21, 2015 at 11:16
11
\$\begingroup\$

Perl, 13 bytes

perl -040pe '$_="\u$_"'

9 bytes plus 4 bytes for 040p (assuming I've interpreted the rules on special invocations correctly).

-040 sets the input record separator $/ to a single space, so spaces are preserved; the \u escape sequence converts the next character to title case.

\$\endgroup\$
1
  • \$\begingroup\$ Great work, honorable mention for using the command line! \$\endgroup\$ May 27, 2015 at 22:28
10
\$\begingroup\$

Javascript (ES6), 77 bytes

alert(prompt().split(' ').map(x=>x&&x[0].toUpperCase()+x.slice(1)).join(' '))

Commented

alert( // output
    prompt(). // take input
    split(' '). // split by spaces
    map(x=> // map function to array
        x && // if x, empty string "" is falsey and returns itself
        x[0].toUpperCase() + x.slice(1) // capaitalize 1st char and concatenate the rest
    ).
    join(' ') // join array with spaces
)
\$\endgroup\$
5
  • \$\begingroup\$ What happens if words are separated by multiple spaces? [4b] \$\endgroup\$
    – Caek
    May 11, 2015 at 2:35
  • 3
    \$\begingroup\$ @Caek It's handled by the x&&. An empty string is falsey so the && short-circuits and returns the left operand, the empty string. Spaces are preserved. \$\endgroup\$
    – nderscore
    May 11, 2015 at 2:38
  • \$\begingroup\$ Awesome, thanks for the explanation. Might help me figure out how I can get it to work now. \$\endgroup\$
    – Caek
    May 11, 2015 at 2:49
  • \$\begingroup\$ This will capitalize even non Ascii characters, so that å will become Å! \$\endgroup\$
    – leo
    May 13, 2015 at 8:38
  • \$\begingroup\$ -4 bytes by calling split` ` and join` ` as Tagged Templates \$\endgroup\$ Mar 28, 2022 at 3:51
8
\$\begingroup\$

Perl Version < 5.18, 30 27 26 25

say map"\u$_",split$,=$"

24 characters +1 for -n.

\u makes the next character in a string uppercase. @ThisSuitIsBlackNot pointed this out to save 1 byte. Before we were using the function ucfirst.

From the perldocs,

As another special case, split emulates the default behavior of the command line tool awk when the PATTERN is either omitted or a literal string composed of a single space character (such as ' ' or "\x20" , but not e.g. / / ). In this case, any leading whitespace in EXPR is removed before splitting occurs, and the PATTERN is instead treated as if it were /\s+/ ; in particular, this means that any contiguous whitespace (not just a single space character) is used as a separator. However, this special treatment can be avoided by specifying the pattern / / instead of the string " " , thereby allowing only a single space character to be a separator. In earlier Perls this special case was restricted to the use of a plain " " as the pattern argument to split, in Perl 5.18.0 and later this special case is triggered by any expression which evaluates as the simple string " " .

Since $" evaluates to a space, this will preserve the spaces. Since we want to both set $, to a space character, and input a space character to the split, @nutki pointed out we can do both as the input to the split. That saves 3 bytes from what we had before, which was first setting $, and then inputting $" to the split.

Using a , for map instead of {} saves an additional byte, as @alexander-brett pointed out.

Run with:

echo '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' | perl -nE'say map"\u$_",split$,=$"'
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Save 1 byte with ...map"\u$_",split... \$\endgroup\$
    – alyx-brett
    May 12, 2015 at 15:19
  • \$\begingroup\$ @alexander-brett thanks! I updated the answer. \$\endgroup\$
    – hmatt1
    May 12, 2015 at 16:51
7
\$\begingroup\$

CJam, 17 15 bytes

lS/{S+(eu\+}/W<

Test it here.

Fairly straightforward implementation of the spec. Make use of the new {}& to avoid errors for consecutive spaces.

Two bytes saved by Dennis.

\$\endgroup\$
6
  • \$\begingroup\$ Great stuff! Is CJam primarily just a golfing language or does it have some practical commercial applications? \$\endgroup\$ May 10, 2015 at 23:47
  • 6
    \$\begingroup\$ @WallyWest No it's just a golfing language. It definitely doesn't have commercial applications, but I personally use it occasionally for quick throw-away scripts (because it has a lot of built-ins, and if you know what you're doing, then typing fewer characters is quicker than typing more characters ;)). \$\endgroup\$ May 10, 2015 at 23:49
  • \$\begingroup\$ You can save a few bytes by appending a space to each word. Depending on the OP's answer to my question, this could get you to either 14 or 12 bytes. \$\endgroup\$
    – Dennis
    May 11, 2015 at 0:58
  • \$\begingroup\$ @Dennis Oh right, I was playing around with that, but didn't consider simply adding it before pulling off the first character. I'll change that tomorrow, thank you! \$\endgroup\$ May 11, 2015 at 1:00
  • \$\begingroup\$ @Dennis Thanks, I changed it, but I'm not sure what 14-byte version you meant. If you're talking about omitting the second +, then that breaks if the input contains trailing spaces. \$\endgroup\$ May 11, 2015 at 9:02
7
\$\begingroup\$

C, 64 63 bytes

a;main(c){while(~(c=getchar()))putchar(a?c:toupper(c)),a=c-32;}

Fix: some compilers (such as Clang) don't like an int parameters in place of argv, so I moved it to a global variable. The byte count stays the same. Thanks to squeamish ossifrage for noticing. Down to 63 bytes, thanks Dennis.

Ungolfed:

int a;

int main(int c) {
    while(~(c = getchar()))
        putchar(a ? c : toupper(c)),
        a = c - ' ';
}

Pretty straightforward: if a is false, the character is converted to uppercase. It is set after reading a space: c - ' ' is false only if c == ' '. toupper() ignores everything that is not a lowercase letter, so symbols and multiple spaces are fine. -1 has all bits set, so when getchar() returns -1 the NOT operator makes it zero, and the loop stops. a is declared as a global variable, so it is initializd to zero (false). This ensures that the first word is capitalized.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ while(~(c=getchar()) — I like that. Clang won't actually compile this, but you can get the same character count with c;main(a){...} \$\endgroup\$
    – r3mainer
    May 11, 2015 at 13:24
  • 1
    \$\begingroup\$ If you swap the declarations of a and c and the order of the ternary operator, you can replace == with - to save one byte. \$\endgroup\$
    – Dennis
    May 11, 2015 at 16:45
  • \$\begingroup\$ You are right, of course. \$\endgroup\$ May 11, 2015 at 17:10
  • \$\begingroup\$ Nice! +1 The program would work the same when using while(!(c = getchar())), right? \$\endgroup\$
    – Spikatrix
    May 13, 2015 at 11:17
  • 1
    \$\begingroup\$ @Cool Guy: Nope, the bitwise ~ and the logical ! are not the same. In C anything that is not zero is considered true, so your condition would be like while((c = getchar()) == 0) which of course won't work. The bitwise NOT operator ~ negates the value bit-by-bit. To break the loop, ~c must be zero: this means that all bits have to be one, so that when negated they become all zeroes. That value (for a 32bit int) is 0xFFFFFFFF, which, if signed, is -1 (EOF). \$\endgroup\$ May 13, 2015 at 12:38
7
\$\begingroup\$

Python 3, 59 56 bytes

f=1
for c in input():print(end=f*c.upper()or c);f=c==" "

Thanks to @Reticality for 3 bytes.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ How about print(end=f*c.upper()or c)? That would save 4 bytes \$\endgroup\$
    – user34736
    May 11, 2015 at 15:45
  • \$\begingroup\$ @Reticality Oh wow, I had no idea you could have an empty print with just a keyword arg. Thanks! \$\endgroup\$
    – Sp3000
    May 11, 2015 at 23:01
5
\$\begingroup\$

><> (Fish), 39 bytes

</?-' 'o:;?(0:<-*' '*('{'$)'`'::i
i/.0e

Method:

  • Take one char and capitalize it if in range a-z then print it out. (left-to-right code for this part is i::'backquote')$'{'(*' '*+)
  • If the last taken char is an EOF char then exit else print it
  • If the last taken char is a space char then go to point 1 else take a new letter and go to point 2.
\$\endgroup\$
5
\$\begingroup\$

JAVA, 273 bytes

EDIT

import static java.lang.System.*;class x{public static void main(String[] s){char[] a=new java.util.Scanner(in).nextLine().toCharArray();boolean f=1>0;for(int i=0;i<a.length;i++){if(a[i]==' '){f=1>0;continue;}if(f){a[i]=Character.toUpperCase(a[i]);f=1<0;}}out.println(a);}}
\$\endgroup\$
10
  • \$\begingroup\$ This is my first answer in PCG, not sure if this is acceptable. \$\endgroup\$ May 11, 2015 at 2:15
  • \$\begingroup\$ Welcome aboard! You might try removing whitespace and using single characters for variable names. There are some other tips for golfing JAVA as well. \$\endgroup\$
    – nderscore
    May 11, 2015 at 2:19
  • \$\begingroup\$ Thanks @nderscore for the hint, I have edited my answer using the tips. \$\endgroup\$ May 11, 2015 at 2:51
  • \$\begingroup\$ Looking better! I also added the byte count into your post for you. \$\endgroup\$
    – nderscore
    May 11, 2015 at 3:26
  • 1
    \$\begingroup\$ @TuukkaX He doesn't have public in front of the class.. And if you mean he can remove the public in front of the static void main(..., then you are wrong, unless he also changes the class to interface and uses Java 8+. \$\endgroup\$ Jun 20, 2016 at 13:01
5
\$\begingroup\$

JavaScript (regex solution) - 104 bytes

Someone has to bite the bullet and post the RegEx solution! 74 characters, plus the +30 character penalty:

alert(prompt().replace(/(^| )[a-z]/g,function(m){return m.toUpperCase()}))

Or if you want to read and understand the code in its non-compacted fashion:

//     Matches the (beginning of the line or a space), followed by a lowercase English character.  
string.replace( /(^| )[a-z]/g ,
                function(match) { return match.toUpperCase(); }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Clever... though of course, you've paid the price with a 30 character penalty... I take my hat off to you for biting the bullet... \$\endgroup\$ May 21, 2015 at 11:12
5
\$\begingroup\$

Vim, 11, 10 bytes

qqvUW@qq@q

Explanation:

qq           #Start recording in register 'q'
  vU        #Make the character under the cursor uppercase
     W       #Move forward a WORD
      @q     #recursively call macro 'q'
        q    #stop recording
         @q  #Call the recursive macro

Do I get a gold-badge for outgolfing Dennis?

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

brainfuck, 342 310 bytes

>-[-[-<]>>+<]>-[->+>>>>+<<<<<]>[-<+>],[<[->>+>+<<<]>>>[-<<<+>>>]<<[->>+>+<<<]>>>[-<<<+>>>]<<[->-<]>>+<[>->>>+[+[<]>>+<+]>[-<<<<<<->>>>>>]<<<+++++[>+++++<-]>+>>+<<[<<<<[->+>>+<<<]>[-<+>]>>[[-]>>+<<]>>-[<<<[-<<<<->>>>]>>>+>-<]<<<<<->>>>-]>>[-<<<<[-]>>>>]<<<<<<[-]]>[->[-]<<<<<[->>>+>>+<<<<<]>>>[-<<<+>>>]>]<<<.,]

Try it online!

Explanation:

[
* Many constants were taken from the BF constants page on esolangs.org.
*
* Cells:
*
* true number: the true index of the cell
* fake number: the relative cell index as referenced in the code
*
* true# | fake# | info
*   0       -     Used only for initialization of (fake) cell 0
*   1       -     Used only for initialization of (fake) cell 0
*   2       -     Used only for initialization of (fake) cell 0
*   3       -     Used only for initialization of (fake) cell 0
*   4       0     Holds constant 32 / ' ', which is used for cell 5 (space flag) and for subtracting (' ') from input
*   5       1     Holds the input/output char during the main loop. Also used in setup for copying cell 0 to cell 5
*   6       2     Used to hold 32 / ' ' (temporarily, to subtract it from the input)
*   7       3     Used to hold a copy of the input that gets mangled throughout the loop, being subtracted from to 
*                 check what the input character was. Also used in space code to copy cell 0 to cell 5.
*   8       4     Used primarily as a flag to decide which part of the space/not space conditional to run (if 1, the 
*                 space code runs; if 0, the not-space code runs). Also used when copying cell 3 to 6 (for checking 
*                 if cell 3 == 0), and to copy cell 1 to 3 (input).
*   9       5     Holds the 'space flag' (different from cell 4). When a space is encountered, this cell is set to 32 
*                 ('a' - 'A'). When a lowercase character is encountered, this cell is subtracted cell 1 (input), 
*                 clearing it by default (subtraction without copying implicitly clears the cell). This makes it so
*                 that only the first character after a space is converted to uppercase.
*   10      6     Used as a temporary cell when initializing constants 65 ('a' - ' ') and 2, also used in the
*                 lowercase check loop to set cell 8 (cell 3 == 0 flag)
*   11      7     Used as the counter in the lowercase check loop, goes from 26 to 0 (decrementing each iteration).
*                 Also used as a temporary cell when initializing constant 65.
*   12      8     Used to hold (cell 3 == 0) flag, which subtracts cell 5 from cell 1 if it is 1 (which means that 
*                 cell 1 is a lowercase letter).
*   13      9     Used as a flag to figure out if the else branch of the lowercase checker should run. If one, the
*                 character is not a lowercase letter or space and so cell 5 is cleared.
]

>-[-[-<]>>+<]>-    set cell 0 to 32 (=' ') 

[->+>>>>+<<<<<]    set cells 1 and 5 to 32 (end on 0)
>[-<+>]            move 1 back to 0 (end on 1) 

,[                 loop over input (cell 1) 
    
    copy cell 0 to cell 2
    <[->>+>+<<<]     [move cell 0 to cells 2 and 3 (end on 0)]
    >>>[-<<<+>>>]    [move cell 3 back to cell 0 (end on 3)] 
    
    copy cell 1 to cell 3
    <<[->>+>+<<<]    [move cell 1 to cells 3 and 4 (end on 1)]
    >>>[-<<<+>>>]    [move cell 4 back to cell 1 (end on 4)] 
    
    <<[->-<]         [subtract cell 2 from cell 3 (end on 2)] 
    
    >                cell 3 / input minus ' ' 
    
    >+<              set cell 4 as flag to run space code if set (end on 3) 
    
    [                not space branch (check if in lowercase zone)
        >-                 clear cell 4 (end on 4) 
        
        >>>+[+[<]>>+<+]>   set cell 9 to 65 (='a' minus ' ') (uses 6 7 8 as tmp) (end on 9) 
        
        [-<<<<<<->>>>>>]   [subtract cell 9 from cell 3 (end on 9)] 
        
        [need to check if cell 3 is from 0-26, it could be above and not a lowercase letter] 
        
        <<<                cell 6
        +++++[>+++++<-]>+  set cell 7 to 26
        >>+<<              set cell 9 to 1 (end on 7) 
        
        [                  do 26 times 
            
            <<<<                   cell 3
            [->+>>+<<<]            [move cell 3 to cell 4 and 6 (end on 3)]
            >[-<+>]                [move cell 4 back to cell 3 (end on 4)] 
            
            >>                     cell 6 
            
            [[-]>>+<<]             [if cell 6 is set, set cell 8 to 1 (end on 6)] 
            
            >>-                    decrement cell 8 (if cell 3 was not zero cell 8 is now zero) (if cell 3 was zero cell 8 is now 255) 
            
            [                      if cell 3 is zero (start here on 8)
                <<<                    cell 5
                [-<<<<->>>>]           [sub cell 5 from cell 1 (end on 5)] 
                
                >>>+                   clear cell 8 (end on 8)
                >-<                    set cell 9 to 0 (end on 8)
            ] 
            
            <<<<<-                 decrement cell 3 (end on 3)
            >>>>-                  end on 7 and decrement
        ] 
        
        >>[                cell 9 set (else branch so we have no lowercase letter)
            -                  [clear cell 9] 
            
            <<<<               cell 5
            [-]                [clear cell 5]
            >>>>               cell 9
        ] 
        
        <<<<<<             cell 3
        [-]                [clear cell 3]
    ] 
    
    >                cell 4
    [                space branch
        -                      clear cell 4 (end on 4)
        
        >[-]                   clear cell 5 (space flag/may have been set)
        <<<<<[->>>+>>+<<<<<]   [set space flag (cell 5) (coincidentally, it is also 32 so we can copy from cell 0) (0-> 5 and 3) (end on 0)]
        >>>[-<<<+>>>]          [3 to 0 (end on 3)] 
        
        >                      end on 4
    ] 
    
    <<<.             from 4 to 1 (output 1)
,]
\$\endgroup\$
4
\$\begingroup\$

Python 2, 73 bytes

i=raw_input()
print''.join((c,c.upper())[p==' ']for p,c in zip(' '+i,i))

This program capitalises a letter if preceded by a space (with a kludge for the first character in the string). It relies on the .upper() string method to capitalise correctly.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ You could save 2 bytes by porting to Python 3. (-4 raw_input => input, +2 print => print()) \$\endgroup\$ May 11, 2015 at 19:27
  • \$\begingroup\$ Thanks Steven. I had considered the savings in bytes by coding in Python 3. Then I thought, if I was to change language to be competitive, I would change to Pyth. I am happy to compete in the Python 2 sub-league. I code in Python 2 every day for work, so this experience makes me better at my job (but my work code is not golfed!). \$\endgroup\$ May 16, 2015 at 11:11
4
\$\begingroup\$

PHP 64 76 77 83 84 89 bytes

Does $_GET count as input in PHP?
If so, here is my first CG attempt

foreach(explode(' ',$_GET[@s])as$k=>$v)echo$k?' ':'',ucfirst($v)

Thanks manatwork :)

One could just use the ucwords function, which would result in 21 bytes:

<?=ucwords($_GET[@s])

thanks Harry Mustoe-Playfair :)

\$\endgroup\$
11
  • \$\begingroup\$ Personally I consider only fgets(STDIN) to read input. But we have no consensus on $_GET as far as I know. \$\endgroup\$
    – manatwork
    May 11, 2015 at 9:52
  • \$\begingroup\$ Yup, that works :D \$\endgroup\$
    – Octfx
    May 11, 2015 at 10:16
  • \$\begingroup\$ You don't need the tricks to shut up the warnings. Thei're warnings! Nobody cares about them. \$\endgroup\$ May 11, 2015 at 13:05
  • \$\begingroup\$ Well, didn't thought of that. Guess I'll have to stick to substr \$\endgroup\$
    – Octfx
    May 11, 2015 at 14:05
  • 1
    \$\begingroup\$ This won't work, because if $k evaluates to true it will return 1 which is then echoed \$\endgroup\$
    – Octfx
    May 13, 2015 at 17:13
4
\$\begingroup\$

Haskell, 69

import Data.Char
main=interact$tail.scanl(!)' '
' '!c=toUpper c;_!c=c

Explanation:

scanl takes a function (a -> b -> a) and an initial value a, then iterates over a list of [b]s to make a list of [a]s:

scanl (!) z [a,b,c] == [   z
                       ,   z ! a
                       ,  (z ! a) ! b
                       , ((z ! a) ! b) ! c]

It repeatedly takes the previous result as the left argument of the function passed to it, and a value from the input list as the right argument, to make the next one.

I wrote a function (!) :: Char -> Char -> Char that returns the right character you pass it, but capitalizes it if the left char is ' ' (space). For scanl, this means: return the value from the input list, but capitalize it if the previous result was a space. So scanl (!) ' ' "ab cd" becomes:

    scanl (!) ' ' "ab cd"
==> ' ' : scanl (!) (' ' ! 'a') "b cd"
==> ' ' : scanl (!)     'A'     "b cd"
==> ' ' : 'A' : scanl (!) ('A' ! 'b') " cd"
==> ' ' : 'A' : scanl (!)     'b'     " cd"
==> ' ' : 'A' : 'b' : scanl (!) ('b' ! ' ') "cd"
==> ' ' : 'A' : 'b' : scanl (!)     ' '     "cd"
==> ' ' : 'A' : 'b' : ' ' : scanl (!) (' ' ! 'c') "d"
==> ' ' : 'A' : 'b' : ' ' : scanl (!)     'C'     "d"
==> ' ' : 'A' : 'b' : ' ' : 'C' : scanl (!) ('C' ! 'd') ""
==> ' ' : 'A' : 'b' : ' ' : 'C' : scanl (!)     'd'     ""
==> ' ' : 'A' : 'b' : ' ' : 'C' : 'd' : ""
==> " Ab Cd"

We need the initial value ' ' to capitalize the first letter, but then we chop it off with tail to get our final result.

\$\endgroup\$
4
  • \$\begingroup\$ Nice! Can you please explain it for me? \$\endgroup\$
    – poida
    May 12, 2015 at 10:23
  • \$\begingroup\$ I wrote an explanation. \$\endgroup\$
    – Lynn
    May 12, 2015 at 15:06
  • \$\begingroup\$ Some more scanl examples: one, two. \$\endgroup\$
    – Lynn
    May 12, 2015 at 15:14
  • \$\begingroup\$ @Mauris kudos for using such a great algorithmm like this... :) \$\endgroup\$ May 21, 2015 at 11:11
3
\$\begingroup\$

Pyth, 20 bytes

uXGHr@GH1fqd@+dzTUzz

These multiple spaces really sucks. Otherwise there would have been a really easy 12 bytes solution.

Try it online: Pyth Compiler/Executor

Explanation

                      implicit: z = input string
         f       Uz   filter [0, 1, 2, ..., len(z)-1] for elements T, which satisfy:
          qd@+dzT        " " == (" " + z)[T]
                      (this finds all indices, which should be capitalized)
u                  z  reduce, start with G = z, for H in idices ^ update G by
 XGH                     replace the Hth char of G by
    r   1                upper-case of
     @GH                 G[H]
                      implicitly print result

edit: 16 chars is possible with @Dennis algorithm.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ The multiple space thing is there to make it a lot more challenging... otherwise it would be a simple case of string.split(" ") or something similar... But you've done well to do it in 20 characters \$\endgroup\$ May 11, 2015 at 1:05
3
\$\begingroup\$

CJam, 14 bytes

It's not the shortest, but...

qS/Sf.{\eu}s1>

Another answer using similar ideas:

qS/Laf.{;eu}S*

.x only changes the first item if one of the parameters has only one item.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Chaining f and . is pretty ingenious. Another 14 bytes variant: qS/Sf.{\eu}S.- \$\endgroup\$
    – Dennis
    May 12, 2015 at 15:44
3
\$\begingroup\$

Lua, 64 62 61 bytes

Lua is a horrendous language to golf in, so I'm pretty proud of myself for this one.

print(string.gsub(" "..io.read(),"%s%l",string.upper):sub(2))

[Try it here]1 Outdated, will update tommorow

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Welcome to PPCG! Surely, you don't need those spaces after commas? \$\endgroup\$ May 11, 2015 at 23:59
  • \$\begingroup\$ Wow, I'm so new to this I didnt even know spaces counted. 62 bytes! \$\endgroup\$
    – user40734
    May 12, 2015 at 0:52
  • 2
    \$\begingroup\$ I also just noticed it's not entirely correct: you are capitalising letters after all non-letters, so abc_def will give Abc_Def. However only letters after spaces should be turning into upper case. The good news is, fixing it saves a byte. ;) \$\endgroup\$ May 12, 2015 at 0:57
3
\$\begingroup\$

JAVA, 204 211 226 bytes

My first entry on CG, I hope it's fine:

class U{public static void main(String[]s){int i=0;char[]r=s[0].toCharArray();r[0]=Character.toUpperCase(r[0]);for(char c:r){if(c==' '&&i>0)r[i+1]=Character.toUpperCase(r[i+1]);i++;System.out.print(c);}}}

Saved 7 bytes thanks to @TNT

\$\endgroup\$
2
  • \$\begingroup\$ Involving my poor Java skills: public class U{public static void main(String[]s){int i=-1,j;char[]r=s[0].toCharArray();for(char c:r)if(++i==0||c==' '&&i>0)r[j=i+(i==0?0:1)]=Character.toUpperCase(r[j]);System.out.print(r);}} \$\endgroup\$
    – manatwork
    May 11, 2015 at 16:36
  • 1
    \$\begingroup\$ Welcome to PPCG! The public modifier isn't necessary so you can save 7 more. \$\endgroup\$
    – TNT
    May 11, 2015 at 16:38
3
\$\begingroup\$

PHP: 76 74 characters

foreach($l=str_split(fgets(STDIN))as$c){echo$l?ucfirst($c):$c;$l=$c==" ";}

Sample run:

bash-4.3$ php -r 'foreach($l=str_split(fgets(STDIN))as$c){echo$l?ucfirst($c):$c;$l=$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\$
6
  • \$\begingroup\$ Instead of ucfirst($c), use $c^' '. (Tip: if you bitwise-xor a letter with a space, it will be converted from uppercase to lowercase, and the oposite applies too) \$\endgroup\$ May 12, 2015 at 15:50
  • \$\begingroup\$ @IsmaelMiguel, that works fine in your solution as you process only lowercase letters. But in my solution all first characters are processed. So for the (otherwise great) xor trick my code would also need some character type filtering. :( \$\endgroup\$
    – manatwork
    May 12, 2015 at 15:59
  • \$\begingroup\$ That didn't crossed my mind. There must be a bitwise trick to check if it is a letter or not. \$\endgroup\$ May 12, 2015 at 16:08
  • 1
    \$\begingroup\$ One thing you can do is $l=str_split(fgets(STDIN)), which reduces the code by 2 bytes! \$\endgroup\$ May 12, 2015 at 17:10
  • 1
    \$\begingroup\$ Now I'm going mad. Man, how long I starred to that initialization and missed it. Thank you, @IsmaelMiguel. \$\endgroup\$
    – manatwork
    May 12, 2015 at 17:14
3
\$\begingroup\$

C, 74 bytes

a,b=1;main(){while((a=getchar())>0)b=isspace(putchar(b?toupper(a):a));}

Makes no assumptions about the run-time character set (ASCII, EBCDIC, Baudot, ...whatever). Does assume that EOF is negative (I think C guarantees that).

a,b=1;
main()
{
    while((a=getchar())>0)
        b=isspace(putchar(b?toupper(a):a));
}

a is the input character; b is true if the last character was space. The only non-obvious bit is that we use the fact that putchar returns the character printed if there's no error.

\$\endgroup\$
3
\$\begingroup\$

C# Linq - 187

This is nowhere close to winning but I just love Linq too much.

namespace System{using Linq;class P{static void Main(string[]a){Console.Write(a[0].Substring(1).Aggregate(a[0][0].ToString().ToUpper(),(b,c)=>b[b.Length-1]==32?b+char.ToUpper(c):b+c));}}}
\$\endgroup\$
3
\$\begingroup\$

Java 8, 135 bytes

It's rare that I beat all the other answers that use the same language.

interface M{static void main(String[]a){int c=0;for(char i:a[0].toCharArray()){System.out.print(c==0?(i+"").toUpperCase():i);c=i-32;}}}

TIO

\$\endgroup\$
1
  • \$\begingroup\$ Suggest var i:a[0] instead of char i:a[0] \$\endgroup\$
    – ceilingcat
    Jan 23, 2023 at 7:58
2
\$\begingroup\$

Bash, 61

a="${@//: / }"
a=(${a//: / })
a="${a[@]^}"
echo "${a//:/ }"

Note the colons are simply to make the program display OK here. In reality these can be some non-printable character, such as BEL.

Output

$ ./cap1st.sh "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
$ 

Bash, 12

Sadly this one doesn't preserve leading/mutliple/trailing spaces, but otherwise it works:

echo "${@^}"

Output

$ ./cap1st.sh 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\$
2
  • 5
    \$\begingroup\$ But that's half the challenge! \$\endgroup\$
    – Sp3000
    May 11, 2015 at 2:47
  • 1
    \$\begingroup\$ @Sp3000 there I fixed it (at as cost of 49 chars) \$\endgroup\$ May 11, 2015 at 3:41
2
\$\begingroup\$

Pip, 15 + 1 for -s = 16

{IaUC:a@0a}Ma^s

Explanation:

                  a is first cmdline arg (implicit)
            a^s   Split a on spaces
{         }M      Map this function to each element:
 Ia                 If the word is not empty,
   UC:a@0             uppercase its first character
         a          Return the word
                  Output the resulting list (implicit) joined on spaces (-s flag)

One interesting feature of Pip that this program draws on is the : assignment meta-operator. Most C-like languages have some set of compute-and-assign operators: e.g. x*=5 does the same thing as x=x*5. In Pip, however, you can tack : onto any operator and turn it into a compute-and-assign operator. This even goes for unary operators. So -:x computes -x and assigns it back to x, the same as x:-x would. In this case, UC: is used (together with Pip's mutable strings) to uppercase the first character of a word.

The program takes input from the command-line, requiring an invocation like this:

python3 pip.py -se "{IaUC:a@0a}Ma^s" "test teSt TEST  _test"
\$\endgroup\$
2
\$\begingroup\$

C, 125

Not the shortest of solutions, but I really like to golf in C.

char b[99];main(c){while(scanf("%[A-Za-z_-]",b)==1)islower(*b)&&(*b&=223),printf("%s",b);~(c=getchar())&&putchar(c)&&main();}

ungolfed:

char b[99];
main(c)
{
  while(scanf("%[A-Za-z_-]", b) == 1) {
    if(islower(b[0])) {
      b[0] &= 0xDF;
    }
    printf("%s", b);
  }
  if((c = getchar()) != -1) {
      putchar(c);
      main();
  }
}

I don't know wheter using regex-like syntax in scanf is streching the rules, but it works quite nicely. (Well, technically it's not a full regex)

An other thing to consider is that this code only works for words shorter than 99 bytes. But I think this solution will work for most cases.

\$\endgroup\$
1
  • \$\begingroup\$ Hint: &=223 --> -=32 \$\endgroup\$
    – edc65
    May 11, 2015 at 8:19
2
\$\begingroup\$

Haskell: 127 characters

import Data.List
import Data.Char
i=isSpace
s a b=i a==i b
u (w:ws)=(toUpper w):ws
f w=concatMap u$groupBy s w
main=interact f
\$\endgroup\$
1
  • \$\begingroup\$ I got down to 69 bytes. \$\endgroup\$
    – Lynn
    May 11, 2015 at 17:11
2
\$\begingroup\$

PHP, 82

echo join(' ',array_map(function($s){return ucfirst($s);},explode(' ',$argv[1])));

Usage :

$ php code.php "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\$

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
    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
    May 11, 2015 at 4:25
  • \$\begingroup\$ try "using C=System.Console;" instead of using system \$\endgroup\$
    – Ewan
    May 11, 2015 at 11:38

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.