Kızımın alfabesi


65

Geçen gün kızımla birlikte buzdolabı mıknatısı olan cümleler yazıyorduk. Bazılarını ( I love cat) yapabildiğimiz halde , I love you tooyetersiz harflerden o(4) dolayı diğerlerini ( ) yapmak için yeterli mektubumuz yoktu.

Daha sonra bir sette 3 eharf varken sadece 2 oharf olduğunu öğrendim . Muhtemelen http://en.wikipedia.org/wiki/Letter_frequency esinlenerek bu hala "buzdolabındaki" gerçek durumu yansıtmayacaktı.

Sorun

Her satırın bir "örnek cümle" içerdiği metin dosyası göz önüne alındığında, birinin buzdolabına yazmak isteyeceği, minimum miktarda harf içeren ancak her cümleyi ayrı ayrı yazmak için yeterli olan bir alfabe önerin.

Not: Vakaları yoksay, tüm mıknatıs harfleri zaten büyük harf olur.

Giriş

Dosya yeni satır ayrılmış cümleler içeriyor:

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

Çıktı

Her harfin, yalnızca herhangi bir cümleyi yazmaya yetecek kadar göründüğü sıralı harflerin listesini geri verin:

acdddeghillmmmoostvyy

(teşekkürler, isaacg!)

kazanan

En kısa uygulama (kod)

GÜNCELLEME: Test

Ekstra bir test oluşturdum ve burada çeşitli yanıtlarla denedim:

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


2
vÇıktıda bir harf olmalı ;)
Antonio Ragagnin

40
Biz / Bir baş aşağı yerine gerekli izin verilen Mbir için W, ya bir yana doğru Nbir için Z? ;-)
Ilmari Karonen

4
Temel olarak Is ile herhangi bir harf oluşturabilirsiniz .
homoseksüel

7
Daha da önemlisi , "vakaları yoksay" derken , girişin zaten aynı durumda olduğunu varsayabileceğimizi mi yoksa hepsini aynı duruma dönüştürmemiz gerektiğini mi kastediyorsunuz ? Ayrıca, çıktının bazı önde gelen boşlukları içermesi uygun mudur?
Ilmari Karonen

3
@Doorknob:_\¯
Ilmari

Yanıtlar:


18

GolfScript, 28/34 karakter

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

Yukarıdaki 28 karakterlik program, tüm giriş harflerinin aynı durumda olduğunu varsaymaktadır. Bu gerekli olmasa {95&}%da, toplam 34 karakter için, kodu hazırlayarak bunları büyük harfe zorlayabiliriz :

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

Notlar:

  • Doğru işlem için, giriş en az bir yeni satır içermelidir. Bu, her satırın sonunda yeni satırlara sahip normal metin dosyaları için geçerli olacaktır; ancak giriş, izleyen satır sonları olmayan tek bir satırdan oluşuyorsa doğru olmayabilir. Bu n+, koda hazırlanarak iki ekstra karakter pahasına düzeltilebilir .

  • 34 karakterlik versiyonda kullanılan üst kademe gerçekten kaba - küçük harfli ASCII harflerini büyük harf eşdeğerlerine (ve boşlukları NULs) eşler , fakat tam bir sayı karışıklığı ve noktalama işaretleri yapar. Girdide böyle karakterler bulunmayacağını varsayıyorum.

  • 28 karakterlik sürüm tüm giriş karakterlerini (yeni satırlar ve s'ler hariç NUL) eşit şekilde ele alır. Özellikle giriş herhangi bir boşluk içeriyorsa, çıkışta da bir kısmı görünür; elverişli bir şekilde, diğer yazdırılabilir ASCII karakterlerinden önce sıralanırlar. 34 karakterlik versiyon ise boşlukları görmezden geliyor (çünkü bunun bana fazladan bir paraya mal olmadan bunu yapabilirim).

Açıklama:

  • İsteğe bağlı {95&}%önek, her giriş baytının ( ) ASCII kodunun altıncı bitini sıfırlayarak girişi büyük harfe çevirir . Bu, küçük ASCII harflerini büyük harfe, boşlukları boş baytlara eşleştirir ve yeni satırları değiştirmez.95 = 64 + 31 = 10111112

  • n/girişi yeni satırlara böler ve :aelde edilen diziyi değişkene atar a. Ardından {|}*dizideki dizgilerin küme birliğini hesaplar (dizinin en az iki öğeye sahip olduğu varsayılarak) girdideki tüm benzersiz (yeni satır olmayan) karakterleri içeren bir dize verir.

  • Aşağıdaki { }%döngü, bu benzersiz karakterlerin her biri üzerinde yinelenir. Döngü gövdesinin içinde, iç döngü a{.[2$]--}%dizideki dizeler üzerinde yinelenir a, her dizgiden dış döngünün yinelediği karaktere eşit olmayan tüm karakterleri siler.

    İç döngü, geçerli karakterin ASCII kodunu, filtrelenmiş dizinin altındaki yığın üzerinde bırakır. Bunu, filtrelenmiş diziyi, ASCII koduyla ( *) belirtildiği gibi, ( ) sıralamadan ( $) ve son elemanı ( -1=) almadan önce tekrarlayarak kullanırız . Aslında, bu, filtrelenmiş dizideki en uzun dizgiyi verir (hepsi aynı karakterin tekrarlarından oluşur, sözcükler sıralaması sadece uzunluğu göre sıralar), karakterin ASCII kodunu sıfır içermesi dışında , bu durumda hiçbir şey vermez.

  • Sonunda, $sonunda sadece çıktı alfabetik olarak sıralanır.


3
İnanılmaz. TODO: GolfScript'i Öğrenin!
DLosc

1
Hatta 26'ya bunu azaltabilir: n/:a{|}*{{{=}+,}+a%$-1=}%$.
Howard,

13

J - 37 karakter

Stdin'den okur, konsola çıkar.

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

1!:1]3stdin çağrısı. tolower;._2Çizgileri bölerek ve aynı anda küçük harf yaparak çift görevi yerine getirir. Daha sonra her satırda bir karakterin kaç kez meydana geldiğini sayar +/"2=/&a.ve tüm satırlarda nokta yönünden maksimum değeri alırız >./.

Sonunda, karakterlerin çoğunu alfabenin dışına çıkarırız #&a.. Bu, tümü ASCII değerinin düşük olması nedeniyle ön tarafta bulunan boşlukları içerir, bu nedenle yalnızca önde gelen boşlukları sileriz dlb.


12

JavaScript (ECMAScript 6) - 148 139 135 Karakterler

Versiyon 2:

Dizi anlama kullanımı güncellendi:

[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])]

Versiyon 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])

Varsayalım ki:

  • Giriş dizesi değişkende s;
  • Girişin durumunu görmezden gelebiliriz (soru tarafından belirtildiği gibi - yani hepsi büyük veya küçük harf olarak);
  • Çıktı, bir karakter dizisidir (OP'nin karakter listesi gereksinimine göre JavaScript'in alabileceği değere yakındır); ve
  • Çıktı konsolda gösterilecek.

Yorumlarla:

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.

Eğer istersen:

  • Bir dize olarak döndür .join('')ve sonuna ekle ;
  • Bir kullanıcıdan girdi alın, sonra sdeğişkeni prompt(); veya
  • Bir fonksiyon olarak yazınız, fsonra f=s=>başa ekleyiniz .

Koşu:

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])

Çıktısını verir:

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

1
Güzel! Sen azaltarak 3 bayt kaydedebilirsiniz /\s*/için / */ve etrafında parens çıkarmadanj=0
nderscore

1
...yerine kullanamaz applymısın?
Ven

İkinize de teşekkürler - bu 9 karakter kazandırıyor - spread ( ...) operatörü daha önce rastlamadığım bir operatör.
MT0

[].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``;
12m2

11

Perl - 46 bayt

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

Shebang'ı 1 olarak saymak. Bu, Ruby çözümünün gevşek bir çevirisidir.


Yakut 1.8 - 72 bayt

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

Giriş alındı stdin.

Örnek kullanım:

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

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

Çıktının sıralanması gerekiyor.
Matt

@Matt şimdi düzeltildi.
primo

Güzel. Perl’iniz belli belirsiz olsa, /ive arasında bir boşluk isteyeceksiniz for.
tobyink

8

Python - 206 204 199 177 145 129 117 94 88 karakter

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

Dosya adını nasıl elde edeceğimden emin değildim, bu yüzden kod şu anda adında bir değişkende olduğunu varsayar f. Lütfen bunu değiştirmem gerekirse haberim olsun.


8
unix ruhunda - stdin'den okuyabilirsin.
romaninsh

5
her zaman dosya adını bir karakter uzunluğunda yapar ...

3
@Tal Ben de yeniyim ama karakterleri kaydederse, neden olmasın?

1
fGirilen dosya adını varsayarak ve büyük harf kullanarak (tüm mıknatıs harfleri büyük harf olur) 91:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
Gabe

1
@ njzk2 peki, eğer bunu konsolda çalıştırırsak, teoride sonucu sadece kendi başına basar ...
Tal

6

Yakut 1.9+, 51 (veya 58 veya 60)

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

Her şeyin küçük harf olduğunu varsayar. Büyük küçük harf.upcase duyarsızlığı 7 karakter , büyük küçük harf duyarlılığı ve küçük harf çıkışı ise 9 karakterdir .downcase.


4

R (156, dosya okuma dahil)

İle masaya ben her cümle için mektup frekans tablosu oluşturmak. Sonra her harf için maksimum değeri alarak bitirdim.

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="")

Ungolfed:

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="")

Çözüm:

acdddeghillmmmoooooostuvyy

@lambruscoAcido size vereceğiniz üç ilk satırı (topraksız kodun) vektörlendirebilir 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=""), ancak sadece 3 karakter daha kısadır
jkd

Sadece 112 karakterli başka bir yaklaşım ise, dosya cat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")f
isminin

4

Haskell, 109 108

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

Program stdin'den okuyor ve sdtout'a yazıyor.

Oldukça basittir: dizgiyi bir satır listesine böler ve listeyi yineleyerek ve her satırda bulunan yeni harfleri ekleyerek yeniden oluşturur.


Vay canına, neden daha önce hiç duymadım?
Flonk


4

Perl 6: 56 53 karakter; 58 55 bayt

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

Her satır için bu, alt kasalı dizginin ( comb /\S/,.lc) boşluk olmayan karakterleri için onu tarar ve Bagher karakterin bir veya bir koleksiyonunu ve kaç kez meydana geldiğini oluşturur. s'nin [∪]birleşimini Bagtüm satırların üzerinden geçirir, bu da karakterin maksimum kaç kez geçtiğini gösterir. .pick(*)burada hack-y, ancak Bagçoğaltılan tüm karakterleri, oluşma sayısına göre çoğaltmanın en kısa yoludur .

EDIT: Daha kısa olup olmayacağını görmek için, histokratının Ruby cevabını tercüme etmeye çalıştım . 63 karakterdir, ancak ben hala yaklaşımı çok seviyorum:

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

3

Haskell, 183 162 159

Dosyanın içinde olduğunu varsayalım 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 içeriyorsa, örneğin

abcde
abcdef
aaf

Script çıkacak

aabcdef

Temel olarak her alfabeye tüm alfabeyi ekliyorum, böylece gruplama ve sıralama yaparken, 27 eleman içeren bir listeyle sonuçlanacağımdan eminim. Bu dizideki her satır, örneğin, her satırında bir harf frekansları oluşur, böylece Ardından, "frekans tablosu" devrik ["a","","aaa","aa","aaaa"]. Daha sonra her dizinin maksimum değerini seçiyorum ( Orddizgelerin işleyiş şeklinden dolayı istediğim gibi çalışıyor) ve başlangıçta eklediğim mektubu bırakıyorum, boşluklardan kurtuluyorum ve sonucu çıkarıyorum.


1
Bunun yerine drop 1, sadece kullanıntail
Bergi

@ Bergi Haha derp, teşekkürler! Postada değiştirdim.
Flonk

3

C, 99 karakter

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

Birden fazla newline verilirse çöküyor. Bence kolayca düzeltilebilir.


Denedim ama doğru sonuç vermedi. gist.github.com/romaninsh/11159751
romaninsh

3

kdb (q / k): 59 karakter:

d:.Q.a! 26#0
.z.pi:{d|:.Q.a##:'=_y}.z.exit:{-1@,/.:[d]#'!:d}
  • Alfabeden önceden sıralanmış tohum sözlüğü hazırlayabilir .Qa
  • her girdi satırını işleyin, küçük harfe dönüştürün, sözlüğe dönüştürün, her bir öğeyi sayın, sonuçtan alfabetik karakterleri alın (yani, bu aşamada boşlukları, yeni satırları buda).
  • Bir sınırlayıcıyı kurtarmak için .z.pi'ye geçen ancak orada kullanılmayan çıkış işleyicisini tanımlayın. Karakter listesini oluşturmak için her bir anahtar-değerden alın, düzeltin ve son olarak stdout'a yazdırın.

-1, yeni bir satır ekler, 1 kullanarak bir karakteri kaydeder ancak belirtilen çıktıyı oluşturur. Keşke 14 karakter kaldıracak .z.pi / .z.exit kazanından kurtulabilseydim.

Düzenleme: tohum sözlüğü kullanarak iç / artan kullanımından kaçının.


3

Perl, 46

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

İşte bir başka Perl çözümü, STDIN'den okur, -nanahtar gerektirir (sayma için +1), primo'nun puanıyla bağlanır ancak şikayetsiz çalışır :-). Bitwise orsonucunun daha uzun string string argümanına sahip olduğu gerçeğinden faydalanır .


1
Testimle denedim ve harika çalıştı.
romaninsh

3

Kendi çözümümü ekliyorum:

Bash - 72

Girişin "i" dosyasında olduğunu varsayar.

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

açıklama

Her olası harf için, bunu yalnızca böyle bir şeyle sonuçlanan girdi dosyasından filtreler:

AAA
A
A

AAAA

A
AAAAAAAAAAAAAAAA

Sonra sonuç sıralanır ve en uzun çizgi seçilir. echo -nnewlines kaldırmak için var.


3

Bash, 171 159 Önemsiz çıkışlı 158, 138

Sadece küçük harf girişi gerektirir. Dosyanın çağrıldığını varsayar _(alt çizgi). Girdi dosyalarında splityarattığı sinir bozucu dosya adları nedeniyle maksimum 26 satır (xaa, xab ... xaz, ???).

In bash, {a..z}çıktılar 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

Örnek çıktı

acdddeghillmmmoostvyy

açıklama

touch {a..z}

Daha sonra okuyacağımız dosyalar oluşturun, böylece bash var olmadığından şikayet etmez. Bu satırı kaldırırsanız 13 karakter kazanırsınız ancak çok fazla önemsiz çıktı alırsınız.

split _ -1

Giriş dosyasını her biri 1 satır saklayan bölümlere ayırın. Bu komutun yarattığı dosyalar xaa, xab, xac vb. Olarak adlandırılır, nedenini bilmiyorum.

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

Her harf için $l, dosyalarda saklanan tüm satırları okuyun xa$s.

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

-s1 char tasarruf etmek ve çok fazla önemsiz çıktı almak için anahtarı çıkarın . grepVarolmayan dosyalar hakkında şikayet etmeyi önler (26 satırlık bir girişiniz olmadıkça ortaya çıkar). Bu, dosyayı işler, meydana gelen xa$sşeyleri kaldırır $lve çıktıya gönderir b$l. Böylece “annemi seviyorum” $l, m olduğunda her harften sonra yeni satırlarla “mmm” olur .

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

Eğer yarattığımız dosyadaki satır sayısı, şuna eşit veya ondan büyükse (yani satır başına bir harf olduğundan daha fazla harf), şimdiye kadarki en yüksek sonucumuzdaki satır sayısı (içinde saklanır $l) ...

then mv b$l $l

... yeni rekorumuzu dosyada saklayın $l. Bu döngünün sonunda, tüm satırları geçtikten sonra, dosya $lher bir harfi içeren x satırını depolar $l; burada x, o harfin tek bir satırdaki en yüksek sayılarının olduğu sayıdır.

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

Yeni satırları kaldırarak söz konusu harf için dosyamızın içeriğini çıktılayın. Eğer yeni satırlar kaldırmak istemiyorsanız, satırı değiştirmek triçin echo $l6 karakter tasarruf.

done

GNU bash, sürüm 3.2.51 (elma), ancak giriş verilerini içeren geçerli bir klasörde '-l1aa' dosyasıyla denedi ..
romaninsh

@romaninsh Farklı bir sürümünüz olabilir split(coreutils'den). Şu anda Ubuntu 14.04'te GNU bash 4.3.8 ve GNU coreutils 8.21 kullanıyorum ve iyi çalışıyor (yükseltmeden önce Ubuntu 13.10'da da çalıştı). Ancak, düzgün çalışması için programı ve giriş dosyasını ayrı bir dizine yerleştirmem gerekti - bunun yalnızca ana klasörümdeki milyonlarca önemsiz dosyadan kaynaklandığından şüpheleniyorum .

Aslında, @romaninsh, betiğin tam komutuna bakarsanız: split _ -l1girdilerinizin kaydedildiğini -l1aafark ederseniz, sürümünüzün bir seçenek olarak split tanımadığını -l1ve bunun yerine çıktı için önek aldığını düşünüyorum . Arasına boşluk koyarak deneyin -lve 1ya koyarak --lines=1, ya da sadece -1(bu şimdi ile yayınında güncellenir eski bir ve daha Golfy sözdizimi gibi görünüyor).

3

C #, 172 bayt

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();

Zeki ... zeki ... linq ile oynamayı düşündüm, ama bu sıkışık foreachs için kısa olacağından şüphe :)
Noctis

2

Python 2 - 129

@Tal adlı kullanıcının fikri

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)

Aynı şeyi aynı sayıda karakterde yapmanın birkaç yolu:

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

Bu, dosyanın erişilebilir bir dizine f olarak kaydedildiğini varsayar. Bu program doğrudan çalıştırılabilir ve ilave giriş yapılmasına gerek yoktur.


Neden aşağı oy? Yanlış bir şey yaptıysam özür dilerim.
isaacg

2

Mathematica v10 - 110

Henüz bitmedi, ancak yeni belgeleri çok dikkatli bir şekilde okumak , bunun işe yarayacağını düşünüyorum:

StringJoin@MapIndexed[#2~Table~{#1}&,Rest@Merge[Counts/@Characters@StringSplit[ToLowerCase@Input[],"\n"],Max]]

2

Scala, 125 karakter

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

İlk önce girişi okudum, küçük harfe dönüştürüp bir boş satır ekledim.

Sonra her harf için aiçin zbunu hatlarının herhangi görünür kez o mektup maksimum sayıda tekrarlamak (Boş hat istiyorum bu yüzden: maxBir enpty girişine denilen olamaz). Sonra sadece sonuçları birleştirip çıktılara yazdırırım.

Yerine, bir dosyadan okumak için stdinbirlikte fromFile("FILENAME")+ dosya adı uzunluğu 132 karakterle kod boyutunu artırmak,.


2

Javascript, 261 karakter

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(...)Gerçek kodu almak için ve komutunu kaldırın ; bu ( biraz ) sıkıştırılmıştır.

sSatır dizisi ve çıkarılan dize gibi çoklu işlevler, satır hbaşına harflerin Hhistogramını içerir ve bugüne kadar maksimum değerlerle histogramı içerir. Büyük / küçük harfe duyarsızdır ve sadece az ve AZ dışında hiçbir şeyi yok sayar (Sanırım ... JS dizileri bazen gariptir).

Şimdi doğru :)


Bu sadece karakterlerin toplamıdır, tam olarak sorulan soru değil. Harfler, girişte hepsi değil, tek bir cümle oluşturacak şekilde ayarlanan en düşük düzeyde toplanmalıdır. Yine de çıktıyı sıralama ihtiyacını önleme yaklaşımınızı sevdim.
Matt

@Matt oh bu doğru ... Daha sonra tamir edeceğim. Şu an gerçekten vaktim olmadı.
14'te

1
@Sonuna kadar neler olup bittiğini merak ettim.
Matt

2

JavaScript ( ES5 ) 141 bayt

Değişkeni varsayalım s, durum kontrol gereksinimi ve dizi çıkışı olmayan girdi dizisi:

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()

Çözümünüzü test ettim ve bir çıktı için "o" nun içine bakıyordum, ancak düzgün şekilde sıralanmıyor gibi görünüyor. (bkz. gist.github.com/romaninsh/11159751 )
romaninsh

@ romaninsh Ben senin yumruk görüyorum çıktı düzgün sıralanmış görünüyor
nderscore

Evet, bu bir referans / doğru çıktı. Kodunuzu denediğimde, şunu aldım: gist.github.com/romaninsh/11161018
romaninsh

Örneğinizi yanlış uyguladıysam özür dilerim.
romaninsh

@ romaninsh ah, sadece tarayıcının konsolunda çalıştırılması için tasarlanmıştı. İşte düğüm üzerinde çalışan bir biçimlendirilmiş versiyon: gist.github.com/nderscore/96aa888c77d275c26c15
nderscore

2

PowerShell - 141

'A' adlı bir dosyadaki metni okur.

$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

Groovy, 113/127 102/116 karakter

Dosyanın hepsinin tek bir durumda olduğunu varsayalım (102 karakter):

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

Dosyanın karışık durumda olduğu varsayılarak (116 karakter):

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

Temelde:

  • t=new File('f').text Dosyanın metnini almak için.
  • t.findAll('[A-Z]').unique().sort().each{c-> Benzersiz karakterleri almak için bunları sıralayın ve yineleyin.
  • print c*t.readLines()*.count(c).max() Maksimum boşlukları tek bir satıra alın ve karakteri o kadar yazdırın.

2

Bash (çoğunlukla 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'

Metin awk (veya bir dosya olarak belirtilmiş) olarak aktarılmalıdır.

Örnek Giriş

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

Örnek çıktı

ACDDDEGHILLMMMOOSTVYY

PHP (muhtemelen daha iyi olabilir) - 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;

Dize $ s değişkeninde bulunduğunu varsayar

Örnek Giriş

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

Örnek çıktı

ACDDDEGHILLMMMOOSTVYY

2

Bunun muhtemelen en etkili cevap olmadığını fark ettim, ancak sorunu yine de denemek ve çözmek istedim. İşte ObjC varyasyonum:

- (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:)];
}    

Sonra ne olursa olsun dize için çağırabilir:

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

Daha fazla miktarda metin içeren uygulamalar hakkında düşünüyordum ve dizimi saymam gerekmedi. Bunun için, bunu elde etmek için yönteme ekledim:

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

Gibi koş:

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

Sana vereceğim:

{a = 2; b = 0; c = 1; d = 4; e = 5; f = 0; g = 1; h = 1; i = 3; j = 0; k = 0; 1 = 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; }

Çok fazla miktarda metne sahip olsaydım hangisinin daha iyi olacağını bilmem gerekiyordu.



2

Python 2, 154 bayt

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

PCG'ye Hoşgeldiniz! Bu site, kodunuzu biçimlendirmek için kullanabileceğiniz Markdown sözdizimini desteklemektedir, böylece iyi görünebilir: sadece 4 satırlık satırların her birini girin.
algorithmshark

Koleksiyonları içe aktarmak için gereken karakterleri eklemeniz gerekir.
isaacg

1
Her cümleyi tek tek yazmak için minimum miktarda harfe ihtiyacınız olduğundan soruyu cevaplamıyor. Kodunuzda, aynı anda tüm cümleleri yazmak için gereken harf sayısını gösterirsiniz.
njzk2

İfadenin ssonunda bir noktayı kaçırıyorsunuz importve withblok girintiden yoksun. Ve bu kod golf olduğu için, gereksiz yere beyaz boşlukların kaldırılması büyük ölçüde size yardımcı olacaktır.
Fraxtil

bu kod golf olduğundan, with ifadesini kaldırın (açmak için sadece bir çağrı üzerinden döngü yapın) ve öğelerin sıralamaya ihtiyacı olduğunu sanmıyorum.
RemcoGerlich

2

C, 298 bayt

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 dizisi, her satır için harfe ait harfleri tutar, sonra maksimum sayı C'ye kopyalanır.

Not: Dün cevabımı koydum ama şimdi listelenmemiş, belki de yanlışlıkla düzenlemek yerine silmek için basmalıyım?


Sadece 271 bayt. Ayrıca çok fazla yabancı yeni hattınız var. Ayrıca, size atlayabilirsiniz olabilir intgelen int main()ve int j,n;.
nyuszika7h

Ayrıca, önceki cevabın hala orada.
nyuszika7h

2

PHP, 143 bayt

Bu girişin değişkende geçtiğini varsayalım $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));}

açıklama

Her olası harf için, her bir satırı kullanılan karakter sayısıyla değiştiren, kullanıcı tanımlı bir işlev aracılığıyla dizelerin listesini içeren diziyi eşleştiriyorum. 'D' harfi için “Anne babayı seviyor” satırı 3 ile eşleştirilecektir.

Daha sonra dizi ve çıkış harfinde maksimum değeri sadece bu defa buldum. İşte çok satırlı versiyonu:

$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, örnek dahil, 136 olmadan.):

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()))

Bu öğleden sonra bir PYG örneği göndereceğim.


Python dizelerinin bir sayma yöntemi olduğu hakkında hiçbir fikrim yoktu ... Sanırım bu yeni bulunan bilgiyi kullanmak için soruma cevabımı değiştirmenin yasal olduğunu düşünmüyorum? : p
Tal

@tal Onlar değil. Daha yakından bakarsanız, listenin bir yöntemidir
ɐɔıʇǝɥʇuʎs

1
Ah, anlıyorum ... ama beklenmedik bir twistte, o dizgelerin de görünüşe göre bu yönteme sahip olduğu anlaşılıyor (yine de 3.x'te)
Tal
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.