Buat kembali kalimatnya

12

Tantangan ini terdiri dari dua bagian. Pemenang akan menjadi solusi dengan jumlah byte total terendah. Bahasa yang sama harus digunakan untuk kedua tantangan.

Bagian 1:

Tulis fungsi atau program yang mengambil kalimat dengan hanya kata - kata yang valid sebagai input, dan menampilkan daftar karakter yang digunakan, berapa kali setiap huruf digunakan, dan jumlah huruf di setiap kata dalam kalimat asli. Output dari program ini harus merupakan input yang valid ke program berikutnya (persis seperti yang dikeluarkan)

Saya akan menambahkan contoh dan aturan rinci lebih jauh ke bawah.

Bagian 2:

Tulis fungsi atau program yang mengambil output dari program pertama sebagai input dan menggunakan daftar kata - kata bahasa Inggris ini dan membuat ulang kalimat dengan informasi dari output. Kalimat tidak harus sama dengan kalimat aslinya.

Informasi lebih lanjut aturan dan batasan:

Bagian 1:

  • Input pertama dapat berupa format yang sesuai, dengan atau tanpa tanda kutip, sebagai argumen fungsi atau dari STDIN, dengan atau tanpa tanda kurung dll.
  • Kalimat input tidak akan berisi tanda baca atau karakter khusus, kecuali titik / titik pada akhirnya. Kecuali untuk simbol periode, semua karakter yang ada dalam input akan ada dalam daftar kata.
  • Huruf pertama dari kalimat akan menjadi huruf besar, sisanya akan menjadi huruf kecil.
  • Keluaran dari bagian 2 harus dimulai dengan huruf besar yang sama dengan kalimat asli (jadi mengonversi input ke huruf kecil tidak dianjurkan (tapi OK).
  • Outputnya bisa dalam format apa saja yang sesuai:
    • Harus dimungkinkan untuk menyalin-menempelkan output langsung ke program / fungsi berikutnya
    • Tidak ada perubahan yang dapat dilakukan saat copy-paste, seluruh output harus disalin dan ditempelkan secara keseluruhan, bukan sebagian.
    • Misalnya, Anda dapat menampilkan histogram dari semua huruf dalam alfabet, atau hanya huruf yang digunakan (secara umum, apa pun yang diperlukan untuk menyelesaikan bagian 2)
    • Anda tidak dapat menampilkan daftar karakter di mana beberapa kejadian berulang. Misalnya, The queuetidak dapat menghasilkan output: Teeehquu (3,5), itu harus sesuatu seperti: Tehqu, (1 3 1 1 2),(3 5).

Bagian 2:

  • Program / fungsi harus menerima input persis seperti dari bagian 1 (satu pengecualian, lihat komentar di bawah tentang mengambil nama file sebagai input.).
    • Jika tanda kurung di sekelilingnya, tanda kutip atau yang serupa diperlukan untuk mengurai input maka ini harus menjadi bagian dari output dari bagian 1.
  • Daftar kata dapat ditemukan di sini.
    • Daftar kata dapat disimpan secara lokal sebagai w.txt, atau dapat diambil dari url. Url hanya akan dihitung sebagai 5 byte, jadi Anda tidak perlu pemendek-url.
    • Jika program tidak dapat membuka file tanpa membaca nama sebagai input dari STDIN (saya percaya ini adalah kasus untuk Pyth setidaknya), maka nama file dapat diambil sebagai argumen input yang terpisah.
  • Output harus hanya berupa kalimat (daftar kata yang valid), diakhiri dengan titik dan baris opsional.
    • Output harus memiliki kata-kata dengan jumlah huruf yang sama dengan kalimat asli di bagian 1 (dalam urutan yang benar)
    • Semua huruf yang digunakan dalam kalimat asli harus digunakan dalam output baru.
    • Kalimat harus dimulai dengan huruf besar sama dengan kalimat input asli dan diakhiri dengan tanda titik.

Kedua bagian:

  • Tidak satu pun dari bagian-bagian itu harus memakan waktu lebih dari 2 menit untuk dieksekusi (memilih secara acak kata-kata sampai solusi tercapai tidak diterima).

Dengan aturan yang tercantum di atas, harus ada peluang yang adil bahwa kalimat yang sama persis direproduksi, namun itu bukan persyaratan.

Contoh:

Dalam contoh di bawah ini, beberapa format input dan output yang berbeda ditampilkan. Banyak lagi yang diterima.

Bagian 1:

Memasukkan:

Zulus win.

Tipe output 1:

Z i l n s u w
1 1 1 1 1 2 1
5 3

Tipe output 2:

(('Z',1),('i',1),('l',1),('n',1),('s',1),('u',2),('w',1)), (5,2)

Tipe output 3:

'Zilnsuuw',[1,1,1,1,1,2,1],[5,2]

Bagian 2:

Input: Salinan persis dari output dari bagian 1. Output:

Zulus win.

Perhatikan bahwa kombinasi kata lain diterima selama mereka mulai dengan a Z, dan kata pertama memiliki 5 huruf dan yang kedua memiliki 3.

Kode terpendek dalam byte menang.

Stewie Griffin
sumber
Inilah komitnya
PurkkaKoodari
@ LegionMammal978: Ya, Anda bisa melakukan ini di bawah batasan berikut: Output dari f1yang disisipkan ke f2harus berisi semua data yang ditentukan dalam tantangan. Tidak ada data tambahan yang dapat menjadi bagian dari output dari f1. Tidak ada data yang dapat "disimpan" dalam f1membuat informasi tersedia saat memanggilnya f2. f1hanya dapat mengambil satu string sebagai input per panggilan.
Stewie Griffin
1
Peluang untuk mengeluarkan kalimat yang sama dengan lebih dari 3 kata sebenarnya cukup buruk, saya kira
Eumel
Secara umum ya, tetapi ada banyak kasus di mana Anda cenderung mendapatkan kalimat yang sama. Jika nenek Anda lelah mengulangi sweater lama Anda, dia mungkin: "berhenti rajutan rajutan". Saya belum memeriksa, tetapi saya pikir nenek Anda akan tetap berhenti setelah bagian 2. Juga kombinasi kata-kata yang lebih panjang mungkin memberikan kalimat yang sama kembali.
Stewie Griffin
1
@StewieGriffin Anda bisa dengan mudah mendapatkan "Wig ... wows." kembali dengan contoh kalimat itu.
question_asker

Jawaban:

5

LabVIEW, 166 LabVIEW Primitif

Pertama-tama saya tidak membuat 2 program terpisah karena Labview melakukan aliran data sehingga benar-benar tidak perlu.

Menyimpan histogram dengan elemen pertama = kode ASCI dari istirahat huruf pertama dari 1-26 pergi dengan jumlah. Panjang cukup disimpan dalam array.

Kata pertama memiliki 3 cek, huruf pertama, panjang dan huruf yang tersedia dalam histogram. Pemeriksaan huruf pertama berhenti setelah kata pertama.

Saya memeriksa histogram dengan menurunkannya untuk setiap huruf dan memeriksa apakah itu akan jatuh di bawah 0.

Jika saya menemukan kata ke-N saya dan tidak ada kata-kata yang dapat dibangun dari huruf sisa saya akan mulai menghapus kata-kata dari kamus dan mengulang kata ke-N dan seterusnya sampai saya menemukan solusi.

Ini mungkin atau mungkin tidak berfungsi untuk kalimat yang ada, karena itu akan memakan waktu lama untuk dihitung (contoh saya sudah beberapa detik)

Apa yang saya coba

In: Zulus win.
Out: Zulus win.

In: Dovecot flagships oleander.
Out: Dolphin advocates forelegs.

In: Abash abel mammal test.
Out: Amass abbe hamlet malt.

Eumel
sumber
3

Python 2.7, 353 byte

Sayangnya, saya tidak dapat mengujinya dengan file ATM w.txt yang sebenarnya karena QPython untuk Android sepertinya tidak dapat menangani file I / O. Ini bekerja dengan data yang saya salin dan tempel.

Bagian 1, 76 byte

h=lambda s:({c:s.count(c)for c in s if c.isalnum()},map(len,s[:-1].split()))

Di: 'Hi there.'

Di luar: {'H':1, 'i':1, 't':1, 'h':1, 'e':2, 'r':1}, (2, 5)

jadi, daftar berisi:

  • sebuah hashmap dengan histogram

  • daftar jumlah surat

Bagian 2, 277 byte

import itertools as i
m=lambda c:' '.join([s for s in i.product(*[[w for w in open('w.txt')if len(w)==length]for length in c[1]])if sorted(''.join(s))==sorted(sum([[k.lower()]*n for k,n in c[0].items()],[]))and s[0][0]==filter(str.isupper,c[0])[0].lower()][0]).capitalize()+'.'

Saya sangat senang saya berhasil membuatnya 100% murni fungsional. Tidak yakin apakah itu membantu dengan bermain golf yang sebenarnya, tetapi saya benar-benar mendapatkan bagian kebingungan: D Inilah versi pt yang lebih ramah manusia. 2 (aliran yang persis sama, tetapi dengan nama variabel):

from itertools import product

def matching(counts):
  histo, word_lengths = counts
  first_letter = filter(str.isupper, histo)[0].lower()

  letters_nested = [ [char.lower()]*count for char, count in histo.items() ]
  letters = sum(letters_nested, [])

  word_options = [[word for word in open('w.txt') if len(word)==length] for length in word_lengths]

  sentences = product(*word_options)

  valid = [sentence for sentence in sentences if sorted(''.join(sentence))==sorted(letters) and sentence[0][0]==first_letter]
  return ' '.join(valid[0]).capitalize()+'.'
uryga
sumber
3

Perl, 516 504 byte

termasuk 2x +1 untuk -p

@l=map{length}/\w+/g;s/\w/$c{$&}++/eg;@h=map{"$_$c{$_}"}keys%c;$_="@h @l";chomp(@w=`cat w.txt`);s/([A-Z])1//;$o=$1;s/(\w)(\d)/$h{$1}=$2,''/eg;@L=/\d/g;$l=shift@L;@O=$_,s/^.//,g([@L],%h)&&last for grep{$l==length&&/^$o/i&&h(\%h,substr$_,1)}@w;$_="@O.";s/^./uc$&/e;sub g{my%g;($R,%g)=@_;my@R=@$R;if($j=shift@R){s/./$g{$&}--/eg;my@C=grep{$j==length&&h(\%g,$_)}@w;push(@O,$_),g([@R],%g)and return 1 or pop@O for@C;0}else{1}}sub h{($y,$z)=@_;my%T;$z=~s/\w/$T{$&}++/eg;$K=1;$K&=$T{$_}<=$y->{$_}for keys%T;$K}

Harus ada w.txtdalam format unix ( \nakhir baris). Menggunakan catuntuk membaca file; ubah ke typeuntuk windows.
Simpan oneliner di atas 534.pldan jalankan sebagai echo Test. | perl -p 534.pl.

Cukup besar, tapi ini awal - banyak peluang bermain golf, tapi saya hanya ingin mempostingnya untuk membuat LabVIEW menjawab lebih sedikit kesepian ;-). Saya telah menghilangkan optimisasi untuk eksekusi sub-detik, menghemat 30+ byte.


Cuplikan pertama (73 byte):

@l=map{length}/\w+/g;s/\w/$c{$&}++/eg;@h=map{"$_$c{$_}"}keys%c;$_="@h @l"

Ini menghasilkan histogram dan kata lenghts dalam format yang kompak. Untuk input Zulus win.itu menghasilkan output tipe-2 tanpa (,), yang tidak perlu di sini:

s1 l1 u2 Z1 w1 i1 n1 5 3

Ini dia, ungolfed:

sub i{
    $_=shift;                       # get parameter
    @l = map{length} /\w+/g;        # cound word lengths
    s/\w/$c{$&}++/eg;               # count letters in hash %c
    @h=map{"$_$c{$_}"}keys%c;       # construct letter-frequency pairs
    "@h @l"                         # implicit interpolation with $" (space) separator
}

Cuplikan kedua (441 byte)

Bagian utama ini berkaitan dengan I / O dan perlakuan khusus dari huruf pertama, menggunakan subrutin gdan hyang tercantum di bawah ini.

sub o {
    $_=shift;
    chomp(@w=`cat w.txt`);          # load the wordlist.

    s/([A-Z])1//; $o=$1;            # get and remove the uppercase character,
    s/(\w)(\d)/$h{$1}=$2,''/eg;     # reconstruct histogram in hash %h.
    @L=/\d/g;                       # get the word counts.

    $l = shift @L;                  # get the first word length.

    @O = $_,                        # initialize output with first word,
    s/^.//,                         # strip first char of word
    g([@L],%h) && last              # call the main algoritm and quit on success

    for grep {                      
            $l==length &&           # check length
            /^$o/i &&               # only match words starting with the uppercase char
            h(\%h,substr$_,1)       # check if the word satisfies the histogram
        } @w;                       # iterates all words (speedups removed).

    $_="@O.";                       # construct output sentence.
    s/^./uc$&/e;                    # make first char uppercase.
    $_
}

Fungsi rekursif ini mengambil salinan histogram, salinan jumlah kata yang tersisa, dan kata saat ini. Jika array kata-panjang kosong, mengembalikan true. Jika tidak, maka akan mengurangi hitungan histogram untuk huruf dalam kata yang diberikan, mengambil panjang kata berikutnya, dan menemukan daftar kata yang sesuai dari daftar kata. Untuk setiap kata yang cocok, kata itu berulang.

sub g {
    my%g;                           # local version of histogram
    ($R,%g)=@_;                     # get parameters.
    my@R=@$R;                       # dereference arrayref copy of word lengths.

    if($j=shift @R)                 # get the next word-length.
    {
        s/./$g{$&}--/eg;            # update histogram

        my @C =                     # get a list of suitable words.
        grep { $j==length && h(\%g,$_) }
        @w;

        push(@O,$_),                # append word to output
        g( [@R], %g )               # recurse.
            and return 1            # true: append word we're done.
            or pop @O               # remove word from output
        for @C                      # (for some reason the @C=grep doesn't work here)

        ;0
    } else { 1 }                    # no more words, done!
}

Dan akhirnya, subrutin ini diberi kata dan kalimat histogram. Ini menghitung histogram baru untuk kata dan memeriksa apakah semua huruf tidak muncul lebih sering daripada yang diizinkan oleh histogram kalimat.

# check if first histogram is within bounds of second
sub h{
    ($y,$z)=@_;
    my%T; $z =~ s/\w/$T{$&}++/eg;    # calc histogram

    $K=1;
    $K &= $T{$_} <= $y->{$_}
    for keys %T;#$_[0];
    $K
}

Anda dapat menempelkan cuplikan yang tidak dipisahkan ( sub i/o/g/h) dalam satu file dan menambahkan kode tes di bawah ini.

sub t {
    print $i=i(shift),$/,o($i),$/x2;
    %c=%h=@L=@X=@O=();
}

t "Test.";                              # Test.
t "Zulus win.";                         # Zulus win.
t "Happy solstice.";                    # Happy solstice.
t "Abash abel mammal test.";            # Abase alms embalm that.
t "Dovecot flagships oleander.";        # Dangled horoscope festival.
t 'This code requires further golfing.';# Tech deer fighting ferrous liquors.

  • pembaruan 504 : simpan 12 byte menghilangkan a substrdan parameter untuk sub g.
Kenney
sumber
Begitu ya, mencuri contoh saya! Hanya bercanda para rasul yang lucu XD
Eumel
@Eumel Ya, mereka berbeda dengan Anda jadi saya memasukkan mereka :-)
Kenney