ETAOIN SHRDLU高尔夫


43

挑战的简短描述:
基于ETAOIN SHRDLU,您的挑战是要使用任何语言编写最短的程序或函数,根据输入频率来输出26个英文字母。

真正长久,干燥且彻底的规格:

  • 您的程序/函数将接收一串文本作为输入,其中将包含一个或多个大写和/或小写字母,还可能包含标点符号,数字,符号和其他非字母字符。
  • 程序/功能必须输出英文字母的26个大写字母,包括那些未出现在输入中的字母,根据它们在输入中出现的次数从高到低排列。
  • 编辑:频率是不区分大小写的,但是输出必须为大写。
  • 如果两个或多个字母具有相同的频率,则它们可以以任何顺序排列。
  • 不允许其他输出,例如空格。
  • 编辑7/1/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条联系。

编辑:

比赛结束了!感谢所有参加的人。现在为获胜者!:丹尼斯的CJamisaacg的Pyth答案都高达19个字符。(对不起,但是我不会接受其中的任何一个答案,因为我认为这对其他人都不公平。) 编辑:听取丹尼斯的建议,我将他的答案标记为已接受,因为他是第一个回答。达到19个字符。值得一提的是,Ilmari Karonen的第三位Golfscript答案为22个字符,以及地下单轨铁路的75个字符的Python答案,该投票获得了最多的好评。再次感谢所有参与的人!


是否仅针对输入的大写字母测量频率?
2014年

2
@IlmariKaronen是的,换行符被视为空格,因此将不允许使用。
亚伯拉罕

8
@亚伯拉罕:IMO;如果某些语言允许(特别是)尾随换行符,则所有语言通常应允许;至少是因为文本流应以换行符和EOF结尾。
Williham Totland

3
@WillihamTotland根据您评论的投票数,我将修改规则以允许尾随换行符。
亚伯拉罕

1
如果用最短的代码得到两个答案,该怎么办?建议将绿色复选标记授予较早的解决方案。isaacg首先发布了他的答案,我首先将我的高尔夫球打到了19个字节。无论您选择哪一个领带打破者都对我都很好,但我认为根本没有公认的答案有点反气候。
丹尼斯

Answers:


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

Python 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!
Izkata 2014年

6
@Izkata重要的是它向您显示读取代码的顺序。因为开始阅读高尔夫球代码的最佳位置很少见,特别是当它变得比这更复杂或更简洁时。
Martin Ender

1
漂亮的演示!
xnor

3
@Izk我的目标是使不了解python的人可以理解它。在一个真实的项目中,我永远不会发表这样的评论。
地下

2
@imm号count不是变量或其他任何东西,它是文字函数。能够-1通过-在前面加一个a来乘以一个函数的返回值,就像python所没有的功能那样酷。
地下

15

Bash,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可移植性通常不是代码高尔夫答案中的关注点。
凯文(Kevin)

1
没有可移植性,此答案的作用尚不明确。
克里斯·

@ChrisDown:我已经测试了一些字符串和一些语言环境,但是我找不到一个uniq行为不正确的示例。你能给我看看吗?
丹尼斯

@ChrisDown如果外壳为bash或ksh93,则此脚本可移植性足以使用BSD版本的fold,sort,tr,uniq在OpenBSD上运行。其他shell(例如zsh)无法扩展{A..Z}。所有LC_COLLATE语言环境都可以使用,因为OpenBSD仅具有LC_COLLATE = C。
kernigh

12

Pyth 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):列表[Z中的k个计数,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:将输入转换为大写并存储在J中。

o:(打印)排序方式

_cJN:-1 *(J中的N个数)

UG:在大写字母中超过N。

这不是合法的解决方案,因为从Pyth 1.0.2到1.0.4的一些更改(包括添加o,sort by,函数)是针对此问题的。


我建议您将Pyth链接更新到Pyth的官方页面(如果存在)。
AL

@AL这是Pyth的官方页面,直到我张贴了esolang条目。
isaacg 2014年

为什么需要将输入存储在变量Z中以便以后再次引用它?只是将表达式Z放在其位置会导致多次读取输入吗?
xnor

@xnor Z所使用的位置在lambda函数内部,因为它在映射的第一个参数中,因此需要将其保存到变量中。使用Uw确实会导致输入被读取26次。
isaacg 2014年

1
@AL好吧,Pyth在esolang和github上都可以使用。github链接位于esolang页面的底部,该链接在答案中。Github会进行代码着色。
isaacg 2014年

11

使用Javascript(ES6119 117

编辑:(-2)删除了toUpperCasesplit调用中使用不区分大小写的RegEx的需要。

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
溅出一串……令人愉快!
Bergi 2014年

10

GolfScript,22个字符

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

在线尝试。

说明:

  • :?将输入字符串分配给符号?。(我使用标点符号,以便不会将以下数字91解析为符号名称的一部分。)
  • 91,构造一个从0到90(ASCII码为Z)的数字的列表。
  • + 将此列表附加到输入字符串,从而将其从ASCII代码数组转换为字符串(并且还方便地从堆栈中删除输入字符串)。
  • -26>接受此字符串的最后26个字符,产生一个字符串,其中包含从A到的大写ASCII字母Z
  • { }$代码块应用于输入字符串中的所有字符,并根据结果对这些字符进行排序。
  • 在代码块内,.复制字符32+并将副本从大写转换为小写。的]这两个字符收集到一个数组,?\-需要存储在输入串?并从它移除阵列中的字符的所有实例,并,计数剩余的字符串的长度,这将是排序键。字符将通过此键以升序排序,因此以出现次数降序排序。

1
看起来我们有几乎相同的想法。小错误:字母Z丢失。应该是91,+-26>
丹尼斯2014年

@丹尼斯:嗯,哎呀。已修正,尽管谁仍然需要那封信?:)
Ilmari Karonen 2014年

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-呢?
林恩

@毛里斯很好抓住!我对其进行了编辑并删除了另一个字符。
Flonk

6

Ruby 2.0,53个字符

编辑:修复为正确使用多行字符串,谢谢@ 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个字符。
Paul Prestidge 2014年

6

Perl,54个 46字节

更新:经过进一步的优化后,它可能被压缩为46个字节:(thx dennis表示-n/ {}hack;Chinese perl goth表示<=>-> -hack)

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

它与run with一起运行 perl -nE

原始解决方案(不需要特殊的Perl选项):

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

在Perl 5.8.3、5.14.2中验证

如果你得到一个警告,独立的egfor有空间(+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 2014年

1
是的,-n环绕while(<>){...}代码。我避免编辑其他用户的代码。太容易犯错误,有些东西只有在某些电脑上工作,等等
丹尼斯

1
乔:我说的是}{“注射”,而不仅仅是众所周知的-n选择。有人可能会想到的是,代码串其实技术上由while循环代码串执行之前包裹,不仅只是它在某种程度上作品等作为,如果它被包裹..
mykhal

1
保存另外两个字符:替换$h{$b}<=>$h{$a}$h{$b}-$h{$a}
chinese perl goth 2014年

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
Martin Ender

4

C ++,185个 183 179 177字节

当然不会期望赢(C ++会赢吗?),但还是一个有趣的练习。

#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

常规- 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个字母,而不仅仅是输出在输入字符串中的那些字母。
algorithmhark

@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 Lp 2014年

4

SAS-217(我认为)

输入应该放在cards4语句之后的行上,或者放置在适合您系统的打孔卡上。我认为与尝试引用输入相比,这种方法节省了一些字符。

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 中是正确的。我可以在代码高尔夫中使用它,但是脚本的其余部分太罗word了。我使用了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 157156字节

编辑:将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年就有了我发现更有趣的代码,但是舒适地drei的排序方法更短,并且需要len(一个或多个),这使得第一个循环的“ for”比“ 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,否则您将始终打印整个字母。
comfortablydrei

1
@comfortablydrei需要打印整个字母。“程序/功能必须仅输出英文字母的26个大写字母,包括那些未出现在输入中的字母”
JesterBLUE 2014年

哇 想念那个。那是我的错 谢谢!
2014年

3

J- 38 35个字符

以右侧输入为字符串的函数。不是赢家,但写得很有趣。

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

解释:

  • toupper是标准库中的动词,用于大写字符串。然后,它成为动词的右侧参数,而左侧参数是字母:ASCII代码点65到90。

  • [,e.~#])选择(#)右侧arg(])中属于e.~左侧()元素的,然后在(,)左侧arg([)之前加上前缀。明智的做法是,我们仅保留大写字符,并在末尾添加单个字母副本,以确保我们将它们全部捕获。

  • #/.~@然后给出每个字符的频率。碰巧这是按字母顺序给出的,因此之后我们可以对(\:对字母()进行降序(左参数[)。

下面是一个简单的懒惰示例。请随时在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'输出而言,bot不是应该的,它应该返回XYZABCDEFGHIJKLMNOPQRSTUVW,而是使用yield XYABCDEFGHIJKLMNOPQRSTUVWZ。猜猜为什么.. :)
mykhal 2014年

@mykhal:固定。
Heiko Oberdiek

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”可以节省一个字节,因为不必引用它。
AurelBílý14年

嗯谢谢 现在有意义。
亚伯拉罕

1
就PHP中的一切有意义而言。天哪。
蓬松的

echo join(array_keys($f));可以保存一个字节
Titus

3

LINQPad中的C#-203字节

我采用了另一种方法来回答洛根·达姆(Logan Dam)。我首先确保输入字符串中的每个字符都按其外观排序,并且在输出字符串中仅存在一次。之后,我将字母表中所有缺少的字符添加到输出字符串中。

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中完成的话,它不会击败Logan Dam的答案。

更具可读性的版本:

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
拉丹2014年

3

C#(与LINQ)255个 226 210字节

使用Patrick Huizinga的建议,查询语法现在变得更短:

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而不是Programand string[]a而不是string[] argsand c=>...来命名来节省很多字符(c)=>...
Num Lock

除了两个using语句,您还可以将您的类放在System.Linq名称空间中,并使用using语句删除它们。然后,您可以保存一些字符,它将仍然可以正常工作。
ProgramFOX

@NumLock对,甚至都没有想到:) @ProgramFOX不会为我节省任何费用,因为namespace它的长度超过using,而另外两个{}s会使我付出更多。
拉丹2014年

1
namespace System.Linq{}显然比using System;using System.Linq;仅仅看短。这个想法是using完全省略两者。
Num Lock

嗯,是的,它同时删除了两个。谢谢。
拉丹2014年

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 ++上编译的事实

说明:

我们使用iota()将A到Z填充到字符串中,这确保了当我们计算出现次数时,即使每个字符不在输入中,它也会出现。

transform()从标准输入中逐字符复制字符,并在每一个调用toupper()之后将其放入s的末尾

映射中每个字符的数量递减(通过保持负数,我们无需额外代码即可进行降序排序)

将计数映射条目复制到一组对,将(字符,计数)交换为(计数,字符)。由于集合是有序的,我们通过减少频率计数来对它们进行排序

最后,我们使用transform和select2nd()将集合的内容复制到标准输出中以仅挑选出该对中的第二个成员。

该代码相当可读。C ++ 11解决方案看起来会更漂亮,因为我们可以使用lambda

C ++ 11版本-不需要lambda,但基于的自动和范围使事情变得非常干净(想起来,您可以使用常规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; }
}

下一次迭代(为什么我们在有argv时从stdin中读取):

#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个字节感谢Outgolfer的Erik(JHT老师)


9个字节:ØAŒuċ¥@ÞU
Erik the Outgolfer

@EriktheOutgolfer哦,太好了,谢谢!
HyperNeutrino

2

C ++ 377

使用数组n中的字母计数实现qsort以便对数组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的输入将错误地增加字母频率。为了解决这个问题,更换常数95223,在1个额外的字节的成本。
  • 这将在含有ASCII码255字符要在1个额外的字节,变化的成本解决这个问题的投入提前终止char c;只是c;++cc=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

锡兰,98字节

String f(String s)=>String(('A':26).sort(byDecreasing((Object c)=>s.uppercased.count(c.equals))));

2

APL,26个 20个字符

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

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

-6感谢亚当。


1
('\w'⎕r'\u0')1(819⌶)
亚当
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.