17
\$\begingroup\$

Write a program that takes an input to STDIN and makes all of the lowercase letters (including accented letters) in the 2k-1th word uppercase and all the uppercase letters (also including accented letters) in the 2kth word lowercase (k is a positive integer). The program should not affect any other characters in any word. For example, if the string is Ook! O0k!, then the output should be OOK! o0k!.

A new word is formed when there is a nonzero amount of whitespace after a non-whitespace character. Whitespace at the beginning of an input should be ignored. If a word does not contain any changed characters, the program should still consider it as a word and continue.

Sample inputs (Different inputs are separated by a blank newline)

Nineteen Eighty-Four (1984)

Programming Puzzles & Code Golf   - 
Hooray for Code Golf Stack Exchange!

     2be or not 2be, that is the ~~~QuEsTiOn~~~

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

Sample outputs

NINETEEN eighty-four (1984)

PROGRAMMING puzzles & code GOLF   - 
HOORAY for CODE golf STACK exchange!

     2BE or NOT 2be, THAT is THE ~~~question~~~

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

This is code golf, fellas. Standard CG rules apply. Shortest program in bytes wins.


I'm pretty sure I covered all the loopholes regarding whitespace and non-letter characters, but if I've missed any, please tell me.


Thanks to @Optimizer for creating the following code snippet. To use, click "Show code snippet", scroll to the bottom and click "► Run code snippet".

/* Configuration */

var QUESTION_ID = 59464; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 43444; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "http://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="language-list">
  <h2>Shortest Solution by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
  • 5
    \$\begingroup\$ What about accented characters? Do we have to ignore those? Are functions allowed? \$\endgroup\$ – Downgoat Oct 3 '15 at 1:42
  • \$\begingroup\$ I didn't have accente characters in mind when I wrote the question, but I suppose they would count. Functions are allowed. \$\endgroup\$ – Arcturus Oct 3 '15 at 15:31
  • \$\begingroup\$ Which whitespace characters do we have to account for? Can we assume that non-whitespace characters will be printable? \$\endgroup\$ – Dennis Oct 4 '15 at 6:05
  • \$\begingroup\$ All whitespace characters, and yes. \$\endgroup\$ – Arcturus Oct 4 '15 at 14:24

16 Answers 16

4
\$\begingroup\$

Vim script, 22 21 bytes

nm Q vEUWvEuWQ|norm Q

Explanation:

The first command maps Q to:

vEU make word uppercase
W go to next word
vEu make word lowercase
W go to next word
Q repeat recursive mapping

and |norm Q executes the mapping

Usage of the program

This is how you get Vim to read from stdin:

$ vim - -c 'nm Q vEUWvEuWQ|norm Q'
Vim: Reading from stdin
This is the first line!
This is the second line!
This is the third and last line I type to check if this works!
^D

This will open up Vim displaying this:

THIS is THE first LINE.
this IS the SECOND line.
THIS is THE third AND last LINE i TYPE to CHECK if THIS works!
~
~
~
\$\endgroup\$
6
\$\begingroup\$

GNU sed, 28

Score includes +2 for -rz passed to GNU sed.

s/(\S+\s*)(\S*)/\U\1\L\2/g

Test output

$ for t in 'Nineteen Eighty-Four (1984)' \
> 'Programming Puzzles & Code Golf   - 
> Hooray for Code Golf Stack Exchange!' \
> '     2be or not 2be, that is the ~~~QuEsTiOn~~~' \
> '++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.'; do
> echo "$t" | sed -zrf PRINTlikeTHIS.sed
> done
NINETEEN eighty-four (1984)
PROGRAMMING puzzles & code GOLF   - 
HOORAY for CODE golf STACK exchange!
     2BE or NOT 2be, THAT is THE ~~~question~~~
++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
$ 
\$\endgroup\$
5
\$\begingroup\$

Perl, 26 bytes

25 bytes code + 1 byte command line

s/\S+/++$i%2?uc$&:lc$&/eg

Thanks to ThisSuitIsBlackNot for fixing a couple of bugs!

Usage:

perl -p entry.pl
\$\endgroup\$
3
\$\begingroup\$

Pyth, 23

jdmjbmrk=xZ!!kcdbcjb.zd

Try it online or run the test suite

Alternates between pyth's lower and upper functions, which are r...0 or r...1. This will probably affect unicode characters, waiting on OP clarification to change.

I feel like something must be golfable. Particularly the XOR to change the switch on which of upper/lower should be used.

\$\endgroup\$
  • \$\begingroup\$ If I interpreted the question correctly, input A\nB should print A\nb. \$\endgroup\$ – Dennis Oct 4 '15 at 6:17
  • \$\begingroup\$ That is not a correct interpretation of the question. A new word is formed when there is a nonzero amount of whitespace after a non-whitespace character. The output for A\nB is A\NB. But it seems like your CJAM answer got it right. \$\endgroup\$ – Arcturus Oct 4 '15 at 14:27
  • \$\begingroup\$ @Dennis thanks, should be fixed now. \$\endgroup\$ – FryAmTheEggman Oct 4 '15 at 16:03
2
\$\begingroup\$

Perl, 87 bytes

After screwing with both regular expressions and map for a while, I could not come up with an elegant solution, so this is the result:

@a=split(" ",lc(<>));while($i<=$#a/2){@a[$i*2]=uc(@a[$i*2]);$i++;}print(join(" ", @a));
\$\endgroup\$
  • 1
    \$\begingroup\$ Nice solution. Could <STDIN> be replaced with <> to save a few bytes? Also, could the $i=0 be skipped? \$\endgroup\$ – steve Oct 3 '15 at 6:42
  • \$\begingroup\$ @steve Thanks; and yes, that along with a minor fix (tested it with a different input, and it had a small error,) are now included. Thanks for the ideas! I'm very used to verbose, explicit coding :P \$\endgroup\$ – Codefun64 Oct 3 '15 at 6:46
  • 1
    \$\begingroup\$ @Codefun64 Welcome to PPCG! You can skip most of your parentheses to save more bytes as they're optional in Perl, eg. lc(<>), could be lc<> and using a statement modifier for your while allows you to skip the parenthesis too eg. print$i++while$i<10 vs. while($i<10){print$i++}. There's a useful page that helped me a lot Tip for Golfing in Perl \$\endgroup\$ – Dom Hastings Oct 3 '15 at 7:56
2
\$\begingroup\$

Ruby, 56 bytes

$><<gets.gsub(/\S+/){($.+=1)%2>0?$&.downcase: $&.upcase}
\$\endgroup\$
2
\$\begingroup\$

JavaScript ES6, 74 71 bytes

.toUpperCase() and .toLowerCase() absolutely slaughter the byte count (adds 32 bytes 0.o). Most work-arounds end up with more bytes though

s=>s.replace(/(\S+\s*)(\S*)/g,(_,a,b)=>a.toUpperCase()+b.toLowerCase())
\$\endgroup\$
1
\$\begingroup\$

Groovy, 108 125 120

System.in.eachLine{def b;it.split(" ").any{if(!it.empty)b=!b;print "${b?it.toUpperCase():it.toLowerCase()} "};println()}

Not as clean as I was hoping it would be, which seems to be a theme with my Groovy answers.

  • +17 to fix behavior with leading whitespace
  • -5 for removing trailing newline and switching from .isEmpty() to .empty

 

$ cat tests.txt 
Nineteen Eighty-Four (1984)

Programming Puzzles & Code Golf   - 
Hooray for Code Golf Stack Exchange!

     2be or not 2be, that is the ~~~QuEsTiOn~~~

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
$ groovy PRINTlikeTHIS.groovy < tests.txt 
NINETEEN eighty-four (1984) 

PROGRAMMING puzzles & code GOLF   - 
HOORAY for CODE golf STACK exchange! 

     2BE or NOT 2be, THAT is THE ~~~question~~~ 

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. 
\$\endgroup\$
1
\$\begingroup\$

Lua, 96 bytes

i=0 print(io.read'*l':gsub('%S+',function(x)i=i+1 return i%2==1 and x:upper() or x:lower()end))
\$\endgroup\$
  • \$\begingroup\$ This prints out a number after the output. \$\endgroup\$ – Trebuchette Oct 4 '15 at 6:21
1
\$\begingroup\$

Python 3, 103 95 bytes

print(' '.join(b.lower()if a%2 else b.upper()for a,b in enumerate(input().strip().split(' '))))
\$\endgroup\$
  • \$\begingroup\$ You can replace the conditional with [b.upper(),b.lower()][a%2] to save 4 bytes (assuming I counted correctly on mobile). \$\endgroup\$ – PurkkaKoodari Oct 3 '15 at 19:49
1
\$\begingroup\$

STATA, 252 bytes

insheet using a.b
g b=word(v,1)
gl c=0
forv x=1/`=_N'{
loc d=1
while b[`x']!=""{
if !$c replace v=subinword(v,b,upper(b),1) if `x'==_n
if $c replace v=subinword(v,b,lower(b),1) if `x'==_n
loc ++d
replace b=word(v,`d') if `x'==_n
gl c=1-$c
}
di v[`x']
}

Expects input as a csv file (one column) called a.b.

Explanation:

Read data in (default variable name is v1, shortenable to v). Make a new variable b equal to the first word (space separated token) of v for each line. For each line, while the next word is not empty (only occurs if no more characters on that line), replace the word in v with the upper or lower case version of that word in the current line, depending on how many (mod 2) words have already been found. Then get the next word and repeat. Print out the whole line when finished with it.

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

Delphi, 290 bytes

program P;uses SysUtils;var s:string;i:word;w:byte;f:boolean;begin repeat readln(s);w:=0;f:=false; for I:=1 to length(s) do begin if s[i]>' ' then begin if w=0 then f:=not f;w:=1;if f then s[i]:=uppercase(s[i])[1] else s[i]:=lowercase(s[i])[1] end else w:=0 end;writeln(s)until false;end.

Not really a good language to golf with ...

\$\endgroup\$
  • \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! \$\endgroup\$ – Dennis Oct 4 '15 at 5:59
1
\$\begingroup\$

Lua, 88 bytes

a=io.read():gsub("%g+",function(s)m=not m return m and s:upper()or s:lower()end)print(a)
\$\endgroup\$
1
\$\begingroup\$

CJam, 28 bytes

q{C' >Sc'!<*X^:XCelCeu?:S}fC

I'm currently considering the first 33 ASCII/Unicode characters (and only those) whitespace. I'm awaiting clarification to know whether this is valid or not.

Try it online in the CJam interpreter.

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

Pyth, 17 22 bytes

FGcwd=+YrG=Z%+1Z2;jdY

Try it here

\$\endgroup\$
  • \$\begingroup\$ Leading space case fails but still nice. \$\endgroup\$ – tjbtech Oct 3 '15 at 18:12
  • \$\begingroup\$ This also does not handle input on more than one line, and prints a trailing space. \$\endgroup\$ – FryAmTheEggman Oct 4 '15 at 16:07
  • \$\begingroup\$ I'll refactor when I can, thanks :D \$\endgroup\$ – clap Oct 4 '15 at 16:12
0
\$\begingroup\$

C#, 104 100 99 bytes

static void Main(){string.Join(" ","".Split(' ').Select((o,i)=>i++%2==0?o.ToUpper():o.ToLower()));}

It's 79 bytes with

string.Join(" ","".Split(' ').Select((o,i)=>i++%2==0?o.ToUpper():o.ToLower()));
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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