32
\$\begingroup\$

Introduction

How much of the English alphabet does a given string use? The previous sentence uses 77%. It has 20 unique letters (howmucftenglisapbdvr), and 20/26 ≃ 0.77.

Challenge

For an input string, return the percentage of letters of the English alphabet present in the string.

  • The answer can be in percentage or in decimal form.

  • The input string can have upper and lower case, as well as punctuation. However you can assume they have no diacritics or accentuated characters.

Test cases

Input

"Did you put your name in the Goblet of Fire, Harry?" he asked calmly.

Some valid outputs

77%, 76.9, 0.7692

Input:

The quick brown fox jumps over the lazy dog

All valid outputs:

100%, 100, 1

The expected output for "@#$%^&*?!" and "" is 0.

\$\endgroup\$
  • 3
    \$\begingroup\$ Suggested test cases: "@#$%^&*?!", "" \$\endgroup\$ – Adám Jun 21 at 10:35
  • 4
    \$\begingroup\$ If 77% and 76.9 is accepted, is 77 accepted too? \$\endgroup\$ – Grzegorz Oledzki Jun 21 at 10:43
  • \$\begingroup\$ Percentages can have decimal parts too... \$\endgroup\$ – Jo King Jun 21 at 11:54
  • 2
    \$\begingroup\$ @Shaggy Last edit for OP was 16 hours ago, your answer was at 15 and your comment at 14. I mean, you're right but ??? \$\endgroup\$ – Veskah Jun 22 at 4:16
  • 6
    \$\begingroup\$ If 20/26 may be rounded to 0.7692, 0.769 or 0.77, can I also round it to 0.8, 1 or 0? ;-) \$\endgroup\$ – Noiralef Jun 22 at 22:42

47 Answers 47

1
\$\begingroup\$

K4, 14 13 bytes

Solution:

avg .Q.a in _

Explanation:

Rather stolen from inspired by Luis Mendo's Octave solution...

avg .Q.a in _ / the solution
            _ / lowercase the input
         in   / 'in' function
    .Q.a      / "abcdefghijklmnopqrstuvwxyz"
avg           / average (mean)
\$\endgroup\$
1
\$\begingroup\$

Stax 1.1.4 online interpreter, 8 bytes, noncompeting

äQæ╟r◘Oñ

Run and debug it at staxlang.xyz!

Unpacked (9 bytes) and explanation:

Va%26!/vN
Va           Push the lowercase alphabet
  %          Length...?! Shouldn't this always be 26?
   26!       Push 26.0
      /      Divide
       vN    Subtract from one (decrement and negate)

That shouldn't work. Looking at it, you would expect an output of 0 always. Heck, it doesn't even take input! There's a bug in the online interpreter, however, which I have exploited for this answer.

Now, I've marked this answer noncompeting for a reason. As far as I can tell, this exploit requires some human interaction to set up. Here's what you gotta do:

  • Put your input in the input field
  • Unpack
  • Insert v at the start of the code and |b immediately after Va
  • Run
  • Remove the characters you added to the code
  • Repack

Now you have an 8-byte program that will give the correct output each time you run it! At least until you change the input field or reload the page.

What in the seven hells is going on:

Va%26!/vN
Va           Push the lowercase alphabet, EXCLUDING characters that existed in the input field in either case any time the vVa|b version was run
  %26!/vN    Everything else works as expected

That little bug handles case checking and filtering for free, at the expense of leaving me with the wrong set of letters (wasting two bytes on the vN). I think this can be improved rather easily, but I'm at work right now.

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

Haskell, 52 bytes

f s=sum[1|n<-[0..25],or[elem([c..]!!n)s|c<-"aA"]]/26

Try it online!

Avoids case conversion (which base Haskell lacks) and ASCII-code conversions (which are lengthy) in favor of writing [c..] to enumerate characters. For example, ['A'..] is a very long list that starts with ABCDEFGHI....

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

Ohm v2, 7 bytes

ÁαA}εÆm

Try it online!

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

Pyth, 9 bytes

cl@rw0G26

Try it online!

c      26 # Float division by 26 (alternative: replace 26 by lG)
 l        #   Length of
  @       #     intersection of
   r 0    #       lowercase
    w     #         input
      G   #       and the lowercase alphabet
\$\endgroup\$
1
\$\begingroup\$

Emacs Lisp, 91 bytes

(lambda(a)(load"cl")(/(count-if(lambda(x)(< ?` x ?z))(remove-duplicates(downcase a)))26.0))

Try it online!

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

V, 30, 29 bytes

ÓÁ
òó㈁“±òAÝ/26.0|Óá
C="

Try it online!

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

EXCEL, 55 bytes

Cell A1 as input. Place in any cell by doing Ctrl+Shift+Enter . +2 bytes if {} is included in the count.

=SUM(--ISNUMBER(FIND(CHAR(ROW(A65:A91)),UPPER(A1))))/26
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 61 54 51 bytes

s=>new Set(s.toLowerCase().match(/[a-z]/g)).size/26
\$\endgroup\$
  • 1
    \$\begingroup\$ 57 bytes \$\endgroup\$ – Arnauld Jun 21 at 11:36
  • 2
    \$\begingroup\$ You can't just do replace(/[^a-z]/g) because matched characters will be replaced with 'undefined' (as a string). For instance, "*abc" will create the set Set { 'u', 'n', 'd', 'e', 'f', 'i', 'a', 'b', 'c' }. \$\endgroup\$ – Arnauld Jun 21 at 12:34
  • 2
    \$\begingroup\$ Was just about to post this myself: 51 bytes \$\endgroup\$ – Shaggy Jun 21 at 14:04
0
\$\begingroup\$

MATLAB, 53 bytes

Anonymous function taking a string:

@(a)length(unique(upper(a(isstrprop(a,'alpha')))))/26
\$\endgroup\$
0
\$\begingroup\$

Oracle, 199 bytes

CREATE FUNCTION f(s LONG)RETURN FLOAT IS
r FLOAT;BEGIN
SELECT COUNT(DISTINCT c)/26 INTO r
FROM(SELECT LOWER(SUBSTR(s,LEVEL,1))c
FROM dual
CONNECT BY LEVEL<=LENGTH(s))WHERE
c>'`'AND'{'>c;RETURN r;END;

More readable version:

CREATE FUNCTION f(s LONG) RETURN FLOAT IS
    r FLOAT;
  BEGIN
    SELECT COUNT(DISTINCT c) / 26 INTO r
    FROM (
      SELECT
        LOWER(SUBSTR(s, LEVEL, 1)) AS c
      FROM dual
      CONNECT BY LEVEL <= LENGTH(s)
    )
    WHERE c > '`' AND '{' > c;
    RETURN r;
  END;

Try it on SQL Fiddle!

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

Haskell, 86 Bytes

Still golfable, probably.

import Data.Char
import Data.List
((/26).toEnum.length.nub.filter isLower.(toLower<$>))

Is there any better way to convert an Int to a Float?

\$\endgroup\$
  • \$\begingroup\$ map toLower is shorter than (toLower<$>) \$\endgroup\$ – Laikoni Aug 10 at 8:23
0
\$\begingroup\$

Wolfram Language (Mathematica), 39 bytes

Length[Alphabet[]⋂ToLowerCase@#]/26.&

Try it online!

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

Wolfram Language (Mathematica), 71 70 59 bytes

Count[Union@ToCharacterCode@ToUpperCase@#,x_/;64<x<91]/26.&

Try it online!

Thanks to attinat for suggesting Union to replace DeleteDuplicates.

\$\endgroup\$
  • \$\begingroup\$ Union is 11 bytes shorter than DeleteDuplicates. \$\endgroup\$ – attinat Aug 5 at 5:02
0
\$\begingroup\$

jq -R, 36 + 3 = 39 bytes

1/length*([scan("[a-zA-Z]")]|length)

The -R flag is required, otherwise stdin needs to be a quoted string.

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

C# .NET, 158 bytes

public class P{public static void Main(string[]z){var i=0;for(int q=65;q<91;q++)if(z[0].ToUpper().IndexOf((char)(q))>-1)i++;System.Console.Write(100D/26*i);}}

Try Online

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

MathGolf, 8 bytes

▄æl!\╧]▓

Try it online!

Based on the 05AB1E solution, so be sure to upvote that. I noticed a bug in the "contains" operator, which if resolved would remove the need of the swap.

Explanation

▄          lowercase alphabet as string
 æ         start block of length 4
  l!       push input lowercased
    \      swap top elements
     ╧     pop a, b, a.contains(b)
           loop ends here
      ]    end array / wrap stack in array
       ▓   get average of list
\$\endgroup\$

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.