ETAOIN SHRDLU гольф


43

Короткий і солодкий опис виклику:
Виходячи з ETAOIN SHRDLU , ваше завдання полягає в тому, щоб написати найкоротшу програму або функцію будь-якою мовою, яка видає 26 літер англійського алфавіту, виходячи з їх частоти на вводі.

Дійсно довга, суха та ретельна специфікація:

  • Ваша програма / функція отримає як вхідний рядок тексту, який буде містити одну чи більше великих та / або малих літер, а також може містити розділові знаки, цифри, символи та інші не алфавітні символи.
  • Програма / функція повинна виводити лише 26 літер ПОВЕРХНЕНОГО англійського алфавіту, включаючи ті, які не відображаються на вводі, впорядковані від більшості до найменших частот залежно від того, скільки разів вони з'являються на вводі.
  • Редагувати: Частота обчислюється без регістру, але вихід повинен бути великим.
  • Якщо дві або більше літер мають однакову частоту, вони можуть бути в будь-якому порядку.
  • Жоден інший вихід, наприклад пробіл, не дозволений.
  • Редагувати 01.07.2014: На основі зворотного зв'язку я внесення змін до цього правила. Єдиний інший вихід, який дозволений, - це необов'язковий провідний та / або пробільний пробіл, такий як кінцевий новий рядок. Жоден інший вихід не дозволений.
  • Не визначена поведінка дозволена для введення, який не містить літер.

Переможця вибиратимуть через 7 днів, тому набирайте пальці!


Приклад введення:

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae erat velit. Mauris gravida euismod libero ut tincidunt. Phasellus elit dui, consectetur et egestas in, aliquam vitae diam. Donec eget varius ante. Vestibulum cursus diam aliquet, egestas orci quis, placerat dolor. Proin vel nisi lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam erat volutpat. Etiam libero tortor, ornare id dui eget, posuere dignissim libero. Pellentesque commodo consequat volutpat. Integer hendrerit sapien libero, vel viverra augue facilisis sit amet. Quisque consectetur eget nisl quis dignissim. Ut lacinia pretium quam a placerat.
Morbi sed interdum risus, nec pretium lectus. Morbi imperdiet est id accumsan molestie. Duis sed fermentum nisl. Nunc vitae augue mattis, dictum lectus vel, accumsan nisl. Sed ultricies adipiscing rhoncus. Vivamus eu lacus a enim venenatis eleifend. Praesent consectetur tortor non eleifend ultricies. Mauris et odio posuere, auctor erat at, fringilla est. Proin in vestibulum erat. Maecenas congue commodo ante vel varius. Sed tempus mi ut metus gravida, nec dictum libero dapibus. Morbi quis viverra elit. Ut pharetra neque eget lacus tincidunt dictum. Fusce scelerisque viverra tellus et pretium.
Fusce varius adipiscing odio. Nulla imperdiet faucibus sem, at rhoncus ipsum adipiscing vitae. Phasellus imperdiet congue lacus et mollis. Nullam egestas mauris magna, et mollis lectus varius ut. Sed sollicitudin adipiscing dolor, vel elementum elit laoreet molestie. Aliquam nec nulla vel sem ultrices ullamcorper. Nullam nec felis magna. Duis sodales orci non justo aliquam tempus. Integer mi diam, tempor sed vulputate et, varius et nunc. Vestibulum sodales ipsum id mi pharetra, ut convallis mi accumsan. Sed dictum volutpat vestibulum.
Quisque ac dolor sagittis, aliquam libero at, euismod enim. Nulla ullamcorper posuere nulla vitae varius. Nam at dolor non libero elementum pellentesque in in lorem. Fusce porttitor turpis in quam placerat varius. Donec lorem orci, condimentum eu sapien sit amet, aliquet commodo magna. Quisque sed lectus sit amet arcu euismod accumsan et non nunc. Phasellus placerat congue metus, feugiat posuere leo dictum quis. Sed ultricies feugiat eros dignissim bibendum.
Mauris scelerisque consectetur libero eget varius. Aenean neque nunc, ullamcorper vitae orci in, auctor ornare sapien. Nam lacinia molestie imperdiet. Nam vitae mattis nibh. Vestibulum consequat tellus ac nisi sagittis pulvinar. Nullam mollis ornare quam, et venenatis leo porttitor sit amet. Nulla urna neque, dignissim non orci ut, volutpat ultrices erat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque vestibulum tellus nec eros faucibus porta.

Приклад виводу:

EITUSALNROMCDPVGQBFHJKWXYZ

Примітка: KWXYZдля цього входу існує 5-ти напрямний зв'язок .

Редагувати:

Конкурс закінчився! Дякуємо всім, хто взяв участь. А тепер для переможця (ів!): І Джаніс Джаніс, і відповіді Ісаакгського Піта прийшли з величезними 19 символами. (Вибачте, але я не збираюся приймати жодну з відповідей, тому що я думаю, що це було б несправедливо щодо інших.) Редагувати: Беручи поради Денніса, я відзначу його відповідь прийнятим, оскільки його першим досягають 19 символів. Почесні згадки - це відповідь Ільмарі Каронена на третьому місці Гольфскрипта на 22 символи, а також відповіді на підземний монорельс на 75 знаків Python, що отримала найбільше відгуків. Ще раз дякую всім, хто взяв участь!


Чи вимірюється частота лише для великих літер вводу?
Говард

2
@IlmariKaronen так, що нові рядки вважаються пробілами, щоб не було дозволено.
Авраам

8
@Abraham: IMO; якщо дозволений новий рядок (конкретно) дозволений для деяких мов, він повинен бути дозволений, як правило, для всіх мов; не в останню чергу тому, що текстовий потік повинен бути припинений новим рядком, за яким слідує EOF.
Вілліхам Тотланд

3
@WillihamTotland, виходячи з кількості оновлених вами коментарів, я змінитиму правила, щоб дозволити зворотний новий рядок.
Авраам

1
Що робити, якщо є дві відповіді з найкоротшим кодом? пропонує присвоїти зелену галочку попередньому рішенню. Свою відповідь isaacg опублікував першим, я спершу провів шахту на 19 байт. Який би ви не вибрав краватку краватки, мені буде добре, але, не маючи прийнятої відповіді, на мою думку, це трохи антикліматично.
Денніс

Відповіді:


26

CJam, 21 19 байт

qeu:A;'[,65>{A\-,}$

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

Приклад

$ cjam etaoin.cjam <<< "~XyxY YyxZ"
YXZABCDEFGHIJKLMNOPQRSTUVW

(немає нового рядка)

Як це працює

qeu:A; " Read from STDIN, convert to uppercase, save in the variable “A” and discard, ";
'[,    " Push an array of all ASCII characters before “[” (NUL to “Z”).               ";
65>    " Remove the first 64 characters (NUL to “@”).                                 ";
{      " Sort the array of characters by the following mapping:                       ";
  A\   " Swap the character with the string saved in variable “A”.                    ";
  -    " Remove all occurrences of the character from the string.                     ";
  ,    " Push the length of the string.                                               ";
}$     "                                                                              ";

Більше випадків означає, що більше символів видаляється, тому найчастіші символи з’являються на початку масиву.


Дійсно дуже розумний.
Авраам

Вітаємо @Dennis з перемогою в конкурсі!
Авраам

43

Пітон 2 або 3 - 77 75 байт

f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1]

Я мав відповідь, що схопив дані від STDIN, але я зрозумів, що це технічно недійсно. Я використовував, input()який отримує лише один рядок, але приклад прикладу питання передбачає, що він повинен обробляти кілька рядків одночасно. Щоб зустріти специфікацію, я перетворив свою відповідь у функцію, яка бере аргумент рядка. На мій подив, це було на два байти менше! Мені це не прийшло в голову print(...)і input()були довші за f=lambda s:та s.

Це також робить відповідь сумісною як з Python 2, так і з Python 3. Спочатку це був лише Python 3, оскільки він використовувався input()(який називався raw_input()у 2). Тепер, коли це функція, вона працює в обох.

Пояснив

                                  range(65,91)                              # The numbers 65 to 90
                          map(chr,range(65,91))                             # Convert to ASCII

                                                    s                       # The input string
                                                    s.upper()               # Convert to uppercase
                                                    s.upper().count         # Function literal for 'how many times the argument appears in the string'

                   sorted(map(chr,range(65,91)),key=s.upper().count)        # Sort by that function
           ''.join(sorted(map(chr,range(65,91)),key=s.upper().count))       # Concatenate to string
           ''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Step through by -1 (i.e. reverse string)

  lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Make it a function (`return` is implicit for lambdas)
f=lambda s:''.join(sorted(map(chr,range(65,91)),key=s.upper().count))[::-1] # Give it a name

2
З іншого боку, коментарі у поясненні викликають у мене обличчя. Ласкаво просимо в CS 101!
Ізката

6
@Izkata Важливим є те, що він показує, в якому порядку читати код. Тому що найкраще місце для початку читання коду для гольфу рідко очевидно, особливо коли він стає трохи складнішим або коротшим, ніж це.
Мартін Ендер

1
Прекрасна презентація!
xnor

3
@Izk Моєю метою було зробити його зрозумілим для людей, які не знають python. Я б ніколи не коментував подібних коментарів у реальному проекті.
підземниймонорельс

2
@imm Ні. countЦе не змінна чи що-небудь, це буквальна функція. Настільки ж круто, як було б уміти помножити повернене значення функції, -1поклавши на -передню частину, це не особливість, яку має питон.
підземниймонорельс

15

Баш, 65 байт

(tr a-z A-Z;echo {A..Z})|fold -1|sort|uniq -c|sort -nr|tr -dc A-Z

Приклад

$ bash etaoin.sh <<< "~AbaB BbaC"
BACZYXWVUTSRQPONMLKJIHGFED

Як це працює

(              #
  tr a-z A-Z   # Turn lowercase into uppercase letters.
  echo {A..Z}  # Print all uppercase letters.
) |            #
fold -1 |      # Split into lines of length 1.
sort |         # Sort those lines (required for piping to uniq).
uniq -c |      # Print the frequencies of all lines.
sort -nr |     # Sort by frequency (reversed).
tr -dc A-Z     # Remove everything that's not an uppercase letter.

1
Це не портативний локальний код, вам потрібно змусити LC_COLLATE = C (або коротше, LC_ALL).
Кріс Даун

6
Переносність @ChrisDown взагалі не викликає занепокоєння у кодовому відповіді на гольф.
Кевін

1
Без портативності те, що ця відповідь робить, не є чітко визначеним.
Кріс Даун

@ChrisDown: Я перевірив декілька рядків і кілька локалів, але не зміг знайти приклад, коли uniq поводиться з алфавітними символами. Не могли б ви мені показати?
Денніс

@ChrisDown Цей скрипт є достатньо портативним для запуску на OpenBSD з використанням BSD версій fold, sor, tr, uniq, якщо оболонка bash або ksh93. Інші оболонки, як-от zsh, не вдається розширитись {A..Z}. Всі локальні локації LC_COLLATE працюють, оскільки у OpenBSD є лише LC_COLLATE = C.
kernigh

12

Піт 1.0.2 , 19 20

=ZUwsVm;dSm[cZkk)UG

Спробуйте тут: http://ideone.com/fork/YlWpEJ

Докладніше про Pyth тут: http://esolangs.org/wiki/Pyth

Приклад:

Виходячи з ETAOIN SHRDLU, ваше завдання полягає в тому, щоб написати найкоротшу програму або функцію будь-якою мовою, яка виводить 26 літер англійського алфавіту, виходячи з їх частоти на вході.

Дає:

TENOHARSIULGFPYDCBWQMZXVKJ

Пояснення:

=ZUw: Перетворення введення у великі регістри та збереження у Z.

sV: Надрукуйте суму зворотного числа

m;d: Останні записи

S: Відсортовано за першим записом, у порядку збільшення

m[cZkk): Списки [кількість k у Z, k]

UG: Для k у великих літерах.

Груб еквівалент Python:

G='abcdefghijklmnopqrstuvwxyz'
Z=copy(upper(input()))
print(_sum(rev(_map(lambda d:d.pop(),sorted(_map(lambda k:_list(count(Z,k),k),upper(G)))))))

Це не запис, я просто думав, що людям це може подобатися. У Pyth 1.0.4 наступна програма є рішенням у 10 символів:

JUwo_cJNUG

Пояснення:

JUw: Перетворення введення в великі регістри та збереження в Дж.

o: (Друк) Сортувати за

_cJN: -1 * (кількість N у Дж)

UG: Більше N великих літер.

Це не є правовим рішенням, оскільки кілька змін із Pyth 1.0.2 до 1.0.4, включаючи додавання функції o, сортування за функцією, були відповіддю на цю проблему.


Я пропоную вам оновити посилання Pyth на офіційну сторінку Pyth, якщо вона існує.
AL

@AL Це офіційна сторінка Pyth, поки я не виклав запис esolang.
isaacg

Чому вам потрібно зберігати вхід у змінній, Zщоб звернутися до нього один раз пізніше? Чи просто встановлення виразу для Zнього на місці викликає читання введення кілька разів?
xnor

@xnor Позиція Z використовується всередині функції лямбда, оскільки вона знаходиться в першому аргументі карти, тому її потрібно зберегти до змінної. Використання Uw дійсно призведе до того, що введення прочитане 26 разів.
isaacg

1
@AL Добре, Pyth працює як на esolang, так і на github. Посилання github знаходиться внизу сторінки esolang, яка пов'язана у відповіді. Github робить колоризацію коду.
isaacg

11

Javascript ( ES6 ) 119 117

Редагувати: (-2) Видалено необхідність toUpperCaseвикористання RegEx, нечутливого до регістру, у splitвиклику.

a=prompt(f=x=>a.split(RegExp(x,'i')).length)
alert([...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort((b,c)=>f(c)-f(b)).join(''))

Альтернатива (однакова довжина): Зведений сортування та підрахунок символів до однієї функції.

a=prompt()
alert([...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort(f=(b,c)=>c?f(c)-f(b):a.split(RegExp(b,'i')).length).join(''))

Як функція: 105 104

Редагувати: (-1) Об'єднати сортування та підрахунок символів до однієї функції.

F=a=>[...'ABCDEFGHIJKLMNOPQRSTUVWXYZ'].sort(f=(b,c)=>c?f(c)-f(b):a.split(RegExp(b,'i')).length).join('')

1
Цікава техніка.
Метт

1
Бризки струни ... чудовий!
Бергі

10

GolfScript, 22 символи

:?91,+-26>{.32+]?\-,}$

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

Пояснення:

  • :?присвоює символу рядок введення ?. (Я використовую розділовий символ, щоб наступне число 91не було проаналізовано як частину назви символу.)
  • 91,будує список чисел від 0 до 90 (код ASCII Z).
  • + додає цей список до рядка введення, тим самим перетворюючи його з масиву кодів ASCII в рядок (і зручно також видаляти вхідну рядок зі стека).
  • -26>приймає останні 26 символів цього рядка, виробляючи рядок , що містить заголовних ASCII букви від Aдо Z.
  • { }$Застосовує блок коду для всіх символів у вхідному рядку, і сортує ці символи в відповідно до результату.
  • Всередині блоку коду .дублюється символ і 32+перетворюється копія з верхнього регістру в нижній регістр. ]Збирає ці два символи в масив, ?\-приймає вхідні рядок , що зберігається в ?і видаляє всі входження символів в масиві з нього, і ,підраховує довжину залишилася рядка, яка буде ключем сортування. Символи будуть відсортовані у порядку зростання за цією клавішею, таким чином, у порядку зменшення за кількістю подій.

1
Схоже, у нас була майже однакова ідея. Незначна помилка: літера Z відсутня. Це повинно бути 91,+-26>.
Денніс

@Dennis: Ах, ой. Виправлено, хоча кому взагалі потрібен цей лист? :)
Ільмарі Каронен

2
@IlmariKaronen На основі відгуків спільноти я змінив правила, щоб дозволити отримання нового рядка (див. Питання для повного опису). Ваша оцінка зараз 22, а не 25:)
Авраам

8

Haskell, 110 байт

import Data.List
import Data.Char
a%f=compare(f a).f
f t=sortBy(% \c->length$filter((/=c).toUpper)t)['A'..'Z']

Приклад використання:

λ> f "Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input."
"ETNAHORISULFGPBCDYMQWJKVXZ"

1
А як бути (/=c)і позбутися від 0-?
Лінн

@Mauris приємний улов! Я відредагував це і поголив іншого персонажа.
Флонк

6

Ruby 2.0, 53 символи

EDIT : Виправлено, щоб правильно працювати з багаторядковими рядками, дякую @ durron597!

f=->s{$><<(?A..?Z).sort_by{|c|-s.upcase.count(c)}*''}

Створює функцію, яку називають, fяку можна використовувати наступним чином:

f['jackdaws love my big sphinx of quartzzz']

Друкує до STDOUT:

AZOSICGHEJKLMBFPQRDTUVWXYN

2
Ця відповідь не правильна. Він дає таку відповідь: EITASUROLNCMPDVQGBHFKJWXYZдля прикладу у запитанні
durron597

1
@ durron597 Дякую, ти маєш рацію! Не вдалося правильно обробляти багаторядкові рядки - getsповертає рядок за один раз. Це може бути виправлено шляхом зміни , getsщоб gets$nале змінити його в функцію 1 символ коротше.
Пол Престиждж

6

Perl, 54 46 байт

ОНОВЛЕННЯ: після подальших оптимізацій його можна буде стиснути до 46 байт: (thx dennis for -n/ {}hack; китайський perl goth for <=>-> -hack)

s/./$h{uc$&}++/eg}{say sort{$h{$b}-$h{$a}}A..Z

Він повинен бути запущений з run з perl -nE

Оригінальне рішення (не потребує спеціальних опцій Perl):

s/./$h{uc$&}++/egfor<>;print sort{$h{$b}<=>$h{$a}}A..Z

Перевірено в Perl 5.8.3, 5.14.2

Якщо ви отримаєте попередження, окремий egі forз простором (+1 напівкоксу), якщо ви НЕ заперечуєте

Приклад використання:

$ python -c 'import this' | perl -le 's/./$h{uc$&}++/egfor<>;print sort{$h{$b}<=>$h{$a}}A..Z' 2>/dev/null
ETAISONLRHPBUCDYMFGXVWKZJQ

ПОЯСНЕННЯ: Для кожного символу ( .) кожного вхідного рядка ( for<>) застосуйте «шаблон» підстановки, який насправді оцінюється як вираз ( eпрапор s///), що збільшує збільшення ( uc) коротший символ ( ./ $&коротший, ніж більш очевидний (.)/ $1) рахувати в (неініціалізованому) хеші ( %h). Тоді хеш частоти літер використовується в функції порівняння для друку великого алфавіту в потрібному порядку.


1
Коротші та без повідомлення про помилки:perl -ne 's/./$h{uc$&}++/eg}{print sort{$h{$b}<=>$h{$a}}A..Z'
Dennis

Денніс: Дуже цікаво, це схоже на друкарську помилку ... що це? У мене було кілька варіантів використання -nі END{}, але вони завжди були більше .. НЕ соромтеся оновити відповідь, якщо ви хочете
mykhal

1
Так, -nобгортання while(<>){...}коду. Я уникаю редагування коду інших користувачів. Надто просто помилитися, деякі речі працюють лише на деяких комп’ютерах тощо
Денніс

1
Джо: я говорив про }{"ін'єкцію", а не лише про добре відомий -nваріант. Чи не було б очікувати , що код рядка на насправді технічно це обгорнуте в той час як код циклу рядки перед виконанням, а не тільки що - то працює ніби як якщо б він був загорнутий ..
mykhal

1
збережіть ще два знаки: замініть $h{$b}<=>$h{$a}на$h{$b}-$h{$a}
китайський perl goth

5

R, 123 байт

Код покращено завдяки пропозиціям @RichieCotton.

text <- "Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input."

f=function(x){b=plyr::count(toupper(strsplit(x,"")[[1]]));c=merge(LETTERS,b,all.x=T);paste(c[order(-c$freq),1],collapse="")}

f(text)

Вихід:

> f(text)
[1] "ETNAHORISULFGPBCDYMQWJKVXZ"

1
@RichieCotton: Я вже два рази відкидав запропоновані вами зміни. Я не знаю, чи отримуєте ви повідомлення про причину відхилення голосування, тому якщо ви прочитаєте це: будь ласка, надайте в коментарях поліпшення для гольфу, щоб ОП могла їх переглянути. Ось чому: meta.codegolf.stackexchange.com/a/1619/8478
Мартін Ендер

4

C ++, 185 183 179 177 байт

Звичайно, не очікується перемоги (чи може колись перемогти С ++?), Але все-таки веселої вправи.

#include <algorithm>
#include <stdio.h>
int f[256],p;main(){for(p=65;p<91;p++)f[p]=p;while(~(p=getchar()))f[p&95]+=256;p=256;std::sort(f,f+p);while(p--)f[p]&95&&putchar(f[p]);}

Пояснення:

#include <algorithm>         // for std::sort
#include <stdio.h>           // for getchar, putchar
int f[256],p;                // declare an array of count-prefixed chars, and a counter
main(){
    for(p=65;p<91;p++)       // 65 == 'A', 91 == the character after 'Z'
        f[p]=p;              // set the character for the slot
    while(~(p=getchar()))    // read characters until EOF
        f[p&95]+=256;        // increment the packed count for the character stripped of the 'lowercase bit'
    p=256;                   // start a countdown
    std::sort(f,f+p);        // sort the array
    while(p--)               // do the countdown
        f[p]&95 &&           // if the masked-off character is set...
          putchar(f[p]);     // print it
}

4

VBScript 181 109

Оновлено для використання зовсім іншого алгоритму. Биє JavaScript!

Досить:

dim b(99):i=ucase(inputbox(k))
for y=65to 90
    c=chr(y)
    a=len(replace(i,c,k))
    b(a)=c+b(a)
next
msgbox join(b,k)

Гольф:

dim b(99):i=ucase(inputbox(k)):for y=65to 90:c=chr(y):a=len(replace(i,c,k)):b(a)=c+b(a):next:msgbox join(b,k)

4

J 41 35 байт

(u:65+i.26)([\:[#/.~@,e.~#])toupper

Демонстрація:

i=: 'This is a test to see whether this is still working'
(u:65+i.26)([\:[#/.~@,e.~#])toupper i
STIEHLORWAGKNBCDFJMPQUVXYZ

Пояснення:

(u:65+i.26) & ( [ \: [ #/.~@,e.~#]) toupper) )
ABCDE...          |    |    |   |      uppercase the right argument
                  |    |    |   \copy from right only member from left
                  |    |     \append the left argument
                  |    \ Afterwards Count apperances of each letter
                  \ Sort the left according to the appearances

Ключ - додати лівий масив таким чином, щоб усі літери були доступні і вже були в порядку. Кумедним наслідком використання іменника як третього зубця до вилки є те, що він працює як дієслово, так і як словосполучення.


4

Groovy - 130 123 115 112 98 92

Відповідно до порад @ cfrick (двічі!):

f={('A'..'Z').collectEntries{c->[c,it.grep(~/(?i)$c/).size()]}.sort{-it.value}*.key.join()}

Невеликий тест (безсоромно викрадений з @jpjacobs):

assert f('This is a test to see whether this is still working') == 
    'STIEHLORWAGKNBCDFJMPQUVXYZ'

І запропонований тест також проходить


1
Функція повинна виводити всі 26 літер, а не лише ті, що присутні у рядку введення.
алгоритм

@algorithmshark, справді, моя помилка виправлена
Буде Лп

f={('A'..'Z').collectEntries{c->[c,it.toUpperCase().findAll(c).size()]}.sort{-it.value}.keySet().join()}на 104
cfrick

1
ще 6 байт: it.grep(~/(?i)$c/)замістьit.toUpperCase().grep(c)
cfrick

@cfrick Нічого собі! Знову дякую! Це toUpperCaseтурбувало пекло від мене.
Буде Lp

4

SAS - 217 (я думаю)

Введення має бути розміщено на рядку після заяви4, або на відповідних перфокартах для вашої системи. Я думаю, що такий підхід економить декілька символів порівняно з спробою цитувати вхід.

data a;
input;
S = upcase(compress(_INFILE_,,'ak'));
do i=1 to length(S);
l=substr(S,i,1);
output;
end;
cards4;
;;;;
run;
proc sql;
select l into :o separated by '' from
(select l, 1/count(l) as f from a group by l) order by f;
quit;

Я знаю, що це не відповідає повній специфікації, оскільки воно лише повертає символи, які відображаються у вхідному рядку. Мені може знадобитися трохи переосмислити це.


Не відповідає специфікації, але все ще круто, тому +1: D
кішка

4

AppleScript, 278

Я помітив, що "a" = "A"це правда в AppleScript. Я можу використовувати це в коді гольфу, але решта сценарію занадто багатослівна. Я використовував AppleScript 1.8.3.

Це визначає функцію f. Якщо ви додасте f("a string")внизу сценарію і запустите його в редакторі сценаріїв, він покаже результат.

on c(n)
ASCII character(64+n)
end
on f(s)
set{a,r}to{{},""}
repeat with i from 1 to 26
set j to 0
repeat with b in s
if b&""=c(i)then set j to j+1
end
set a to a&j
end
repeat with j from 0 to(count s)
repeat with i from 1 to 26
if a's item i=j then set r to c(i)&r
end
end
r
end

Відформатовано та прокоментовано:

-- Returns nth letter of alphabet.
on c(n)
    ASCII character (64 + n)
end c

-- Returns letters in s sorted by frequency.
on f(s)
    -- a: list of letter counts
    -- r: resulting string
    set {a, r} to {{}, ""}

    -- For each letter from A to Z,
    -- count letters in string s.
    repeat with i from 1 to 26
        set j to 0
        repeat with b in s
            -- Can't use b = c(i), because
            -- b is a reference to a string
            -- and = never dereferences its
            -- operands. Get contents of b,
            -- here by coercing b to string.
            if b & "" = c(i) then set j to j + 1
        end repeat
        -- Set item i of a to count j.
        set a to a & j
    end repeat

    -- Sort letters by frequency.  Do a counting sort
    -- because AppleScript lacks a sort command.
    repeat with j from 0 to (count s)
        repeat with i from 1 to 26
            if a's item i = j then set r to c(i) & r
        end repeat
    end repeat
    r
end f

-- Example call:
f("Now is the time for all good men to come to the aid of their country.")
-- Result: "OTEIRNMHLFDCAYWUSGZXVQPKJB"

3

VBScript 157 156 байт

Редагувати: змінено msgbox (p) на msgbox p

Більше читати:

s=ucase(InputBox(z))    'z is empty.
L=len(s)
Dim a(255)
for i=1to L
    x=asc(mid(s,i))
    a(x)=a(x)+1
next
for t=0to L
    For i=65To 90
        If a(i)=t then p=chr(i)&p
    next
next
msgbox p

Гольф: (155 символів + 1 повернення каретки)

s=ucase(InputBox(z)):L=len(s):Dim a(255):for i=1to L:x=asc(mid(s,i)):a(x)=a(x)+1:next:for t=0to L:For i=65To 90:If a(i)=t then p=chr(i)&p
next:next:msgbox p

У мене це було на 171 раніше з кодом, який мені здався цікавішим, але зручно метод сортування є більш коротким і вимагає len (s), що робить "для" коротше, ніж "while" для першого циклу. (позіхати)

's=UCase(InputBox(Z))&8 'just need any extra character.  0-7 don't work because &7 is octal

s=UCase(InputBox(Z)) 'nevermind
Dim a(999)
While Len(s)
    x=Asc(s) 'returns ascii of first char
    a(x)=a(x)-1 'going negative saves a character later...
    s=Mid(s,2) 'doesn't care if you run out of string
Wend
for j=1 to 26 'this used to be   While Len(p)<26
    For i=65To 90
        If a(i)<a(y) Then y=i 'it is barely not worth it to do a(i)+a(i+32)>a(y) here to skip the ucase() above
    Next
    p=p&Chr(y)
    a(y)=1 'if I didn't go negative this would have to be -1.  arrays default to 0.
Next
MsgBox(p)

Я дізнався кілька цікавих хитрощів з цього поста! Дякую за згадку теж. Одне: я думаю, що for t=0має бути for t=1, інакше ви завжди друкуєте весь алфавіт.
комфортноdrei

1
@comfortablydrei Потрібно друкувати весь алфавіт. "Програма / функція повинна виводити лише 26 літер англійського алфавіту
ПОНОВНЕННЯ

ого. пропустив того. то це моя помилка. Дякую!
комфортноdrei

3

J - 38 35 char

Функція, що приймає введення праворуч як рядок. Не переможець, але писати було весело.

(u:65+i.26)([\:[#/.~@,e.~#])toupper

Пояснили:

  • toupper- це дієслово в стандартній бібліотеці, яке збільшує рядок. Потім це стає правильним аргументом дієслова, тоді як лівим аргументом є алфавіт: кодові точки ASCII від 65 до 90.

  • [і ,e.~#])вибирає ( #) ті літери правого аргументу ( ]), які є елементами ( e.~) ліворуч, а потім попередньо ( ,) лівий аргумент ( [). На думку, ми зберігаємо лише великі символи та додаємо єдину копію алфавіту до кінця, щоб переконатися, що ми їх усіх спіймали.

  • #/.~@потім дає частоти кожного символу. Так трапляється, що це задано в алфавітному порядку, тому відразу після цього ми можемо знецінити ( \:) алфавіт (лівий аргумент [).

Швидкий лінивий приклад нижче. Ви можете спробувати його для себе в tryj.tk .

   (u:65+i.26)([\:[#/.~@,e.~#])toupper 'Based off ETAOIN SHRDLU, your challenge is to write the shortest program or function in any language that outputs the 26 letters of the English alphabet based on their frequency in the input.'
ETNAHORISULFGPBCDYMQWJKVXZ

3

T-SQL 178

В основному це моє рішення VBScript, але реалізоване в SQL.

Це зловживання виведенням XML для об'єднання стовпця. У практичному використанні його можна приєднати до зовнішньої таблиці для імітації GROUP_CONCATфункцій у MySQL та інших.

Оголошення @змінної:

DECLARE @ CHAR(1024)= 'enter your text here';

Код:

with y AS(
    SELECT UPPER(@)i,0l,91y
    UNION ALL
    SELECT i,len(replace(i,char(y-1),'')),y-1
    FROM y
    WHERE y>65
)
SELECT LTRIM(
(
    SELECT char(y)
    FROM y
    WHERE y<91
    ORDER BY l
    FOR XML PATH(''))
)

3

Perl, 78 байт

undef$/;$i=<>;$r{$i=~s/$_//gi}.=$_ for A..Z;print$r{$_}for sort{$b<=>$a}keys%r
  • Лише 26 великих літер ASCII без пробілу виводяться в порядку частоти.
  • Зв'язані символи подаються в алфавітному порядку.

Результат для прикладу у запитанні:

EITUSALNROMCDPVGQBFHJKWXYZ

Безголівки:

# read input
# ----------
undef $/; # disable input separator
$i = <>;  # $i holds the complete input as one string

# analyze
# -------
# For each uppercase letter (A upto Z) its occurences are counted
# via the number of substitutions made by s/$_//gi. The lowercase
# letter is included via modifier "i".
# 
# The occurrence count is then used as key for hash %r.
# The uppercase letter is appended to the value of that hash entry.
$r{$i =~ s/$_//gi} .= $_ for A..Z;

# output
# ------
# The hash keys are sorted numerically in reverse order by
# the specified sort function.
print $r{$_} for sort {$b<=>$a} keys %r

Це може працювати для прикладу, бот не є, наприклад, для echo -e 'x\ny\n\nz\n'виводу, який повинен повертатися XYZABCDEFGHIJKLMNOPQRSTUVW, а дає вихід XYABCDEFGHIJKLMNOPQRSTUVWZ. Здогадайтесь, чому .. :)
mykhal

@mykhal: Виправлено.
Хайко Обердік

3

PHP - 105 байт

<?preg_filter(~‹§æ“Ö¢‹ö,'$f[$0&fl]++',join('',range(a,z)).$argv[1]);arsort($f);foreach($f as$l=>$F)echo$l;

Ось шістнадцятковий привід спеціальних символів:

0000000 3c 3f 70 72 65 67 5f 66 69 6c 74 65 72 28 7e dc
0000010 a4 be d2 85 a2 dc 9a 2c 27 24 66 5b 24 30 26 df
0000020 5d 2b 2b 27 2c 6a 6f 69 6e 28 27 27 2c 72 61 6e
0000030 67 65 28 61 2c 7a 29 29 2e 24 61 72 67 76 5b 31
0000040 5d 29 3b 61 72 73 6f 72 74 28 24 66 29 3b 66 6f
0000050 72 65 61 63 68 28 24 66 20 61 73 24 6c 3d 3e 24
0000060 46 29 65 63 68 6f 24 6c 3b                     
0000069

І дещо менш гольф-версія:

<?
preg_filter(           // regular expression
  "#[A-z]#e",          // matches every letter + 'eval' flag
  '$f[$0&fl]++',        // so this code runs for every letter
                       // $f is an array whose indices are uppercase letters
                       //   and whose values represent the number of occurences
                       // lowercase is converted to uc with the bitwise and
                       //   fl is 11011111 in binary, every bit except for 32's is set
  join('', range(a,z)) // adding abcdefghijklmnopqrstuvwxyz to the input
    .$argv[1]);        //   because not all letters have to appear in the input
arsort($f);            // sort $f in reverse, maintaining indices
foreach($f as$l=>$F)   //
  echo$l;              // print each index in order

Приклад:

 $ php etaoin_shrdlu.php "This function sorts an array such that array indices maintain their correlation with the array elements they are associated with."
 ATIRESHNOCYUWMDLFXZBVGPQKJ

Як працюють спеціальні персонажі preg_filter()?
Авраам

3
У PHP ~ це побітовий оператор NOT, і ви можете застосувати його і до рядків, і в цьому випадку він працює на кожному символі. Крім того, PHP із задоволенням аналізує рядки тексту як літеральні рядки, враховуючи, що в них немає спеціальних символів (наприклад, оператори, $ для змінних, крапка з комою, парагрази ...). Отже, написання ~ ‹§æ“ Ö ¢ ‹ö (побітна перевернута версія) замість“ # [Az] #e ”зберігає один байт, оскільки його не потрібно цитувати.
Aurel Bílý

А, дякую. Має сенс зараз.
Авраам

1
Наскільки все в PHP має сенс. Святий молі.
пухнастий

echo join(array_keys($f));можна зберегти один байт
Тіт

3

C # в LINQPad - 203 байт

Я по-іншому підходив до відповіді Логана Греблі. Спочатку я переконався, що кожен символ у вхідному рядку відсортований за своїм виглядом і існує лише один раз у вихідному рядку. Після цього я додав кожен вихідний символ з алфавіту у вихідний рядок.

void e(string i){var a="";foreach(var d in i.ToUpper().GroupBy(x=>x).OrderByDescending(u=>u.Count()))if(d.Key<91&&d.Key>64){a+=d.Key;}for(int x=65;x<91;x++)if(!a.Contains((char)x)){a+=(char)x;}a.Dump();}

На жаль, це не перемогло б відповідь Логана Дам, якби я зробив це у Visual Studio.

Більш прочитана версія:

void e(string i)
    {
        var a = "";
        foreach (var d in i.ToUpper().GroupBy(x => x).OrderByDescending(u => u.Count()))
        {
            if (d.Key < 91 && d.Key > 64)
            {
                a += d.Key;
            }
        }
        for (int x = 65; x < 91; x++)
        {
            if (!a.Contains((char)x))
            {
                a += (char)x;
            }
        }
        a.Dump();
    }

Так, більше LINQ любові! : D
ldam

3

C # (і LINQ) 255 226 210 байт

Використовуючи поради Патріка Хуізінга, синтаксис запитів тепер коротший:

namespace System.Linq{class P{static void Main(string[]a){Console.Write((from c in(a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper()where c>'@'&&c<'['group c by c into g orderby-g.Count()select g.Key).ToArray());}}}

Пояснення:

Console.Write(
    (from c //declare our range variable
       in (a[0] + "ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper() //declare the datasource
     where c > '@' && c < '[' //include only letters
     group c by c into g //run of the mill group by
     orderby -g.Count() //order by descending
     select g.Key //we only want the actual letters
     ).ToArray() //mash it all into an array
  );

Синтаксис еквівалентного методу (217):

namespace System.Linq{class P{static void Main(string[]a){Console.Write((a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper().GroupBy(c=>c).OrderBy(c=>-c.Count()).Where(c=>c.Key>'@'&&c.Key<'[').Select(c=>c.Key).ToArray());}}}

Оригінальна публікація:

namespace System.Linq{class P{static void Main(string[]a){(a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper().GroupBy(c=>c).OrderByDescending(c=>c.Count()).Where(c=>c.Key>'@'&&c.Key<'[').ToList().ForEach(c=>Console.Write(c.Key));}}}

Це моє перше в історії подання, і я повинен робити речі на роботі, але це виглядало так весело, тому що я відчував, що можу реально брати участь один раз.

Пояснення:

(a[0] + "ABCDEFGHIJKLMNOPQRSTUVWXYZ") //ensure each character appears once
  .ToUpper()
  .GroupBy(c => c) //get access to .Count()
  .OrderByDescending(c => c.Count())
  .Where(c => c.Key > '@' && c.Key < '[') //exclude anything other than letters
  .ToList() //Only lists have a .ForEach() :(
  .ForEach(c => Console.Write(c.Key)); //print output

Я ніколи не використовую синтаксис методу для LINQ, тому для мене це був досвід навчання :) Також, думаючи про це, я міг би зберегти 2 байти, замінивши букве символів їхніми цілими аналогами, але, мех.

Скорочене завдяки порадам від ProgramFOX та Num Lock :)

Еквівалентний синтаксис запиту (трохи довше):

(from c in (a[0]+"ABCDEFGHIJKLMNOPQRSTUVWXYZ").ToUpper() where c>'@'&&c<'[' group c by c into g orderby g.Count() descending select g.Key).ToList().ForEach(c=>Console.Write(c));

1
З першого погляду ви можете зберегти багато символів, назвавши свій клас просто Pзамість Programі string[]aзамість, string[] argsа не c=>...замість (c)=>....
Num Lock

Замість двох usingоператорів ви також можете помістити свій клас у область System.Linqімен та видалити обидва, використовуючи оператори. Тоді ви можете зберегти деякі символи, і це все одно буде добре.
ProgramFOX

@NumLock Правильно, навіть не думав про це :) @ProgramFOX, що нічого не врятує, тому що namespaceдовше, usingі два зайвих {}s обійдуться мені дорожче.
ldam

1
namespace System.Linq{}явно коротше, ніж using System;using System.Linq;просто дивлячись на це. Ідея полягає в тому, щоб повністю опустити обидва usings.
Num Lock

Ага так, це видаляє обидва, ти маєш рацію, я думав, що це видалило лише одне. Дякую.
ldam

3

C ++ 701 322 232 байт

Перша версія 701 байт (ідіоматичне використання STL)

#define _HAS_TRADITIONAL_STL 1
#include <numeric>
#include <iostream>
#include <iterator>
#include <string>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#define ALL(x) x.begin(), x.end()
using namespace std;
typedef istream_iterator<char> iic;typedef pair<int, char> pic;map<char, int> c;set<pic> d;
void f1(char x) {c[x]--;}
void f2(const pic &p) {d.insert(make_pair(p.second, p.first));}
int main(){string s(26, 0);stdext::iota(ALL(s), 65);copy(ALL(s), ostream_iterator<char>(cout));transform(iic(cin), iic(), back_inserter(s), toupper);for_each(ALL(s), f1);for_each(ALL(c), f2);transform(ALL(c2), ostream_iterator<char>(cout), select2nd<pic>());}

Розширена чиста версія:

#define _HAS_TRADITIONAL_STL 1
#include <numeric>
#include <iostream>
#include <iterator>
#include <string>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
using namespace std;

typedef istream_iterator<char> iic;
map<char, int> counts;
set<pair<int, char> > counts2;

void docount(char ch) { counts[ch]--; }
void toCounts2(const pair<char, int> &p) { counts2.insert(make_pair(p.second, p.first)); }

int main()
{
    string s(26, 0);
    stdext::iota(s.begin(), s.end(), 65);
    transform(iic(cin), iic(), back_inserter(s), toupper);
    for_each(s.begin(), s.end(), docount);
    for_each(counts.begin(), counts.end(), toCounts2);
    transform(counts2.begin(), counts2.end(), ostream_iterator<char>(cout), select2nd< pair<int, char> >());
}

Ідея полягає в тому, щоб продемонструвати "правильну" програму C ++ без жодних злому. Ігноруйте котельну плиту і той факт, що вона збирається лише на VC ++

Пояснення:

Ми заповнюємо від A до Z у рядок з iota () , це гарантує, що коли ми підраховуємо події, кожен символ з'являється, навіть якщо його немає у вході.

transform () копіює символ за символом зі стандартного вводу і ставить його в кінець s після виклику toupper () на кожному з них

Кількість кожного символу зменшується на карті (зберігаючи від’ємні підрахунки, ми можемо мати низхідний сорт без додаткового коду)

Записи на карті підрахунків копіюються на набір пар, змінюючи (char, count) на (count, char). Оскільки набори впорядковані, ми отримуємо їх сортування за зменшенням кількості частот

Нарешті ми копіюємо вміст набору для стандартного використання, використовуючи перетворення та використовуючи select2nd (), щоб вибрати лише другого члена пари.

Код досить читабельний. Рішення C ++ 11 виглядало б набагато красивіше, оскільки ми можемо використовувати лямбда

Версія C ++ 11 - не потрібні лямбдахи, але автоматичний і діапазон на основі робить речі дуже чистими (подумайте про це, ви можете зробити дуже схоже з звичайним C ++ 98)

#include<iostream>
#include<iterator>
#include<map>
#include<set>
using namespace std;int main(){istream_iterator<char> b(cin),e;map<char,int> c;set<pair<int,char>> d;for(char i='A';i<='Z';++i){--c[i];}for(auto i=b;i!=e;++i){c[toupper(*i)]--;}for(auto p:c){d.insert(make_pair(p.second,p.first));}for(auto p:d){cout<<p.second;}}

Розширена версія:

#include <iostream>
#include <iterator>
#include <map>
#include <set>
using namespace std;
int main()
{
    istream_iterator<char> b(cin), e;
    map<char, int> c;
    set<pair<int, char>> d;
    for(char i = 'A'; i <= 'Z'; ++i) {--c[i];}
    for(auto i = b; i != e; ++i) {c[toupper(*i)]--;}
    for(auto p : c) { d.insert(make_pair(p.second, p.first)); }
    for(auto p : d) { cout << p.second; }
}

Наступна ітерація (чому читати зі stdin, коли у нас є argv):

#include <set>
#include <iostream>
int c[256];int main(int n, char **s){std::set<std::pair<int,char>> d;while(*s[1]){c[toupper(*s[1]++)]--;}for(n=65;n<92;++n){d.insert(std::make_pair(--c[n],n));}for(auto p:d){std::cout<<p.second;}}

Розширена версія:

#include <set>
#include <iostream>
int c[256];
int main(int n, char **s)
{
    std::set<std::pair<int, char>> d;
    while (*s[1])
    {
        c[toupper(*s[1]++)]--;
    }
    for (n = 65; n < 92; n++)
    {
        d.insert(std::make_pair(--c[n], n));
    }
    for (auto p : d)
    {
        std::cout << p.second;
    }
}

3

Желе , 9 байт (не конкуруючий)

ØAŒuċ¥@ÞU

Пояснення

ØAŒuċ¥@ÞU  Main Link
       Þ   Sort
ØA         The uppercase alphabet by
  Œuċ¥@    number of occurrences in the input:
  Œu       Uppercase
    ċ      Count occurrences
     ¥     Grammar: Last two links as a dyad
      @    Swap arguments
        U  Reverse (because sort sorts up)

Це звучить як "сортування великого алфавіту за кількістю входів у верхньому регістрі вводу, переверненому", що є досить буквальним перекладом завдання: P

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

Ця проблема була пов'язана з Jelly HyperTraining, де ми вирішили цю проблему. Я розмістив це, тому що я першим дійшов до 10 байт.

-1 байт завдяки Еріку Побіжному (вчитель JHT)


9 байт:ØAŒuċ¥@ÞU
Ерік Атголфер

@EriktheOutgolfer О, здорово, спасибі!
HyperNeutrino

2

C ++ 377

Реалізує qsort, використовуючи кількість літер у масиві n, щоб сортувати алфавіт у масиві A. Запустити через командний рядок: golf.exe < in.txt

int n[26],c,k,N;
char A[26];
int C(const void*a,const void*b)
{
int i=(int)(*(char*)a -'A');
int j=(int)(*(char*)b -'A');
return n[j]-n[i];
}
int main()
{
for(;k<26;k++)
{
A[k]=k+'A';
}
N=sizeof(A);
c=getchar();
while(c>0)
{
c=toupper(c);
c=c-'A';
if(c>=0&&c<26)n[c]++;
c=getchar();
}
qsort(A,N,1,C);
for(k=0;k<N;k++)
{
putchar(A[k]);
}
return 0;
}

2

C, 117 (119) байт

x[256];m=1;char c;main(){while(c=getchar()+1)++x[c-1&95];for(;m=x[++c]<x[m]?m:c;x[m<65|m>90||c?m*!c:putchar(m)]=-1);}
  • Деякі входи, що містять коди ASCII> = 128, неправильно збільшать частоту букв. Щоб виправити це, замініть постійну95 на 223, вартістю 1 зайвий байт.
  • Це припиняється достроково на входах, що містять символ з кодом ASCII 255. Щоб виправити це за рахунок 1 додаткового байта, перейдіть char c;на справедливий c;і ++cна c=c+1%255.

2

PowerShell - 139 символів

По-перше, я не експерт PowerShell. Досить впевнений, що коротші за це. Але був задоволений цим і вирішив поділитися.

$a = Read-host
$b = ($a.ToUpper() -replace '[^A-Z]','').ToCharArray() + (65..90|%{[char[]]$_})|Group|sort Count -desc|%{$_.Name}
-join $b

Як це працює:

$a = Read-host            # read from stdin and save into a string var $a
$a.ToUpper()              # Convert the string to UPPERCASE
-replace'[^A-Z]',''       # Remove all non A-Z characters from the str
(...).ToCharArray()       # Convert the inner object (string) to a Char Array
+  (65..90|%{[char[]]$_}) # Create another char array with A-Z chars expanded, 
                          #  and append it to the previous one.
|Group                    # Group the char array by value for each element, 
                          #  consolidates them and count each char occurrence. Example:
                          #  Count | Name
                          #  ----- | -----
                          #      4 | B
                          #      1 | F
                          #      2 | C 
                          #     .. | ..
                          # 
|sort Count -desc         # Sorts the previous hash-table by the 'Count' column 
                          #   in desc ordering
|%{$_.Name}               # Grab only the 'Name' column from the previous sorted hash-table. 
                          # The retuslt obj will be a simple char array again, 
                          #   with the letters in the desired order
$b = (...)                # Saves the resulting char array into a new variable $b
-join $b                  # join the resulting char array elements into a single 
                          #   string, and print it to stdout. 


2

APL, 26 20 символів

⎕a[⍒+/⎕a∘.=('\w'⎕r'\u0')⍞]

⎕a[⍒+/⎕a∘.=1(819⌶)⍞]

-6 дякую Адамові.


1
('\w'⎕r'\u0')1(819⌶)
Adám
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.