Recrie a frase

12

Este desafio consiste em duas partes. O vencedor será a solução com a menor contagem total de bytes. O mesmo idioma deve ser usado para ambos os desafios.

Parte 1:

Escreva uma função ou programa que use uma frase com apenas palavras válidas como entrada e produz uma lista dos caracteres usados, o número de vezes que cada letra é usada e o número de letras em cada uma das palavras na frase original. A saída deste programa deve ser válida para o próximo programa (exatamente como é emitida)

Vou adicionar exemplos e regras detalhadas mais adiante.

Parte 2:

Escreva uma função ou programa que use a saída do primeiro programa como entrada e use esta lista de palavras em inglês e recrie uma frase com as informações da saída. A sentença não precisa ser igual à sentença original.

Mais Informações. regras e restrições:

Parte 1:

  • A primeira entrada pode estar em qualquer formato adequado, com ou sem aspas, como argumento de função ou de STDIN, com ou sem colchetes, etc.
  • A frase de entrada não conterá pontuação ou caracteres especiais, exceto um ponto / ponto no final. Exceto pelo símbolo do período, todos os caracteres que estão na entrada estarão na lista de palavras.
  • A primeira letra da frase será em maiúscula, o restante será em minúscula.
  • A saída da parte 2 deve começar com a mesma letra maiúscula que a frase original (portanto, a conversão da entrada para minúscula não é recomendada (mas OK).
  • A saída pode estar em qualquer formato adequado:
    • Deve ser possível copiar e colar a saída diretamente no próximo programa / função
    • Nenhuma alteração pode ser feita ao copiar e colar, toda a saída deve ser copiada e colada como um todo, não em partes.
    • Por exemplo, você pode imprimir um histograma de todas as letras do alfabeto ou apenas as que são usadas (em geral, o que for necessário para concluir a parte 2)
    • Você não pode exibir uma lista de caracteres em que várias ocorrências são repetidas. Por exemplo, The queuenão pode produzir uma saída: Teeehquu (3,5), deve ser algo como: Tehqu, (1 3 1 1 2),(3 5).

Parte 2:

  • O programa / função deve aceitar a entrada exatamente como na parte 1 (uma exceção, consulte o comentário abaixo sobre como colocar o nome do arquivo como entrada).
    • Se colchetes, aspas ou similares forem necessários para analisar a entrada, eles deverão fazer parte da saída da parte 1.
  • A lista de palavras pode ser encontrada aqui.
    • A lista de palavras pode ser salva localmente como w.txtou pode ser buscada no URL. O URL contará apenas 5 bytes, portanto você não precisa de um encurtador de URL.
    • Se o programa não puder abrir um arquivo sem ler o nome como uma entrada do STDIN (acredito que esse seja o caso de Pyth, pelo menos), o nome do arquivo poderá ser considerado como um argumento de entrada separado.
  • A saída deve ser apenas uma frase (lista de palavras válidas), terminando com um ponto final e uma nova linha opcional.
    • A saída deve conter palavras com o mesmo número de letras da sentença original na parte 1 (na ordem correta)
    • Todas as letras que foram usadas na frase original devem ser usadas na nova saída.
    • A frase deve começar com a mesma letra maiúscula que a frase de entrada original e terminar com um ponto.

Ambas as partes:

  • Nenhuma das partes deve levar mais de 2 minutos para ser executada (escolher palavras aleatoriamente até que uma solução seja alcançada não é aceito).

Com as regras listadas acima, deve haver uma chance razoável de que a mesma frase seja reproduzida, no entanto, isso não é um requisito.

Exemplos:

Nos exemplos abaixo, são mostrados alguns formatos diferentes de entrada e saída. Muitos mais são aceitos.

Parte 1:

Entrada:

Zulus win.

Tipo de saída 1:

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

Tipo de saída 2:

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

Tipo de saída 3:

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

Parte 2:

Entrada: uma cópia exata da saída da parte 1. Saída:

Zulus win.

Observe que outras combinações de palavras são aceitas desde que comecem com ae Za primeira palavra tem 5 letras e a segunda 3.

O código mais curto em bytes vence.

Stewie Griffin
fonte
Aqui está o commit: github.com/isaacg1/pyth/commit/…
PurkkaKoodari
@ LegionMammal978: Sim, você pode fazer isso sob as seguintes restrições: A saída f1colada f2deve conter todos os dados especificados no desafio. Nenhum dado adicional pode fazer parte da saída de f1. Nenhum dado pode ser "armazenado" ao f1disponibilizar as informações ao chamá-lo f2. f1pode receber apenas uma sequência como entrada por chamada.
Stewie Griffin
1
A chance de obter a mesma frase com mais de 3 palavras é realmente muito ruim eu acho
Eumel
Em geral, sim, mas há muitos casos em que você provavelmente pronuncia a mesma frase. Se sua avó está cansada de refazer seu suéter velho, ela pode estar: "parando de recolocar o tricô". Eu não verifiquei, mas acho que sua avó ainda vai desistir depois da parte 2. Também combinações de palavras mais longas podem devolver a mesma frase.
Stewie Griffin
1
@StewieGriffin Você pode facilmente obter "Wig ... uau". de volta com essa frase de exemplo.
question_asker

Respostas:

5

LabVIEW, 166 Primitivas do LabVIEW

Primeiro de tudo, eu não criei dois programas separados porque o Labview faz o fluxo de dados, então não há realmente nenhuma necessidade.

Salva o histograma com o primeiro elemento = código ascii do resto da primeira letra de 1 a 26 por quantidade. O comprimento simplesmente é salvo em uma matriz.

A primeira palavra possui 3 cheques, primeira letra, comprimento e letras disponíveis no histograma. A verificação da primeira letra é interrompida após a primeira palavra.

Verifico o histograma decrementando-o para cada letra e verificando se ele ficaria abaixo de 0.

Se eu encontrei minha enésima palavra e não há palavras que possam ser construídas a partir das letras que sobraram, começarei a excluir palavras do dictonário e refarei a enésima palavra e assim por diante até encontrar uma solução.

Isso pode ou não funcionar para as frases existentes, pois isso levaria uma eternidade para ser calculado (meu exemplo já levou alguns segundos).

O que eu tentei

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
fonte
3

Python 2.7, 353 bytes

Infelizmente, não posso testá-lo com o arquivo ATM w.txt real, porque o QPython para Android parece não conseguir lidar com a E / S do arquivo. Porém, funcionou com os dados que eu copiei e colei.

Parte 1, 76 bytes

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

No: 'Hi there.'

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

então, uma lista contendo:

  • um hashmap com o histograma

  • uma lista de contagens de letras

Parte 2, 277 bytes

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

Estou muito feliz por ter conseguido torná-lo 100% puro funcional. Não tenho certeza se isso ajuda com o golfe real, mas eu certamente entendi direito a parte da ofuscação: D Aqui está uma versão mais amigável do pt. 2 (exatamente o mesmo fluxo, mas com nomes de variáveis):

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
fonte
3

Perl, 516 504 bytes

inclui 2x +1 para -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}

Requer ter w.txtno formato unix ( \nfinais de linha). Usa catpara ler o arquivo; mude para typepara janelas.
Salve o oneliner acima em 534.ple execute como echo Test. | perl -p 534.pl.

Muito grande, mas é um começo - muitas oportunidades de golfe, mas eu só queria publicá-la para tornar a resposta do LabVIEW menos solitária ;-). Omiti as otimizações para execução em menos de um segundo, economizando mais de 30 bytes.


Primeiro trecho (73 bytes):

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

Produz um histograma e a palavra se prolonga em um formato compacto. Para entrada Zulus win., produz uma saída do tipo 2 sem a (,), que não é necessária aqui:

s1 l1 u2 Z1 w1 i1 n1 5 3

Aqui está, não destruído:

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
}

Segundo trecho (441 bytes)

Esta parte principal trata da E / S e do tratamento especial da primeira letra, usando sub g- rotinas e hlistadas abaixo.

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

Essa função recursiva tira uma cópia do histograma, uma cópia da contagem de palavras restantes e a palavra atual. Se a matriz de comprimento de palavras estiver vazia, retornará true. Caso contrário, diminui a contagem do histograma para as letras da palavra especificada, pega o próximo comprimento de palavra e encontra uma lista de palavras adequadas da lista de palavras. Para cada palavra adequada, ela se repete.

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, finalmente, essa sub-rotina recebe uma palavra e o histograma da frase. Ele calcula um novo histograma para a palavra e verifica se todas as letras não ocorrem com mais frequência do que o permitido pelo histograma da 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
}

Você pode colar os trechos não destruídos ( sub i/o/g/h) em um único arquivo e anexar o código de teste abaixo.

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.

  • atualização 504 : economize 12 bytes, eliminando a substre um parâmetro para sub g.
Kenney
fonte
Entendo, roubando meus exemplos! Brincadeirinha os rasults são XD hilariante
Eumel
@Eumel Sim, elas eram diferentes dos seus, então eu incluído-los :-)
Kenney