Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Create the shortest program that given an input string it outputs the opposite-cased string. For example if I pass the string "HeLlO" the program should output "hElLo".

Of course, neither aggregate functions can be used, nor framework functions like toupper() or tolower(). Any language is welcome.

share|improve this question
1  
Do I have to handle characters that aren't letters or spaces? –  Ourous Aug 25 at 22:47
1  
Those are irrelevant –  defmx Aug 25 at 22:50
    
@defmx what about uppercase numbers like ^? –  Sammitch Aug 25 at 23:03
3  
Does the program have to handle letters other than A-Za-z? For example, what should the program output for ёЖик уКраЇнА? –  Peter Olson Aug 26 at 0:38
7  
Can you define "aggregate function" in the context of this question? –  DigitalTrauma Aug 26 at 0:42

15 Answers 15

Bash shell, 16 characters

tr A-Za-z a-zA-Z

Sample runs:

llama@llama:~$ tr A-Za-z a-zA-Z
ThIs is a TeSt!
tHiS IS A tEsT!
llama@llama:~$ echo 'Programming Puzzles & Code Golf Stack Exchange' | tr A-Za-z a-zA-Z
pROGRAMMING pUZZLES & cODE gOLF sTACK eXCHANGE

It works in a file, too (of course):

llama@llama:~$ echo 'tr A-Za-z a-zA-Z' > swapcase.sh
llama@llama:~$ echo 'This is a test!' | bash swapcase.sh
tHIS IS A TEST!
share|improve this answer
    
I don't think anybody could possibly get their program any shorter than this –  ThreeFx Aug 25 at 23:03
    
@ThreeFx you are right it is very short, however this question comes to my mind: is it really a program? I think this only invokes a program; I'm not disqualifying the idea, just help me get this clear. –  defmx Aug 25 at 23:17
    
@defmx It is indeed a Bash program; I suppose you could think of tr as a function in other languages. (You could even say that most small shell scripts are kind of just a lot of tiny scripts glued together to make a bigger script. :P) It runs as an executable if you add a #!/bin/bash to the beginning of the swapcase.sh file, so it is a program. In fact, I could even say that this is a 13-character program in tr, but that would be stretching it :) –  Doorknob 冰 Aug 25 at 23:31
    
@Doorknob Excellent, yes we could say it is a program in tr because it is the interpreter, cool! –  defmx Aug 25 at 23:37
    
echo ${1~~} for 11 chars, but I suppose this undocumented feature might counts as "framework functions" –  DigitalTrauma Aug 26 at 1:13

CJam - 5

q32f^

Try it at http://cjam.aditsu.net/

Let me know if I missed something.

share|improve this answer
1  
Wow, very nice! This seems to strip spaces and non-alphabetic characters, however. –  Doorknob 冰 Aug 25 at 23:54
1  
@Doorknob well, it xor's everything with 32, space becomes NUL, but in my understanding, non-alphabetic characters are irrelevant –  aditsu Aug 25 at 23:56

Perl, 16 (17 counting -p flag as 1)

y/A-Za-z/a-zA-Z/

Fundamentally the same as the sh solution. The only room for golfing is using the y synonym for tr.

I'd like to protest that all of these solutions are only correct for ASCII, though. I'd like to see someone produce a solution that's correct for Unicode 7.0, without using library functions or external data :-P

share|improve this answer
    
That's evil. Post it as a challenege ;-) If someone did that, you'd probably see everyone starting off with the same long Chinese-character filled string to cram the data in once someone makes it :) Not all letters have a round-trip case conversion ( lc(uc(lc('ẞ'))) -> 'ss' (not ß), for instance). –  guifa Aug 31 at 20:18
    
@guifa I'll investigate. Going to see whether (IMO) the amount of information contained in the case mappings is "reasonable" for a challenge. If so, I'll write it. –  hobbs Aug 31 at 21:10
    
To be honest, it will be too much. You'd need to know which characters have upper or lower versions which at two bits per character you're at ~16KB total just for masking whether the transformation can happen. Then you'll need 1-4 bytes to express the transformation per letter that can transform. I'd try limiting it to, say, just particular Latin code tables to make it feasible without coding in actual data compression –  guifa Aug 31 at 22:00
1  
@guifa I'm optimistic that cleverness can get it down to perhaps 2kB without algorithms like gzip. Setting out to prove it :) –  hobbs Aug 31 at 23:19
1  
This is a polyglot - it's also a valid sed script which does the same thing! –  professorfish Sep 2 at 10:29

Vim, 2

~G

In Normal mode, with the cursor on the first line, and with 'tildeop' set, this command will swap the case of every character in the current buffer. This probably shouldn't count, but it's also very likely the fewest number of characters one need type to perform the operation in question, so I figured I'd share.

share|improve this answer
    
How about norm gg~G (9 chars) as a valid statement in VimL? –  hobbs Aug 26 at 3:48

C, 67 chars

main(c,d){while(~(c=getchar()))d=c|32,putchar(d>96&&d<123?c^32:c);}

Input/output via STDIN/STDOUT:

$ ./swapcase <<< "HELLO world!"
hello WORLD!
$

C, 41 chars

main(){while(putchar(getchar()^32)<127);}

If we strictly only care about alphabetical letters.

$ printf %s {a..z} {A..Z} | ./swapcase
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$ 
$ 
share|improve this answer

Marbelous - 249

00 @0 00 @1
&2 &0 // &0
.. /\ @0 \/
]] !! 0A
RR .. \\ &2
=0 \\ 00
&2 @1 /\
:R
}0 .. 00 @2
=A .. &1 +Z @3
@0 .. {0 +U //
.. /\ .. &0
>Z {0 >Z @4
-Z .. -Z 
>T @2 >Z
-U .. -Z
<Q @3 >Q
+Z .. -S
+Z .. <Q &0
+R @4 +Z \/
\\ .. +S @0
.. &2 // &1
.. {0 .. \/
share|improve this answer
1  
Don't forget to count newlines as characters, however, if you take out the spaces (which marbelous supports) you can get it down to 211 bytes, including newlines. –  overactor Sep 4 at 6:14

Python 106

import sys
s=''
for c in sys.argv[1]:
  n=ord(c)
  if 64<n<91:n+=32
  elif 96<n<123:n-=32
  s+=chr(n)
print s
share|improve this answer
    
Would appending to a string and printing it at the end instead of all the messy sys stuff save any characters? –  Doorknob 冰 Aug 25 at 23:05
    
@Doorknob 2 chars is 2 chars! –  Sammitch Aug 25 at 23:25
    
Heh, well at least it's shorter! Couldn't you remove the ,sys on the first line now? –  Doorknob 冰 Aug 25 at 23:26
    
@Doorknob newp, need it for argv. –  Sammitch Aug 25 at 23:27
    
Oh, right. Actually, you could just use input() instead (in Python 3), which is shorter and also removes the need for sys. (you would have to add parentheses for print, but you would save many more characters) –  Doorknob 冰 Aug 25 at 23:28

Befunge 93 - 45

>~:55+-#v_@>
_v#`g19:<] ^,-g29
 >92g+,    ^

Terminates when a NL is entered.

share|improve this answer

Python - 68

import sys
print''.join(chr((ord(l)-33)%64+65) for l in sys.argv[1])

Simple python script featuring no ifs or elses.

share|improve this answer

Cobra - 100 (or 81)

class P
    def main
        for c in Console.readLine,Console.write(if(c.isLetter,((c to int)^32)to char,c))

If only letters matter

class P
    def main
        for c as int in Console.readLine,Console.write((c^32)to char)
share|improve this answer

Rebol - 25

forall s[s/1: s/1 xor 32]

Usage example (in Rebol console):

>> ;; s is the input string

>> s: "HeLlO"
== "HeLlO"

>> forall s [s/1: s/1 xor 32]
== #"o"

>> s
== "hElLo"

>> forall s [s/1: s/1 xor 32] 
== #"O"

>> s
== "HeLlO"
share|improve this answer

Lua - 78

while""do a=io.read(1)b=a<']'and 32 or-32 io.write(string.char(a:byte()+b))end

Nothing special, and it ups any character smaller ']' and downs any one larger.

share|improve this answer

Python - 44

print''.join(chr(ord(c)^32)for c in input())

The program expects an input string quotes "HeLLo", which should be legit. Using Python 3 we can easily pass the string without quotes like HeLLo at the cost of two more characters for the print-brackets.

share|improve this answer

CoffeeScript - 85 (or 77 67)

Since non-alphabetic characters don't matter:

f=(x)->x.split('').map((c)->String.fromCharCode((c.charCodeAt(0)-33)%64+65)).join('')

Discarding whitespace and other non-alphabetic characters:

f=(x)->x.split('').map((c)->String.fromCharCode(c.charCodeAt(0)^32)).join('')

Even shorter:

f=(x)->(String.fromCharCode(c.charCodeAt(0)^32)for c in x).join('')
share|improve this answer

Clojure - 182 chars

I'm a Clojure newbie. Golfed:

(defn b[i x y](if(and(> i x)(< i y)) true false))(print(apply str(map #(let[i(int %)](if(b i 64 92)(char (+ i 32))(if(b i 96 123)(char (+ i -32)) %))) (first *command-line-args*))))

Ungolfed:

(defn b[i x y] (if (and(> i x)(< i y)) true false))
(print (apply str (map 
        #(let [i (int %)] (if (b i 64 92) 
                             (char (+ i 32)) 
                             (if (b i 96 123) (char (+ i -32)) %))) 
        (first *command-line-args*))))
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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