33
\$\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.

| improve this question | | | | |
\$\endgroup\$
  • 3
    \$\begingroup\$ Suggested test cases: "@#$%^&*?!", "" \$\endgroup\$ – Adám Jun 21 '19 at 10:35
  • 4
    \$\begingroup\$ If 77% and 76.9 is accepted, is 77 accepted too? \$\endgroup\$ – Grzegorz Oledzki Jun 21 '19 at 10:43
  • \$\begingroup\$ Percentages can have decimal parts too... \$\endgroup\$ – Jo King Jun 21 '19 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 '19 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 '19 at 22:42

47 Answers 47

18
\$\begingroup\$

Python 3, 42 bytes

lambda s:len({*s.upper()}-{*s.lower()})/26

Try it online!

We filter all the non-alphabetic characters out of the string by taking the (set) difference of the uppercase and lowercase representations. Then, we take the length and divide by 26.

Python 3, 46 bytes

lambda s:sum(map(str.isalpha,{*s.lower()}))/26

Try it online!

Count the unique alphabetic (lowercase) characters, and divide by 26. In Python 2 it would require 3 more characters; two for changing {*...} to set(...), and one for making 26 a float: 26., to avoid floor division.

Python 3, 46 bytes

lambda s:sum('`'<c<'{'for c in{*s.lower()})/26

Try it online!

Same length, essentially the same as the previous one, but without "built-in" string method.

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ Why does the second one return 1.0 and not 1? (I didn't want to specifically disallow it so it wouldn't disadvantage specific languages, but I'm curious) \$\endgroup\$ – Teleporting Goat Jun 21 '19 at 12:05
  • 10
    \$\begingroup\$ @TeleportingGoat Division with a single slash always gives floats in Python 3, even if the operands are integers. For integer division, you'd use //, but then it would always be integer division, which is obviously not what we want here. It makes sense that they didn't make the data type of the output dependent on the specific values of the operands, which means always floats, even if it's a whole number. \$\endgroup\$ – ArBo Jun 21 '19 at 12:09
11
\$\begingroup\$

MATL, 8 bytes

2Y2jkmYm

Try it at MATL Online

Explanation

2Y2    % Predefined literal for 'abcdefghijklmnopqrstuvwxyz'
j      % Explicitly grab input as a string
k      % Convert to lower-case
m      % Check for membership of the alphabet characters in the string. 
       % Results in a 26-element array with a 1 where a given character in 
       % the alphabet string was present in the input and a 0 otherwise
Ym     % Compute the mean of this array to yield the percentage as a decimal
       % Implicitly display the result
| improve this answer | | | | |
\$\endgroup\$
8
\$\begingroup\$

Octave / MATLAB, 33 bytes

@(s)mean(any(65:90==upper(s)',1))

Try it online!

Explanation

@(s)                               % Anonymous function with input s: row vector of chars
             65:90                 % Row vector with ASCII codes of uppercase letters
                    upper(s)       % Input converted to uppercase
                            '      % Transform into column vector
                  ==               % Equality test, element-wise with broadcast. Gives a
                                   % matrix containing true and false
         any(                ,1)   % Row vector containing true for columns that have at
                                   % least one entry with value true
    mean(                       )  % Mean
| improve this answer | | | | |
\$\endgroup\$
7
\$\begingroup\$

05AB1E, 8 7 6 bytes

lASåÅA

-1 byte thanks to @LuisMendo.

Try it online or verify a few more test cases.

6 bytes alternative provided by @Grimy:

láÙg₂/

Try it online or verify a few more test cases.

Both programs output as decimal.

Explanation:

l       # Convert the (implicit) input-string to lowercase
 AS     # Push the lowercase alphabet as character-list
   å    # Check for each if it's in the lowercase input-string
        # (1 if truthy; 0 if falsey)
    ÅA  # Get the arithmetic mean of this list
        # (and output the result implicitly)

l       # Convert the (implicit) input-string to lowercase
 á      # Only leave the letters in this lowercase string
  Ù     # Uniquify it
   g    # Get the amount of the unique lowercase letters by taking the length
    ₂/  # Divide this by 26
        # (and output the result implicitly)
| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ @LuisMendo alternatively, láêg₂/ is also a 6-byter. \$\endgroup\$ – Grimmy Jun 21 '19 at 10:44
  • 1
    \$\begingroup\$ @LuisMendo Thanks (and you as well Grimy)! :) \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 10:49
7
\$\begingroup\$

C# (Visual C# Interactive Compiler), 56 49 bytes

a=>a.ToUpper().Distinct().Count(x=>x>64&x<91)/26f

Try it online!

-6 bytes thanks to innat3

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ you can save 6 bytes by comparing the decimal values of the characters 50 bytes (Character codes) \$\endgroup\$ – Innat3 Jun 21 '19 at 10:56
  • \$\begingroup\$ @Innat3 49 bytes by changing the && to &. \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 11:09
  • \$\begingroup\$ @KevinCruijssen ~2 mins off getting the -1 byte credit, already did that and was editing \$\endgroup\$ – Expired Data Jun 21 '19 at 11:10
  • \$\begingroup\$ @ExpiredData Np, it was an obvious golf. Was mainly directing it to Innat :) \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 11:11
6
\$\begingroup\$

APL (Dyalog Extended), 10 bytesSBCS

Anonymous tacit prefix function. Returns decimal fraction.

26÷⍨∘≢⎕A∩⌈

Try it online!

 uppercase

⎕A∩ intersection with the uppercase Alphabet

 tally length

 then

26÷⍨ divide by twenty-six

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ ⌹∘≤⍨⎕A∊⌈­­­­­ \$\endgroup\$ – ngn Jun 22 '19 at 10:45
  • \$\begingroup\$ @ngn That's very clever, but completely different. Go ahead and post that yourself. I'll be happy insert the explanation if you want me to. \$\endgroup\$ – Adám Jun 22 '19 at 23:32
  • \$\begingroup\$ done&explained \$\endgroup\$ – ngn Jun 23 '19 at 12:11
6
\$\begingroup\$

Perl 6, 27 24 bytes

-3 bytes thanks to nwellnhof

*.uc.comb(/<:L>/).Set/26

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ +1 Also, while this works just fine (and .lc would work too), from a "correctness" standpoint, .fc might be better (particularly if the challenge had non-English letters) \$\endgroup\$ – user0721090601 Jun 25 '19 at 1:49
6
\$\begingroup\$

Bash and Gnu utils (81 78 68 60 42 bytes)

bc -l<<<`grep -io [a-z]|sort -fu|wc -l`/26

-8 bytes thanks to @wastl

-18 bytes thanks to Nahuel using some tricks I didn't know:

  • sort -f and grep -i ignore case
  • sort -u is a replacement for | uniq
| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 60 bytes: echo $(tr A-Z a-z|tr -cd a-z|fold -1|sort -u|wc -l)/26|bc -l \$\endgroup\$ – wastl Jun 21 '19 at 13:12
  • \$\begingroup\$ Right. The variable is a reminder after another attempt. Thanks! \$\endgroup\$ – Grzegorz Oledzki Jun 21 '19 at 15:24
  • 3
    \$\begingroup\$ 42 bytes \$\endgroup\$ – Nahuel Fouilleul Jun 21 '19 at 15:29
  • \$\begingroup\$ Can't "grep -io [a-z]" be shortened to "grep -o [A-z]" ? \$\endgroup\$ – Gnudiff Jun 23 '19 at 6:13
  • \$\begingroup\$ @Gnudiff Assuming ASCII, that would also match all of [\^_`]. \$\endgroup\$ – jnfnt Jun 23 '19 at 23:45
6
\$\begingroup\$

K (oK), 19 15 bytes

Solution:

1%26%+/26>?97!_

Try it online!

Explanation:

Convert input to lowercase, modulo 97 ("a-z" is 97-122 in ASCII, modulo 97 gives 0-25), take unique, sum up results that are lower than 26, and convert to the percentage of 26.

1%26%+/26>?97!_ / the solution
              _ / lowercase
           97!  / modulo (!) 97
          ?     / distinct
       26>      / is 26 greater than this?
     +/         / sum (+) over (/)
  26%           / 26 divided by ...
1%              / 1 divided by ...

Notes:

  • -1 bytes thanks to ngn, 1-%[;26] => 1-1%26%
  • -3 bytes inspired by ngn #(!26)^ => +/26>?
| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ I'm looking forward to the explanation! I have no idea what that 97 is doing here \$\endgroup\$ – Teleporting Goat Jun 21 '19 at 23:28
  • \$\begingroup\$ Another 19 bytes alternative \$\endgroup\$ – streetster Jun 22 '19 at 9:58
  • 1
    \$\begingroup\$ %[;26] -> 1%26% \$\endgroup\$ – ngn Jun 22 '19 at 10:23
  • 2
    \$\begingroup\$ 1%26%#?(26>)#97!_ \$\endgroup\$ – ngn Jun 22 '19 at 10:25
  • 1
    \$\begingroup\$ 1%26%+/26>?97!_ for 15 \$\endgroup\$ – streetster Jun 23 '19 at 4:44
6
\$\begingroup\$

PowerShell, 55 52 bytes

($args|% *per|% t*y|sort|gu|?{$_-in65..90}).count/26

Try it online!

First attempt, still trying random ideas

EDIT: @Veskah pointed out ToUpper saves a byte due to the number range, also removed extra () and a space

Expansion:
($args|% ToUpper|% ToCharArray|sort|get-unique|where{$_-in 65..90}).count/26

Changes string to all loweruppercase, expands to an array, sorts the elements and selects the unique letters (gu needs sorted input), keep only characters of ascii value 97 to 122 (a to z) 65 to 90 (A to Z), count the total and divide by 26 for the decimal output

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ Uppercase saves a byte \$\endgroup\$ – Veskah Jun 21 '19 at 14:57
  • 1
    \$\begingroup\$ oh, just noticed you have an extra space after -in. \$\endgroup\$ – Veskah Jun 21 '19 at 19:04
6
\$\begingroup\$

R, 47 bytes

function(x)mean(65:90%in%utf8ToInt(toupper(x)))

Try it online!

Converts to upper case then to ASCII code-points, and checks for values 65:90 corresponding to A:Z.

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ This fails when there are quotes in the input. \$\endgroup\$ – C. Braun Jun 21 '19 at 14:35
  • 1
    \$\begingroup\$ @C.Braun Not in my tests... For instance, the first test case on TIO includes quotes and gives the correct result. Could you give an example? \$\endgroup\$ – Robin Ryder Jun 21 '19 at 17:34
  • 1
    \$\begingroup\$ I do not quite understand what you have done in the header part on TIO, but running just the code above in an R interpreter does not work. You seem to be redefining scan to not split on quotation marks, like the default does? \$\endgroup\$ – C. Braun Jun 24 '19 at 18:37
  • 1
    \$\begingroup\$ @C.Braun Got it, thanks! I've explicitly made it into a function (at a cost of 3 bytes) and I think it's OK now. \$\endgroup\$ – Robin Ryder Jun 24 '19 at 20:38
4
\$\begingroup\$

Retina 0.8.2, 45 bytes

T`Llp`ll_
+`(.)(.*\1)
$2
.
100$*
^
13$*
.{26}

Try it online! Link includes test cases. Explanation:

T`Llp`ll_

Lowercase letters and delete punctuation.

+`(.)(.*\1)
$2

Deduplicate.

.
100$*

Multiply by 100.

^
13$*

Add 13.

.{26}

Integer divide by 26 and convert to decimal.

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ I think retina is the only language here using percentages for the output! \$\endgroup\$ – Teleporting Goat Jun 21 '19 at 12:35
  • \$\begingroup\$ Oh, nice trick with adding unary 13 before dividing! Why didn't I think of that.. >.> It would make my answer 44 bytes. I'll still leave my previous version, though. \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 13:11
  • \$\begingroup\$ @TeleportingGoat Probably because Retina is also the only language from the ones posted thus far which doesn't have decimal division available. Only (unary) integer-division is possible. \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 13:19
4
\$\begingroup\$

APL (Dyalog Extended), 8 bytes

⌹∘≤⍨⎕A∊⌈

Try it online!

loosely based on Adám's answer

 uppercase

⎕A∊ boolean (0 or 1) vector of length 26 indicating which letters of the English Alphabet are in the string

⌹∘≤⍨ arithmetic mean, i.e. matrix division of the argument and an all-1 vector of the same length

| improve this answer | | | | |
\$\endgroup\$
3
\$\begingroup\$

Charcoal, 11 bytes

I∕LΦβ№↧θι²⁶

Try it online! Link is to verbose version of code. Output is as a decimal (or 1 for pangrams). Explanation:

  L         Length of
    β       Lowercase alphabet
   Φ        Filtered on
     №      Count of
        ι   Current letter in
      ↧     Lowercased
       θ    Input
 ∕          Divided by
         ²⁶ Literal 26
I           Cast to string
            Implicitly printed
| improve this answer | | | | |
\$\endgroup\$
3
\$\begingroup\$

Batch, 197 bytes

@set/ps=
@set s=%s:"=%
@set n=13
@for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do @call set t="%%s:%%c=%%"&call:c
@cmd/cset/an/26
@exit/b
:c
@if not "%s%"==%t% set/an+=100

Takes input on STDIN and outputs a rounded percentage. Explanation:

@set/ps=

Input the string.

@set s=%s:"=%

Strip quotes, because they're a headache to deal with in Batch.

@set n=13

Start with half a letter for rounding purposes.

@for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do @call set t="%%s:%%c=%%"&call:c

Delete each letter in turn from the string. Invoke the subroutine to check whether anything changed, because of the way Batch parses variables.

@cmd/cset/an/26

Calculate the result as a percentage.

@exit/b
:c

Start of subroutine.

@if not "%s%"=="%t%" set/an+=100

If deleting a letter changed the string then increment the letter count.

| improve this answer | | | | |
\$\endgroup\$
3
\$\begingroup\$

Pepe, 155 138 bytes

rEeEeeeeeEREeEeEEeEeREERrEEEEErEEEeReeReRrEeeEeeeeerEEEEREEeRERrErEErerREEEEEeREEeeRrEreerererEEEEeeerERrEeeeREEEERREeeeEEeEerRrEEEEeereEE

Try it online! Output is in decimal form.

Explanation:

rEeEeeeeeE REeEeEEeEe # Push 65 -> (r), 90 -> (R)
REE # Create loop labeled 90 // creates [65,66,...,89,90]
  RrEEEEE # Increment (R flag: preserve the number) in (r)
  rEEEe # ...then move the pointer to the last
Ree # Do this while (r) != 90

Re # Pop 90 -> (R)
RrEeeEeeeee rEEEE # Push 32 and go to first item -> (r)
REEe # Push input -> (R)
RE RrE # Push 0 on both stacks, (r) prepend 0
rEE # Create loop labeled 0 // makes input minus 32, so the
    # lowercase can be accepted, since of rEEEEeee (below)
  re # Pop 0 -> (r)
  rREEEEEe REEee # Push item of (R) minus 32, then go to next item 
  RrE # Push 0 -> (R)
ree # Do while (R) != 0

rere # Pop 0 & 32 -> (r)
rEEEEeee # Remove items from (r) that don't occur in (R)
         # Remove everything from (r) except the unique letters
rE # Push 0 -> (r)
RrEeee # Push reverse pointer pos -> (r)
REEEE # Move pointer to first position -> (R)
RREeeeEEeEe # Push 26 -> (R)
rRrEEEEee reEE # Divide it and output it
| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ Since Pepe is only a 4 command language really it's like 34.5 bytes if you encoded it as 2 bits per r e R E? \$\endgroup\$ – Expired Data Jun 26 '19 at 13:09
3
\$\begingroup\$

K (oK), 19 bytes

1%26%26-#(!26)^97!_

Try it online!

J, 30 bytes

26%~26-u:@(97+i.26)#@-.tolower

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 32! is too broad - it makes the rest of the expression treat some punctuation chars as letters, for instance try adding : in the example input \$\endgroup\$ – ngn Jun 22 '19 at 10:35
  • \$\begingroup\$ @ngn I didn't test with punctuation at first. Thanks for reminding me.! \$\endgroup\$ – Galen Ivanov Jun 22 '19 at 15:41
3
\$\begingroup\$

Retina, 57 46 35 bytes

.
$L
[^a-z]

D`.
.
100*
^
13*
_{26}

-11 bytes taking inspiration from @Neil's trick of adding unary 13 before dividing.
Another -11 bytes thanks to @Neil directly.
Rounds (correctly) to a whole integer.

Try it online.

57 46 40 bytes version which works with decimal output:

.
$L
[^a-z]

D`.
.
1000*
C`_{26}
-1`\B
.

Same -11 bytes as well as an additional -6 bytes thanks to @Neil.

Outputs with one truncated decimal after the comma ( i.e. \$0.1538\$ (\$\frac{4}{26}\$) is output as 15.3 instead of 15.4). This is done by calculating \$\lfloor{\frac{1000 × \text{unique_letters}}{26}\rfloor}\$ and then inserting the decimal dot manually.

Try it online.

Explanation:

Convert all letters to lowercase:

.
$L

Remove all non-letters:

[^a-z]

Uniquify all letters:

D`.

Replace every unique letter with 1000 underscores:

.
1000*

Count the amount of times 26 adjacent underscores fit into it:

C`_{26}

Insert a dot at the correct place:

-1`\B
.
| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ The .* could just be . for a 1 byte saving, but you can save another 10 bytes by using Deduplicate instead of doing it manually! \$\endgroup\$ – Neil Jun 21 '19 at 18:37
  • \$\begingroup\$ @Neil Ah, didn't knew about the D-builtin, thanks! And not sure why I used .* instead of ... Thanks for -11 bytes in both versions! :) \$\endgroup\$ – Kevin Cruijssen Jun 21 '19 at 19:25
  • 1
    \$\begingroup\$ FYI I had a slightly different approach for the same byte count: Try it online! \$\endgroup\$ – Neil Jun 21 '19 at 21:00
  • 1
    \$\begingroup\$ For the decimal version I found that -1`\B matches the desired insertion position directly. \$\endgroup\$ – Neil Jun 22 '19 at 23:17
  • \$\begingroup\$ @Neil Thanks again. \$\endgroup\$ – Kevin Cruijssen Jun 23 '19 at 15:10
3
\$\begingroup\$

Java 8, 62 59 bytes

s->s.map(c->c&95).distinct().filter(c->c%91>64).count()/26.

-3 bytes thanks to @OlivierGrégoire.

Try it online.

Explanation:

s->                     // Method with IntStream as parameter and double return-type
  s.map(c->c&95)        //  Convert all letters to uppercase
   .distinct()          //  Uniquify it
   .filter(c->c%91>64)  //  Only leave letters (unicode value range [65,90])
   .count()             //  Count the amount of unique letters left
    /26.                //  Divide it by 26.0
| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ 59 bytes \$\endgroup\$ – Olivier Grégoire Jun 23 '19 at 11:28
  • \$\begingroup\$ @OlivierGrégoire Thanks! I always forget about c&95 in combination with c%91>64 for some reason. I think you've already suggested that golf a few times before to me. \$\endgroup\$ – Kevin Cruijssen Jun 23 '19 at 15:18
  • \$\begingroup\$ Yes, I already suggested those, but that's OK, no worries ;-) \$\endgroup\$ – Olivier Grégoire Jun 23 '19 at 15:37
  • \$\begingroup\$ Way longer, but more fun: s->{int r=0,b=0;for(var c:s)if((c&95)%91>64&&b<(b|=1<<c))r++;return r/26.;} (75 bytes) \$\endgroup\$ – Olivier Grégoire Jun 24 '19 at 8:15
3
\$\begingroup\$

Julia 1.0, 34 bytes

s->sum('a':'z'.∈lowercase(s))/26

Uses the vectorized version of the ∈ operator, checking containment in the string for all characters in the range from a to z. Then sums over the resulting BitArray and divides by total number of possible letters.

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ Welcome and great first answer! \$\endgroup\$ – mbomb007 Jul 3 '19 at 21:43
2
\$\begingroup\$

C, 96 bytes

float f(char*s){int i=66,l[256]={};for(;*s;)l[1+*s++&~32]=1;for(;i<92;*l+=l[i++]);return*l/26.;}

Try it online!

| improve this answer | | | | |
\$\endgroup\$
2
\$\begingroup\$

Perl 5 -MList::Util=uniq -p, 24 bytes

$_=uniq(lc=~/[a-z]/g)/26

Try it online!

| improve this answer | | | | |
\$\endgroup\$
2
\$\begingroup\$

Stax, 9 bytes

░║üy$}╙+C

Run and debug it

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You can take a byte off the unpacked version by dropping u and using |b, but the savings disappear under packing. I might have an 8-byter, but the online interpreter is being weird and buggy. \$\endgroup\$ – Khuldraeseth na'Barya Jul 2 '19 at 19:58
  • \$\begingroup\$ @Khuldraesethna'Barya: Nice find. I think the bug is probably an array mutation. I'm seeing some of that behavior now. Working on a minimal repro... \$\endgroup\$ – recursive Jul 2 '19 at 20:11
  • \$\begingroup\$ Here's a repro of the problem I guess you're having with |b. It incorrectly mutates its operand rather than making a copy. I've created a github issue for the bug. github.com/tomtheisen/stax/issues/29 As a workaround, |b will work correctly the first time. After that, you may have to reload the page. If you found a different bug, if you can provide a reproduction, I'll probably be able to fix it. \$\endgroup\$ – recursive Jul 2 '19 at 20:20
  • \$\begingroup\$ Stax 1.1.4, 8 bytes. Instructions: unpack, insert v at the start, insert |b after Va, run, remove the first v, remove |b, repack. Yep, that's the bug I found. \$\endgroup\$ – Khuldraeseth na'Barya Jul 2 '19 at 20:31
  • \$\begingroup\$ @Khuldraesethna'Barya: I've released 1.1.5, and I believe this bug is fixed now. You can let me know if you still have trouble. Thanks. \$\endgroup\$ – recursive Jul 9 '19 at 0:27
2
\$\begingroup\$

Jelly, 8 bytes

ŒuØAe€Æm

Try it online!

Explanation

Œu       | Convert to upper case
  ØAe€   | Check whether each capital letter is present, returning a list of 26 0s and 1s
      Æm | Mean
| improve this answer | | | | |
\$\endgroup\$
2
\$\begingroup\$

JavaScript (Node.js), 45 bytes

s=>~-s.match(/$|([a-z])(?!.*\1)/ig).length/26

Try it online!


JavaScript (Node.js), 47 bytes

s=>(s.match(/([a-z])(?!.*\1)/ig)||[]).length/26

Try it online!

| improve this answer | | | | |
\$\endgroup\$
2
\$\begingroup\$

Python 3, 51 49 bytes

51 -> 49 bytes, thanks to alexz02

lambda s:len({*filter(str.isalpha,s.lower())})/26

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ 49 bytes lambda s:len({*filter(str.isalpha,s.lower())})/26 \$\endgroup\$ – alexz02 Jun 24 '19 at 8:34
  • \$\begingroup\$ @alexz02 Thank you! :) \$\endgroup\$ – ruohola Jun 24 '19 at 8:42
1
\$\begingroup\$

Japt, 9 bytes

;CoU Ê/26

Try it

;CoU Ê/26     :Implicit input of string U
;C            :Lowercase alphabet
  oU          :Remove the characters not included in U, case insensitive
     Ê        :Length
      /26     :Divide by 26
| improve this answer | | | | |
\$\endgroup\$
1
\$\begingroup\$

Python 2, 57 bytes

lambda i:len(set(o for o in i.lower()if o.isalpha()))/26.

Try it online!

A bit longer than the Python 3 answer from ArBo but posted as a different approach in Python 2 anyway.

| improve this answer | | | | |
\$\endgroup\$
1
\$\begingroup\$

Ruby -n, 38 34 bytes

-4 bytes from @historcrat!

p (?A..?Z).count{|c|~/#{c}/i}/26.0

Try it online!

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ @histocrat you are correct \$\endgroup\$ – Value Ink Jun 21 '19 at 21:50
1
\$\begingroup\$

C, 95 bytes

f(char*s){int a[256]={},z;while(*s)a[*s++|32]=1;for(z=97;z<'z';*a+=a[z++]);return(*a*100)/26;}

(note: rounds down)

Alternate decimal-returning version (95 bytes):

float f(char*s){int a[256]={},z;while(*s&&a[*s++|32]=1);for(z=97;z<'z';*a+=a[z++]);return*a/26.;}

This borrows some from @Steadybox' answer.

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome! Good first answer. It might be helpful for people reading your answer if you provide a short explanation of your code or an ungolfed version. It may also be helpful to provide a link to an online interpreter with your runnable code (see some other answers for examples). Many use TIO, and here's the gcc interpreter \$\endgroup\$ – mbomb007 Jun 23 '19 at 0:13

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.