10
\$\begingroup\$

yOu wiLl bE giVen A sTriNg wHich cOnsiSts oF pRintAble asCii cHarActErs.

yOu iTeraTe tHrougH thE sTrIng tHen chAnge rAndOM(uNifoRm, 50% cHanCe uPPercAse) lEtteRs to uPPercAse aNd eVerytHing elSe tO lOwercAse.

tHat'S iT.

(sorry for the punctuation, it was for the concept of the question)

Readable version:

You will be given a string which consists of printable ASCII characters.

You iterate through the string and change random(uniform, 50% chance uppercase) letters to uppercase, and everything else to lowercase.

that's it.

exaMplEs

iNpuT => pOssiBle oUtPUt
Programming puzzles and Code Golf => pRogRaMMiNg pUzzlEs aNd coDe goLf
dErpity deRp derP => deRpiTy dErp DerP
CAAAPSLOOOCK => cAAapslOoocK
_#$^&^&* => _#$^&^&*
\$\endgroup\$
11
  • 2
    \$\begingroup\$ What does "randomly" mean exactly? Can there be two consecutive capital letters (your test cases don't have any such configurations)? I'd say this question is underspecified in its current state, but I'm not going to vote on it yet. Please specify these two things. \$\endgroup\$
    – hyper-neutrino
    Apr 7, 2017 at 16:02
  • \$\begingroup\$ Is time%2 allowed for pseudorandomness? \$\endgroup\$ Apr 7, 2017 at 16:06
  • \$\begingroup\$ @fəˈnɛtɪk Sure (if it is uniform) \$\endgroup\$ Apr 7, 2017 at 16:08
  • 2
    \$\begingroup\$ you say printable ASCII, but your test cases only include alphabetic characters. Should the program be able to deal with non-alphabetic characters, or can we expect the input to be purely alphabetic? \$\endgroup\$ Apr 7, 2017 at 16:59
  • 5
    \$\begingroup\$ I think most of the existing answers also assume that the decision is independent for each letter, but that's nowhere in the question. At present I think it would technically be compatible with the spec to write something along the lines of (pseudocode) s=>rand()%2?s.upper():s.lower() \$\endgroup\$ Apr 7, 2017 at 21:02

21 Answers 21

10
\$\begingroup\$

C – 65 bytes

Pretty good for a mainstream language!

main(c){while((c=getchar())>0)putchar(isalpha(c)?c^rand()&32:c);}

Uses XOR to randomly flip the bit at 0x20 for each alphabetic character. Program assumes ASCII character set and that EOF < 0.

Sample run on its own source!

$ main < main.c
MaIN(c){WhILe((C=GETChAr())>0)pUtCHaR(iSALpha(C)?C^rANd()&32:C);}

Very derpy.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ "Pretty good for a mainstream language!" - C is often surprisingly good for golfing. \$\endgroup\$
    – Steadybox
    Apr 8, 2017 at 22:03
7
\$\begingroup\$

JavaScript, 87 bytes

function(s){return s.replace(/./g,c=>Math.random()<.5?c.toLowerCase():c.toUpperCase())}

68 bytes in ES6:

f=
s=>s.replace(/./g,c=>c[`to${Math.random()<.5?`Low`:`Upp`}erCase`]())
<input oninput=o.textContent=f(this.value)><pre id=o>

\$\endgroup\$
4
  • \$\begingroup\$ the second code does work but the first one: Uncaught SyntaxError: Unexpected token ( \$\endgroup\$ Apr 8, 2017 at 2:20
  • \$\begingroup\$ @FeloVilches You have to use it in an expression context for it to work, otherwise the engine tries to parse it as a function statement. \$\endgroup\$
    – Neil
    Apr 8, 2017 at 9:43
  • \$\begingroup\$ Can be shortened using ES6. \$\endgroup\$ Jul 10, 2017 at 18:00
  • \$\begingroup\$ @CalculatorFeline To 68 bytes, no doubt? \$\endgroup\$
    – Neil
    Jul 10, 2017 at 18:34
5
\$\begingroup\$

Jelly, 6 bytes

,ŒsXµ€

Try it online!

How?

Lower casing all chars of the input and then uppercasing each with 50% probability is the same as choosing one of the original char and the swapped-case char with equal probability...

,ŒsXµ€ - Main link: string s
    µ  - monadic chain separation
     € - for each char c in s
,      -     pair c with
 Œs    -     swapped case of c
   X   -     choose a random item from the list (of the two chars)
       - implicit print
\$\endgroup\$
4
  • \$\begingroup\$ Ohh. Clever interpretation of the challenge. \$\endgroup\$ Apr 7, 2017 at 16:22
  • \$\begingroup\$ By the way: is this uniform? \$\endgroup\$ Apr 7, 2017 at 16:25
  • \$\begingroup\$ @SIGSEGV If by "uniform" you mean each char has a 50% chance of being each case then yes - X is implemented using Python's random.choice, so when presented with a list of 2 chars will pick each with 50% probability - every char in the input produces such a list (non-alphabetic chars will be a list of 2 equal chars, but that does not matter if the interpretation of "uniform" above is correct). \$\endgroup\$ Apr 7, 2017 at 16:34
  • \$\begingroup\$ Here is an example of line feed separated lists from which one char of each would be chosen. \$\endgroup\$ Apr 7, 2017 at 16:38
5
\$\begingroup\$

PowerShell, 64 60 bytes

-join([char[]]"$args".ToLower()|%{"$_".ToUpper(),$_|random})

Try it online! (make sure that "disable output cache" is checked if you want random results)

Exact translation of the challenge. Takes the input string, ToLower()s it, converts it to a char array, loops through each character |%{...}, and randomly selects between either the existing character or the uppercase variant. Then -joins them all back together into a single string. This works because ToUpper and ToLower only affect alphabetical characters, leaving punctuation and the like unchanged.

(Dennis fixed the alias list on TIO so that Random isn't trying Linux random but correctly aliases to Get-Random as a PowerShell command, as it should. Thanks, Dennis!)

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

MATL, 13 12 bytes

"@ktXkhlZr&h

Try it at MATL Online

Explanation

        % Implicitly grab input as a string
"       % For each character...
  k     % Convert to lowercase
  tXk   % Make a copy and convert to uppercase
  h     % Horizontally concatenate these two characters
  lZr   % Randomly select one of them
  &h    % Horizontal concatenate the entire stack
        % Implicit end of for loop and implicit display
\$\endgroup\$
4
\$\begingroup\$

Japt, 10 bytes

®m"uv"gMq2

Try it online!

Explanation

So this is kind of a cheesy hack, but it works. In JavaScript you can do something like

x[`to${Math.random()<.5?"Upp":"Low"}erCase`]()

to randomly convert x to upper- or lowercase. In Japt, the equivalent functions are u for toUpperCase and v for toLowerCase. But in Japt there is no direct way to get a calculated property value (x[expression] in JavaScript).

One of my favorite features of Japt is that if you have a function which is composed of a single method call (e.g. mX{Xq}, or .m(X=>X.q()) in JS), you can leave out everything except the name of the method, e.g. mq. The compiler then turns this into a string which gets passed to the original method call (.m("q")), and the method turns this back into a function. So there's no difference between mq and m"q"; both produce the same output.

Now, where I was going with this: while we can't directly call a random method on a string, we can call m on that string with a random method name. So, for the explanation:

®m"uv"gMq2
®           // Replace each char in the input by this function:
 m          //   Replace each char in this char by this function:
      g     //     the char at index
       Mq2  //       random integer in [0,2)
  "uv"      //     in "uv".
            //   This randomly calls either .u() or .v() on the char.
            // Implicit: output result of last expression
\$\endgroup\$
2
  • \$\begingroup\$ Doesn't Mq default to 2? Or was that recently added? \$\endgroup\$
    – Oliver
    Jul 10, 2017 at 18:00
  • \$\begingroup\$ @obarakon I think that was more recent. A quick search on GitHub says it was May 5 \$\endgroup\$ Jul 10, 2017 at 18:49
4
\$\begingroup\$

PHP, 53 Bytes

for(;a&$c=$argn[$i++];)echo(lu[rand()&1].cfirst)($c);
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Nice trick w/ the strto.*.er. :) \$\endgroup\$ Apr 7, 2017 at 18:46
  • 1
    \$\begingroup\$ Save a byte w/ rand()&1 \$\endgroup\$ Apr 7, 2017 at 18:46
  • 1
    \$\begingroup\$ Save a bunch of bytes by using foreach(str_split($argv[1]as$c)... instead of array indexing. \$\endgroup\$ Apr 7, 2017 at 18:48
2
\$\begingroup\$

Perl 5, 26 bytes

25 bytes + -p flag.

s/./rand 2&1?uc$&:lc$&/ge

Try it online!

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

Perl 6,  32  29 bytes

{[~] .comb.map:{(.lc,.uc).pick}}

Try it

{S:g/./{($/.uc,$/.lc).pick}/}

Try it

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

Python 2, 77 74 bytes

lambda s:"".join(map(choice,zip(s.upper(),s.lower())))
from random import*

Try it online!

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

Japt, 12 10 bytes

£M¬?Xv :Xu

Explanation:

£M¬?Xv :Xu
£             // Iterate through the input. X becomes the iterative item
 M¬           // Return a random number, 0 or 1
    ?         // If 1:
     Xv       //   X becomes lowercase
        :     // Else:
         Xu   //   X becomes uppercase 

Try it online!

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

MATL, 12 11 bytes

1 byte removed using Jonathan Allan's idea of directly changing case.

"@rEk?Yo]&h

Try at MATL online!

Explanation

"         % Implicit input. For each
  @       %   Push current char
  r       %   Random number uniformly distributed on (0,1)
  Ek      %   Duplicate, floor: gives 0 or 1 with the same probability
  ?       %   If nonzero
    Yo    %     Change case. Leaves non-letters unaffected
  ]       %   End
  &h      %   Horizontally concatenate evverything so far
          % Implicit end and display
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 8 bytes

vyDš‚.RJ

Try it online!

Explanation

v          # for each char y in input
 yDš‚      # pair lower-case y with upper-case y
     .R    # pick one at random
       J   # join to string
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 77 bytes

x=>x.toLowerCase().split``.map(y=>Math.random()*2|0?y:y.toUpperCase()).join``

Try it online!

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

CJam, 14 bytes

qel{2mr{eu}&}%

Try it online!

Explanation

q               e# Read the input
 el             e# Make it lowercase
   {            e# For each character in it
    2mr         e#  Randomly choose 0 or 1
       {eu}&    e#  If 1, make the character uppercase
            }%  e# (end of block)
\$\endgroup\$
1
\$\begingroup\$

Pyth, 5 bytes

srLO2

Test suite

srLO2
srLO2Q    Variable introduction
  L  Q    Map over the input
 r        Set the case of each character to 
   O2     Random number from [0, 1]. 0 means lowercase, 1 means uppercase.
s         Concatenate
\$\endgroup\$
1
\$\begingroup\$

Befunge, 136 bytes

>~:0`!#@_:"@"`!#v_:"Z"`!#v_:"`"`!#v_:"z"`!#v_,
^,<    <        <                 <
 >?<                     <             -*84<
  >84*+^

Try it online!

There is a lot of whitespace that I think is possible to get rid of. Befunge doesn't have a way of figuring out what's a letter and what isn't, so this is what I'm doing on the first row.

\$\endgroup\$
3
  • \$\begingroup\$ This snippet is a faster way of checking if the top value of the stack is a letter - pushes a 0 if it is, and a 1 if it isn't. It's a lot shorter to "and" conditions together by multiplying them instead of using a bunch of if statements routing to the same place \$\endgroup\$ Apr 8, 2017 at 2:26
  • \$\begingroup\$ I don't understand how that works. When I run it, it always gives me a 0, and it doesn't accept any input. \$\endgroup\$
    – user55852
    Apr 9, 2017 at 4:04
  • \$\begingroup\$ Sorry, in that program you put the value in the first quotation marks. In retrospect, this is a really dumb way to do that. It should be pretty easy to change the first three characters to a ~ \$\endgroup\$ Apr 10, 2017 at 21:58
0
\$\begingroup\$

Bash, 64 bytes

first try

a=$(shuf -e -n 13 {A..Z}|tr -d "\n");b=${a,,};tr $b $a <<<${1,,}

Try it online!

shuffles capital letters, takes first 13, removes newlines and saved to $a. $b holds $a to lowercase. input is set to lowercase by ${1,,} and passed as a heredoc to tr which replaces each ocurrence of $b by $a

This is somewhat non compeating because the same letter is always capitalized.

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

JavaScript + HTML, 115 bytes

<input oninput="this.value=this.value.toLowerCase().split('').map(v=>Math.random()<.5?v.toUpperCase():v).join('')">

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

Bash, 162 Bytes

a=$1
b=1
c="echo $a|head -c$b|tail -c1"
while(($b<=${#a}))
do
r=$[RANDOM%2]
if [ $r = 1 ]
then d=$(eval $c);echo -n ${d^}
else echo -n $(eval $c)
fi
b=$[b+1]
done

Pretty self explanatory. Takes input from command line arg, writes to stdout.

Run like derpifier.sh "Derp this"

Man, once I start applying the tips the code shrinks fast.

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

Swift - way too many bytes (176 167)

uppercased(),lowercased(),arc4random_uniform() really kill the score, besides for me having to add a function since Swift has no standard input method!

import Foundation
func g(x:String){var result="";for i in x.characters{let e=String(i);result+=(arc4random_uniform(2)>0 ?e.uppercased():e.lowercased())};print(result)}

Function with usage: print(g(x: "Your String Here"))

\$\endgroup\$

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