Норма заповнення алфавіту


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приймається також?
Гжегож Оледзкі

Відсотки можуть містити і десяткові частини ...
Jo King

2
@Shaggy Останнє редагування для ОП було 16 годин тому, ваша відповідь була на 15, а ваш коментар - на 14. Я маю на увазі, ви праві, але ???
Веська

6
Якщо 20/26 може бути округлено до 0,7692, 0,769 або 0,77, чи можу я також округлити його до 0,8, 1 або 0? ;-)
Нойралеф

Відповіді:


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? (Я не хотів спеціально забороняти це, щоб це не сприймало конкретні мови, але мені цікаво)
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-байтним.
Гриммі

1
@LuisMendo Дякую (і ви також Grimy )! :)
Кевін Круїссен

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 байт, змінивши &&на &.
Кевін Кройсейсен

@KevinCruijssen ~ 2 хвилини від отримання кредиту -1 байт, вже це зробив і редагував
Термін дії закінчився

@ExpiredData Np, це був очевидний гольф. В основному скеровував його до Інната :)
Кевін Круїссен

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можливо, буде краще (особливо, якщо виклик мав не англійські літери)
user0721090601

6

Утиліти Bash and Gnu ( 81 78 68 60 42 байт)

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

-8 байт завдяки @wastl

-18 байт завдяки Нахуелю, використовуючи деякі хитрощі, яких я не знав:

  • 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

Правильно. Змінна є нагадуванням після чергової спроби. Спасибі!
Гжегож Оледзкі


Чи не можна "grep -io [az]" скоротити до "grep -o [Az]"?
Gnudiff

@Gnudiff Припускаючи ASCII, це також відповідатиме всім [\ ^ _ `].
jnfnt

6

К (оК) , 19 15 байт

Рішення:

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

Спробуйте в Інтернеті!

Пояснення:

Перетворіть вхід у малі регістри, модуль 97 ("az" - 97-122 в ASCII, модуль 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

Спробуйте в Інтернеті!

Перша спроба, як і раніше намагаються випадкові ідеї

EDIT: @Veskah вказав, що ToUpper економить байт завдяки діапазону чисел, а також видаляє зайві ()та пробіл

Розширення:
($args|% ToUpper|% ToCharArray|sort|get-unique|where{$_-in 65..90}).count/26

Змінює рядок на всі нижні регістри, розширюється на масив, сортує елементи та вибирає унікальні літери (гу потребує впорядкованому введенні), зберігає лише символи значення ascii від 97 до 122 (від a до z) від 65 до 90 (від A до Z), порахуйте загальну суму і діліть на десятковий вихід 26



1
о, щойно помітив, у вас є додатковий простір після -ін.
Веська

6

R , 47 байт

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

Спробуйте в Інтернеті!

Перетворюється у верхній регістр, тоді в кодові точки ASCII, і перевіряє значення 65:90, відповідні A: Z.


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 Extended) , 8 байт

⌹∘≤⍨⎕A∊⌈

Спробуйте в Інтернеті!

вільно ґрунтуючись на відповіді Адама

 великі літери

⎕A∊логічне значення (0 або 1) вектор довжини 26 , який вказує на літери англійського 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:"=%

Стрип-котирування, тому що вони болять головою в Batch.

@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-ма командна мова насправді це як 34,5 байт, якщо ви закодували її як 2 біти на повторний RE?
Термін дії даних закінчився

3

K (oK) , 19 байт

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

Спробуйте в Інтернеті!

J , 30 байт

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

Спробуйте в Інтернеті!


1
32!занадто широкий - він змушує решту виразів трактувати деякі знаки пунктуації як літери, наприклад, спробуйте додати: в приклад введення
ngn

@ngn Спочатку я не перевіряв розділові знаки. Дякую, що нагадали.
Гален Іванов

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.315.41000×unique_letters26

Спробуйте в Інтернеті.

Пояснення:

Перетворити всі літери в малі регістри:

.
$L

Видаліть усі нелітери:

[^a-z]

Уніфікація всіх літер:

D`.

Замініть кожен унікальний лист на 1000 підкреслень:

.
1000*

Порахуйте кількість разів, що вміщуються до нього 26 сусідніх підкреслень:

C`_{26}

Вставте крапку в потрібному місці:

-1`\B
.

1
Це .*може бути лише .для 1 байта, але ви можете зберегти ще 10 байт, використовуючи Deduplicate, а не робити це вручну!
Ніл

@Neil Ах, не знав про D-builtin, дякую! І не впевнений, чому я використовував .*замість ... Дякую за -11 байт в обох версіях! :)
Кевін Круїссен

1
FYI У мене був дещо інший підхід для тієї ж кількості байтів: Спробуйте в Інтернеті!
Ніл

1
Для десяткової версії я виявив, що безпосередньо -1`\Bвідповідає бажаному положенню вставки.
Ніл

@Neil Дякую ще раз.
Кевін Кройсейсен

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чомусь. Я думаю, ти вже кілька разів раніше пропонував мені гольф.
Кевін Кройсейсен

Так, я вже запропонував це, але це нормально, не хвилюйтесь ;-)
Олів'є Грегоар

Шлях довше, але веселіше: s->{int r=0,b=0;for(var c:s)if((c&95)%91>64&&b<(b|=1<<c))r++;return r/26.;}(75 байт)
Олів'є Грегоар

3

Джулія 1,0 , 34 байти

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

Використовує векторизовану версію оператора ∈, перевіряючи вміст у рядку для всіх символів у діапазоні від a до z. Потім підсумовує отриманий BitArray і ділиться на загальну кількість можливих літер.

Спробуйте в Інтернеті!


Ласкаво просимо і чудова перша відповідь!
mbomb007



2

1
Ви можете зняти байт з розпакованої версії, відкинувши uта скориставшись |b, але економія зникає при упаковці. У мене може бути 8-байтний, але онлайн-перекладач дивний і клопітний.
Khuldraeseth na'Barya

@ Khuldraesethna'Barya: Приємна знахідка. Я думаю, що помилка - це, ймовірно, мутація масиву. Зараз я бачу деяку поведінку. Робота над мінімальним докором ...
рекурсивна

Ось докір проблеми, яку я маю на увазі |b. Він неправильно мутує свій операнд, а не робить його копію. Я створив проблему github для помилки. github.com/tomtheisen/stax/issues/29 Як вирішення, |bперший раз буде працювати правильно. Після цього вам, можливо, доведеться перезавантажити сторінку. Якщо ви знайшли іншу помилку, якщо зможете надати відтворення, я, ймовірно, зможу її виправити.
рекурсивна

Stax 1.1.4, 8 байт. Інструкції: розпакуйте, вставте vна початку, вставіть |bпісля Va, запустіть, видаліть перше v, видаліть |b, перепакуйте. Так, я знайшов помилку.
Khuldraeseth na'Barya

@ Khuldraesethna'Barya: Я випустив 1.1.5, і я вважаю, що ця помилка виправлена ​​зараз. Ви можете повідомити мені, якщо у вас все ще виникають проблеми. Спасибі.
рекурсивна







1

C, 95 байт

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;}

(Примітка: округлює вниз)

Альтернативна версія десяткового повернення (95 байт):

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.;}

Це запозичує частину відповіді @Steadybox.


1
Ласкаво просимо! Гарна перша відповідь. Користувачам, які читають вашу відповідь, може бути корисно, якщо ви надасте коротке пояснення свого коду чи версію, яка не має волі. Також може бути корисно надати посилання на онлайн-перекладача з вашим запущеним кодом (див. Деякі інші відповіді для прикладів). Багато хто використовує TIO, а ось інтерпретатор gcc
mbomb007,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.