字母完成率


32

介绍

给定的字符串使用多少英文字母?前一句使用77%。它有20个独特的字母(howmucftenglisapbdvr)和20/26≃0.77。

挑战

对于输入字符串,返回存在于字符串中的英文字母的百分比。

  • 答案可以是百分比或十进制形式。

  • 输入字符串可以具有大写和小写以及标点符号。但是,您可以假定它们没有变音符号或重音符号。

测试用例

输入值

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

一些有效的输出

77%, 76.9, 0.7692

输入:

The quick brown fox jumps over the lazy dog

所有有效输出:

100%, 100, 1

预期输出"@#$%^&*?!"和""为0。


3
建议的测试用例:"@#$%^&*?!",""
— Adám

4
如果77%和76.9被接受,也77被接受吗?
— Grzegorz Oledzki

百分比也可以有小数部分...
— Jo King

2
@Shaggy对OP的最后编辑是16个小时前,您的回答是15,您的评论是14。我的意思是,您是对的,但是???
— Veskah

6
如果20/26可以四舍五入为0.7692、0.769或0.77,我是否也可以将其四舍五入为0.8、1或0?;-)
— Noiralef

Answers:


18

Python 3,42个字节

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

在线尝试!

通过采用大写和小写表示的(集合)差,我们从字符串中过滤掉所有非字母字符。然后,我们将长度除以26。

Python 3,46个字节

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

在线尝试!

计算唯一的字母(小写)字符,然后除以26。在Python 2中,它将需要3个以上的字符;两种用于更改{*...}为set(...),另一种用于使26成为浮点数:26.,以避免分隔地板。

Python 3,46个字节

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

在线尝试!

长度相同,与上一个长度基本相同,但是没有“内置”字符串方法。


为什么第二个返回1.0而不返回1?(我不想特别禁止这样做,这样就不会不利于特定语言,但我很好奇)
— 传送山羊

10
@TeleportingGoat除法运算符只有一个斜杠,即使操作数是整数,也总是在Python 3中产生浮点数。对于整数除法,您可以使用//,但是它始终是整数除法,这显然不是我们想要的。它们没有使输出的数据类型取决于操作数的特定值是有道理的,这意味着即使它是整数也总是浮点数。
— ArBo

11

MATL,8字节

2Y2jkmYm

在MATL Online上尝试

说明

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

八度 / MATLAB,33字节

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

在线尝试!

说明

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

lASåÅA

-1个字节感谢@LuisMendo。

在线尝试或验证更多测试用例。

@Grimy提供的6字节替代:

láÙg₂/

在线尝试或验证更多测试用例。

两个程序都输出为十进制。

说明:

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 láêg₂/还是6乘。
— 6

1
@LuisMendo谢谢(您也包括Grimy)!:)
— Kevin Cruijssen

7

C#(Visual C#交互式编译器),56 49字节

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

在线尝试!

-6字节归功于innat3


1
通过比较字符的十进制值50字节 (字符代码)可以节省6个字节
— Innat3

@ Innat3 49个字节通过改变&&到&。
— 凯文·克鲁伊森

@KevinCruijssen〜2分钟获得-1个字节的信用,已经这样做并正在编辑
— Expired Data

@ExpiredData Np,这显然是一场高尔夫。主要将其定向到Innat :)
— Kevin Cruijssen


6

Perl 6的,27 24个字节

-3字节归功于nwellnhof

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

在线尝试!


1
+1同样,虽然这很好用(并且.lc也可以用),但是从“正确性”的角度来看.fc可能更好(特别是如果挑战使用非英语字母)
— user0721090601

6

Bash和Gnu utils(81 78 68 60 42字节)

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

-8个字节,感谢@wastl

-18字节感谢Nahuel使用一些我不知道的技巧:

  • sort -f 和 grep -i忽略大小写
  • sort -u 替代 | uniq

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

对。该变量是另一次尝试后的提醒。谢谢!
— Grzegorz Oledzki


不能将“ grep -io [az]”缩写为“ grep -o [Az]”吗?
— 格努迪夫

@Gnudiff假定为ASCII,也将匹配所有[\ ^ _`]。
— jnfnt

6

K(oK),19 15字节

解:

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

在线尝试!

说明:

将输入转换为小写,以97为模(ASCII中的“ az”为97-122,以97为模为0-25),取唯一值,将低于26的结果求和,然后转换为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 ...

笔记:

  • -1个字节感谢ngn,1-%[;26] =>1-1%26%
  • -3个字节受ngn启发#(!26)^=>+/26>?

1
我很期待这个解释!我不知道97这里在做什么
— 传送山羊


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



6

PowerShell,55 52字节

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

在线尝试!

第一次尝试,仍然尝试随机想法

编辑:@Veskah指出,由于数字范围,ToUpper保存了一个字节,也删除了多余的字节 ()的空格

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

将字符串更改为所有小写大写,扩展为数组,对元素进行排序并选择唯一字母(gu需要对输入进行排序),仅保留ascii值从97到122(a到z)的字符65到90(A到Z),计算总数,然后除以26得到小数输出



1
哦,刚注意到-in后您还有多余的空间。
— Veskah

6

R,47个字节

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

在线尝试!

转换为大写字母,然后转换为ASCII码点,并检查与A:Z对应的值65:90。


1
当输入中有引号时,此操作将失败。
— C. Braun

1
@ C.Braun在我的测试中...例如,在TIO上的第一个测试用例包含引号并给出正确的结果。你能举个例子吗?
— 罗宾·赖德

1
我不太了解您在TIO的标头部分中做了什么,但是仅在R解释器中运行上面的代码不起作用。您似乎正在重新定义scan不像引号一样分割引号?
— C. Braun

1
@ C.Braun知道了,谢谢!我已经明确地使其成为一个函数(花费3个字节),我认为现在还可以。
— 罗宾·赖德

4

视网膜0.8.2,45字节

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

在线尝试!链接包括测试用例。说明:

T`Llp`ll_

小写字母并删除标点符号。

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

重复数据删除。

.
100$*

乘以100。

^
13$*

加13。

.{26}

整数除以26,然后转换为十进制。


我认为视网膜是此处使用百分比输出的唯一语言!
— 传送山羊

哦,在除法之前添加一元数13很妙!我为什么不这样想呢..>>它将使我的回答达到44个字节。不过,我仍将保留以前的版本。
— 凯文·克鲁伊森

@TeleportingGoat可能是因为Retina也是迄今为止所发布语言中唯一没有十进制除法的语言。仅(一元)整数除法是可能的。
— 凯文·克鲁伊森

4

APL(Dyalog扩展),8字节

⌹∘≤⍨⎕A∊⌈

在线尝试!

基于Adám的回答

⌈ 大写

⎕A∊长度为26的布尔(0或1)向量,指示字符串中的英语A lphabet 字母是什么

⌹∘≤⍨ 算术平均值,即参数的矩阵除法和相同长度的全1向量


3

木炭,11字节

I∕LΦβ№↧θι²⁶

在线尝试!链接是详细版本的代码。输出为小数(或1为小写)。说明:

  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

批次,197个字节

@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

在STDIN上输入并输出舍入百分比。说明:

@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

从字符串中依次删除每个字母。由于Batch解析变量的方式,调用子例程以检查是否有任何更改。

@cmd/cset/an/26

计算结果的百分比。

@exit/b
:c

子程序的开始。

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

如果删除字母更改了字符串,则增加字母计数。


3

佩佩,155个 138字节

rEeEeeeeeEREeEeEEeEeREERrEEEEErEEEeReeReRrEeeEeeeeerEEEEREEeRERrErEErerREEEEEeREEeeRrEreerererEEEEeeerERrEeeeREEEERREeeeEEeEerRrEEEEeereEE

在线尝试!输出为十进制形式。

说明:

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

由于Pepe只是4种命令语言,如果将其编码为每个RE 2位,则实际上是34.5个字节?
— 过期的数据


3

视网膜,57 46 35字节

.
$L
[^a-z]

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

-11字节的灵感来自@Neil在除法前添加一元数13的技巧。
另外-11个字节,直接感谢@Neil。
四舍五入为一个整数。

在线尝试。

57 46 40字节版本,可用于十进制输出:

.
$L
[^a-z]

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

相同的-11个字节,以及额外的-6个字节,这要归功于 @Neil,。

输出在逗号后加一个截短的†小数点(†即0.1538 (426)15.3代替15.4)输出。这是通过计算⌊1000×unique_letters26⌋ 然后手动插入小数点。

在线尝试。

说明:

将所有字母转换为小写:

.
$L

删除所有非字母:

[^a-z]

统一所有字母:

D`.

将每个唯一字母替换为1000个下划线:

.
1000*

计算26个相邻下划线在其中的匹配次数:

C`_{26}

在正确的位置插入一个点:

-1`\B
.

1
的.*可能仅仅是.一个1个字节保存,但你可以通过使用再节省10个字节Deduplicate,而不是做手工!
— 尼尔

@Neil啊,不知道D-builtin,谢谢!并且不确定为什么我使用.*而不是...感谢两个版本中的-11个字节!:)
— 凯文·克鲁伊森

1
仅供参考,对于相同的字节数,我有一个略有不同的方法:在线尝试!
— 尼尔

1
对于十进制版本,我发现它-1`\B与所需的插入位置直接匹配。
— 尼尔·

@尼尔再次感谢。
— 凯文·克鲁伊森

3

Java 8,62 59字节

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

-3个字节,感谢@OlivierGrégoire。

在线尝试。

说明:

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谢谢!由于某些原因,我总是忘记c&95结合使用c%91>64。我想您已经向我建议过几次高尔夫球。
— 凯文·克鲁伊森

是的,我已经建议过这些,但是没关系,不用担心;-)
— OlivierGrégoire

时间更长,但更有趣:s->{int r=0,b=0;for(var c:s)if((c&95)%91>64&&b<(b|=1<<c))r++;return r/26.;}(75个字节)
— OlivierGrégoire




2

Stax,9 个字节

░║ü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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.