# Ratio of Uppercase Letters to Lowercase

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.

## Examples

PrOgRaMiNgPuZzLeS & CoDe GoLf
0.52 uppercase

DowNGoAT RiGHtGoAt LeFTGoat UpGoAT
0.58 uppercase

Foo BaR Baz
0.56 lowercase


## Specifications

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.

• Esolangs do not scare my friends. Does that mean my code can be wildly verbose? – Alex A. Dec 25 '15 at 17:21
• @AlexA. verbose code scares you, so your code will also need to be golfed. – Downgoat Dec 25 '15 at 17:22
• Oh right, I had forgotten about my recurring Java nightmares. – Alex A. Dec 25 '15 at 17:23
• Will there be input with only one case? – manatwork Dec 25 '15 at 18:02
• 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? – hvd Dec 25 '15 at 23:03

# 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


# 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
s.replace(
/[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
)

• I believe you could save one byte by using && ${t-l>l?1-l/t+'upp':l/t+'low'}ercase . – ETHproductions Dec 25 '15 at 18:43 • Also, c=>l+=++t&&c>'Z' would work, I think...? – ETHproductions Dec 25 '15 at 18:47 • @ETHproductions your first hint does not seem useful, the second is clever, thx – edc65 Dec 25 '15 at 19:09 • Can we see the ungolfed version with an explanation? – Cyoce Dec 26 '15 at 0:46 • @Cyoce explanation added - it's simple in fact – 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... ### Explanation 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) • 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. – ETHproductions Dec 27 '15 at 16:14 • 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. – ETHproductions Dec 27 '15 at 16:19 • @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 – nicael Dec 27 '15 at 16:56 • @ETH Ok, managed to use that invisi-char :) – nicael Dec 27 '15 at 17:03 • 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]". – 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 ;) function(x)cat(max(U<-mean(utf8ToInt(gsub('[^a-zA-Z]',"",x))<91),1-U),c("lowercase","uppercase")[1+2*U])  Try it online! • shaved off 1 more byte. – 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  ### Examples >> 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  ### Explanation 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. Ungolfed: 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" end  Saved 2 bytes thanks to edc65! • U can surely save 2 bytes using ercase instead of case – edc65 Dec 25 '15 at 17:42 • @edc65 Great idea, thanks! – 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  Usage: # give it a lexical name my &code = {...} .say for ( 'PrOgRaMiNgPuZzLeS & CoDe GoLf', 'DowNGoAT RiGHtGoAt LeFTGoat UpGoAT', 'Foo BaR Baz', )».&code;  0.52 uppercase 0.580645 uppercase 0.555556 lowercase  • Strike-through code blocks? That's something new... – Bojidar Marinov Dec 26 '15 at 9:34 • Lose 3 chars by swapping ternary for max("0.55 upp","0.45 low"): Try It – Phil H May 8 '18 at 12:04 # C#, 135 bytes Requires: 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 i=input() 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'  • 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). – PurkkaKoodari Dec 26 '15 at 2:32 • 106 bytes – 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? :-) Original: 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'; }  • Given the $u+=…, I suppose you already have error_reporting on default, so silencing warnings. Then remove some quotes: ' '.($u<$l?low:upp).ercase. – manatwork Dec 28 '15 at 9:08
• 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]; – manatwork Dec 28 '15 at 9:22
• 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]; – manatwork Dec 28 '15 at 9:30 • 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 :-) – 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!

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

# Gema, 125 characters

\A=@set{l;0}@set{u;0}
<J1>=@incr{l}
<K1>=@incr{u}
?=
\Z=0.@div{@cmpn{$l;$u;$u;;$l}00;@add{$l;$u}} @cmpn{$l;$u;upp;;low}ercase


Sample run:

bash-4.3$for input in 'PrOgRaMiNgPuZzLeS & CoDe GoLf' 'DowNGoAT RiGHtGoAt LeFTGoat UpGoAT' 'Foo BaR Baz'; do > gema '\A=@set{l;0}@set{u;0};<J1>=@incr{l};<K1>=@incr{u};?=;\Z=0.@div{@cmpn{$l;$u;$u;;$l}00;@add{$l;$u}} @cmpn{$l;$u;upp;;low}ercase' <<< "$input"
>     echo " <- $input" > done 0.52 uppercase <- PrOgRaMiNgPuZzLeS & CoDe GoLf 0.58 uppercase <- DowNGoAT RiGHtGoAt LeFTGoat UpGoAT 0.55 lowercase <- Foo BaR Baz  • -1 because esolangs scare your friends. (jk, upvoted) – ev3commander Dec 25 '15 at 21:43 ## Seriously, 58 bytes " upp"" low"k"ercase"@+╗,;;ú;û+∩@-@-;l@ú@-l/;1-k;i<@╜@ZEεj  Hex Dump: 22207570702222206c6f77226b2265726361736522402bbb2c3b3ba33b 962bef402d402d3b6c40a3402d6c2f3b312d6b3b693c40bd405a45ee6a  It only works on the downloadable interpreter...the online one is still broken. Explanation: " 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 AeSK.e,s/LzbkrBG1s[cGshMKd?H"upp""low""ercase  ### Explanation  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 and 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 K0VzI}NG=hZ)I}NrG1=hK;ceS,ZK+ZK+?>ZK"low""upp""ercase  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".  • ,<any><any> is a two arity command that is the same as [<any><any>) which can save you a byte – 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 ʒ.u}gság/Dò©_αð„Œ„›…#'ƒß«®èJ  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. Explanation: s->{ // Method with String as both parameter and return-type float l=s.replaceAll("[^a-z]","").length(); // Amount of lowercase l/=l+s.replaceAll("[^A-Z]","").length(); // 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 a=arg(1) l=n(upper(a)) u=n(lower(a)) c.0='upp';c.1='low' d=u<l say 1/((u+l)/max(u,l)) c.d'ercase' n:return length(space(translate(a,,arg(1)),0))  • 141 bytes – ovs May 8 '18 at 12:30 # Perl 5-p, 72 bytes $_=(($u=y/A-Z//)>($l=y/a-z//)?$u:$l)/($u+$l).$".($u>$l?upp:low).'ercase'  Try it online! # Kotlin, 138 bytes ## Code let{var u=0.0 var l=0.0 forEach{when{it.isUpperCase()->u++ it.isLowerCase()->l++}} "${maxOf(u,l)/(u+l)} ${if(u>l)"upp" else "low"}ercase"}  ## Usage fun String.y():String =let{var u=0.0 var l=0.0 forEach{when{it.isUpperCase()->u++ it.isLowerCase()->l++}} "${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 Jml@dQrBG1+jdeS.T,cRsJJc2."kw񽙽""ercase  Try it here ### Explanation Jml@dQrBG1+jdeS.T,cRsJJc2."kw񽙽""ercase 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!

• You can save two free bytes by making it a filter instead of a function, i.e. filter F(code) – Veskah May 9 '18 at 2:33
• I never knew this was a thing! Thanks, Veskah! – 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

{m←+/⍵∊⎕A⋄n←+/⍵∊⎕a⋄∊((n⌈m)÷m+n),{m>n:'upp'⋄'low'}'ercase'}


test:

  h←{m←+/⍵∊⎕A⋄n←+/⍵∊⎕a⋄∊((n⌈m)÷m+n),{m>n:'upp'⋄'low'}'ercase'}
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:

main()
{char *p="PrOgRaMiNgPuZzLeS & CoDe GoLf", *q="DowNGoAT RiGHtGoAt LeFTGoat UpGoAT", *m="Foo BaR Baz";
f(p);printf("\n");f(q);printf("\n");f(m);printf("\n");
}


results

0.520000 uppercase
0.580645 uppercase
0.555556 lowercase


It suppose Ascii character set.

• 116 bytes – ceilingcat Jan 2 at 18:13
• @ceilingcat you can update your to that 116 bytes... This 120 bytes for me if is enough... – RosLuP Jan 3 at 10:46