Ricrea la frase


12

Questa sfida consiste in due parti. Il vincitore sarà la soluzione con il conteggio dei byte totali più basso. La stessa lingua deve essere utilizzata per entrambe le sfide.

Parte 1:

Scrivi una funzione o un programma che accetta come input una frase con solo parole valide e genera un elenco dei caratteri utilizzati, il numero di volte in cui ogni lettera viene utilizzata e il numero di lettere in ciascuna delle parole della frase originale. L'output di questo programma deve essere input valido per il programma successivo (esattamente come viene emesso)

Aggiungerò esempi e regole dettagliate più avanti.

Parte 2:

Scrivi una funzione o un programma che prende l'output dal primo programma come input e usa questo elenco di parole inglesi e ricrea una frase con le informazioni dall'output. La frase non deve essere la stessa della frase originale.

Maggiori informazioni. regole e restrizioni:

Parte 1:

  • Il primo input può essere su qualsiasi formato adatto, con o senza virgolette, come argomento di funzione o da STDIN, con o senza parentesi ecc.
  • La frase di input non conterrà punteggiatura o caratteri speciali, ad eccezione di un punto / punto alla fine. Ad eccezione del simbolo del punto, tutti i caratteri che si trovano nell'input saranno nell'elenco delle parole.
  • La prima lettera della frase sarà maiuscola, il resto sarà minuscolo.
  • L'output della parte 2 deve iniziare con la stessa lettera maiuscola della frase originale (quindi non è consigliabile convertire l'input in lettere minuscole (ma OK).
  • L'output può essere in qualsiasi formato adatto:
    • Deve essere possibile copiare e incollare l'output direttamente nel programma / funzione successivo
    • Non è possibile apportare modifiche durante il copia-incolla, l'intero output deve essere copiato e incollato nel suo insieme, non in parti.
    • Ad esempio, è possibile produrre un istogramma di tutte le lettere dell'alfabeto o solo quelle utilizzate (in generale, tutto ciò che è necessario per completare la parte 2)
    • Non è possibile generare un elenco di caratteri in cui si ripetono più ricorrenze. Per esempio, The queuenon può produrre un output: Teeehquu (3,5), dovrebbe essere qualcosa di simile: Tehqu, (1 3 1 1 2),(3 5).

Parte 2:

  • Il programma / funzione deve accettare l'input esattamente come nella parte 1 (un'eccezione, vedere il commento seguente sull'assunzione del nome del file come input).
    • Se sono necessarie parentesi, virgolette o simili circostanti per analizzare l'input, questi devono essere parte dell'output della parte 1.
  • L'elenco delle parole può essere trovato qui.
    • L'elenco delle parole può essere salvato localmente come w.txt, oppure può essere recuperato dall'URL. L'URL verrà conteggiato solo come 5 byte, quindi non è necessario un accorciatore di URL.
    • Se il programma non è in grado di aprire un file senza leggere il nome come input da STDIN ( almeno credo che sia stato il caso di Pyth), il nome del file può essere preso come argomento di input separato.
  • L'output deve essere solo una frase (elenco di parole valide), che termina con un punto e una nuova riga opzionale.
    • L'output deve contenere parole con lo stesso numero di lettere della frase originale nella parte 1 (nell'ordine corretto)
    • Tutte le lettere utilizzate nella frase originale devono essere utilizzate nel nuovo output.
    • La frase deve iniziare con la stessa lettera maiuscola della frase di input originale e terminare con un punto.

Entrambe le parti:

  • Nessuna delle parti dovrebbe richiedere più di 2 minuti per essere eseguita (la selezione casuale delle parole fino al raggiungimento di una soluzione non è accettata).

Con le regole sopra elencate, ci dovrebbe essere una buona probabilità che venga riprodotta la stessa frase esatta, tuttavia questo non è un requisito.

Esempi:

Negli esempi seguenti, vengono mostrati alcuni formati di input e output diversi. Molti altri sono accettati.

Parte 1:

Ingresso:

Zulus win.

Tipo di uscita 1:

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

Tipo di uscita 2:

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

Tipo di uscita 3:

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

Parte 2:

Input: una copia esatta dell'output dalla parte 1. Output:

Zulus win.

Nota che le altre combinazioni di parole sono accettate purché inizino con a Z, e la prima parola abbia 5 lettere e la seconda ne abbia 3.

Vince il codice più breve in byte.



@ LegionMammal978: Sì, puoi farlo in base alle seguenti restrizioni: L'output f1incollato f2deve contenere tutti i dati specificati nella sfida. Nessun dato aggiuntivo può far parte dell'output di f1. Nessun dato può essere "memorizzato" nel f1rendere disponibili le informazioni quando le si chiama f2. f1può accettare solo una stringa come input per chiamata.
Stewie Griffin,

1
La possibilità di ottenere la stessa frase con più di 3 parole è in realtà piuttosto male, penso
Eumel,

In generale sì, ma ci sono molti casi in cui è probabile che tu ottenga la stessa frase. Se tua nonna è stanca di rifare il tuo vecchio maglione, potrebbe essere: "smettere di lavorare a maglia". Non ho controllato, ma penso che tua nonna smetterà ancora dopo la parte 2. Anche combinazioni di parole più lunghe potrebbero restituire la stessa frase.
Stewie Griffin,

1
@StewieGriffin Potresti facilmente ottenere "Wig ... wow." torna con quella frase di esempio.
question_asker il

Risposte:


5

LabVIEW, 166 LabVIEW Primitives

Prima di tutto non ho creato 2 programmi separati perché Labview esegue il flusso di dati, quindi non c'è davvero bisogno.

Salva l'istogramma con il primo elemento = codice ascii del resto della prima lettera da 1-26 in base all'importo. La lunghezza viene semplicemente salvata in un array.

La prima parola ha 3 assegni, prima lettera, lunghezza e lettere disponibili nell'istogramma. Il controllo della prima lettera si interrompe dopo la prima parola.

Controllo l'istogramma decrementandolo per ogni lettera e controllando che scenda al di sotto di 0.

Se ho trovato la mia ennesima parola e non ci sono parole costruibili dalle lettere rimaste, inizierò a cancellare le parole dal dittonario e rifare l'ennesima parola e così via fino a quando non ho trovato una soluzione.

Questo potrebbe o non potrebbe funzionare per le frasi che esistono, dal momento che ci vorrebbe un'eternità per calcolare (il mio esempio impiegava già alcuni secondi).

Quello che ho provato

In: Zulus win.
Out: Zulus win.

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

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


3

Python 2.7, 353 byte

Sfortunatamente, non riesco a provarlo con il file ATM w.txt reale perché QPython per Android non sembra gestire l'I / O dei file. Ha funzionato con i dati che ho copiato e incollato però.

Parte 1, 76 byte

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

Nel: 'Hi there.'

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

quindi, un elenco contenente:

  • un hashmap con l'istogramma

  • un elenco di lettere conta

Parte 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()+'.'

Sono davvero felice di essere riuscito a renderlo funzionale al 100%. Non sono sicuro se questo aiuta con il golf reale, ma ho sicuramente ottenuto la parte di offuscamento giusta: D Ecco una versione più umana del pt. 2 (esattamente lo stesso flusso, ma con nomi di variabili):

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()+'.'

3

Perl, 516 504 byte

include 2x +1 per -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}

Richiede di avere w.txtin formato unix ( \nterminazioni di riga). Utilizza catper leggere il file; passare a typeper windows.
Salvare l'oneliner sopra in 534.pled eseguire come echo Test. | perl -p 534.pl.

Abbastanza grande, ma è un inizio: molte opportunità di golf, ma volevo solo pubblicarlo per rendere la risposta LabVIEW meno solitaria ;-). Ho omesso le ottimizzazioni per l'esecuzione in meno di un secondo, risparmiando oltre 30 byte.


Primo frammento (73 byte):

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

Produce un istogramma e la parola allunga in un formato compatto. Per l'input Zulus win.produce un output di tipo 2 senza il (,), che qui non è necessario:

s1 l1 u2 Z1 w1 i1 n1 5 3

Eccolo, non golfato:

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
}

Secondo frammento (441 byte)

Questa parte principale riguarda l'I / O e il trattamento speciale della prima lettera, usando subroutine ge hche sono elencate di seguito.

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.
    $_
}

Questa funzione ricorsiva prende una copia dell'istogramma, una copia del conteggio delle parole rimanenti e la parola corrente. Se la matrice della lunghezza della parola è vuota, restituisce true. Altrimenti diminuisce il conteggio dell'istogramma per le lettere nella parola data, prende la lunghezza della parola successiva e trova un elenco di parole adatte dall'elenco di parole. Per ogni parola adatta, ricorre.

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!
}

E infine, a questa subroutine viene data una parola e l'istogramma della frase. Calcola un nuovo istogramma per la parola e controlla se tutte le lettere non si presentano più spesso di quanto consentito dall'istogramma della frase.

# 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
}

Puoi incollare i frammenti non memorizzati ( sub i/o/g/h) in un singolo file e aggiungere il seguente codice di prova.

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.

  • aggiornamento 504 : salva 12 byte eliminando un substre un parametro per sub g.

Vedo, rubando i miei esempi! Sto scherzando con gli scherzetti XD esilaranti
Eumel

@Eumel Sì, erano diversi dai tuoi, quindi li ho inclusi :-)
Kenney,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.