Tasso di completamento dell'alfabeto


32

introduzione

Quanto dell'alfabeto inglese utilizza una determinata stringa? La frase precedente utilizza il 77%. Ha 20 lettere uniche (howmucftenglisapbdvr) e 20/26 ≃ 0,77.

Sfida

Per una stringa di input, restituisce la percentuale di lettere dell'alfabeto inglese presente nella stringa.

  • La risposta può essere in percentuale o in forma decimale.

  • La stringa di input può contenere lettere maiuscole e minuscole, nonché punteggiatura. Comunque puoi presumere che non abbiano segni diacritici o accentuati.

Casi test

Ingresso

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

Alcuni output validi

77%, 76.9, 0.7692

Ingresso:

The quick brown fox jumps over the lazy dog

Tutte le uscite valide:

100%, 100, 1

L'output previsto per "@#$%^&*?!"e ""è 0.


3
Casi di test consigliati: "@#$%^&*?!",""
Adám

4
Se 77%e 76.9è accettato, è 77accettato anche?
Grzegorz Oledzki,

Le percentuali possono avere anche parti decimali ...
Jo King il

2
@Shaggy L'ultima modifica di OP è stata di 16 ore fa, la tua risposta era a 15 e il tuo commento a 14. Voglio dire, hai ragione ma ???
Veskah,

6
Se 20/26 può essere arrotondato a 0,7692, 0,769 o 0,77, posso anche arrotondarlo a 0,8, 1 o 0? ;-)
Noiralef il

Risposte:


18

Python 3 , 42 byte

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

Provalo online!

Filtriamo tutti i caratteri non alfabetici fuori dalla stringa prendendo la differenza (imposta) delle rappresentazioni maiuscole e minuscole. Quindi, prendiamo la lunghezza e dividiamo per 26.

Python 3 , 46 byte

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

Provalo online!

Conta i caratteri alfabetici (minuscoli) unici e dividi per 26. In Python 2 richiederebbe altri 3 caratteri; due per passare {*...}a set(...), e uno per rendere 26 un galleggiante:, 26.per evitare la divisione del pavimento.

Python 3 , 46 byte

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

Provalo online!

Stessa lunghezza, sostanzialmente uguale alla precedente, ma senza metodo di stringa "incorporato".


Perché il secondo ritorna 1.0e no 1? (Non volevo specificatamente vietarlo per non svantaggiare specifiche lingue, ma sono curioso)
Teleporting Goat

10
La divisione @TeleportingGoat con una singola barra fornisce sempre float in Python 3, anche se gli operandi sono numeri interi. Per la divisione di interi, useresti //, ma sarebbe sempre la divisione di interi, che ovviamente non è ciò che vogliamo qui. Ha senso che non abbiano fatto dipendere il tipo di dati dell'output dai valori specifici degli operandi, il che significa che è sempre mobile, anche se è un numero intero.
ArBo,

11

MATL , 8 byte

2Y2jkmYm

Provalo su MATL Online

Spiegazione

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

8

Octave / MATLAB, 33 byte

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

Provalo online!

Spiegazione

@(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

7

05AB1E , 8 7 6 byte

lASåÅA

-1 byte grazie a @LuisMendo .

Provalo online o verifica alcuni altri casi di test .

Alternativa a 6 byte fornita da @Grimy :

láÙg₂/

Provalo online o verifica alcuni altri casi di test .

Entrambi i programmi vengono emessi come decimali.

Spiegazione:

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)

@LuisMendo in alternativa, láêg₂/è anche un 6-byte.
Grimmy,

1
@LuisMendo Grazie (e anche tu Grimy )! :)
Kevin Cruijssen il

7

C # (compilatore interattivo Visual C #) , 56 49 byte

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

Provalo online!

-6 byte grazie a innat3


1
puoi salvare 6 byte confrontando i valori decimali dei caratteri 50 byte ( Codici carattere )
Innat3

@ Innat3 49 byte modificando &&in &.
Kevin Cruijssen, il

@KevinCruijssen ~ 2 minuti di sconto ottenendo il credito di -1 byte, l'ho già fatto e stava modificando
Dati scaduti il

@ExpiredData Np, era un golf ovvio. Lo dirigevo principalmente verso Innat :)
Kevin Cruijssen il

6

APL (Dyalog Extended) , 10 byte SBCS

Funzione prefisso tacito anonimo. Restituisce la frazione decimale.

26÷⍨∘≢⎕A∩⌈

Provalo online!

 maiuscolo

⎕A∩ intersezione con l' alfabeto A maiuscolo

 lunghezza del conteggio

 poi

26÷⍨ dividere per ventisei


⌹∘≤⍨⎕A∊⌈­­­­­
ngn

@ngn È molto intelligente, ma completamente diverso. Vai avanti e pubblicalo tu stesso. Sarò felice di inserire la spiegazione se vuoi che lo faccia.
Adám,


6

Perl 6 , 27 24 byte

-3 byte grazie a nwellnhof

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

Provalo online!


1
+1 Inoltre, mentre questo funziona bene (e .lcfunzionerebbe anche), dal punto di vista della "correttezza", .fcpotrebbe essere migliore (in particolare se la sfida avesse lettere non inglesi)
user0721090601

6

Utilità Bash e Gnu ( 81 78 68 60 42 byte)

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

-8 byte grazie a @wastl

-18 byte grazie a Nahuel usando alcuni trucchi che non sapevo:

  • sort -fe grep -iignora il caso
  • sort -u è un sostituto di | uniq

1
60 bytes: echo $(tr A-Z a-z|tr -cd a-z|fold -1|sort -u|wc -l)/26|bc -l
wastl

Right. The variable is a reminder after another attempt. Thanks!
Grzegorz Oledzki


Can't "grep -io [a-z]" be shortened to "grep -o [A-z]" ?
Gnudiff

@Gnudiff Assuming ASCII, that would also match all of [\^_`].
jnfnt

6

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>?

1
I'm looking forward to the explanation! I have no idea what that 97 is doing here
Teleporting Goat


1
%[;26] -> 1%26%
ngn



6

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



1
oh, just noticed you have an extra space after -in.
Veskah

6

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.


1
This fails when there are quotes in the input.
C. Braun

1
@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?
Robin Ryder

1
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?
C. Braun

1
@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.
Robin Ryder

4

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.


I think retina is the only language here using percentages for the output!
Teleporting Goat

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.
Kevin Cruijssen

@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.
Kevin Cruijssen

4

APL (Dyalog Extended), 8 bytes

⌹∘≤⍨⎕A∊⌈

Try it online!

vagamente basato sulla risposta di Adám

 maiuscolo

⎕A∊vettore booleano (0 o 1) della lunghezza 26 che indica quali lettere dell'inglese Alphabet are in the string

⌹∘≤⍨ media aritmetica, ovvero divisione matriciale dell'argomento e un vettore tutto-1 della stessa lunghezza


3

Carbone , 11 byte

I∕LΦβ№↧θι²⁶

Provalo online! Il collegamento è alla versione dettagliata del codice. L'output è un decimale (o 1per i pangrammi). Spiegazione:

  L         Length of
    β       Lowercase alphabet
   Φ        Filtered on
     №      Count of
        ι   Current letter in
      ↧     Lowercased
       θ    Input
 ∕          Divided by
         ²⁶ Literal 26
I           Cast to string
            Implicitly printed

3

Lotto, 197 byte

@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

Accetta input su STDIN e genera una percentuale arrotondata. Spiegazione:

@set/ps=

Inserisci la stringa.

@set s=%s:"=%

Rimuovi le virgolette, perché sono un mal di testa da affrontare in Batch.

@set n=13

Inizia con mezza lettera a scopo di arrotondamento.

@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

Elimina ogni lettera a turno dalla stringa. Richiamare la subroutine per verificare se qualcosa è cambiato, a causa del modo in cui Batch analizza le variabili.

@cmd/cset/an/26

Calcola il risultato in percentuale.

@exit/b
:c

Inizio della subroutine.

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

Se l'eliminazione di una lettera ha modificato la stringa, incrementa il conteggio delle lettere.


3

Pepe , 155 138 byte

rEeEeeeeeEREeEeEEeEeREERrEEEEErEEEeReeReRrEeeEeeeeerEEEEREEeRERrErEErerREEEEEeREEeeRrEreerererEEEEeeerERrEeeeREEEERREeeeEEeEerRrEEEEeereEE

Provalo online! L'output è in forma decimale.

Spiegazione:

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

Dato che Pepe è solo un linguaggio a 4 comandi, in realtà è come 34,5 byte se lo hai codificato come 2 bit per RE?
Dati scaduti il


3

Retina , 57 46 35 byte

.
$L
[^a-z]

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

-11 byte prendendo ispirazione dal trucco di @Neil di aggiungere unario 13 prima di dividere .
Altri -11 byte grazie a @Neil direttamente.
Arrotonda (correttamente) a un intero.

Provalo online.

57 46 versione da 40 byte che funziona con output decimale:

.
$L
[^a-z]

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

Stessi -11 byte e altri -6 byte grazie a @Neil .

Emette un decimale troncato dopo la virgola ( ie0,1538 (426) is output as 15.3 instead of 15.4). This is done by calculating 1000×unique_letters26 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
.

1
The .* could just be . for a 1 byte saving, but you can save another 10 bytes by using Deduplicate instead of doing it manually!
Neil

@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! :)
Kevin Cruijssen

1
FYI I had a slightly different approach for the same byte count: Try it online!
Neil

1
For the decimal version I found that -1`\B matches the desired insertion position directly.
Neil

@Neil Thanks again.
Kevin Cruijssen

3

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


@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.
Kevin Cruijssen

Yes, I already suggested those, but that's OK, no worries ;-)
Olivier Grégoire

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)
Olivier Grégoire

3

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!


Welcome and great first answer!
mbomb007



2

Stax, 9 bytes

░║üy$}╙+C

Run and debug it


1
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.
Khuldraeseth na'Barya

@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...
recursive

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.
recursive

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.
Khuldraeseth na'Barya

@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.
recursive

2

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



1

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



1

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.


1
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
mbomb007
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.