Passwordify the string

Labyrinth, 76 bytes

 `:_64/"32}
,`    (3  :=-{
"`{"; _v2$  ;`3
"`".:@ ; ".5(`3.
<       "" `^`;>

Another collab with @MartinBüttner and on the more insane side of the Labyrinth spectrum – for the first time we have all four of ^>v< in the one program. Try it online!

Explanation

The general algorithm, which runs in a loop, is as follows:

 1.   Read a char
 2.   If EOF:
 3.     Move all digits from auxiliary stack to main
 4.     Output all digits on main stack
 5.     Halt
      Otherwise:
 6.     If char is a letter (c >= 64):
 7.       If random turns left:
 8.         Output char XOR 32
          Otherwise:
 9.         Output char
        Otherwise:
10.       Shift char to auxiliary stack
11.       If char is space (c-32 == 0):
12.         Pull char back from auxiliary stack
13.         Output underscore
          Otherwise:
14.         Continue loop

To keep the explanation compact, here's roughly how each part of the program corresponds to the pseudocode above:

enter image description here

Here are the interesting parts.

Getting randomness in Labyrinth

There's only one way to get randomness in Labyrinth, and it's when the IP tries to go forwards but 1) there's neither a path forwards nor backwards and 2) there's paths available left and right. In this case, the IP randomly chooses between the left and right routes.

This is only possible using the^>v< operators, which pop n and shift the row/column n away by 1. For example, the program (Try it online!)

" 1
""v!@
  2
   !@

outputs either 1 or 2 randomly, since the v shifts the column with offset 0 (i.e. the column the IP is on) by 1, yielding

"
""1!@
  v
  2!@

The IP is facing rightward and tries to go forwards (top of stack is zero) but can't. It also can't move backwards, so it randomly chooses between left or right.

Golf tricks

  • The program starts from the first char in reading order, which you'll notice is actually step 6. However, popping from an empty Labyrinth stack yields 0, so steps 10 and 14 occur, shifting a zero to the auxiliary stack, which is effectively a no-op.

  • The main stack is effectively empty after every iteration, which allows us to golf the code layout by using > and < on the implicit zeroes at the bottom. The > wraps the bottom row around so that the IP moves from the bottom right to the bottom left, and the < shifts the row back. The IP then happily moves up the left column to continue the loop.

  • Digits in Labyrinth pop n and push 10*n + <digit>. In addition, chars are taken modulo 256 before being output. Putting these two together lets us output 95 (underscore) by doing `33 to 32 (space), which works because -3233 % 256 = 95. Even though there are other ways to turn 32 into 95 (;95 being the easiest), working with a negative number here allows us to compact the code a bit with left turns.


Pyth, 15 bytes

s}D`MTrRO2Xzd\_

Demonstration

s}D`MTrRO2Xzd\_
                   Implicit: z = input(), d = ' '
          Xzd\_    In z, replace ' ' with '_'.
      rR           To each character, apply r-function
        O2         Randomly 0 or 1. r 0 is lowercase, r 1 is uppercase.
 }D                Order the characters based on presence in
   `MT             The strings of the numbers 0 to 9.
s                  Concatenate into a string.

05AB1E, 22 21 20 bytes

Code:

þ¹žh-s«ð'_:vyždÈiš}?

Uses CP-1252 encoding.

Try it online!