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 e
huruf itu hanya 2 o
huruf. 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:
v
di output;)M
denganW
, atau menyampingN
untukZ
? ;-)I
s._\¯
Jawaban:
GolfScript, 28/34 karakter
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: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
NUL
s), 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
NUL
s) 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:a
menetapkan array yang dihasilkan ke dalam variabela
. 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 dalama{.[2$]--}%
berulang di atas string dalam arraya
, 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.sumber
n/:a{|}*{{{=}+,}+a%$-1=}%$
.J - 37 char
Baca dari stdin, keluaran ke konsol.
1!:1]3
adalah panggilan ke stdin.tolower;._2
melakukan 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 dengandlb
.sumber
JavaScript (ECMAScript 6) -
148139135 KarakterVersi 2:
Diperbarui untuk menggunakan pemahaman array:
Versi 1:
Menganggap bahwa:
s
;Dengan komentar:
Jika Anda menghendaki:
.join('')
di bagian akhir;s
variabel denganprompt()
; atauf
lalu tambahkanf=s=>
ke awal.Berlari:
Memberikan output:
sumber
/\s*/
ke/ */
dan menghapus parens sekitarj=0
...
bukanapply
?...
) adalah yang belum pernah saya temui sebelumnya.[].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``;
Perl - 46 byte
Menghitung shebang sebagai 1. Ini adalah terjemahan longgar dari solusi Ruby di bawah ini.
Ruby 1,8 - 72 byte
Input diambil dari
stdin
.Penggunaan sampel:
sumber
/i
danfor
.Python -
2062041991771451291179488 karakterSaya 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.sumber
f
nama 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)]))
Ruby 1.9+, 51 (atau 58 atau 60)
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
.sumber
R (156, termasuk file baca)
Dengan tabel saya membuat tabel frekuensi huruf untuk setiap kalimat. Kemudian saya mendapatkan nilai maksimum untuk setiap huruf.
Tidak Disatukan:
Larutan:
sumber
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 pendekcat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")
mengasumsikanf
adalah nama fileHaskell,
109108Program 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.
sumber
Perl 6:
5653 karakter;5855 byteUntuk setiap baris, ini menyisirnya untuk karakter non-spasi dari string yang lebih kecil (
comb /\S/,.lc
), dan membuatBag
, atau koleksi setiap karakter dan berapa kali itu terjadi.[∪]
mengambil penyatuan dariBag
s 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 yangBag
direplikasi 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:
sumber
Haskell,
183 162159Dengan asumsi file ada di
file.txt
!Jika file.txt berisi, misalnya
Script akan ditampilkan
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 bagaimanaOrd
-instance of Strings bekerja), dan letakkan huruf yang saya tambahkan di awal, singkirkan spasi, dan hasilkan hasilnya.sumber
drop 1
, gunakan sajatail
C, 99 karakter
Itu macet jika kurang dari satu baris baru disediakan. Saya pikir itu bisa diperbaiki dengan mudah.
sumber
kdb (q / k): 59 karakter:
-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.
sumber
Perl, 46
Inilah solusi Perl lainnya, dibaca dari STDIN, membutuhkan
-n
sakelar (+1 untuk dihitung), terkait dengan skor primo tetapi berjalan tanpa keluhan :-). Ini mengeksploitasi fakta bahwa hasil bitwiseor
memiliki panjang argumen string yang lebih panjang.sumber
Saya menambahkan solusi saya sendiri:
Bash - 72
Mengasumsikan bahwa input ada dalam file "i"
Penjelasan
Untuk setiap huruf yang mungkin, filter hanya dari file input yang menghasilkan sesuatu seperti ini:
Kemudian hasilnya diurutkan dan garis terpanjang dipilih.
echo -n
ada untuk menghapus baris baru.sumber
Pesta,
171159158, 138 dengan output sampahMembutuhkan input huruf kecil saja. Mengasumsikan bahwa file tersebut disebut
_
(garis bawah). Maksimal 26 baris dalam file input karena nama file yang mengganggu yangsplit
membuat (xaa, xab ... xaz, ???).Dalam
bash
,{a..z}
outputa b c d e f ...
.Output sampel
Penjelasan
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.
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.
Untuk setiap huruf
$l
bacalah semua baris yang tersimpan dalam filexa$s
.Lepaskan
-s
sakelar untuk menghemat 1 char dan dapatkan banyak output sampah. Itu mencegahgrep
dari mengeluh tentang file tidak ada (akan terjadi kecuali jika Anda memiliki 26 baris input). Ini memproses filexa$s
, menghapus apa pun kecuali kejadian$l
, dan mengirimkan output ke fileb$l
. Jadi "i love mommy" menjadi "mmm" dengan baris baru setelah setiap huruf kapan$l
m.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
) ...... simpan catatan baru kami di file
$l
. Pada akhir dari loop ini, ketika kita telah melewati semua baris, file tersebut$l
akan menyimpan x baris yang masing-masing berisi huruf$l
, di mana x adalah jumlah kemunculan tertinggi dari huruf itu dalam satu baris.Keluarkan isi file kita untuk surat khusus itu, hapus baris baru. Jika Anda tidak ingin menghapus baris baru, ubah baris dengan
tr
menjadiecho $l
, simpan 6 karakter.sumber
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 .split _ -l1
dan Anda melihat bahwa input Anda disimpan-l1aa
, saya pikir versi Andasplit
tidak mengenali-l1
sebagai opsi dan alih-alih menganggapnya sebagai awalan untuk output . Cobalah menempatkan spasi di antara-l
dan1
, atau menempatkan--lines=1
, atau hanya-1
(ini tampaknya sintaksis usang dan lebih golf yang sekarang saya akan memperbarui posting dengan).C #, 172 byte
sumber
Python 2 - 129
Ide dari @Tal
Beberapa cara lagi untuk melakukan hal yang sama dalam jumlah karakter yang sama:
Ini mengasumsikan file disimpan sebagai f dalam direktori yang dapat diakses. Program ini langsung dapat dijalankan, tanpa perlu input tambahan.
sumber
Mathematica v10 - 110
Belum keluar, tetapi membaca dokumentasi baru dengan sangat hati-hati, saya pikir ini harus bekerja
sumber
Scala, 125 karakter
Pertama saya membaca input, mengubahnya menjadi huruf kecil dan menambahkan satu baris kosong.
Kemudian untuk setiap huruf dari
a
hinggaz
saya ulangi surat itu berapa kali maksimum muncul di salah satu baris (itu sebabnya saya perlu baris kosong:max
tidak dapat dipanggil pada input enpty). Kemudian saya hanya bergabung dengan hasil dan mencetak ke output.Untuk membaca dari file, ganti
stdin
denganfromFile("FILENAME")
, menambah ukuran kode menjadi 132 karakter + panjang nama file.sumber
Javascript, 261 karakter
Hapus
eval(...)
dan jalankan untuk mendapatkan kode nyata; ini ( agak ) dikompresi.s
multi-fungsi sebagai larik garis dan sebagai string yang dihasilkan,h
berisi histogram huruf per baris danH
berisi 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 :)
sumber
@
sampai saya tiba di akhir. Saya suka :)JavaScript ( ES5 ) 141 byte
Variabel asumsi
s
adalah string input tanpa persyaratan pemeriksaan kasus dan output array:sumber
PowerShell - 141
Membaca teks dari file bernama 'a'.
sumber
Groovy,
113/127102/116 karakterDengan asumsi file semuanya dalam satu kasus (102 karakter):
Dengan asumsi file dalam kasus campuran (116 karakter):
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.sumber
Bash (kebanyakan awk) -
172163157Teks perlu disalurkan ke awk (atau ditentukan sebagai file).
Contoh Input
Contoh Output
PHP (mungkin bisa lebih baik) -
174210Mengasumsikan bahwa string terkandung dalam variabel $ s
Contoh Input
Contoh Output
sumber
Saya menyadari ini mungkin bukan jawaban yang paling efisien, tetapi saya ingin mencoba dan menyelesaikan masalah. Berikut variasi ObjC saya:
Maka Anda dapat menyebutnya untuk string apa pun:
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:
Jalankan seperti:
Akan memberimu:
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.
sumber
K, 34
sumber
Python 2, 154 byte
sumber
s
di akhirimport
pernyataan danwith
blok tidak memiliki lekukan. Dan karena ini adalah kode golf, akan sangat bermanfaat bagi Anda untuk menghapus spasi kosong yang tidak perlu jika memungkinkan.C, 298 byte
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?
sumber
int
dariint main()
danint j,n;
.PHP, 143 byte
Dengan anggapan bahwa input diberikan dalam variabel
$s
: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:
sumber
Python (209, dengan sampel disertakan, 136 tanpa.):
Saya akan mengirim sampel PYG sore ini.
sumber