Remove Spaces, Maintaining Capitalization

27

1

Your input will be an English sentence, phrase, or word. It will only contain a-zA-Z' -,.!?. Your task is to take the input, remove spaces, and then redistribute capitalization such that letters at indexes that were capitalized before (and only letters at indexes that were capitalized before) are capitalized.

For example, if the input is A Quick Brown Fox Jumped Over The Lazy Dog, the (0-based) indexes of the capital letters are 0, 2, 8, 14, 18, 25, 30, 34, 39. Next, remove spaces from the input: AQuickBrownFoxJumpedOverTheLazyDog. Next, lowercase all letters, but uppercase those at 0, 2, 8, 14, 18, 25, 30, 34, 39: AqUickbrOwnfoxJumpEdovertHelazYdog, which is your output.

Input

Your input will be an English sentence, phrase, or word. It can only contain lowercase letters, uppercase letters, hyphens, apostrophes, commas, periods, question marks, exclamation marks, and spaces.

Output

The input with spaces removed, lowercase-d, with letters at the index of capital letters in the input uppercase-d.

NOTE: Your program cannot crash (error such execution terminates) with an IndexOutOfRange or similar error.

Test Cases

Hi! Test!
Hi!tEst!

A Quick Brown Fox Jumped Over The Lazy Dog
AqUickbrOwnfoxJumpEdovertHelazYdog

testing TESTing TeStING testing testing TESTING
testingtESTIngteStInGTEstingtestingtestiNG

TESTING... ... ... success! EUREKA???!!! maybe, don't, NOOOOO
TESTING.........success!eureKA???!!!maybe,don't,nooooo

Enter        PASSWORD ---------
Enterpassword---------

A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Z z
AabbCcddEeffGghhIijjKkllMmnnOoppQqrrSsttUuvvWwxxZz

  TEST
teST

Stephen

Posted 2017-06-28T21:06:04.500

Reputation: 12 293

Sandbox – Stephen – 2017-06-28T21:06:18.613

'For example, if the input is "A Quick Brown Fox Jumped Over The Lazy Dog", the (0-based) indexes of the capital letters are 0, 2, 8, 14, 18, 23, 27, 32' They are 0, 2, 8, 14, 18, 25, 30, 34, 39 – Luke Sawczak – 2017-06-28T21:18:40.413

@LukeSawczak thank you, my bad – Stephen – 2017-06-28T21:23:39.383

Traling spaces not allowed, I assume? – Luis Mendo – 2017-06-28T21:38:12.237

@LuisMendo your assumption is correct. This is code-golf, right? :P – Stephen – 2017-06-28T21:40:12.493

Can we assume the first character won't be a space? – xnor – 2017-06-29T04:47:28.213

@xnor No, I'll add a test case. Sorry. – Stephen – 2017-06-29T12:38:55.253

Answers

7

Jelly, 14 13 bytes

nŒlTɓḲFŒlŒuṛ¦

Try it online!

How it works

nŒlTɓḲFŒlŒuṛ¦  Main link. Argument: s (string)

 Œl            Convert s to lowercase.
n              Perform character-wise "not equal" comparison.
   T           Get the indices of all truthy elements, i.e., the indices of all
               uppercase letters in s. Let's call the resulting array J.
    ɓ          Begin a dyadic chain with left argument s and right argument J.
     ḲF        Split s at spaces and flatten, removing the spaces.
       Œl      Convert s to lowercase.
            ¦  Sparse application:
         Œu        Convert s to uppercase.
           ṛ       Take the resulting items of the uppercased string at all indices
                   in J, the items of the lowercased string at all others.

Dennis

Posted 2017-06-28T21:06:04.500

Reputation: 196 637

14

C (gcc), 82 79 74 72 69 67 66 bytes

f(c){for(char*s=c,*p=c;c=*s++;c&&putchar(c^(*p++|~c/2)&32))c&=95;}

Try it online!

Dennis

Posted 2017-06-28T21:06:04.500

Reputation: 196 637

7

Python 2, 114 bytes

x=input()
X=x.replace(' ','')
print''.join([X[i].upper()if x[i].isupper()else X[i].lower()for i in range(len(X))])

Try it online!

Equivalently:

Python 2, 114 bytes

lambda x:''.join([[str.lower,str.upper][x[i].isupper()](x.replace(' ','')[i])for i in range(len(x)-x.count(' '))])

Try it online!

HyperNeutrino

Posted 2017-06-28T21:06:04.500

Reputation: 26 575

''.join([(X[i].lower,X[i].upper)[x[i].isupper()]()for i in range(len(X))]) for -5 bytes. – ovs – 2017-06-29T12:08:49.003

5

05AB1E, 15 14 bytes

-1 byte thanks to Emigna

ðKuvy¹Nè.lil}?

Try it online!

ðK             # Remove spaces
  u            # Convert to uppercase
   vy          # For each character...
     ¹Nè       #   Get the character at the same index from the original input
        .lil}  #   If it was a lowercase letter change this one to lowercase
             ? # Print without a newline

Riley

Posted 2017-06-28T21:06:04.500

Reputation: 11 345

You save a byte if you uppercase the space-removed string and lowercase it in the condition. – Emigna – 2017-06-29T07:35:51.873

5

Haskell, 98 95 89 88 81 bytes

Thanks to @name, @nimi, @Zgarb, and @Laikoni for helping shave off 14 bytes total

import Data.Char
\s->zipWith(\p->last$toLower:[toUpper|isUpper p])s$filter(>' ')s

Ungolfed:

import Data.Char
\sentence -> zipWith (\oldChar newChar ->
                        if isUpper oldChar
                        then toUpper newChar
                        else toLower newChar)
                     sentence
                     (filter (/= ' ') sentence)

Julian Wolf

Posted 2017-06-28T21:06:04.500

Reputation: 1 139

On mobile, but looks like you can save some bytes with filter(/=' ') – Henry – 2017-06-29T03:29:02.047

Yep, certainly can. Missed the part of the spec noting that spaces were the only whitespace that needed removing. – Julian Wolf – 2017-06-29T04:43:00.940

1filter(>' ') for one byte less – nimi – 2017-06-29T05:33:41.333

2I think the body of the lambda can be shortened to last(toLower:[toUpper|isUpper p])c – Zgarb – 2017-06-29T06:39:25.933

Switching the arguments of zipWith should save one more byte: f s=zipWith(\p->last$toLower:[toUpper|isUpper p])s$filter(>' ')s. – Laikoni – 2017-06-29T07:07:26.337

I tried something cute, but it came out saving 0 bytes: f=toLower;\s->zipWith(\p->last$f:[toUpper|f p<p])s$filter(>' ')s – Lynn – 2017-06-30T16:28:22.753

5

Python 3, 78 75 72 bytes

s=input()
for c in s:s=s[c>' '!=print(end=(c+c).title()[s<'@'or'['<s]):]

Thanks to @xnor for golfing off 6 bytes!

Try it online!

Dennis

Posted 2017-06-28T21:06:04.500

Reputation: 196 637

Can you just compare s instead of s[0]? – xnor – 2017-06-29T04:33:01.960

Yes, of course. Thanks! – Dennis – 2017-06-29T04:35:07.257

1(c*2).title() can get you both cases, though switched. – xnor – 2017-06-29T04:52:53.070

Another 3 bytes. Thanks again! – Dennis – 2017-06-29T05:04:08.467

Tricky! Took me a while to figure out that c>' '!=f() is equivalent to (c>' ') and (' '!=f()). – Chas Brown – 2017-06-29T07:41:46.337

4

V, 24 bytes

ÄVuÓó
ejlDò/¥2lõ
vuk~òGd

Try it online!

These kind of challenges are exactly what V was made for. :)

Explanation:

Ä           " Duplicate this line
 Vu         " Convert it to lowercase
   Óó       " Remove all spaces
e           " Move to the end of this line
 j          " Move down a line (to the original)
  l         " Move one char to the right
   D        " And delete the end of this line
    ò       " Recursively:
     /      "   Search for:
         õ  "     An uppercase character
      ¥2l   "     On line 2
            "     (This will break the loop when there are no uppercase characters left)
vu          "   Convert it to lowercase
  k         "   Move up a line
   ~        "   Convert this to uppercase also
    ò       " Endwhile
     G      " Move to the last line
      d     " And delete it

James

Posted 2017-06-28T21:06:04.500

Reputation: 54 537

@DLosc Good questions! The newlines signal the end of a regex command, such as a substitute (remove) or search command. More detail is on this page: https://github.com/DJMcMayhem/V/wiki/Regexes

– James – 2017-06-29T19:13:25.230

4

Python 2, 100 bytes

s=input()
print"".join([c.lower(),c.upper()][s[i].isupper()]for i,c in enumerate(s.replace(" ","")))

Erik

Posted 2017-06-28T21:06:04.500

Reputation: 51

3Welcome to PPCG, and very good first answer! – ETHproductions – 2017-06-29T19:15:15.947

3

JavaScript (ES6), 94 91 85 bytes

s=>s.replace(/./g,c=>c==" "?"":c[`to${"@"<s[x]&s[x++]<"["?"Upp":"Low"}erCase`](),x=0)
  • 6 bytes saved with assistance from ETHproductions & Arnauld.

Try it

o.innerText=(f=

s=>s.replace(/./g,c=>c==" "?"":c[`to${"@"<s[x]&s[x++]<"["?"Upp":"Low"}erCase`](),x=0)

)(i.value="Hi! Test!");oninput=_=>o.innerText=f(i.value)
<input id=i><pre id=o>

Shaggy

Posted 2017-06-28T21:06:04.500

Reputation: 24 623

Ninjad :P https://codegolf.stackexchange.com/a/128951/65836

– Stephen – 2017-06-28T22:22:19.537

Could you do '@'<s[i]&s[i]<'['?? – ETHproductions – 2017-06-28T23:42:25.717

@StepHen: Aw, man, didn't see that last night while I was working on this. – Shaggy – 2017-06-29T07:38:32.677

@ETHproductions: I was wondering if that might be shorter but I was too lazy to look up which characters I'd need to use :D Turns out it doea save a byte; thanks. – Shaggy – 2017-06-29T07:40:07.730

3

Retina, 77 71 bytes

.+
$&¶$&
T`L `l_`.+$
+`((.)*)[A-Z].*(¶(?<-2>.)*)
$1$3 
.+¶

T`l `L_` .?

Try it online! Link includes test suite. Explanation: The first stage duplicates the line while the second stage lowercases the duplicate and deletes its spaces. The third stage then loops through each uppercase letter from right to left and attempts to place a space before the corresponding character on the second line. The first line is deleted and the spaces are used to uppercase the relevant characters of the result. Edit: Saved 6 bytes thanks to @Kobi.

Neil

Posted 2017-06-28T21:06:04.500

Reputation: 95 035

Small question: Are the (.?) and $4 parts needed? It looks like having an optional group at the end does nothing. – Kobi – 2017-06-29T11:38:40.160

@Kobi Nothing small about that question! It had originally been part of an attempt at using lookarounds to match the characters to be uppercased directly instead of having to translate them as a separate step. – Neil – 2017-06-29T12:26:10.070

3

Alice, 32 bytes

/..- ~l+u~mSloy
\ia''-y.'Qa.+a@/

Try it online!

Explanation

This is a standard template for programs that work entirely in ordinal mode. Unwrapped, the program is as follows:

i.' -l.uQm.lay.a-'~y+'~aS+o@

i       take input as string
.       duplicate
' -     remove spaces from copy
l.u     create all-lowercase and all-uppercase versions
Q       reverse stack, so original string is on top
m       truncate original string to length of spaces-removed string
.lay    convert everything except uppercase characters to \n
.a-'~y  convert everything except \n (i.e., convert uppercase characters) to ~
+       superimpose with lowercase string
        \n becomes the corresponding lowercase character, and ~ remains as is
'~aS    convert ~ to \n
+       superimpose with uppercase string
        lowercase in existing string stays as is because it has a higher code point
        \n becomes corresponding uppercase character
o       output
@       terminate

Nitrodon

Posted 2017-06-28T21:06:04.500

Reputation: 9 181

3

Perl, 95 94 + 1 = 95 bytes

+1 byte penalty for -n

Save one byte by replace from s/\s//g to s/ //g

$s=$_;s/ //g;$_=lc($_);while(/(.)/gs){$p=$&;$p=uc($p)if(substr($s,$-[0],1)=~/[A-Z]/);print$p;}

Try it online!

Explanation:

  1. Make copy of input string.

  2. Remove all spaceses and transform string to lower case.

  3. Then start loop over each letter. Test letter in same position in saved string for upper case. If it upper - make current letter captitalized. Print letter.

Note that perl need to be run with "-n" command line switch

Veitcel

Posted 2017-06-28T21:06:04.500

Reputation: 61

Welcome to PPCG! If you would like, you can add a link to Try It Online: https://tio.run/# (I would add it, but I don't know if this is Perl 5 or Perl 6)

– Stephen – 2017-07-03T18:25:53.487

1I think that you need to count +1 byte for the -n flag. Other than that, this looks good! Welcome to the site! :) – James – 2017-07-03T18:25:58.123

@StepHen it's Perl 5, colud you add link? I failed to run my code there in propper way. – Veitcel – 2017-07-04T17:44:30.950

Happy to see a new Perl golfer! I've added the TIO link to your answer and improved the formatting. – Dada – 2017-07-04T18:06:27.370

2

Python 3, 117 bytes

s=input()
y=list(s.replace(' ','').lower())
i=0
for c in y:
 if s[i].isupper():y[i]=c.upper()
 i+=1
print(''.join(y))

Try It Online!

This is pretty much my first code golf, so it's likely to be bad, minus help from comments below!

P.S. Yes, it's dumb that defining and incrementing i saves bytes over range(len(y)). Oh well.

Luke Sawczak

Posted 2017-06-28T21:06:04.500

Reputation: 415

1Welcome to PPCG! Nice first submission! However, complying to our site's I/O standards, your submission must either be a function of a string or take input; you cannot assume input is in a variable. Hope you enjoy your stay! :) – HyperNeutrino – 2017-06-28T21:29:43.847

Thanks; edited a function in, but also saved 5 bytes in the body :D – Luke Sawczak – 2017-06-28T21:35:47.003

1@LukeSawczak save a ton of bytes by changing to one space for indentation, and maybe add a Try It Online! link if you want to – Stephen – 2017-06-28T21:37:08.640

1You can remove the space after return. – CalculatorFeline – 2017-06-28T21:45:03.210

@StephenS Thank you! Sorry, I deleted my comment after realizing I could both make a working TIO and save bytes by using input/print, but that's good to know. – Luke Sawczak – 2017-06-28T22:17:05.397

2

MATL, 18 bytes

kXz"@GX@)tk<?Xk]&h

Same approach as Riley's 05AB1E answer.

Try it online!

Luis Mendo

Posted 2017-06-28T21:06:04.500

Reputation: 87 464

2

C# (.NET Core), 108 101 bytes

using System.Linq;s=>s.Replace(" ","").Select((c,i)=>s[i]>64&s[i]<91?char.ToUpper(c):char.ToLower(c))

Try it online!

  • 7 bytes saved after realizing that the char class has static ToUpper() and ToLower() methods.

Charlie

Posted 2017-06-28T21:06:04.500

Reputation: 11 448

2

Java 8, 184 177 161 bytes

s->{String r="";for(int i=0,j=i,t,u;i<s.length;){t=s[i++];if(t>32){u=s[j++];r+=(char)(t<65|t>90&t<97|t>122?t:u>64&u<91?t&~32:u>96&u<123|u<33?t|32:t);}}return r;}

Can definitely be golfed some more..
- 16 bytes thanks to @OlivierGrégoire by taking the input as char[] instead of String.

Explanation:

Try it here.

s->{                           // Method with char-array parameter and String return-type
  String r="";                 //  Result-String
  for(int i=0,j=i,t,u;         //  Some temp integers and indices
      i<s.length;){            //  Loop over the String
    t=s[i++];                  //   Take the next character and save it in `t` (as integer)
                               //   and raise index `i` by 1
    if(t>32){                  //   If `t` is not a space:
     u=s[j++];                 //   Take `u` and raise index `j` by 1
     r+=                       //   Append the result-String with:
      (char)                   //    Integer to char conversion of:
       (t<65|t>90&t<97|t>122?  //     If `t` is not a letter:
        t                      //      Simply use `t` as is
       :u>64&u<91?             //     Else if `u` is uppercase:
        t&~32                  //      Take `t` as uppercase
       :u>96&u<123|u<33?       //     Else if `u` is lowercase or a space:
        t|32                   //      Take `t` as lowercase
       :                       //     Else:
        t);                    //      Take `t` as is
    }
  }                            //  End of loop
  return r;                    //  Return result-String
}                              // End of method

Kevin Cruijssen

Posted 2017-06-28T21:06:04.500

Reputation: 67 575

1Take a char[] instead of a String for this one, you'll save up plenty of bytes! – Olivier Grégoire – 2017-06-30T07:57:34.507

On the other hand, I answered too with another algorithm. And here, I take the opposite arguments: in = String, out = char[] :-)

– Olivier Grégoire – 2017-06-30T08:39:15.317

2

Charcoal, 33 bytes

A⁰χFLθ¿⁼§θι A⁺¹χχ¿№α§θ⁻ιχ↥§θι↧§θι

Try it online!

As I still don't know how to pass a string with whitespaces as a single input parameter into Charcoal code, I just assign in the header the test string to the Charcoal variable that represents what would be the first input (θ):

AA Quick Brown Fox Jumped Over The Lazy Dogθ

So the code has the same number of bytes as if the string were passed as first input.

You can see here the verbose version of the code.

Charlie

Posted 2017-06-28T21:06:04.500

Reputation: 11 448

1I said in another answer but just in case you forget, just input as a python array with one element – ASCII-only – 2017-07-27T02:38:52.753

I just require the input to have a trailing newline. – Neil – 2017-12-01T16:58:35.310

2

PHP, 181 bytes

I try get the minor numbers of bytes,this is my code:

<?php
$s=readline();
preg_match_all('/[A-Z]/',$s,$m,PREG_OFFSET_CAPTURE);
$s=strtolower(str_replace(' ','',$s));
while($d=each($m[0]))$s[$d[1][1]]=strtoupper($s[$d[1][1]]);
echo $s;

Try it online!

kip

Posted 2017-06-28T21:06:04.500

Reputation: 141

Instead of a Constant PREG_OFFSET_CAPTURE you can use the value 256 , $argn is a shorter variable as readline() for an input and I think ctype_upper and use of lcfirst and ucfirst will save lots of bytes with one loop and use of $$i and ternary operator – Jörg Hülsermann – 2017-07-02T22:24:15.067

2

Common Lisp, 104 bytes

(defun f(s)(map'string(lambda(x y)(if(upper-case-p x)(char-upcase y)(char-downcase y)))s(remove #\  s)))

Try it online!

Unusually short for the wordy Common Lisp!

Straightforward code:

(defun f (s)                     ; receive the string as parameter
  (map 'string                   ; map the following function of two arguments
       (lambda (x y)             ; x from the original string, y from the string with removed spaces
         (if (upper-case-p x)    ; if x is uppercase
             (char-upcase y)     ; get y uppercase
             (char-downcase y))) ; else get y lowercase
       s
       (remove #\  s)))

Renzo

Posted 2017-06-28T21:06:04.500

Reputation: 2 260

2

Java (OpenJDK 8), 150 117 113 97 bytes

s->{for(int i=0,j=0,c;i<s.length;)if((c=s[i++]&95)>0)System.out.printf("%c",c^(s[j++]|~c/2)&32);}

Try it online!

While golfing more, I came to 102 bytes:

s->{for(int i=0,j=0,c;i<s.length;)if((c=s[i++]&95)>0)System.out.printf("%c",c<64?c|32:c|s[j]&32,j++);}

Try it online!

But I remembered this was starting to look like Dennis' C answer so I simply ported his bit-twiddling and... magic happened. The big gain from the port is removing the branches and the repetitions inside them.

Olivier Grégoire

Posted 2017-06-28T21:06:04.500

Reputation: 10 647

@ceilingcat that doesn't work: Hi! Test! should become Hi!tEst!, but with your solution it becomes Hi!Test. – Olivier Grégoire – 2019-11-10T11:40:40.743

2

Google Sheets, 213 bytes

=ArrayFormula(JOIN("",IF(REGEXMATCH(MID(A1,ROW(OFFSET(A1,0,0,LEN(A1))),1),"[A-Z]"),MID(UPPER(SUBSTITUTE(A1," ","")),ROW(OFFSET(A1,0,0,LEN(A1))),1),MID(LOWER(SUBSTITUTE(A1," ","")),ROW(OFFSET(A1,0,0,LEN(A1))),1))))

Input is in cell A1 and the formula breaks down like this:

  • ArrayFormula() lets us evaluate each term of ROW() independently
  • JOIN() concatenates all those independent results into a single string
  • IF(REGEXMATCH(),UPPER(),LOWER() is what makes it alternate using upper or lower case depending on what the case was at that position in the input
  • ROW(OFFSET()) returns an array of values 1 to A1.length that can be fed into the MID() function so we can evaluate each character in turn

Results of test cases: (It's easier to read if you click though to the larger version.)

TestCases

Engineer Toast

Posted 2017-06-28T21:06:04.500

Reputation: 5 769

2

Ruby, 80 bytes

->a{n=a.downcase.delete' '
n.size.times{|i|(?A..?Z)===a[i]&&n[i]=n[i].upcase}
n}

Try it online!

Alex

Posted 2017-06-28T21:06:04.500

Reputation: 371

You can save a couple bytes by using n.gsub(/./){} instead of n.size.times{};n: n.gsub(/./){(?A..?Z)===a[i]?$&.upcase: $&}. – Jordan – 2017-12-03T02:06:02.940

2

Perl, 92 bytes

$p[$i++]=$-[0]while s/[A-Z]/lc($&)/e;s/\s//g;for$c(@p){substr($_,$c,1)=~tr[a-z][A-Z]};print;

Explanation:

$p[$i++]=$-[0]while s/[A-Z]/lc($&)/e;   #get locations of caps into an array at the same time converting letters to lowercase

s/\s//g;   #delete all spaces

for$c(@p){substr($_,$c,1)=~tr[a-z][A-Z]};   #convert lowercase letters to uppercase where uppercase letters were present

print;   # print (of course) :)

jmatix

Posted 2017-06-28T21:06:04.500

Reputation: 21

1Welcome to PPCG! :) – Stephen – 2017-07-03T20:37:28.480

You need to add -n flag to make your answer valid. A few golfing things: s/ //g is enough (no need \s), y/a-z/A-Z/ is the same as tr[a-z][A-Z], you can use -p flag so you don't need the last print, you don't need the parenthesis in lc$&. – Dada – 2017-07-04T09:44:09.163

1

C, 103 bytes

i,j,c;f(char*s){for(i=j=0;c=tolower(s[j++]);)c-32&&putchar(c-32*(s[i]>64&&s[i]<91&&c>96&&c<123))&&++i;}

Try it online!

Steadybox

Posted 2017-06-28T21:06:04.500

Reputation: 15 798

1

Python 3, 125, 124 bytes

lambda s:''.join(c.upper()if i in(s.find(q)for q in s if q.isupper())else c for i,c in enumerate(s.replace(' ','').lower()))

Try it online!

Christian Dean

Posted 2017-06-28T21:06:04.500

Reputation: 437

1

Python 2, 106 105 bytes

s=input()
print''.join(map(lambda(c,u):[c.lower,c.upper][u](),zip(s.replace(' ',''),map(str.isupper,s))))

Edit: save one byte via print ''.join => print''.join.

Lambda form, 99 bytes

lambda s:''.join(map(lambda(c,u):[c.lower,c.upper][u](),zip(s.replace(' ',''),map(str.isupper,s))))

Chas Brown

Posted 2017-06-28T21:06:04.500

Reputation: 8 959

1

SCALA, 128 chars, 128 bytes

var l=s.toLowerCase().filter(x=>x!=32)
for(i<-0 to l.size-1){if(s(i).isUpper)l=l.substring(0,i)+l(i).toUpper+l.substring(i+1)}
l

Thanks for this challenge. Try it online!

V. Courtois

Posted 2017-06-28T21:06:04.500

Reputation: 868

1

q/kdb+, 49 bytes

Solution:

{@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}

Examples:

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"Hi! Test!"
"Hi!tEst!"

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"A Quick Brown Fox Jumped Over The Lazy Dog"
"AqUickbrOwnfoxJumpEdovertHelazYdog"

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"testing TESTing TeStING testing testing TESTING"
"testingtESTIngteStInGTEstingtestingtestiNG"

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"TESTING... ... ... success! EUREKA???!!! maybe, don't, NOOOOO"
"TESTING.........success!eureKA???!!!maybe,don't,nooooo"

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"Enter        PASSWORD ---------"
"Enterpassword---------"

q){@[a;(&)(#:[a:lower x except" "]#x)in .Q.A;upper]}"A a B b C c D d E e F f G g H h I i J j K k L l M m N n O o P p Q q R r S s T t U u V v W w X x Z z"
"AabbCcddEeffGghhIijjKkllMmnnOoppQqrrSsttUuvvWwxxZz"

q){@[a;(&)#:[a:lower x except" "]#x in .Q.A;upper]}"  TEST"
"teST"

Explanation:

Find indices where input is uppercase and then apply function upper to those indices on a lowercase, space-removed version of the input string. Note that we cannot apply the function beyond the length of the string, so use take (#) to truncate the input string to length of the lowercase, space-removed version.

{@[a;where count[a:lower x except " "]#x in .Q.A;upper]} / ungolfed
{                                                      } / lambda function
 @[ ;                                           ;     ]  / apply FUNC to VAR at INDICES: @[VAR;INDICES;FUNC]
                                                 upper   / uppercase, upper["abc"] -> "ABC"
                                       x in .Q.A         / boolean list where input is in uppercase alphabet ABC..XYZ
                                      #                  / take this many elements from list on the right (ie truncate)
           count[                    ]                   / returns length of the stuff inside the brackets, count["ABC"] -> 3                                        
                         x except " "                    / remove " " from string
                   lower                                 / lowercase, lower["ABC"] -> "abc"
                 a:                                      / save in variable a
     where                                               / returns indices where true where[101b] -> 0 2
   a                                                     / our lowercased, space-stripped input

Bonus:

After reading the answers, thought I'd try a solution where I iterate over the input, so far I've only managed a 53 byte solution:

{a{$[y in .Q.A;upper x;x]}'#:[a:lower x except" "]#x}

streetster

Posted 2017-06-28T21:06:04.500

Reputation: 3 635

1

Swift 3.0, 199 bytes

var s="AS Ff",i=[String](),p=[Int](),j=0;for c in s.characters{if c>="A"&&c<="Z"{p.append(j)};if c != " "{i.append(String(c).lowercased())};j=j+1};for c in p{i[c]=i[c].uppercased()};print(i.joined())

Try it Online!

A. Pooja

Posted 2017-06-28T21:06:04.500

Reputation: 41

1

Perl 5, 40 bytes

37 bytes of code + -F flag. (note that on old versions of Perl, you might need to add -an flags)

print$F[$i++]=~/[A-Z]/?uc:lc for/\S/g

Try it online!

Explanations:
Thanks to -F, @F contains a list of every characters of the input.
for/\S/g iterates over every non-space character of the input. We use $i to count at which iteration we are. If $F[$i++] is an uppercase character (/[A-Z]/), then we print the uppercase current character (uc), otherwise, we print it lowercase (lc). Note that uc and lc return their argument unchanged if it isn't a letter.


Previous version (less golfed: 47 bytes):

 s/ //g;s%.%$_=$&;$F[$i++]=~/[A-Z]/?uc:lc%ge

Try it online!

Dada

Posted 2017-06-28T21:06:04.500

Reputation: 8 279

1

PHP, 110 bytes

$q=strtr($s=$argn,[' '=>'']);foreach(str_split($s)as$k=>$v)echo$v<lcfirst($v)?ucfirst($q[$k]):lcfirst($q[$k]);

Breakdown

$q=strtr($s=$argn,[' '=>''])

We take our input ($argn) and store it in a smaller variable because we need it later, before stripping out all the spaces with strtr

foreach(str_split($s)as$k=>$v)

We then take our original string, split it into an array of characters, and loop through each of them.

echo$v<lcfirst($v)?ucfirst($q[$k]):lcfirst($q[$k])

We check to see if the current letter is uppercase (A is less than a probably because ASCII), and echo out the corresponding letter from the space-stripped string with the appropriate case.

Xanderhall

Posted 2017-06-28T21:06:04.500

Reputation: 1 236

1

Charcoal, 18 bytes

⪫E⪫⪪θ ω⎇№α§θκ↥ι↧ιω

Try it online! Link is to verbose version of code. Explanation:

    θ               Input string
   ⪪                Split on spaces
  ⪫   ω             Join together
 E                  Loop over each character
          §θκ       Get character from original string
        №α          Search uppercase letters
       ⎇            If true (nonzero)
             ↥ι     Uppercase the current character
               ↧ι   Else lowercase the current character
⪫                ω  Join together
                    Implicitly print

The recent addition of StringMap shaves off a couple of bytes:

⭆⪫⪪θ ω⎇№α§θκ↥ι↧ι

is roughly equivalent to ⪫E...ω.

Neil

Posted 2017-06-28T21:06:04.500

Reputation: 95 035

1

GNU sed, 67 + 1 = 68 bytes

+1 byte for -r flag.

:A
s/$/;/
:
s/([A-Z]);(.?)/;\l\1\u\2/
t
s/(\S);/;\1/
t
s/ ;//
/ /bA

Try it online!

Explanation

The algorithm is pretty simple:

  1. Insert a cursor (;) at the end of the line:

    :A
    s/$/;/
    :
    
  2. If the character before the cursor is an uppercase letter, lowercase it (\l) and uppercase the character after the cursor (\u), moving the cursor to the left, and branch back to :

    s/([A-Z]);(.?)/;\l\1\u\2/
    t
    
  3. Otherwise, if the character before the cursor is not a space, move the cursor to the left and branch back to ;:

    s/(\S);/;\1/
    t
    
  4. Otherwise, if the cursor is preceded by a space, delete both:

    s/ ;//
    
  5. Finally, if there are any spaces left, branch back to :A:

    / /bA
    

Jordan

Posted 2017-06-28T21:06:04.500

Reputation: 5 001