字母完成率


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

05AB1E8 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 -fgrep -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

PowerShell55 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.153842615.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.