ETAOIN SHRDLUゴルフ


43

ショートと挑戦の甘い説明:
オフに基づいてETAOIN SHRDLUは、あなたの挑戦は、入力中にその頻度に基づいて、英語のアルファベットの26個の文字を出力し、任意の言語での最短のプログラムや関数を記述することです。

本当に長く、乾燥した完全な仕様:

  • プログラム/関数は、1つ以上の大文字または小文字を含むテキスト文字列を入力として受け取り、句読点、数字、記号、およびその他の非アルファベット文字も含む場合があります。
  • プログラム/関数は、入力に出現しない回数も含めて、入力に出現する回数に基づいて頻度の高い順に並べた、英語のアルファベットの26の大文字のみを出力する必要があります。
  • 編集:頻度は大文字と小文字を区別せずに計算されますが、出力は大文字でなければなりません。
  • 2つ以上の文字が同じ頻度を持っている場合、それらは任意の順序である可能性があります。
  • 空白などの他の出力は許可されません。
  • 編集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文字に達する。称賛に値する言及は、22文字でのIlmari Karonenの3位のGolfscriptの回答と、最も多くの賛成を得た地下モノレールの75文字のPythonの回答です。参加したすべての人に感謝します!


入力の大文字についてのみ頻度が測定されますか?
ハワード14年

2
@IlmariKaronenはい、改行は空白としてカウントされるため、許可されません。
アブラハム14

8
@アブラハム:IMO; 一部の言語で(具体的に)末尾の改行が許可されている場合、一般的にすべての言語で許可される必要があります。少なくともテキストストリームは改行とそれに続くEOFで終了する必要があるためです。
ウィリハムトットランド14

3
@WillihamTotlandは、コメントの賛成票の数に基づいて、末尾の改行を許可するようにルールを変更します。
アブラハム14

1
最短のコードで2つの答えがある場合はどうしますか?以前のソリューションに緑色のチェックマークを付けることをお勧めします。isaacgが最初に彼の答えを投稿しました。最初に19バイトまでゴルフをしました。どちらのタイブレーカーを選んでも大丈夫ですが、受け入れられた答えがまったくないということは、私の意見では少し反気候的です。
デニス14

回答:


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

出現回数が増えると、削除される文字が増えるため、最も頻繁に出現する文字が配列の先頭に表示されます。


本当に賢い。
アブラハム14

@Dennisおめでとうございます!
アブラハム14

43

Python 2または3- 77 75バイト

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

STDINから入力を取得する前に回答がありましたが、技術的に無効であることに気付きました。使用しinput()たのは1行のみですが、質問の入力例では、一度に複数の行を処理する必要があることが示されています。仕様を満たすために、私は答えを文字列引数を取る関数に変えました。驚いたことに、2バイト小さくなりました!それはその私には発生しなかった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へようこそ!
イズカタ14

6
@Izkata重要なことは、コードを読む順番を示していることです。ゴルフされたコードを読み始めるのに最適な場所はめったに明らかではないので、特にこれよりも少し複雑または簡潔になる場合。
マーティンエンダー14

1
美しいプレゼンテーション!
xnor 14

3
@Izk私の目標は、Pythonを知らない人が理解できるようにすることでした。実際のプロジェクトでは、このようなコメントは決してしません。
地下

2
@imm No. countは変数でも何でもありません。リテラル関数です。関数の戻り値に-1a -を前に付けることで乗算できるのと同じくらいクールですが、これはpythonが持つ機能ではありません。
地下

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)を強制する必要があります。
クリスダウン14

6
@ChrisDownポータビリティは、一般的にゴルフの答えのコードでは問題になりません。
ケビン14

1
移植性がなければ、この答えが何をするかは明確に定義されていません。
クリスダウン14

@ChrisDown:いくつかの文字列といくつかのロケールをテストしましたが、uniqがアルファベット文字に対して誤動作する例を見つけることができませんでした。見せていただけますか?
デニス14

@ChrisDownこのスクリプトは、シェルがbashまたはksh93の場合、fold、sort、tr、uniqのBSDバージョンを使用してOpenBSDで実行するのに十分な移植性があります。zshなどの他のシェルは、展開に失敗し{A..Z}ます。OpenBSDにはLC_COLLATE = Cしかないため、すべてのLC_COLLATEロケールが機能します。
カーニグ14

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(ソート、機能の追加を含む)がこの問題に対応していたため、これは法的解決策ではありません。


Pythの公式ページへのリンクがある場合は、それを更新することをお勧めします。
AL

@ALこれは、エソランエントリを作成するまでのPythの公式ページです。
isaacg

Z後で一度参照するために入力を変数に保存する必要があるのはなぜですか?Z代わりに式を置くだけで、入力が複数回読み取られますか?
xnor 14

@xnor Zが使用される位置は、ラムダ関数の内部にあります。これは、マップの最初の引数にあるため、変数に保存する必要があるためです。Uwを使用すると、実際に入力が26回読み取られます。
isaacg 14

1
@AL Alright、Pythはesolangとgithubの両方で稼働しています。githubリンクは、回答にリンクされているesolangページの下部にあります。Githubはコードの色付けを行います。
isaacg 14

11

Javascript(ES6119 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(''))

代替(同じ長さ):ソートと文字カウントを1つの関数に凝縮しました。

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

関数として:105 104

編集:(-1)ソートと文字カウントを1つの関数に凝縮しました。

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

1
興味深いテクニック。
マット14

1
文字列を飛び散る...楽しい!
ベルギ14

10

GolfScript、22文字

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

オンラインでお試しください。

説明:

  • :?入力文字列をシンボルに割り当てます?。(句読点記号を使用して、次の番号91が記号名の一部として解析されないようにします。)
  • 91,0から90までの数字のリスト(ASCIIコードZ)を作成します。
  • + このリストを入力文字列に追加し、ASCIIコードの配列から文字列に変換します(また、スタックから入力文字列を削除すると便利です)。
  • -26>は、この文字列の最後の26文字を受け取り、からAまでの大文字のASCII文字を含む文字列を生成しますZ
  • { }$入力文字列内のすべての文字のコードブロックを適用し、その結果に応じてそれらの文字をソート。
  • コードブロック内で、.文字を複製し32+、コピーを大文字から小文字に変換します。]、アレイにこれらの2つの文字を収集する?\-に格納された入力文字列を受け取り?、そこからアレイ内の文字のすべてのオカレンスを削除し、,ソートキーになり、残りの文字列の長さをカウントします。文字はこのキーによって昇順で、したがって出現回数の降順でソートされます。

1
ほぼ同じ考えを持っていたようです。軽微なバグ:文字Zが欠落しています。あるはずです91,+-26>
デニス14

@デニス:ああ、おっと。とにかく、誰がその手紙を必要としますか?:)
イルマリカロネン14

2
@IlmariKaronenコミュニティのフィードバックに基づいて、末尾の改行を許可するようにルールを修正しました(完全な説明については質問を参照してください)。あなたのスコアは今22ではなく25:)
アブラハム14

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文字

編集:複数行の文字列で正しく動作するように修正、ありがとう@ 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一度に1行を返します。に変更getsすることで修正できますgets$nが、関数に変更すると1文字短くなります。
ポール・プレスティッジ14

6

Perl、54 46バイト

UPDATE:それが圧迫することができ、さらに最適化した後、46バイト:(THX デニス-n/ {}ハック; 中国のperlがゴスのために<=>- > -ハック)

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///upcased(インクリメントこと)uc)文字(./ $&より明白より短いです(.)/ $1)(初期化されていない)ハッシュ()でカウントし%hます。次に、ソート頻度比較関数で文字頻度ハッシュを使用して、大文字のアルファベットを正しい順序で出力します。


1
短く、エラーメッセージなし:perl -ne 's/./$h{uc$&}++/eg}{print sort{$h{$b}<=>$h{$a}}A..Z'
デニス14

デニス:非常に興味深い、タイプミスのように見えます。私はいくつかを使用してバリアント持っていた-nEND{}、彼らは常に長かった..あなたがしたい場合は、その答えを更新して自由に感じる
mykhal

1
はい、コードを-n囲みwhile(<>){...}ます。他のユーザーのコードを編集することは避けます。ミスを犯しやすい、いくつかのコンピューターなどでしか機能しないものなど
デニス

1
ジョー:}{よく知られている-nオプションだけでなく、「注入」についても話していました。一つは、コード文字列が実際に技術的にすることを期待していない可能性がありますされていないだけちょうどそれが何らかの形で機能することを、実行する前に、whileループコード列によってラップとしてのように、それが包まれていた場合...
mykhal

1
さらに2つの文字割引:置き換える$h{$b}<=>$h{$a}$h{$b}-$h{$a}
ゴス中国のperlの

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:提案された編集を2回拒否しました。拒否投票の理由が通知されるかどうかはわかりませんので、これを読んだ場合は、コメントでゴルフの改善を提供してください。そうすれば、OPがそれらを確認できます。その理由は次のとおり
マーティン・エンダー

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

重要なのは、左の配列を追加することです。これにより、すべての文字が使用可能になり、すでに順番に並んでいます。名詞をフォークの3番目のタインとして使用することの面白い結果は、フレーズと同様に動詞としても機能することです。


4

グルービー- 130 123 115 112 98 92

@cfrickのアドバイスに従って(2回!):

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 14

@algorithmshark、確かに、私の間違い、修正
Will Lp 14

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

1
別の6バイト:it.grep(~/(?i)$c/)の代わりit.toUpperCase().grep(c)
cfrick

@cfrickうわー!再度、感謝します!それtoUpperCaseは私に地獄を悩ませていました。
ウィルLp 14

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
cat

4

AppleScript、278

"a" = "A"AppleScriptでもそうだと気付きました。これはコードゴルフで使用できますが、スクリプトの残りの部分は冗長です。AppleScript 1.8.3を使用しました。

これは関数を定義しますff("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でより興味深いコードを見つけましたが、快適に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、さもなければあなたは常にアルファベット全体を印刷する。
快適に14

1
@comfortablydreiアルファベット全体を印刷する必要があります。「入力中に表示されないものも含め、英語のアルファベットの大文字のみ26文字、プログラム/関数を出力しなければならない」
JesterBLUE

おっと。それを逃した。それは私の間違いです。ありがとう!
快適に14

3

J- 38 35文字

右側の入力を文字列として受け取る関数。勝者ではありませんが、書くのは楽しかったです。

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

説明:

  • toupper文字列を大文字にする標準ライブラリの動詞です。これが動詞の右の引数になり、左の引数がアルファベットになります:ASCIIコードポイント65〜90。

  • [そして,e.~#])選択(#右引数で)これらの文字(]の要素(ARE) e.~)放置し、次いでプリペンド(,)左のarg( [)。つまり、大文字だけを保持し、アルファベットのコピーを最後に追加して、すべてをキャッチできるようにします。

  • #/.~@次に、各文字の頻度を示します。そのため、これはアルファベット順で指定されるため、その後すぐに\:アルファベット(左引数[)をダウンソート()できます。

以下に簡単な怠exampleな例を示します。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_CONCATMySQLなどの関数をエミュレートできます。

@変数の宣言:

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 14

@mykhal:修正されました。
ヘイコOberdiek 14

3

PHP-105バイト

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

特殊文字の原因である16進ダンプを次に示します。

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()機能しますか?
アブラハム14

3
PHPでは〜はビット単位のNOT演算子であり、文字列にも適用できます。この場合、すべての文字で機能します。さらに、PHPはテキスト文字列を特別な文字(演算子、変数の$、セミコロン、括弧など)がない場合、文字列リテラルとして解析できます。したがって、 "#[Az] #e"の代わりに〜‹§æ "Ö¢‹ö(ビット単位の反転バージョン)を記述すると、引用符で囲む必要がないため、1バイト節約できます。
オーレルビリー14

ああ、ありがとう。今理にかなっています。
アブラハム14

1
PHPで何かが理にかなっている限り。聖なるモリー。
ふわふわ14

echo join(array_keys($f));1バイトを保存できる
Titus

3

LINQPadのC#-203バイト

ローガン・ダムの答えに対して、私は別のアプローチを取りました。最初に、入力文字列のすべての文字がその外観によってソートされ、出力文字列に1回だけ存在することを確認しました。その後、アルファベットの欠落文字をすべて出力文字列に追加しました。

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
ldam 14

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代わりにProgram、のstring[]a代わりにstring[] args、のc=>...代わりに、の代わりに、多くの文字を節約できます(c)=>...
Num Lock 14

2つのusingステートメントの代わりに、クラスをSystem.Linq名前空間内に配置し、両方のusingステートメントを削除することもできます。その後、いくつかのキャラクターを保存できますが、それでも正常に機能します。
ProgramFOX 14

ので、何も私に保存されません@NumLock右、でもそのことを考えていなかった:) @ProgramFOXをnamespaceより長いusingと2つの余分な{}sがより多くの私の費用がかかります。
ldam 14

1
namespace System.Linq{}using System;using System.Linq;見ているだけでなく、明らかに短いです。アイデアは両方usingのsを完全に省略することです。
Num Lock 14

ああ、それは両方を削除します、あなたは正しいです、私はそれが一方だけを削除したと思っていました。ありがとう。
ldam 14

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()は標準入力から文字ごとにコピーし、それぞれに対してtoupper()を呼び出した後にsの末尾に配置します

各文字のカウントはマップ内で減少します(負のカウントを維持することにより、追加のコードなしで降順ソートを行うことができます)

カウントマップエントリはペアのセットにコピーされ、(char、count)から(count、char)にスワップされます。セットは順序付けられているため、頻度カウントを減らすことでセットをソートします

最後に、セットのコンテンツを標準出力にコピーします。変換を使用し、select2nd()を使用してペアの2番目のメンバーのみを選択します。

コードはかなり読みやすいです。ラムダを使用できるため、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; }
}

次の反復(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バイトに到達したからです。

Erik the Outgolfer(JHT教師)のおかげで-1バイト


9バイト:ØAŒuċ¥@ÞU
エリック・ザ・アウトゴルファー

@EriktheOutgolferああクール、ありがとう!
ハイパーニュートリノ

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以上の一部の入力では、文字の頻度が誤って増加します。これを修正するには、1バイト余分に、定数95をに置き換え223ます。
  • これは、ASCIIコード255の文字を含む入力で早期に終了します。1バイトの追加コストでこれを修正するには、char c;just 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⌶)
アダム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.