In this challenge you and your friends are debating on which case is better, uppercase or lowercase? To find out, you write a program to do this for you.

Because esolangs scare your friends, and verbose code scares you, your code will need to be as short as possible.


PrOgRaMiNgPuZzLeS & CoDe GoLf
0.52 uppercase

0.58 uppercase

Foo BaR Baz
0.56 lowercase


The input will consist only of ASCII characters. All non-alphabetic characters should be ignored. There will be at least 1 character of each case

The output should be the amount of the case that appears the most often over the total amount of alphabetic characters. It should be a decimal accurate to at least 2 decimal places. If uppercase appears more often, the output should end with uppercase, or lowercase.

There will never the the same amount of uppercase and lowercase characters.

  • 7
    \$\begingroup\$ Esolangs do not scare my friends. Does that mean my code can be wildly verbose? \$\endgroup\$ – Alex A. Dec 25 '15 at 17:21
  • \$\begingroup\$ @AlexA. verbose code scares you, so your code will also need to be golfed. \$\endgroup\$ – Downgoat Dec 25 '15 at 17:22
  • 16
    \$\begingroup\$ Oh right, I had forgotten about my recurring Java nightmares. \$\endgroup\$ – Alex A. Dec 25 '15 at 17:23
  • 4
    \$\begingroup\$ Will there be input with only one case? \$\endgroup\$ – manatwork Dec 25 '15 at 18:02
  • 1
    \$\begingroup\$ Does "accurate to at least 2 decimal places" require at least two decimals to be printed, or can a second decimal of zero be left out? \$\endgroup\$ – hvd Dec 25 '15 at 23:03

37 Answers 37


Pyth - 40 bytes

This is the first time i've ever used vectorized string formatting which is pretty cool.

Kml-zrzd2eS%Vm+cdsK" %sercase"Kc"upp low

Test Suite.


JavaScript (ES6) 87 bytes

Edit 1 byte saved thx ETHProductions
Edit 1 more byte saved thx l4me

An anonymous function. Long, but I didn't find a way to golf this more

s=>(l=t=0,s.replace(/[a-z]/ig,c=>l+=++t&&c>'Z'),l/=t,l<.5?1-l+' upp':l+' low')+'ercase'

Less golfed

s=>( // arrow function returning the value of an expression
  // here I use comma for clarity, 
  // in the golfed version it's all merged in a single expression
  t = 0, // counter for letters
  l = 0, // counter for lowercase letters 
    /[a-z]/ig, // find all alphabetic chars, upper or lowercase
    c => // execute for each found char (in c)
        l += ++t && c>'Z', // increment t, increment l if c is lowercase
  l /= t, // l is the ratio now
  ( l < .5 // if ratio < 1/2
    ? (1-l) +' upp' // uppercase count / total (+" upp")
    : l +' low'     // lowrcase count / total (+" low")
  ) + 'ercase' // common suffix
  • \$\begingroup\$ I believe you could save one byte by using &&` ${t-l>l?1-l/t+'upp':l/t+'low'}ercase` . \$\endgroup\$ – ETHproductions Dec 25 '15 at 18:43
  • \$\begingroup\$ Also, c=>l+=++t&&c>'Z' would work, I think...? \$\endgroup\$ – ETHproductions Dec 25 '15 at 18:47
  • \$\begingroup\$ @ETHproductions your first hint does not seem useful, the second is clever, thx \$\endgroup\$ – edc65 Dec 25 '15 at 19:09
  • 1
    \$\begingroup\$ Can we see the ungolfed version with an explanation? \$\endgroup\$ – Cyoce Dec 26 '15 at 0:46
  • \$\begingroup\$ @Cyoce explanation added - it's simple in fact \$\endgroup\$ – edc65 Dec 26 '15 at 2:26

CJam, 47 45 bytes

q__eu-\_el-]:,_:+df/" low upp"4/.+:e>"ercase"

Try it online.

Not golfing for too long...


q               e# Read input.
__eu-           e# Get only the lowercase characters.
\_el-           e# Get only the uppercase characters.
]:,             e# Get the lengths of the two strings.
_:+             e# Sum of the lengths.
df/             e# Lengths divided by the sum of the lengths.
" low upp"4/.+  e# Append the first number with " low" and the second " upp"
:e>             e# Find the maximum of the two.
"ercase"        e# Output other things.

Japt, 58 bytes

A=Uf"[a-z]" l /Uf"[A-Za-z]" l)>½?A+" low":1-A+" upp" +`ÖÐ

(Note: SE stripped a special char, before Ö, so please click the link to get the proper code)

  • \$\begingroup\$ Nice work! Your first regex (including the dollar signs) can be replaced with "[a-z]", and the second with "A-Za-z". 0.5 is equal to ½. You can also remove the final quotation mark. \$\endgroup\$ – ETHproductions Dec 27 '15 at 16:14
  • \$\begingroup\$ With the mentioned changes and string compression, I get 58: A=Uf"[a-z]" l /Uf"[A-Za-z]" l)>½?A+" low":1-A+" upp" +`\x80ÖÐ You can obtain the raw version of the last three bytes with Oc"ercase. \$\endgroup\$ – ETHproductions Dec 27 '15 at 16:19
  • \$\begingroup\$ @Eth \x80 didn't appear to do anything, and ÖÐ produced "case"... Maybe some invisi-chars that got truncated? Btw, provided my own mod, thanks for the tips \$\endgroup\$ – nicael Dec 27 '15 at 16:56
  • \$\begingroup\$ @ETH Ok, managed to use that invisi-char :) \$\endgroup\$ – nicael Dec 27 '15 at 17:03
  • \$\begingroup\$ Unfortunately, backslashes have to be doubled inside strings for the regex parser to work. In this cases, "\w" simply matches all ws, and "\\w" matches all of A-Za-z0-9_. So I think you'll need to keep "[a-z]". \$\endgroup\$ – ETHproductions Dec 27 '15 at 17:11

R, 133 123 118 108 106 105 104 bytes

Golfed down 10 bytes thanks to @ovs,8 thanks to @Giuseppe, and 10 again thanks to @ngm. At this point it's really a collaborative effort where I provide the bytes and others take them off ;)


Try it online!

  • \$\begingroup\$ shaved off 1 more byte. \$\endgroup\$ – JayCe May 25 '18 at 17:59

MATL, 49 50 bytes

Uses current version (4.1.1) of the language, which is earlier than the challenge.

jt3Y2m)tk=Ymt.5<?1w-YU' upp'h}YU' low'h]'ercase'h


>> matl
 > jt3Y2m)tk=Ymt.5<?1w-YU' upp'h}YU' low'h]'ercase'h
> PrOgRaMiNgPuZzLeS & CoDe GoLf
0.52 uppercase

>> matl
 > jt3Y2m)tk=Ymt.5<?1w-YU' upp'h}YU' low'h]'ercase'h
> Foo BaR Baz
0.55556 lowercase


j                   % input string
t3Y2m)              % duplicate. Keep only letters
tk=Ym               % duplicate. Proportion of lowercase letters
t.5<?               % if less than .5
    1w-             % compute complement of proportion
    YU' upp'h       % convert to string and append ' upp'
}                   % else
    YU' low'h       % convert to string and append ' low' 
]                   % end
'ercase'            % append 'ercase'

Julia, 76 74 bytes

s->(x=sum(isupper,s)/sum(isalpha,s);(x>0.5?"$x upp":"$(1-x) low")"ercase")

This is a lambda function that accepts a string and returns a string. To call it, assign it to a variable.


function f(s::AbstractString)
    # Compute the proportion of uppercase letters
    x = sum(isupper, s) / sum(isalpha, s)

    # Return a string construct as x or 1-x and the appropriate case
    (x > 0.5 ? "$x upp" : "$(1-x) low") * "ercase"

Saved 2 bytes thanks to edc65!

  • 1
    \$\begingroup\$ U can surely save 2 bytes using ercase instead of case \$\endgroup\$ – edc65 Dec 25 '15 at 17:42
  • \$\begingroup\$ @edc65 Great idea, thanks! \$\endgroup\$ – Alex A. Dec 25 '15 at 19:38

Perl 6,  91 70 69 63  61 bytes

{($/=($/=@=.comb(/\w/)).grep(*~&' 'ne' ')/$/);"{$/>.5??$/!!1-$/} {<low upp>[$/>.5]}ercase"} # 91
{$/=m:g{<upper>}/m:g{\w};"{$/>.5??$/!!1-$/} {<low upp>[$/>.5]}ercase"} # 70
{"{($/=m:g{<upper>}/m:g{\w})>.5??$/!!1-$/} {<low upp>[$/>.5]}ercase"} # 69
{"{($/=m:g{<upper>}/m:g{\w})>.5??"$/ upp"!!1-$/~' low'}ercase"} # 63

{"{($/=m:g{<:Lu>}/m:g{\w})>.5??"$/ upp"!!1-$/~' low'}ercase"} # 61


# give it a lexical name
my &code = {...}

.say for (
  'PrOgRaMiNgPuZzLeS & CoDe GoLf',
  'DowNGoAT RiGHtGoAt LeFTGoat UpGoAT',
  'Foo BaR Baz',
0.52 uppercase
0.580645 uppercase
0.555556 lowercase
  • 2
    \$\begingroup\$ Strike-through code blocks? That's something new... \$\endgroup\$ – Bojidar Marinov Dec 26 '15 at 9:34
  • 1
    \$\begingroup\$ Lose 3 chars by swapping ternary for max("0.55 upp","0.45 low"): Try It \$\endgroup\$ – Phil H May 8 '18 at 12:04

C#, 135 bytes


using System.Linq;

Actual function:

string U(string s){var c=s.Count(char.IsUpper)*1F/s.Count(char.IsLetter);return(c>0.5?c+" upp":1-c+" low")+"ercase";}

With explanation:

string U(string s)
    var c = s.Count(char.IsUpper) // count uppercase letters
               * 1F               // make it a float (less bytes than (float) cast)
               / s.Count(char.IsLetter); // divide it by the total count of letters
    return (c > 0.5 
        ? c + " upp"  // if ratio is greater than 0.5, the result is "<ratio> upp"
        : 1 - c + " low") // otherwise, "<ratio> low"
        + "ercase"; // add "ercase" to the output string

Python 2, 114 110 bytes

n=1.*sum('@'<c<'['for c in i)/sum(c.isalpha()for c in i)
print max(n,1-n),'ulpopw'[n<.5::2]+'ercase'
  • 1
    \$\begingroup\$ You can save 2 bytes by replacing ['upp','low'][n<.5] with 'ulpopw'[n<.5::2], and 3 more by replacing [n,1-n][n<.5] with max(n,1-n). \$\endgroup\$ – PurkkaKoodari Dec 26 '15 at 2:32
  • \$\begingroup\$ 106 bytes \$\endgroup\$ – ovs May 8 '18 at 18:13

Mathematica, 139 105 bytes

a=ToString;If[(b=1.#~(c=StringCount)~Alphabet[]/c[#,_?LetterQ])<.5,a[1-b]<>" upp",a@b<>" low"]<>"ercase"&

Verbose code is scary, but I'll have to live with it...


PHP, 140 129 characters

My first round of golf -- not too bad for a 'standard' language, eh? :-)


function f($s){$a=count_chars($s);for($i=65;$i<91;$i++){$u+=$a[$i];$l+=$a[$i+32];}return max($u,$l)/($u+$l).($u<$l?' low':' upp').'ercase';}

Shortened to 129 characters thanks to @manatwork:

function f($s){$a=count_chars($s);for(;$i<26;$u+=$a[$i+++65])$l+=$a[$i+97];return max($u,$l)/($u+$l).' '.($u<$l?low:upp).ercase;}

With comments:

function uclcratio($s)
  // Get info about string, see http://php.net/manual/de/function.count-chars.php
  $array = count_chars($s);

  // Loop through A to Z
  for ($i = 65; $i < 91; $i++) // <91 rather than <=90 to save a byte
    // Add up occurrences of uppercase letters (ASCII 65-90)
    $uppercount += $array[$i];
    // Same with lowercase (ASCII 97-122)
    $lowercount += $array[$i+32];
  // Compose output
  // Ratio is max over sum
  return max($uppercount, $lowercount) / ($uppercount + $lowercount)
  // in favour of which, equality not possible per challenge definition
         . ($uppercount < $lowercount ? ' low' : ' upp') . 'ercase';
  • \$\begingroup\$ Given the $u+=…, I suppose you already have error_reporting on default, so silencing warnings. Then remove some quotes: ' '.($u<$l?low:upp).ercase. \$\endgroup\$ – manatwork Dec 28 '15 at 9:08
  • \$\begingroup\$ If you would have only one statement to repeat by the for, you could remove the braces around it. for($i=65;$i<91;$u+=$a[$i++])$l+=$a[$i+32]; \$\endgroup\$ – manatwork Dec 28 '15 at 9:22
  • \$\begingroup\$ With the price of another warning, you can spare the for control variable initialization by looping 0..26 instead of 65..91: for(;$i<26;$u+=$a[$i+++65])$l+=$a[$i+97]; \$\endgroup\$ – manatwork Dec 28 '15 at 9:30
  • \$\begingroup\$ Wow, thank you @manatwork, I didn't know how tolerant PHP is! :D The second one is very smart. I implemented your ideas, bringing the count to 140-4-5-2 = 129 :-) \$\endgroup\$ – Christallkeks Dec 29 '15 at 13:34

Ruby, 81+1=82

With flag -p,

$_=["#{r=$_.count(a='a-z').fdiv$_.count(a+'A-Z')} low","#{1-r} upp"].max+'ercase'

It's lucky that for numbers between 0 and 1, lexicographic sorting is the same as numeric sorting.


Common Lisp, 132 bytes

(setq s(read-line)f(/(count-if'upper-case-p s)(count-if'alpha-char-p s)))(format t"~f ~aercase"(max f(- 1 f))(if(> f .5)"upp""low"))

Try it online!

  • \$\begingroup\$ In the test 0.52 is uppercase not lowercase... \$\endgroup\$ – user58988 Dec 29 '18 at 20:55
  • 1
    \$\begingroup\$ @RosLuP, corrected, thanks a lot! \$\endgroup\$ – Renzo Dec 30 '18 at 9:57

Seriously, 58 bytes

" upp"" low"k"ercase"@+╗,;;ú;û+∩@-@-;l@ú@-l/;1-k;i<@╜@ZEεj

Hex Dump:


It only works on the downloadable interpreter...the online one is still broken.


" upp"" low"k"ercase"@+╗                                    Put [" lowercase"," uppercase"]
                                                            in reg0
                        ,;;ú;û+∩@-@-                        Read input, remove non-alpha
                                    ;l@                     Put its length below it
                                       ú@-                  Delete lowercase
                                          l                 Get its length
                                           /                Get the ratio of upper/total
                                            ;1-k            Make list [upp-ratio,low-ratio]
                                                ;i<         Push 1 if low-ratio is higher
                                                   @        Move list to top
                                                    ╜@Z     Zip it with list from reg0
                                                       E    Pick the one with higher ratio
                                                        εj  Convert list to string.

Pyth, 45 bytes


Try it online. Test suite.


             rBG1               pair of alphabet, uppercase alphabet
    .e                          map k, b over enumerate of that:
      ,                           pair of
           b                          lowercase or uppercase alphabet
        /Lz                           counts of these characters in input
       s                              sum of that
            k                         0 for lowercase, 1 for uppercase
   K                            save result in K
 eS                             sort the pairs & take the larger one
A                               save the number of letters in and the 0 or 1 in H

s[                              print the following on one line:
  cG                              larger number of letters divided by
    shMK                            sum of first items of all items of K
                                    (= the total number of letters)
        d                         space
         ?H"upp""low"             "upp" if H is 1 (for uppercase), otherwise "low"
                     "ercase      "ercase"

CoffeeScript, 104 characters

 (a)->(r=1.0*a.replace(/\W|[A-Z]/g,'').length/a.length)&&"#{(r>.5&&(r+' low')||(1-r+' upp'))+'ercase'}"

coffeescript was initially trying to pass the intended return value as an argument to the "r" value, which failed and was super annoying because r was a number, not a function. I got around it by placing an && between the statements to separate them.


Pyth, 54 53

One byte saved thanks to @Maltysen


Try it online

K0                  " Set K to 0
                    " (Implicit: Set Z to 0)

Vz                  " For all characters (V) in input (z):
  I}NG              " If the character (N) is in (}) the lowercase alphabet (G):
    =hZ             " Increment (=h) Z
  )                 " End statement
  I}NrG1            " If the character is in the uppercase alphabet (rG1):
    =hK             " Increment K
;                   " End all unclosed statements/loops

c                   " (Implicit print) The division of
  e                 " the last element of
    S,ZK           " the sorted (S) list of Z and K (this returns the max value)
+ZK                 " by the sum of Z and K

+                   " (Implicit print) The concatenation of
  ?>ZK"low""upp"    " "low" if Z > K, else "upp"
  "ercase"          " and the string "ercase".
  • \$\begingroup\$ ,<any><any> is a two arity command that is the same as [<any><any>) which can save you a byte \$\endgroup\$ – Maltysen Dec 26 '15 at 6:04

Ruby, 97 characters

->s{'%f %sercase'%[(l,u=[/[a-z]/,/[A-Z]/].map{|r|s.scan(r).size}).max.fdiv(l+u),l>u ?:low: :upp]}

Sample run:

2.1.5 :001 > ['PrOgRaMiNgPuZzLeS & CoDe GoLf', 'DowNGoAT RiGHtGoAt LeFTGoat UpGoAT', 'Foo BaR Baz'].map{|s|->s{'%f %sercase'%[(l,u=[/[a-z]/,/[A-Z]/].map{|r|s.scan(r).size}).max.fdiv(l+u),l>u ?:low: :upp]}[s]}
 => ["0.520000 uppercase", "0.580645 uppercase", "0.555556 lowercase"] 

05AB1E, 28 bytes


Try it online!

ʒ.u}g                        # filter all but uppercase letters, get length.
     ság/                    # Differential between uppercase and input length.
         Dò©                 # Round up store result in register w/o pop.
            _α               # Negated, absolute difference.
              ð              # Push space.
               „Œ„›…         # Push "upper lower"
                    #        # Split on space.
                     'ƒß«    # Concat "case" resulting in [uppercase,lowercase]
                         ®èJ # Bring it all together.

Java 8, 136 130 bytes

s->{float l=s.replaceAll("[^a-z]","").length();l/=l+s.replaceAll("[^A-Z]","").length();return(l<.5?1-l+" upp":l+" low")+"ercase";}

-6 bytes creating a port of @ProgramFOX' C# .NET answer.

Try it online.


s->{                  // Method with String as both parameter and return-type
  float l=s.replaceAll("[^a-z]","").length();
                      //  Amount of lowercase
                      //  Lowercase compared to total amount of letters
  return(l<.5?        //  If this is below 0.5:
          1-l+" upp"  //   Return `1-l`, and append " upp"
         :            //  Else:
          l+" low")   //   Return `l`, and append " low"
        +"ercase";}   //  And append "ercase"

REXX, 144 bytes

say 1/((u+l)/max(u,l)) c.d'ercase'
n:return length(space(translate(a,,arg(1)),0))
  • \$\begingroup\$ 141 bytes \$\endgroup\$ – ovs May 8 '18 at 12:30

Perl 5 -p, 72 bytes


Try it online!


Kotlin, 138 bytes


let{var u=0.0
var l=0.0
"${maxOf(u,l)/(u+l)} ${if(u>l)"upp" else "low"}ercase"}


fun String.y():String =let{var u=0.0
var l=0.0
"${maxOf(u,l)/(u+l)} ${if(u>l)"upp" else "low"}ercase"}

fun main(args: Array<String>) {
    println("PrOgRaMiNgPuZzLeS & CoDe GoLf".y())
    println("DowNGoAT RiGHtGoAt LeFTGoat UpGoAT".y())
    println("Foo BaR Baz".y())

Pyth, 40 39 bytes


Try it here


 m    rBG1                                For the lower and uppercase alphabet...
  l@dQ                                    ... count the occurrences in the input.
J                 cRsJJ                   Convert to frequencies.
               .T,     c2."kw񽙽"          Pair each with the appropriate case.
             eS                           Get the more frequent.
          +jd                    "ercase  Stick it all together.

PowerShell Core, 134128 bytes

Filter F{$p=($_-creplace"[^A-Z]",'').Length/($_-replace"[^a-z]",'').Length;$l=1-$p;(.({"$p upp"},{"$l low"})[$p-lt$l])+"ercase"}

Try it online!

Thanks, Veskah, for saving six bytes by converting the function to a filter!

  • 1
    \$\begingroup\$ You can save two free bytes by making it a filter instead of a function, i.e. filter F(code) \$\endgroup\$ – Veskah May 9 '18 at 2:33
  • \$\begingroup\$ I never knew this was a thing! Thanks, Veskah! \$\endgroup\$ – Jeff Freeman May 9 '18 at 14:10

Tcl, 166 bytes

proc C s {lmap c [split $s ""] {if [string is u $c] {incr u}
if [string is lo $c] {incr l}}
puts [expr $u>$l?"[expr $u./($u+$l)] upp":"[expr $l./($u+$l)] low"]ercase}

Try it online!


APL(NARS), 58 char, 116 bytes



  h "PrOgRaMiNgPuZzLeS & CoDe GoLf"
0.52 uppercase
  h "DowNGoAT RiGHtGoAt LeFTGoat UpGoAT"
0.5806451613 uppercase
  h "Foo BaR Baz"
0.5555555556 lowercase

C, 120 bytes

f(char*a){int m=0,k=0,c;for(;isalpha(c=*a++)?c&32?++k:++m:c;);printf("%f %sercase",(m>k?m:k)/(m+k+.0),m>k?"upp":"low");}

test and result:

{char *p="PrOgRaMiNgPuZzLeS & CoDe GoLf", *q="DowNGoAT RiGHtGoAt LeFTGoat UpGoAT", *m="Foo BaR Baz";


0.520000 uppercase
0.580645 uppercase
0.555556 lowercase

It suppose Ascii character set.

  • \$\begingroup\$ 116 bytes \$\endgroup\$ – ceilingcat Jan 2 '19 at 18:13
  • \$\begingroup\$ @ceilingcat you can update your to that 116 bytes... This 120 bytes for me if is enough... \$\endgroup\$ – user58988 Jan 3 '19 at 10:46

Javascript 80 characters

I'm bad at this but here was my go at Javascript:

a=(s)=>{let a=0,b=0;for(c in s)s[c]==s[c].toUpperCase()?a++:b++;return a/(a+b);}

Readable version:

    let a=0,b=0;
    for(c in s)
    return a/(a+b);

Function is called with: a('hEllO') which outputs 0.4 for example.

I feel like there must be a way to condense the arrow function or something with the words return or toUpperCase that I can do.

  • \$\begingroup\$ I think you also need to mention whether there was more uppercase or lowercase. And you need to print the one of which there was more (so if there's more uppercase than lowercase, you have to print that). \$\endgroup\$ – randomdude999 Oct 22 '19 at 21:35
  • \$\begingroup\$ Oh true... Woops, thanks for the catch \$\endgroup\$ – Justin Nov 22 '19 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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