Alfabet anak saya

65

Suatu hari kami menulis kalimat dengan putri saya dengan surat magnet kulkas. Meskipun kami dapat membuat beberapa ( I love cat), kami tidak memiliki cukup surat untuk membuat yang lain ( I love you too) karena jumlah surat yang tidak cukup o(4)

Saya kemudian menemukan bahwa sementara satu set termasuk 3 ehuruf itu hanya 2 ohuruf. Mungkin terinspirasi oleh http://en.wikipedia.org/wiki/Letter_frequency ini masih tidak mencerminkan situasi aktual "di lemari es".

Masalah

Mengingat file teks di mana setiap baris berisi "contoh kalimat" yang ingin dituliskan di lemari es, usulkan set alfabet dengan jumlah huruf minimum tetapi masih cukup untuk menulis setiap kalimat secara terpisah.

Catatan: abaikan kasing, semua huruf magnet adalah huruf besar.

Memasukkan

File tersebut mengandung kalimat yang dipisahkan dengan baris baru:

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

Keluaran

Berikan kembali daftar surat yang diurutkan, di mana setiap huruf hanya muncul sesering mungkin untuk menulis kalimat apa pun:

acdddeghillmmmoostvyy

(terima kasih, isaacg!)

Pemenang

Implementasi terpendek (kode)

DIPERBARUI: Menguji

Saya telah membuat tes tambahan dan mencoba dengan berbagai jawaban di sini:

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

romaninsh
sumber
2
Seharusnya ada surat vdi output;)
Antonio Ragagnin
40
Apakah kita diizinkan / diminta untuk mengganti terbalik Mdengan W, atau menyamping Nuntuk Z? ;-)
Ilmari Karonen
4
Pada dasarnya Anda dapat membuat huruf apa saja menggunakan Is.
desir
7
Lebih serius lagi, ketika Anda mengatakan "abaikan case", apakah maksud Anda bahwa kami dapat berasumsi bahwa input sudah semuanya dalam case yang sama, atau bahwa kami harus mengubahnya semua menjadi case yang sama? Juga, apakah OK untuk output untuk memasukkan beberapa spasi terkemuka?
Ilmari Karonen
3
@Doorknob:_\¯
Ilmari Karonen

Jawaban:

18

GolfScript, 28/34 karakter

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

Program 28 karakter di atas mengasumsikan bahwa semua huruf input berada dalam kasus yang sama. Jika belum tentu demikian, kita dapat memaksa mereka menjadi huruf besar dengan menambahkan {95&}%kode, dengan total 34 karakter:

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

Catatan:

  • Untuk operasi yang benar, input harus menyertakan setidaknya satu baris baru. Ini akan berlaku untuk file teks normal dengan baris baru di akhir setiap baris, tetapi mungkin tidak benar jika input hanya terdiri dari satu baris tanpa baris baru. Ini dapat diperbaiki dengan biaya dua karakter tambahan, dengan menambahkan n+kode.

  • Huruf besar yang digunakan dalam versi 34-karakter benar-benar kasar - ini memetakan huruf ASCII huruf kecil ke ekuivalen huruf besar mereka (dan spasi ke NULs), tetapi membuat kekacauan total angka dan sebagian besar tanda baca. Saya berasumsi bahwa input tidak akan memasukkan karakter seperti itu.

  • Versi 28 karakter memperlakukan semua karakter input (kecuali baris dan NULs) secara merata. Secara khusus, jika input berisi spasi, beberapa juga akan muncul di output; nyaman, mereka akan mengurutkan sebelum karakter ASCII lainnya yang dapat dicetak. Versi 34-karakter, bagaimanapun, tidak menghiraukan spasi (karena ternyata saya bisa melakukannya tanpa harus mengeluarkan biaya tambahan).

Penjelasan:

  • {95&}%Prefiks opsional mengecilkan input dengan memusatkan bit keenam dari kode ASCII dari setiap byte input ( ). Ini memetakan huruf ASCII huruf kecil ke huruf besar, spasi ke byte nol, dan membuat baris baru tidak berubah.95 = 64 + 31 = 10111112

  • n/memisahkan input pada baris baru, dan :amenetapkan array yang dihasilkan ke dalam variabel a. Kemudian {|}*menghitung gabungan set string dalam array, yang (dengan asumsi bahwa array memiliki setidaknya dua elemen) menghasilkan string yang berisi semua karakter unik (non-baris baru) dalam input.

  • { }%Lingkaran berikut kemudian mengulangi masing-masing karakter unik ini. Di dalam tubuh loop, loop dalam a{.[2$]--}%berulang di atas string dalam array a, menghapus dari setiap string semua karakter tidak sama dengan yang loop luar iterasi.

    Loop dalam meninggalkan kode ASCII dari karakter saat ini di stack, di bawah array yang difilter. Kami menggunakan ini dengan mengulangi array yang difilter sebanyak yang ditunjukkan oleh kode ASCII ( *) sebelum mengurutkannya ( $) dan mengambil elemen terakhir ( -1=). Akibatnya, ini menghasilkan string terpanjang dalam array yang difilter (karena semuanya terdiri dari pengulangan dari karakter yang sama, pengurutan leksikografis hanya mengurutkannya berdasarkan panjangnya), kecuali jika karakter tersebut memiliki kode ASCII nol, dalam hal ini ia tidak menghasilkan apa-apa.

  • Akhirnya, $pada akhirnya hanya mengurutkan output berdasarkan abjad.

Ilmari Karonen
sumber
3
Luar biasa. TODO: Pelajari GolfScript!
DLosc
1
Anda bahkan dapat mengurangi ke 26: n/:a{|}*{{{=}+,}+a%$-1=}%$.
Howard
13

J - 37 char

Baca dari stdin, keluaran ke konsol.

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

1!:1]3adalah panggilan ke stdin. tolower;._2melakukan tugas ganda dengan memisahkan garis-garis dan membuatnya menjadi huruf kecil secara bersamaan. Lalu kami menghitung berapa kali karakter muncul di setiap baris +/"2=/&a., dan ambil maksimum pointwise di atas semua baris >./.

Akhirnya, kami menarik banyak karakter dari alfabet #&a.. Ini termasuk spasi — semua ditemukan di bagian depan karena nilai ASCII-nya yang rendah — jadi kami hanya menghapus spasi kosong dengan dlb.

algoritme hiu
sumber
12

JavaScript (ECMAScript 6) - 148 139 135 Karakter

Versi 2:

Diperbarui untuk menggunakan pemahaman array:

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

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

Menganggap bahwa:

  • String input ada dalam variabel s;
  • Kita dapat mengabaikan kasus input (seperti yang ditentukan oleh pertanyaan - yaitu semuanya dalam huruf besar atau kecil);
  • Outputnya adalah array karakter (yang sedekat JavaScript dapat mencapai persyaratan OP dari daftar karakter); dan
  • Outputnya akan ditampilkan di konsol.

Dengan komentar:

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.

Jika Anda menghendaki:

  • Kembalikan sebagai string lalu tambahkan .join('')di bagian akhir;
  • Ambil input dari pengguna lalu ganti svariabel dengan prompt(); atau
  • Tulis sebagai fungsi flalu tambahkan f=s=>ke awal.

Berlari:

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

Memberikan output:

["A","C","D","D","D","E","G","H","I","L","L","M","M","M","O","O","T","V","Y","Y"]
MT0
sumber
1
Bagus! Anda dapat menyimpan 3 byte dengan mengurangi /\s*/ke / */dan menghapus parens sekitarj=0
nderscore
1
tidak bisakah kamu menggunakan ...bukan apply?
Ven
Terima kasih kepada Anda berdua - yang menghemat 9 karakter - Operator spread ( ...) adalah yang belum pernah saya temui sebelumnya.
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``;
14m2
11

Perl - 46 byte

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

Menghitung shebang sebagai 1. Ini adalah terjemahan longgar dari solusi Ruby di bawah ini.


Ruby 1,8 - 72 byte

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

Input diambil dari stdin.

Penggunaan sampel:

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

$ ruby fridge-letters.rb < in.dat
ACDDDEGHILLMMMOOSTVYY
primo
sumber
Output perlu disortir.
Matt
@ Mat sekarang sudah diperbaiki.
Primo
Bagus. Jika Perl Anda samar-samar baru saja, Anda akan membutuhkan ruang antara /idan 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))))

Saya tidak yakin bagaimana saya seharusnya mendapatkan nama file, jadi saat ini kode mengasumsikan bahwa itu terkandung dalam variabel bernama f. Tolong beri tahu saya jika saya perlu mengubahnya.

Tal
sumber
8
dalam semangat unix - Anda bisa membaca dari stdin.
romaninsh
5
selalu buat nama file satu karakter menjadi panjang ...
3
@Tal Saya juga baru, tetapi jika menyimpan karakter, mengapa tidak?
1
Dengan mengasumsikan fnama file input dan menggunakan huruf besar (semua huruf magnet adalah huruf besar), Anda bisa turun ke 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 baik, jika kita menjalankan ini di konsol, secara teori itu hanya akan mencetak hasilnya dengan sendirinya ...
Tal
6

Ruby 1.9+, 51 (atau 58 atau 60)

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

Asumsikan semuanya dalam huruf kecil. Ketidak sensitifan huruf biaya 7 karakter melalui .upcase, sedangkan ketidakpekaan huruf dan output huruf kecil biaya 9 karakter melalui .downcase.

histokrat
sumber
4

R (156, termasuk file baca)

Dengan tabel saya membuat tabel frekuensi huruf untuk setiap kalimat. Kemudian saya mendapatkan nilai maksimum untuk setiap huruf.

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

Tidak Disatukan:

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

Larutan:

acdddeghillmmmoooooostuvyy
lambruscoAcido
sumber
@ lambruscoAcido Anda bisa membuat vektor tiga baris pertama (dari kode yang tidak diklik) yang akan memberi Anda 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=""), tetapi itu hanya 3 karakter lebih pendek
jkd
Pendekatan lain dengan hanya 112 karakter akan cat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")mengasumsikan fadalah nama file
jkd
4

Haskell, 109 108

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

Program membaca dari stdin dan menulis ke sdtout.

Ini cukup mudah: memecah string menjadi daftar baris, dan membangunnya kembali dengan mengulangi daftar dan menambahkan huruf baru yang terkandung di setiap baris.

lortabac
sumber
Oh wow, mengapa saya tidak pernah mendengar (\\) sebelumnya?
Flonk
4

Perl 6: 56 53 karakter; 58 55 byte

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

Untuk setiap baris, ini menyisirnya untuk karakter non-spasi dari string yang lebih kecil ( comb /\S/,.lc), dan membuat Bag, atau koleksi setiap karakter dan berapa kali itu terjadi. [∪]mengambil penyatuan dari Bags di atas semua baris, yang mendapatkan jumlah maksimum kali karakter terjadi. .pick(*)adalah hack-y di sini, tetapi ini adalah cara terpendek untuk mendapatkan semua karakter dari yang Bagdireplikasi dengan berapa kali itu terjadi.

EDIT: Untuk melihat apakah itu akan lebih pendek, saya mencoba menerjemahkan jawaban Ruby histokrat . Ini adalah 63 karakter, tetapi saya masih sangat menyukai pendekatan ini:

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

Haskell, 183 162 159

Dengan asumsi file ada di 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

Jika file.txt berisi, misalnya

abcde
abcdef
aaf

Script akan ditampilkan

aabcdef

Pada dasarnya saya menambahkan seluruh alfabet untuk setiap baris, sehingga ketika mengelompokkan dan menyortir, saya yakin saya akan berakhir dengan daftar yang berisi 27 elemen. Selanjutnya, saya memindahkan "tabel frekuensi", sehingga setiap baris dalam array ini terdiri dari frekuensi satu huruf di setiap baris, misalnya["a","","aaa","aa","aaaa"] . Saya kemudian memilih maksimum masing-masing array (yang berfungsi seperti yang saya inginkan karena bagaimana Ord-instance of Strings bekerja), dan letakkan huruf yang saya tambahkan di awal, singkirkan spasi, dan hasilkan hasilnya.

Flonk
sumber
1
Alih-alih drop 1, gunakan sajatail
Bergi
@Bergi Haha derp, terima kasih! Saya mengubahnya di pos.
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);}

Itu macet jika kurang dari satu baris baru disediakan. Saya pikir itu bisa diperbaiki dengan mudah.

zakk
sumber
Saya sudah mencoba, tetapi hasilnya tidak benar. 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}
  • menghasilkan kamus benih pra-disortir dari alfabet .Qa
  • proses setiap baris input, konversikan ke huruf kecil, kelompokkan ke kamus, hitung setiap elemen, ambil karakter alfabet dari hasil (mis. ruang pangkas, baris baru, dll pada tahap ini) dan gunakan penugasan maksimal ke global d untuk menjaga total berjalan.
  • tentukan exit handler, yang akan diteruskan ke .z.pi untuk menyimpan pembatas tetapi tidak digunakan di sana. Ambil dari setiap nilai kunci untuk menghasilkan daftar karakter, ratakan dan akhirnya cetak ke stdout.

-1 menambahkan baris baru, menggunakan 1 akan menyimpan karakter tetapi tidak menghasilkan output yang ditentukan. Seandainya saya bisa menyingkirkan boilerplate .z.pi / .z.exit, yang akan menghapus 14 karakter.

Sunting: hindari penggunaan antar / asc dengan menggunakan kamus seed.

pengguna20349
sumber
3

Perl, 46

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

Inilah solusi Perl lainnya, dibaca dari STDIN, membutuhkan -nsakelar (+1 untuk dihitung), terkait dengan skor primo tetapi berjalan tanpa keluhan :-). Ini mengeksploitasi fakta bahwa hasil bitwise ormemiliki panjang argumen string yang lebih panjang.

pengguna2846289
sumber
1
mencoba dengan tes saya dan itu berhasil.
romaninsh
3

Saya menambahkan solusi saya sendiri:

Bash - 72

Mengasumsikan bahwa input ada dalam file "i"

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

Penjelasan

Untuk setiap huruf yang mungkin, filter hanya dari file input yang menghasilkan sesuatu seperti ini:

AAA
A
A

AAAA

A
AAAAAAAAAAAAAAAA

Kemudian hasilnya diurutkan dan garis terpanjang dipilih. echo -nada untuk menghapus baris baru.

romaninsh
sumber
3

Pesta, 171 159 158, 138 dengan output sampah

Membutuhkan input huruf kecil saja. Mengasumsikan bahwa file tersebut disebut _(garis bawah). Maksimal 26 baris dalam file input karena nama file yang mengganggu yang splitmembuat (xaa, xab ... xaz, ???).

Dalam bash, {a..z}output 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

Output sampel

acdddeghillmmmoostvyy

Penjelasan

touch {a..z}

Buat file yang akan kita baca nanti sehingga bash tidak mengeluh bahwa mereka tidak ada. Jika Anda menghapus baris ini, Anda akan menghemat 13 karakter tetapi mendapatkan banyak hasil sampah.

split _ -1

Membagi file input menjadi beberapa bagian, masing-masing menyimpan 1 baris. File yang dibuat oleh perintah ini diberi nama xaa, xab, xac dan sebagainya, saya tidak tahu mengapa.

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

Untuk setiap huruf $lbacalah semua baris yang tersimpan dalam file xa$s.

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

Lepaskan -ssakelar untuk menghemat 1 char dan dapatkan banyak output sampah. Itu mencegah grepdari mengeluh tentang file tidak ada (akan terjadi kecuali jika Anda memiliki 26 baris input). Ini memproses file xa$s, menghapus apa pun kecuali kejadian $l, dan mengirimkan output ke file b$l. Jadi "i love mommy" menjadi "mmm" dengan baris baru setelah setiap huruf kapan $lm.

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

Jika jumlah baris dalam file yang baru saja kita buat lebih besar atau sama dengan (yaitu lebih banyak huruf karena ada satu huruf per baris) jumlah baris dalam hasil tertinggi kami sejauh ini (disimpan dalam $l) ...

then mv b$l $l

... simpan catatan baru kami di file $l. Pada akhir dari loop ini, ketika kita telah melewati semua baris, file tersebut $lakan menyimpan x baris yang masing-masing berisi huruf $l, di mana x adalah jumlah kemunculan tertinggi dari huruf itu dalam satu baris.

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

Keluarkan isi file kita untuk surat khusus itu, hapus baris baru. Jika Anda tidak ingin menghapus baris baru, ubah baris dengan trmenjadi echo $l, simpan 6 karakter.

done

sumber
Sudah dicoba dengan GNU bash, versi 3.2.51 (apple), tetapi file '-l1aa' di folder saat ini yang berisi data input ..
romaninsh
@romaninsh Mungkin Anda memiliki versi berbeda split(dari coreutils). Saya saat ini menjalankan GNU bash 4.3.8 dan GNU coreutils 8.21 di Ubuntu 14.04 dan berfungsi dengan baik (ini juga bekerja di Ubuntu 13.10 sebelum saya memutakhirkan). Namun, saya memang harus meletakkan program dan file input dalam direktori terpisah agar dapat berfungsi dengan baik - saya menduga ini hanya karena jutaan file sampah di folder rumah saya .
@romaninsh sebenarnya, jika Anda melihat perintah yang tepat di skrip: split _ -l1dan Anda melihat bahwa input Anda disimpan -l1aa, saya pikir versi Anda split tidak mengenali -l1sebagai opsi dan alih-alih menganggapnya sebagai awalan untuk output . Cobalah menempatkan spasi di antara -ldan 1, atau menempatkan --lines=1, atau hanya -1(ini tampaknya sintaksis usang dan lebih golf yang sekarang saya akan memperbarui posting dengan).
3

C #, 172 byte

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();
jzm
sumber
Pintar ... pintar ... Saya berpikir tentang bermain dengan LINQ, tetapi ragu itu akan sesingkat ini foreachs berkerut :)
Noctis
2

Python 2 - 129

Ide dari @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)

Beberapa cara lagi untuk melakukan hal yang sama dalam jumlah karakter yang sama:

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

Ini mengasumsikan file disimpan sebagai f dalam direktori yang dapat diakses. Program ini langsung dapat dijalankan, tanpa perlu input tambahan.

isaacg
sumber
Mengapa memilih bawah? Maaf jika saya melakukan sesuatu yang salah.
isaacg
2

Mathematica v10 - 110

Belum keluar, tetapi membaca dokumentasi baru dengan sangat hati-hati, saya pikir ini harus bekerja

StringJoin@MapIndexed[#2~Table~{#1}&,Rest@Merge[Counts/@Characters@StringSplit[ToLowerCase@Input[],"\n"],Max]]
desir
sumber
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)

Pertama saya membaca input, mengubahnya menjadi huruf kecil dan menambahkan satu baris kosong.

Kemudian untuk setiap huruf dari ahingga zsaya ulangi surat itu berapa kali maksimum muncul di salah satu baris (itu sebabnya saya perlu baris kosong: maxtidak dapat dipanggil pada input enpty). Kemudian saya hanya bergabung dengan hasil dan mencetak ke output.

Untuk membaca dari file, ganti stdindengan fromFile("FILENAME"), menambah ukuran kode menjadi 132 karakter + panjang nama file.

Karol S
sumber
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,"))

Hapus eval(...)dan jalankan untuk mendapatkan kode nyata; ini ( agak ) dikompresi.

smulti-fungsi sebagai larik garis dan sebagai string yang dihasilkan, hberisi histogram huruf per baris dan Hberisi histogram dengan nilai maksimum hingga sekarang. Ini case-insensitive, dan hanya mengabaikan apa pun kecuali az dan AZ (saya pikir ... JS array terkadang aneh).

Sekarang benar :)

tommeding
sumber
Ini hanya total karakter, tidak cukup dengan pertanyaan yang diajukan. Huruf-huruf harus dijumlahkan sebagai set minimum yang kosong untuk membentuk satu kalimat tunggal dalam input, tidak semuanya. Saya sangat menyukai pendekatan Anda untuk mencegah kebutuhan untuk mengurutkan output.
Matt
@ Mat oh itu benar ... Saya akan memperbaikinya nanti. Belum benar-benar punya waktu sekarang.
mulai
1
Ingin tahu apa yang terjadi dengan @sampai saya tiba di akhir. Saya suka :)
Matt
2

JavaScript ( ES5 ) 141 byte

Variabel asumsi sadalah string input tanpa persyaratan pemeriksaan kasus dan output array:

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()
nderscore
sumber
Saya menguji solusi Anda dan mencari "o" di dalam untuk output, tetapi tampaknya tidak diurutkan dengan benar. (lihat gist.github.com/romaninsh/11159751 )
romaninsh
@romaninsh output yang saya lihat di intisari Anda terlihat diurutkan dengan benar
nderscore
Ya, itu referensi / keluaran yang benar. Ketika saya mencoba kode Anda, saya mendapatkan ini: gist.github.com/romaninsh/11161018
romaninsh
Maaf jika saya mengeksekusi contoh Anda salah.
romaninsh
@romaninsh ah, saya bermaksud untuk menjalankannya di konsol browser. Berikut adalah versi yang diformat ulang yang berfungsi pada simpul: gist.github.com/nderscore/96aa888c77d275c26c15
nderscore
2

PowerShell - 141

Membaca teks dari file bernama '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""
Rynant
sumber
2

Groovy, 113/127 102/116 karakter

Dengan asumsi file semuanya dalam satu kasus (102 karakter):

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

Dengan asumsi file dalam kasus campuran (116 karakter):

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

Pada dasarnya:

  • t=new File('f').text Untuk mendapatkan teks dari file tersebut.
  • t.findAll('[A-Z]').unique().sort().each{c-> Untuk mendapatkan karakter unik, urutkan, dan ulangi.
  • print c*t.readLines()*.count(c).max() Dapatkan kejadian maksimal dalam satu baris dan cetak karakter itu berkali-kali.
dbramwell
sumber
2

Bash (kebanyakan 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'

Teks perlu disalurkan ke awk (atau ditentukan sebagai file).

Contoh Input

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

Contoh Output

ACDDDEGHILLMMMOOSTVYY

PHP (mungkin bisa lebih baik) - 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;

Mengasumsikan bahwa string terkandung dalam variabel $ s

Contoh Input

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

Contoh Output

ACDDDEGHILLMMMOOSTVYY
Tyzoid
sumber
2

Saya menyadari ini mungkin bukan jawaban yang paling efisien, tetapi saya ingin mencoba dan menyelesaikan masalah. Berikut variasi ObjC saya:

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

Maka Anda dapat menyebutnya untuk string apa pun:

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

Saya sedang memikirkan aplikasi dengan jumlah teks yang lebih besar dan saya lebih suka tidak perlu menghitung array saya. Untuk ini, saya menambahkan metode untuk mendapatkan ini:

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

Jalankan seperti:

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

Akan memberimu:

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

Yang saya pikir lebih baik jika saya memiliki jumlah teks yang sangat besar dan saya hanya perlu tahu berapa banyak setiap huruf yang saya perlukan.

Logan
sumber
2

K, 34

{`$a@<a:,/(.:a)#'!:a:|/#:''=:'0:x}
tmartin
sumber
2

Python 2, 154 byte

import collections
c = collections.Counter()
for line in open("input.txt"):
    c |= collections.Counter(line.upper())
print "".join(sorted(c.elements()))
Frankfurt
sumber
Selamat datang di PCG! Situs ini mendukung sintaks Markdown, yang dapat Anda gunakan untuk memformat kode Anda, sehingga tampak bagus: cukup indentasi setiap baris spasi kode 4.
algorithmshark
Anda harus menambahkan karakter yang diperlukan untuk mengimpor koleksi.
isaacg
1
tidak menjawab pertanyaan, karena Anda memerlukan jumlah minimum huruf untuk menulis setiap kalimat secara terpisah. Dalam kode Anda, Anda menghasilkan jumlah huruf yang dibutuhkan untuk menulis semua kalimat pada saat yang bersamaan.
njzk2
Anda melewatkan tanda sdi akhir importpernyataan dan withblok tidak memiliki lekukan. Dan karena ini adalah kode golf, akan sangat bermanfaat bagi Anda untuk menghapus spasi kosong yang tidak perlu jika memungkinkan.
Fraxtil
karena ini adalah kode golf, hapus pernyataan with (hanya putaran panggilan untuk membuka) dan saya tidak berpikir elemen perlu disortir.
RemcoGerlich
2

C, 298 byte

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

Array D menyimpan penghitungan huruf untuk setiap baris, kemudian jumlah maksimum disalin ke C.

Catatan: Saya memasukkan jawaban saya kemarin tetapi sekarang tidak terdaftar, mungkin saya menekan hapus alih-alih mengedit karena kesalahan?

bacchusbeale
sumber
Ini hanya 271 byte. Anda juga memiliki banyak baris baru yang asing. Anda juga dapat menghilangkan intdari int main()dan int j,n;.
nyuszika7h
Juga, jawaban Anda sebelumnya masih ada.
nyuszika7h
2

PHP, 143 byte

Dengan anggapan bahwa input diberikan dalam variabel $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));}

Penjelasan

Untuk setiap huruf yang mungkin saya pemetaan array yang berisi daftar string melalui fungsi yang ditentukan pengguna yang menggantikan setiap baris dengan jumlah karakter yang digunakan. Untuk huruf 'd' baris "Mommy loves daddy" akan dipetakan menjadi 3.

Setelah itu saya menemukan nilai maksimum di dalam array dan surat keluaran hanya ini berkali-kali. Ini adalah versi multi-baris:

$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));
}
romaninsh
sumber
1

Python (209, dengan sampel disertakan, 136 tanpa.):

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

Saya akan mengirim sampel PYG sore ini.

ɐɔıʇǝɥʇu
sumber
Saya tidak tahu string Python memiliki metode penghitungan ... Saya tidak berpikir itu dianggap sah untuk mengubah jawaban saya atas pertanyaan untuk menggunakan pengetahuan yang baru ditemukan ini? : p
Tal
@tal Mereka tidak. Ini adalah metode daftar, jika Anda melihat lebih dekat
Aprıʇǝɥʇu
1
Oh, begitu ... tetapi dalam putaran yang tidak terduga ternyata string ternyata memiliki metode ini juga (dalam 3.x pula)
Tal