อัตราการเติมตัวอักษร


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
แนะนำกรณีทดสอบ: "@#$%^&*?!",""
อดัม

4
ถ้า77%และ76.9เป็นที่ยอมรับก็เป็นที่77ยอมรับเช่นกัน?
Grzegorz Oledzki

เปอร์เซ็นต์สามารถมีส่วนทศนิยมได้ด้วย ...
โจคิง

2
@Shaggy การแก้ไขล่าสุดสำหรับ OP คือ 16 ชั่วโมงที่ผ่านมาคำตอบของคุณคือที่ 15 และความคิดเห็นของคุณที่ 14. ฉันหมายถึงคุณพูดถูก แต่ไม่ใช่ ???
Veskah

6
หาก 20/26 อาจถูกปัดเศษเป็น 0.7692, 0.769 หรือ 0.77 ฉันสามารถปัดเศษเป็น 0.8, 1 หรือ 0 ได้หรือไม่ ;-)
Noiralef

คำตอบ:


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

ลองออนไลน์!

ความยาวเท่ากันโดยพื้นฐานเหมือนกับความยาวก่อนหน้านี้ แต่ไม่มีเมธอดสตริง "built-in"


ทำไมคนที่สองถึงกลับมา1.0และไม่กลับมา1? (ฉันไม่ต้องการที่จะไม่อนุญาตเป็นการเฉพาะดังนั้นมันจะไม่ทำให้เสียเปรียบเฉพาะภาษา แต่ฉันอยากรู้อยากเห็น)
Teleporting Goat

10
@TeleportingGoat Division ที่มีเครื่องหมายสแลชเดี่ยวให้ลอยใน 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

ลองออนไลน์หรือตรวจสอบกรณีทดสอบอีกสองสามข้อ

ทางเลือก 6 ไบต์โดย@Grimy :

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-byter
Grimmy

1
@LuisMendo ขอบคุณ (และคุณก็ทำเหมือนGrimy )! :)
Kevin Cruijssen

7

C # (Visual C # Interactive Compiler) , 56 49 ไบต์

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

ลองออนไลน์!

-6 ไบต์ขอบคุณinnat3


1
คุณสามารถบันทึก 6 ไบต์โดยการเปรียบเทียบค่าทศนิยมของอักขระ50 ไบต์ ( รหัสอักขระ )
Innat3

@ Innat3 49 ไบต์โดยการเปลี่ยนไป&& &
Kevin Cruijssen

@KevinCruijssen ~ 2 นาทีเพื่อรับ -1 ไบต์เครดิตทำเช่นนั้นและแก้ไข
ข้อมูลหมดอายุ

@ ExpiredData Np มันเป็นสนามกอล์ฟที่ชัดเจน โดยส่วนใหญ่จะเป็นผู้กำกับที่ Innat :)
Kevin Cruijssen

6

APL (Dyalog Extended) , 10 ไบต์SBCS

ฟังก์ชันนำหน้าเงียบโดยไม่ระบุชื่อ ส่งคืนเศษส่วนทศนิยม

26÷⍨∘≢⎕A∩⌈

ลองออนไลน์!

 ตัวพิมพ์ใหญ่

⎕A∩ แยกกับตัวพิมพ์ใหญ่A lphabet

 ความยาวนับ

 แล้วก็

26÷⍨ หารด้วยยี่สิบหก


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

@ngn มันฉลาดมาก แต่แตกต่างอย่างสิ้นเชิง ไปข้างหน้าและโพสต์เอง ฉันจะมีความสุขแทรกคำอธิบายถ้าคุณต้องการให้ฉัน
อดัม


6

Perl 6 , 27 24 ไบต์

-3 ไบต์ขอบคุณ nwellnhof

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

ลองออนไลน์!


1
+1 ในขณะที่วิธีนี้ใช้ได้ดี (และ.lcก็ใช้ได้เช่นกัน) จากมุมมอง "ความถูกต้อง" .fcอาจดีกว่า (โดยเฉพาะถ้าความท้าทายมีตัวอักษรที่ไม่ใช่ภาษาอังกฤษ)
0721090601

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
สูญเสีย

ขวา. ตัวแปรนี้เป็นเครื่องเตือนความจำหลังจากพยายามอีกครั้ง ขอบคุณ!
Grzegorz Oledzki


ไม่สามารถ "grep -io [az]" ถูกย่อให้เป็น "grep -o [Az]" ได้หรือไม่
Gnudiff

@Gnudiff สมมติว่า ASCII ซึ่งจะตรงกับทั้งหมดของ [\ ^ _ `]
jnfnt

6

K (oK) , 19 15 ไบต์

วิธีการแก้:

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

ลองออนไลน์!

คำอธิบาย:

แปลงอินพุตเป็นตัวพิมพ์เล็ก modulo 97 ("az" คือ 97-122 ใน ASCII, modulo 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


1
1%26%+/26>?97!_สำหรับ 15
ท้องถนน

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
โอ้เพิ่งสังเกตเห็นว่าคุณมีพื้นที่พิเศษหลังจาก - ใน
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


3

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

3

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.


3

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

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


3

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




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







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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.