20
\$\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). Please note the third example, which should have leading spaces, and have the first be capitalised.

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
  • 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
  • 1
    \$\begingroup\$ If you require accented characters, you should add a test case for them. \$\endgroup\$
    – xigoi
    Nov 15 '20 at 8:27

19 Answers 19

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\$
6
\$\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\$
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\$
0
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\$
3
  • \$\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\$ 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\$
3
  • 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\$ 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\$
2
\$\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\$
1
  • \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! \$\endgroup\$
    – Dennis
    Oct 4 '15 at 5:59
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\$
1
  • \$\begingroup\$ This prints out a number after the output. \$\endgroup\$ 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\$
1
  • \$\begingroup\$ You can replace the conditional with [b.upper(),b.lower()][a%2] to save 4 bytes (assuming I counted correctly on mobile). \$\endgroup\$ 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\$

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\$
3
  • \$\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\$ Oct 4 '15 at 16:07
  • \$\begingroup\$ I'll refactor when I can, thanks :D \$\endgroup\$
    – clapp
    Oct 4 '15 at 16:12
1
\$\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\$
1
\$\begingroup\$

Perl 5 + -040plF/^ +$/, 17 bytes

$_=($|-=@F)?uc:lc

Try it online!

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

Husk, 12 bytes

z?a_mȯ%2Lwḣ¹

Try it online!

Preserves whitespace in the input, in agreement with the test cases.

z?a_mȯ%2Lwḣ¹
z             # zip two lists together,
              # using this function on each pair of elements:
 ?            # if element from list1 is truthy
  a           # uppercase the element from list2
   _          # otherwise lowercase the element from list2
    mȯ%2Lwḣ¹  # list1:
    mȯ        # map this function on each element of 
          ḣ¹  # all the prefixes of the input string:
        Lw    # number of elements after splitting on whitespace
      %2      # modulo 2
              # list2: the input string

A different program which uppercases & lowercases in words, and does "not affect any other characters in any word" (which I wrote after reading the instructions, but before realising that the third "Sample output" should also be considered as part of the specification), could be only 10 bytes:

wzom?a_ݬw

Try it online!

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

PowerShell, 106 bytes

$k=@();$i=0;$args[0].trim().split(' ')|%{if($i%2){$k+=$_.tolower()}else{$k+=$_.toupper()};$i++};$k-join" "

Try it online!

Shameless port of python 3 solution, Just horrible attempt to golf ;-(

\$\endgroup\$
3

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.