27
\$\begingroup\$

Given string s of even length as input, randomly capitalize exactly half of the letters.

  • You can assume the input will always be a non-zero, even length
  • You can assume the input will consist of only lowercase letters ([a-z])
  • Exactly half of the letters should be capitalized in the output
  • Every permutation that has exactly half of the characters capitalized should have an equal probability of being output

Scoring

This is so fewest bytes in each language wins!

\$\endgroup\$
1

42 Answers 42

1
2
0
\$\begingroup\$

Python 3, 124 bytes:

import random as r
j=range
f=lambda s:(lambda v:''.join(chr(ord(s[i])-32*(i in v))for i in j(l)))(r.sample(j(l:=len(s)),l//2))
\$\endgroup\$
0
\$\begingroup\$

(new Array(s.length)).fill(0).map((i,j)=> j % 2).sort(() => Math.random() - 0.5).map((i, j) => (i ? s[j].toUpperCase() : s[j])).join("")

\$\endgroup\$
3
  • \$\begingroup\$ This site is for code golf. And shorter answer is better. So you may try to minimize your byte count by at least remove unnecessary space characters. Also, you should include what language you are using and the byte count in the post. And it would be even better if a code snippet or link to online runner is provided so everyone may test your code. \$\endgroup\$
    – tsh
    Commented Dec 2, 2021 at 12:03
  • \$\begingroup\$ How does this take input? It doesn't look like it has input. \$\endgroup\$
    – Wheat Wizard
    Commented Dec 2, 2021 at 12:30
  • 1
    \$\begingroup\$ Welcome to Code Golf! This doesn't actually have a uniform chance of capitalizing the different characters, as .sort(() => Math.random() - 0.5) is a biased way to shuffle. \$\endgroup\$
    – rydwolf
    Commented Dec 2, 2021 at 14:29
0
\$\begingroup\$

Ly, 44 bytes

irysp>l[0f1f,,]p<[>sprl0y?[,sprl]psp<l' *-o]

Try it online!

This one works by generating a list of 0 1 pairs on a list the size of the input string. Then for each input character it reverses the list of 0 1 pairs a random number of times, then pops the top off the resulting stack. That value is used to decide whether or not to capitalize the character before printing it out.

  1. Prep the input strings
ir      - read input codepoints into the stack, reverse the stack
  ysp   - save the number of char, delete that from the stack
     >  - switch to an empty stack
  1. Generate a list of 0 1 pairs
      l[0f1f,,]p
      l[    ,,]p  - loop "n/2" times adding "0,1" pairs to the stack
        0f        - add a "0" to the stack, pull the iterating var forward
          1f      - add a "1" to the stack and pull the iterator forward again
  1. Process each of the input chars on the input stack
<[                         ] - loop until the input stack is empty
  *3.1*                      - get a random 0/1 from the boolean stack
                    <l       - back to input stack, load boolean 0/1 capitalization choice
                      ' *    - multiple " " by the boolean
                         -   - subtract to capitalize (of boolean was true)
                          o  - print the current input char

3.1 Pull a random boolean off the list

>                   - switch to the boolean stack
 sprl               - disrupt pattern on list, move top entry to the bottom
     0y?            - pick a random number between 0 and the stack size
        [,sp l]p    - loop that number of time, using backup cell for iterator val
            r       - reverse the stack
                sp  - save the random boolean to the backup cell
\$\endgroup\$
0
\$\begingroup\$

MathGolf, 14 bytes

δ^hr¥áÅ;v^mÅ~§

I/O as a list of characters.

Try it online.

Explanation:

δ              # Capitalize each character in the (implicit) input-list
               #  e.g. ['a','b','c','d','e'] → ['A','B','C','D','E']
 ^             # Zip it with the (implicit) input-list
               #  → [['a','A'],['b','B'],['c','C'],['d','D'],['e','E']]
  h            # Push the length (without popping)
               #  → 5
   r           # Pop and push a list in the range [0,length)
               #  → [0,1,2,3,4]
    ¥          # Mod-2 on each
               #  → [0,1,0,1,0]
     á         # Sort it by,
      Å        # using the following 2 characters as inner code-block:
       ;       #  Discard the value
        v      #  Push a random integer in the range [-2147483648,2147483647]
               #  e.g. [0,1,0,0,1]
         ^     # Zip these shuffled 0s/1s with the earlier pair of characters
               #  → [[['a','A'],0],[['b','B'],1],[['c','C'],0],[['d','D'],0],[['e','E'],1]]
          m    # Map over each,
           Å   # using 2 characters as inner code-block again:
            ~  #  Dump the pair and integer separated to the stack
             § #  Index the integer into the pair
               #  → ['a','B','c','d','E']
               # (after which the entire stack is output implicitly as result)
\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 160 bytes

Input Str1
length(Str1
Ans/2≥randIntNoRep(1,Ans→S
"abcdefhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ→Str2
".
For(I,1,dim(ʟS
Ans+sub(Str2,inString(Str2,sub(Str1,I,1))+26ʟS(I),1
End
sub(Ans,2,dim(ʟS

Output is stored in Ans and displayed. Only works on calculators that support randIntNoRep(.

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

T-SQL, 142 bytes

SELECT top(len(@)/2)@=stuff(@,number+1,1,upper(substring(@,number+1,1)))FROM
spt_values WHERE number<len(@)and'P'=type
ORDER BY newid()PRINT @

Try it online

This will always give return the same result. In Microsoft SQL Server Management Studio, the result is randomized. The reason could be the explanation below by Fmbalbuena

\$\endgroup\$
1
  • \$\begingroup\$ The "Try it online" is not actual SQL Interpreter, its Stack Exchange Data Explorer Interpreter. \$\endgroup\$
    – Fmbalbuena
    Commented Dec 3, 2021 at 8:53
0
\$\begingroup\$

Clojure, 142 bytes

(defn r[s](let[l(count s)z(apply str(update(vec s)(rand-int l)clojure.string/upper-case))](if(<(count(re-seq #"[A-Z]" z))(/ l 2))(recur z)z))) 

Un-golfed version:

(defn randomly-capitalize-half-of [s]
  (let [v  (vec s)                                 ; convert string s to a vector of characters - e.g. "abcd" becomes [\a \b \c \d]
        l  (count s)                               ; length of string s
        i  (rand-int l)                            ; choose a random index from 0 to (length of s)-1
        v2 (update v i clojure.string/upper-case)  ; convert character at index i in v to upper case
        s2 (apply str v2)                          ; collapse vector-of-characters to a single string
        c  (count (re-seq #"[A-Z]" s2)) ]          ; count number of upper-case letters in s2
    (if (< c (/ l 2))                              ; if count of upper-case letters < 1/2 of length of s
      (recur s2)                                   ;   then recursively invoke randomly-capitalize with partially-upcased string as input
      s2)))                                        ;   else return half-uppercased string  
\$\endgroup\$
0
\$\begingroup\$

x86_64 machine code, 33 bytes

\x89\xf1\x0f\xc7\xf0\x73\xfb\x31\xd2\xf7\xf6\xf6\x04\x17
\x20\x74\xf1\x80\x24\x17\xdf\x83\xe9\x02\x75\xe8\xc3

Try it online!

It uses the hardware random generator rdrand, which is very slow BTW.

original assembly (nasm)

f: ; rdi = string, rsi = number of characters, SysV calling convention
    mov ecx, esi
.loop:
    rdrand eax
    jnc .loop
    xor edx, edx
    div esi
    test byte [rdi + rdx], 0x20
    jz .loop
    and byte [rdi + rdx], 0xdf
    sub ecx, 2
    jnz .loop
    ret
\$\endgroup\$
0
\$\begingroup\$

JavaScript (V8), 88 86 bytes

f=s=>(r=s.replace(/./g,c=>Math.random()>.5?c:c.toUpperCase(a+=2),a=0)).length-a?f(s):r

Try it online!

This was my first submission on the site! I got my second Yearling badge today so I thought I'd come back and golf some of my earliest submissions.

Explanation:

f=s=>                     // function f taking string argument s
  (r=                     //   assign variable r to
    s.replace(/./g,c=>    //     s with each character c mapped to:
      Math.random()>.5    //       random true/false
        ?c                //       if true, leave c unchanged
        :c.toUpperCase(a+=2), //   else, uppercase c, and add 2 to a
      a=0                 //     a defaults to 0
    ))                    //   end assignment
  .length-a               //   (length of r) - a
    ?f(s)                 //   if nonzero, start over
    :r                    //   else, return r
\$\endgroup\$
1
0
\$\begingroup\$

Swift, 103 bytes

let f={zip($0+"",(0..<$0.count).shuffled().map{$0%2<1}).map{(x,y)in y ?x.uppercased():"\(x)"}.joined()}
\$\endgroup\$
0
\$\begingroup\$

JavaScript (Node.js), 72 bytes

s=>Buffer(s).map(c=>Math.random()<n/l--/2?(n-=2,c-32):c,n=l=s.length)+''

Try it online!

Basic idea: To Choose \$n\$ items from \$l\$ candidates, each item have \$\frac{n}{l}\$ probability to be chosen. And once the first item is chosen, we need to choose \$n-1\$ items from remaining \$l-1\$ candidates. If the first item is not chosen, we need to choose \$n\$ items from remaining \$l-1\$ candidates.

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

Japt, 10 bytes

I/O as a character array

ímUîuiv)ö¬

Try it

ð ö¬ígUËpu

Try it

\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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