娘のアルファベット


65

先日、私たちは娘と冷蔵庫のマグネットレターで文章を書いていました。一部(I love cat)を作成することはできましたがI love you too、文字数が不足しているためo(4)

次に、1つのセットに3 e文字が含まれていたのに、2 o文字しかなかったことがわかりました。おそらくhttp://en.wikipedia.org/wiki/Letter_frequencyに触発されたものですが、これは「冷蔵庫」の実際の状況をまだ反映していません。

問題

各行に "サンプル文"が含まれているテキストファイルを冷蔵庫に書きたい場合、最小限の文字数で、各文を個別に書くのに十分なアルファベットセットを提案します。

注:大文字小文字は無視してください。磁石文字はすべて大文字です。

入力

ファイルには改行で区切られた文が含まれます。

hello
i love cat
i love dog
i love mommy
mommy loves daddy

出力

バックソートされた文字のリストを提供します。各文字は、文章を書くのに十分な回数だけ表示されます。

acdddeghillmmmoostvyy

(ありがとう、isaacg!)

勝者

最短の実装(コード)

更新:テスト

私は追加のテストを作成し、さまざまな答えをここで試しました:

https://gist.github.com/romaninsh/11159751


2
v出力に手紙があるはずです;)
アントニオラガニン14

40
我々は逆さま代用するために必要な/許可されているMためにW、または横向きNのためにZ?;-)
イルマリカロネン14

4
基本的に、Is を使用して任意の文字を作成できます。
スウィッシュ

7
もっと深刻なことに、「ケースを無視する」と言うとき、入力がすでにすべて同じケースにあると仮定できるのか、それともすべてを同じケースに変換しなければならないという意味ですか?また、出力に先行スペースが含まれていても問題ありませんか?
イルマリカロネン14

3
@Doorknob:_\¯
イルマリカロネン14

回答:


18

GolfScript、28/34文字

n/:a{|}*{a{.[2$]--}%*$-1=}%$

上記の28文字のプログラムは、すべての入力文字が同じ大文字と小文字であると想定しています。これが必ずしもそうでない場合は{95&}%、コードの先頭に合計34文字を追加することで、大文字にすることができます。

{95&}%n/:a{|}*{a{.[2$]--}%*$-1=}%$

ノート:

  • 正しく動作させるには、入力に少なくとも1つの改行を含める必要があります。これは、各行の最後に改行がある通常のテキストファイルには当てはまりますが、入力が末尾の改行なしの1行だけで構成される場合は当てはまらない場合があります。これはn+、コードの先頭に追加することにより、2文字の追加コストで修正できます。

  • 34文字バージョンで使用される大文字は実際には粗雑です。小文字のASCII文字を大文字の同等の文字(およびNULsにスペース)にマップしますが、数字とほとんどの句読点を完全に混乱させます。入力にはそのような文字は含まれないと想定しています。

  • 28文字バージョンは、すべての入力文字(改行とNULs を除く)を同等に扱います。特に、入力にスペースが含まれている場合は、出力にもスペースが含まれます。便利なことに、他の印刷可能なASCII文字の前にソートされます。ただし、34文字バージョンはスペースを無視します(余分な文字を必要とせずに実行できることがわかっているため)。

説明:

  • オプションの{95&}%プレフィックスは、各入力バイトのASCIIコードの6ビット目をゼロにすることで入力を大文字にします()。これにより、小文字のASCII文字が大文字に、スペースがNULLバイトにマップされ、改行は変更されません。95 = 64 + 31 = 10111112

  • n/入力を改行で分割し:a、結果の配列を変数に割り当てますa。次に{|}*、配列内の文字列の和集合を計算します(配列に少なくとも2つの要素があると仮定すると)、入力内のすべての一意の(改行以外の)文字を含む文字列が生成されます。

  • 次の{ }%ループは、これらの一意の文字のそれぞれに対して繰り返します。ループ本体の内部では、内側のループa{.[2$]--}%が配列内の文字列を反復処理し、a各文字列から、外側のループが反復している文字とは異なる文字をすべて削除します。

    内側のループは、現在の文字のASCIIコードを、フィルタリングされた配列の下のスタックに残します。これを利用するには、ASCIIコード(*)で示される回数だけフィルターされた配列を繰り返してから、ソート($)し、最後の要素(-1=)を取得します。実際には、これは(それらはすべて同じ文字の繰り返しで構成されて、辞書式ソートはちょうど長さによってそれらをソート)し、濾過し、配列の中で最も長い文字列を生成する以外の文字が、それは何も得なかった場合にはASCIIコードのゼロを持っている場合。

  • 最後に、最後に$出力をアルファベット順に並べ替えます。


3
すごい。TODO:GolfScriptを学ぶ!
DLosc 14

1
26:に減らすこともできますn/:a{|}*{{{=}+,}+a%$-1=}%$
ハワード14年

13

J-37文字

stdinから読み取り、コンソールに出力します。

dlb#&a.>./+/"2=/&a.tolower;._2[1!:1]3

1!:1]3stdinへの呼び出しです。tolower;._2行を分割して同時に小文字にすることにより、二重の義務を果たします。次に+/"2=/&a.、で各行に文字が何回出現するかをカウントし、ですべての行にわたって点ごとの最大値を取得し>./ます。

最後に、各文字の多くをからアルファベットから引き出し#&a.ます。これにはスペースが含まれます(ASCII値が低いためにすべて前面にありdlbます)。先頭の空白はで削除します。


12

JavaScript(ECMAScript 6)-148 139 135文字

バージョン2:

配列内包表記を使用するように更新:

[a[i][0]for(i in a=[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort())if(a[i-1]<a[i])]

バージョン1:

[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

次のことを想定しています:

  • 入力文字列は変数にありますs;
  • 入力の大文字小文字を無視することができます(質問で指定されたとおり-つまり、すべて大文字または小文字のいずれかです)。
  • 出力は文字の配列です(これは、JavaScriptがOPの文字リストの要件に到達できる程度に近い)。そして
  • 出力はコンソールに表示されます。

コメント付き:

var l = s.split('\n')             // split the input up into sentences
         .map(x=>x.split(/ */)   // split each sentence up into letters ignoring any
                                  // whitespace
                  .sort()         // sort the letters in each sentence alphabetically
                  .map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))
                                  // append the frequency of previously occurring identical
                                  // letters in the same sentence to each letter.
                                  // I.e. "HELLO WORLD" =>
                                  // ["D0","E0","H0","L0","L1","L2","O0","O1","R0","W0"]
[].concat(...l)                   // Flatten the array of arrays of letters+frequencies
                                  // into a single array.
  .sort()                         // Sort all the letters and appended frequencies
                                  // alphabetically.
  .filter((x,i,a)=>a[i-1]!=x)     // Remove duplicates and return the sorted
  .map(x=>x[0])                   // Get the first letter of each entry (removing the
                                  // frequencies) and return the array.

あなたがしたい場合は:

  • 文字列として返し.join('')、最後に追加します。
  • ユーザーからの入力を受け取り、s変数をprompt();に置き換えます。または
  • 関数として記述してから、先頭にf追加f=s=>します。

ランニング:

s="HELLO\nI LOVE CAT\nI LOVE DOG\nI LOVE MOMMY\nMOMMY LOVE DADDY";
[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

出力を与えます:

["A","C","D","D","D","E","G","H","I","L","L","M","M","M","O","O","T","V","Y","Y"]

1
いいね!あなたは減らすことによって、3つのバイトを保存することができます/\s*// */して周りの括弧を削除j=0
nderscore

1
...代わりに使用できませんapplyか?
ヴェン14

お二人に感謝します-それは9文字を節約します- スプレッド...)演算子は私が今まで出会ったことのないものです。
MT0 14

[].concat(...s.split`N`.map(x=>x.split(/ */).map((x,i,a)=>x+(a[x]=a[x]?++j:j=1)))).sort().map((x,i,a)=>a[i-1]<x?x[0]:'').join``;
l4m2

11

Perl-46バイト

#!perl -p
$s=~s/$_//ifor/./g;$s.=uc}for(sort$s=~/\w/g){

シバンを1として数えます。これは、以下のRubyソリューションの緩やかな翻訳です。


Ruby 1.8-72バイト

s='';s+=$_.upcase.scan(/./){s.sub!$&,''}while gets;$><<s.scan(/\w/).sort

入力はから取得されstdinます。

サンプル使用法:

$ more in.dat
Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

$ ruby fridge-letters.rb < in.dat
ACDDDEGHILLMMMOOSTVYY

出力はソートする必要があります。
マット14

@Mattが修正されました。
プリモ14

いいね ただし、Perlの曖昧さが最近の場合は、/iとの間にスペースが必要ですfor
tobyink 14

8

Pythonの- 206 204 199 177 145 129の 117 94の 88文字

print(''.join(c*max(l.lower().count(c)for l in open(f))for c in map(chr,range(97,123))))

ファイル名を取得する方法がわからなかったため、現時点では、コードは、という名前の変数に含まれていると想定していますf。変更する必要がある場合はお知らせください。


8
UNIXの精神で-あなたは標準入力から読むことができます。
romaninsh 14

5
常に長い... 1文字のファイル名を作る

3
@Tal私も新しいですが、文字を保存するのであれば、なぜですか?

1
仮定することによりf、入力ファイル名を大文字を使用して(すべての磁石の文字がとにかく大文字されている)、あなたは91にそれを得ることができます:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
ゲイブ

1
@ njzk2よく、コンソールでこれを実行すると、理論的には結果をそれだけで印刷するでしょう...-14
タル

6

Ruby 1.9 +、51(または58または60)

a=*$<
?a.upto(?z){|c|$><<c*a.map{|l|l.count c}.max}

すべてが小文字であると想定します。大文字と小文字を.upcase区別しない場合は7文字、大文字と小文字を区別しない場合は小文字 9文字かかります.downcase


4

R(156、ファイル読み取りを含む)

Iは、それぞれの文のための文字頻度テーブルを構築します。その後、各文字の最大値を取得することになります。

a=c();for(w in tolower(read.csv(fn,h=F)$V1))a=c(a,table(strsplit(w,"")[[1]]));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")

ゴルフをしていない:

a=c()
words = read.csv(fn,h=F)$V1
for(w in tolower(words))
  a=c(a, table(strsplit(w, "")[[1]]))
a = tapply(seq(a), names(a), function(i) max(a[i]))[-1] ## The -1 excludes the space count.
cat(rep(names(a), a), sep="")

解決:

acdddeghillmmmoooooostuvyy

@lambruscoAcidoを使用すると、3つの最初の行(ベクトル化されていないコード)をベクトル化できますが、a=unlist(lapply(readLines(fn),function(x)table(strsplit(tolower(x),""))));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")3文字だけ短くなります
-jkd

112文字のみの別のアプローチは、ファイル名cat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")f
-jkd

4

ハスケル、 109 108

import Data.List
import Data.Char
main=interact$sort.filter(/=' ').foldl1(\x y->x++(y\\x)).lines.map toLower

プログラムはstdinから読み取り、sdtoutに書き込みます。

文字列を行のリストに分割し、リストを繰り返して各行に含まれる新しい文字を追加することで再構築します。


なんて前に(\\)なんて聞いたことないの?
フランク14


4

Perl 6:56 53文字; 58 55バイト

say |sort
([∪] lines.map:{bag comb /\S/,.lc}).pick(*)

これは、各行について、小文字の文字列(comb /\S/,.lc)のスペース以外の文字を検索しBag、各文字のコレクション、または各文字とその出現回数を作成します。[∪]は、Bagすべての行でsの和集合を取り、文字が発生した最大回数を取得します。.pick(*)ここではハックですが、Bagそれは発生した回数で複製されたすべてのキャラクターを取得する最短の方法です。

編集:それが短くなるかどうかを確認するために、私はhistocratのRubyの答えを翻訳してみました。63文字ですが、私はまだアプローチがとても好きです:

$!=lines».lc;->$c{print $c x max $!.map:{+m:g/$c/}} for"a".."z"

3

ハスケル、183 162 159

ファイルが中にあると仮定しますfile.txt

import Data.Char
import Data.List
main=readFile"file.txt">>=putStr.concat.tail.map(tail.maximum).transpose.map(group.sort.(++' ':['a'..'z'])).lines.map toLower

たとえば、file.txtに含まれている場合

abcde
abcdef
aaf

スクリプトは出力します

aabcdef

基本的に、各行にアルファベット全体を追加するので、グループ化と並べ替えを行うときに、27個の要素を含むリストが作成されます。次に、この配列の各行が各行の1文字の頻度で構成されるように、「頻度表」を転置します["a","","aaa","aa","aaaa"]。次に、各配列の最大値を選択し(OrdStrings の-instance がどのように機能するかにより、希望どおりに動作します)、先頭に追加した文字をドロップし、スペースを取り除き、結果を出力します。


1
代わりにdrop 1、ちょうど使用tail
Bergi

@Bergi Haha derp、ありがとう!投稿で変更しました。
フランク14

3

C、99文字

t[256];main(c){for(--*t;++t[1+tolower(getchar())];);for(c=97;c<123;c++)while(t[c]--)putchar(c-1);}

改行が1つより少ないと、クラッシュします。簡単に修正できると思います。


試しましたが、正しい結果が得られませんでした。gist.github.com/romaninsh/11159751
romaninsh

3

kdb(q / k):59文字:

d:.Q.a! 26#0
.z.pi:{d|:.Q.a##:'=_y}.z.exit:{-1@,/.:[d]#'!:d}
  • アルファベット.Qaから事前にソートされたシード辞書を生成します
  • 入力の各行を処理し、小文字に変換し、辞書にグループ化し、各要素をカウントし、結果からアルファベット文字を取得します(つまり、この段階でスペース、改行などを削除します)。
  • 区切り記号を保存するために.z.piに渡されるが、それ以外はそこで使用されない出口ハンドラーを定義します。各Key-Valueから文字のリストを生成し、フラット化して最終的に標準出力に出力します。

-1は改行を追加します。1を使用すると文字が保存されますが、指定された出力は生成されません。.z.pi / .z.exitボイラープレートを削除できれば、14文字が削除されます。

編集:シード辞書を使用して、inter / ascの使用を避けます。


3

Perl、46

for$:(a..z){$a[ord$:]|=$:x s/$://gi}}{print@a

ここに別のPerlソリューションがあります。STDINから読み取り、-nスイッチ(カウントするには+1)が必要で、primoのスコアと結びついていますが、文句なしに実行されます:-)。ビット単位orの結果の文字列引数の長さが長いという事実を利用します。


1
私のテストで試してみましたが、うまくいきました。
ロマンニンシュ14

3

私は自分のソリューションを追加しています:

バッシュ-72

入力がファイル「i」にあると仮定します

for x in {A..Z};do echo -n `cat i|sed "s/[^$x]//g"|sort -r|head -1`;done

説明

考えられる各文字について、入力ファイルからのみフィルターし、次のような結果になります。

AAA
A
A

AAAA

A
AAAAAAAAAAAAAAAA

次に、結果がソートされ、最も長い行が選択されます。echo -n改行を削除するためにあります。


3

バッシュ、171 159 158、138、ジャンク出力

小文字のみの入力が必要です。ファイルが呼び出されると仮定します_(アンダースコア)。split(xaa、xab ... xaz、???)を作成する迷惑なファイル名のため、入力ファイルの最大26行。

bash{a..z}出力しますa b c d e f ...

touch {a..z}
split _ -1
for l in {a..z}
do for s in {a..z}
do grep -so $l xa$s>b$l
if [ `wc -l<b$l` -ge `wc -l<$l` ]
then mv b$l $l
fi
done
tr -d '\n'<$l
done

サンプル出力

acdddeghillmmmoostvyy

説明

touch {a..z}

後で読み込むファイルを作成して、bashがそれらが存在しないことを不平を言わないようにします。この行を削除すると、13文字を節約できますが、大量のジャンク出力が得られます。

split _ -1

入力ファイルをセクションに分割し、各セクションに1行を格納します。このコマンドが作成するファイルの名前はxaa、xab、xacなどです。その理由はわかりません。

for l in {a..z}
do for s in {a..z}

$lファイルに保存されたすべての行を通読する各文字についてxa$s

do grep -so $l xa$s>b$l

-sスイッチを削除して1文字を節約し、大量のジャンク出力を取得します。grep存在しないファイルについて不平を言うことを防ぎます(26行の入力がない限り発生します)。これはファイルを処理し、発生xa$s以外のものを削除$lし、出力をファイルに送信しますb$l。したがって、「i love mommy」は「mmm」になり、各文字$lがmであるときに改行されます。

if [ `wc -l<b$l` -ge `wc -l<$l` ]

作成したファイルの行数が、これまでで最高の結果の行数(に格納されている$l)以上(つまり、1行に1文字あるため文字数が多い)の場合...

then mv b$l $l

...新しいレコードをファイルに保存します$l。このループの最後で、すべての行を調べた後、ファイルに$lはそれぞれがletterを含むx行が格納されます$l。xは、1行でのその文字の最大出現回数です。

fi
done
tr -d '\n'<$l

その特定のレターのファイルの内容を出力し、新しい行を削除します。新しい行を削除したくない場合は、行をtrに変更してecho $l、6文字を節約します。

done

GNU bashバージョン3.2.51(アップル)で試してみましたが、入力データを含む現在のフォルダーにファイル '-l1aa'があります。
romaninsh

@romaninsh split(coreutilsから)の異なるバージョンを使用している可能性があります。現在、GNU bash 4.3.8とGNU coreutils 8.21をUbuntu 14.04で実行していますが、正常に動作します(アップグレードする前にUbuntu 13.10でも動作しました)。ただし、プログラムと入力ファイルを適切に動作させるには別のディレクトリに配置する必要がありました-これは、ホームフォルダーにある無数のジャンクファイルが原因であると思われます

実際、@ romaninshは、スクリプト内の正確なコマンドを見るsplit _ -l1と、入力がに保存されていることに気づいた場合-l1aa、あなたのバージョンはオプションとしてsplit 認識さ-l1れず、代わりに出力のプレフィックスとして使用されると思います。-lとの間にスペースを入れてみてください1。または--lines=1、またはちょうどを入れてみてください-1(これは時代遅れでゴルフのような構文のようです。

3

C#、172バイト

var x="";foreach(var i in File.ReadAllText(t).ToLower().Split('\r','\n'))foreach(var j in i)if(x.Count(c=>c==j)<i.Count(c=>c==j))x+=j;string.Concat(x.OrderBy(o=>o)).Trim();

賢い...賢い...私はlinqで遊ぶことを考えたが、これらのゆがんだforeachsと同じくらい短いだろうとは思わない:)
Noctis

2

Python 2-129

@Talのアイデア

a,r=[0]*26,range(26)
for l in open('f'):a=[max(a[i],l.lower().count(chr(i+97)))for i in r]
print''.join(chr(i+97)*a[i]for i in r)

同じ文字数で同じことを行うためのさらに2つの方法:

a=[0]*26
b='(chr(i+97)))for i in range(26)'
exec'for l in open("f"):a=[max(a[i],l.lower().count'+b+']\nprint"".join(a[i]*('+b+')'

a=[0]*26
b='(chr(i+97)))for i in range(26))'
exec'for l in open("f"):a=list(max(a[i],l.lower().count'+b+'\nprint"".join(a[i]*('+b

これは、ファイルがアクセス可能なディレクトリにfとして保存されることを前提としています。このプログラムは直接実行可能で、追加の入力は不要です。


なぜ反対票なのか?私が何か間違ったことをしたらすみません。
isaacg 14


2

Scala、125文字

val i=""::io.Source.stdin.getLines.toList.map(_.toLowerCase);println('a'to'z'map(c=>(""+c)*i.map(_.count(_==c)).max)mkString)

最初に入力を読み取り、小文字に変換して1行の空行を追加します。

次に、からaまでの各文字について、その文字をz任意の行に表示される回数だけ繰り返します(そのため、空の行が必要です:max enpty入力では呼び出せません)。次に、結果を結合して出力に出力します。

ファイルから読み取るには、に置き換えstdinfromFile("FILENAME")、コードのサイズを132文字+ファイル名の長さに増やします。


2

Javascript、261文字

eval('s=prompt().toUpperCase().split("\\n");Z=[########0,0];H=Z.slice();s@r){h=Z.slice();r.split("")@c){if(c.match(/\\w/))h[c.charCodeAt(0)-65]++});H=H@V,i){return V>h[i]?V:h[i]})});s="";H@n,i){s+=Array(n+1).join(String.fromCharCode(i+97))});s'.replace(/@/g,".map(function(").replace(/#/g,"0,0,0,"))

を削除しeval(...)て実行し、実際のコードを取得します。これは(やや)圧縮されています。

s行の配列および出力文字列としての多機能には、行hごとの文字のヒストグラムがH含まれ、これまでの最大値のヒストグラムが含まれます。大文字と小文字を区別せず、azとAZ以外は無視します(JS配列は時々奇妙です)。

今正しい:)


これは、単に質問が尋ねたものではなく、文字を合計するだけです。文字は、すべてではなく、入力内の任意の単一の文を形成するための最低限のセットになるように合計する必要があります。ただし、出力を並べ替える必要がないようにするためのアプローチが非常に気に入っています。
マット14

@Matt ohそうです...後で修正します。今は本当に時間がありません。
tomsmeding

1
@私が最後に着くまで、何が起こっていたのか疑問に思いました。私はそれが好きです:)
マット14

2

JavaScript(ES5)141バイト

変数sが大文字と小文字のチェック要件と配列出力のない入力文字列であると仮定します:

for(a in s=s[o=_='',y='split']('\n'))for(i=0;x=s[a][i++];)o+=x!=0&&(l=s[a][y](x).length-~-o[y](x).length)>0?Array(l).join(x):_;o[y](_).sort()

私はあなたのソリューションをテストし、出力のために「o」の中を探していましたが、適切にソートされていないようです。(gist.github.com/romaninsh/11159751を参照)
romaninsh 14

私はあなたの主旨に表示出力が正しくソート見える@romaninsh
nderscore

はい、それは参照/正しい出力です。あなたのコードを試したとき、私はこれを手に入れました:gist.github.com/romaninsh/11161018
romaninsh

あなたの例を間違って実行した場合、おologiesびします。
romaninsh 14

@romaninshああ、私はそれがブラウザのコンソールで実行されることを意図していた。ノードで動作するように再フォーマットされたバージョンを次に示します。gist.github.com
nderscore

2

PowerShell-141

「a」という名前のファイルからテキストを読み取ります。

$x=@{}
gc a|%{[char[]]$_|group|%{$c=$_.name.tolower().trim()
$n=$_.count;$x[$c]=($n,$x[$c])[$n-lt$x[$c]]}}
($x.Keys|sort|%{$_*$x[$_]})-join""

2

グルービー、113/127 / 102/116文字

ファイルがすべて1つのケース(102文字)であると仮定します。

t=new File('f').text;t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

ファイルが大/小文字混合(116文字)であると仮定します。

t=new File('f').text.toUpperCase();t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

基本的に:

  • t=new File('f').text ファイルのテキストを取得します。
  • t.findAll('[A-Z]').unique().sort().each{c-> 一意の文字を取得するには、それらを並べ替えて、繰り返します。
  • print c*t.readLines()*.count(c).max() 1行で最大の出現回数を取得し、その文字を何度も印刷します。

2

Bash(主にawk)- 172 163 157

awk -v FS="" '{delete l;for(i=1;i<=NF;i++)l[toupper($i)]++;for(i in l)o[i]=(o[i]>l[i]?o[i]:l[i])}END{for(i in o)for(j=0;j<o[i];j++)print i}'|sort|tr -d ' \n'

テキストをawkにパイプする(またはファイルとして指定する)必要があります。

入力例

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

出力例

ACDDDEGHILLMMMOOSTVYY

PHP(おそらくより良い可能性があります)- 174 210

$o=array();foreach(explode("\n",$s) as $a){$l=array();$i=0;while($i<strlen($a)){$k=ucfirst($a[$i++]);if($k==' ')continue;$o[$k]=max($o[$k],++$l[$k]);}}ksort($o);foreach($o as $k=>$v)for($i=0;$i<$v;$i++)echo $k;

文字列が変数$ sに含まれていると仮定します

入力例

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

出力例

ACDDDEGHILLMMMOOSTVYY

2

これはおそらく最も効率的な答えではないことを理解していますが、とにかく問題を解決しようと思いました。これが私のObjCバリエーションです。

- (NSArray *) lettersNeededForString:(NSString *)sourceString {
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }
    return [arr sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}    

その後、どんな文字列に対しても呼び出すことができます:

NSArray * letters = [self lettersNeededForString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@",letters);

テキストの量が多いアプリケーションについて考えていたので、配列を数える必要はありません。このために、これを取得するメソッドに追加しました:

- (NSDictionary *) numberOfLettersNeededFromString:(NSString *)sourceString {

    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }

    static NSString * alphabet = @"abcdefghijklmnopqrstuvwxyz";
    NSMutableDictionary * masterDictionary = [NSMutableDictionary new];
    for (int i = 0; i < alphabet.length; i++) {
        NSString * alphabetLetter = [alphabet substringWithRange:NSMakeRange(i, 1)];
        NSIndexSet * indexes = [arr indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
            if ([[(NSString *)obj lowercaseString] isEqualToString:alphabetLetter]) {
                return YES;
            }
            else {
                return NO;
            }
        }];

        masterDictionary[alphabetLetter] = @(indexes.count);
    }

    return masterDictionary;
}

次のように実行します:

NSDictionary * lettersNeeded = [self numberOfLettersNeededFromString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@", lettersNeeded);

あなたに与えます:

{a = 2; b = 0; c = 1; d = 4; e = 5; f = 0; g = 1; h = 1; i = 3; j = 0; k = 0; l = 6; m = 6; n = 0; o = 8; p = 0; q = 0; r = 0; s = 1; t = 1; u = 0; v = 4; w = 0; x = 0; y = 3; z = 0; }

非常に大量のテキストがあり、必要な各文字の数を知る必要がある場合、これは良いと思います。



2

Python 2、154バイト

import collections
c = collections.Counter()
for line in open("input.txt"):
    c |= collections.Counter(line.upper())
print "".join(sorted(c.elements()))

PCGへようこそ!このサイトはMarkdown構文をサポートしています。Markdown構文を使用してコードを書式設定できるため、見栄えがよくなります。コード4の各行をインデントするだけです。
algorithmshark 14

コレクションをインポートするために必要な文字を追加する必要があります。
isaacg

1
各文を個別に書くために最小限の文字が必要なので、質問に答えません。コードでは、すべての文を同時に書くのに必要な文字数を出力します。
njzk2

あなたが欠落しているsの終わりにimport文と、withブロックはインデントを欠いています。また、これはコードゴルフであるため、可能な場合は不要な空白を削除すると非常に役立ちます。
Fraxtil

これはコードゴルフなので、withステートメントを削除し(openの呼び出しをループするだけです)、要素を並べ替える必要はないと思います。
RemcoGerlich

2

C、298バイト

char c;
int j,n;
char C[26];
char D[26];
int main()
{
char a='a';
while((c=getchar())>=0)
{
c=tolower(c);
if(c>=a&&c<='z'){j=c-a;D[j]++;}
if(c=='\n'){
for(j=0;j<26;j++){
if(D[j]>C[j])
{C[j]=D[j];}
D[j]=0;
}
}
}
for(j=0;j<26;j++)
{
n=C[j];
while(n--)
{
putchar(a+j);
}
}
}

配列Dは各行の文字の集計を保持し、最大カウントがCにコピーされます。

注:昨日答えを入力しましたが、リストに表示されなくなりました。誤って編集する代わりに削除を押した可能性があります。


たった271バイトです。また、余分な改行もたくさんあります。また、intfrom int main()およびを省略できますint j,n;
nyuszika7h

また、前の答えはまだそこにあります。
nyuszika7h 14

2

PHP、143バイト

入力が変数で渡されると仮定します$s

$i=explode("\n",$s);foreach(range('a','z')as$c){$x=array_map(function($l)use($c){return substr_count($l,$c);},$i);echo str_repeat($c,max($x));}

説明

可能な文字ごとに、各行を使用する文字数で置き換えるユーザー定義関数を使用して、文字列のリストを含む配列をマッピングしています。文字「d」の場合、「Mommy loves daddy」という行は3にマッピングされます。

その後、配列内で最大値を見つけ、文字を何回も出力します。複数行バージョンは次のとおりです。

$i=explode("\n",$s);
foreach(range('A','Z')as $c){
    $x=array_map(function($l)use($c){
        return substr_count($l,$c);
    },$i);
    echo str_repeat($c,max($x));
}

1

Python(209、サンプルあり、136なし):

from collections import*;c=Counter()
for i in ["Hello","I love cat", "I love Dog", "I love mommy", "Mommy loves daddy"]:
 for j in i.lower(): c[j]=max(c[j],list(i).count(j))
print "".join(sorted(c.elements()))

今日の午後にPYGサンプルを投稿します。


Pythonの文字列にcountメソッドが含まれているとは思いもしませんでした...この新しい発見された知識を使用するために質問への答えを変更することは合法だとは思わないでしょうか?:p
タル14

@talしません。それはあなたがより近く見れば、リストの方法だ
ɐɔıʇǝɥʇuʎs

1
ああ、わかりました...しかし、予想外のひねりを加えて、文字列には明らかにこのメソッドもあることがわかります(とにかく3.xで)
タル2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.