Recréer la phrase

12

Ce défi se compose de deux parties. Le gagnant sera la solution avec le nombre d'octets total le plus bas. Le même langage doit être utilisé pour les deux défis.

Partie 1:

Écrivez une fonction ou un programme qui prend en entrée une phrase contenant uniquement des mots valides et génère une liste des caractères utilisés, le nombre de fois où chaque lettre est utilisée et le nombre de lettres dans chacun des mots de la phrase d'origine. La sortie de ce programme doit être une entrée valide pour le programme suivant (exactement comme elle est sortie)

J'ajouterai des exemples et des règles détaillées plus bas.

Partie 2:

Écrivez une fonction ou un programme qui prend la sortie du premier programme en entrée et utilise cette liste de mots anglais et recrée une phrase avec les informations de la sortie. La phrase ne doit pas nécessairement être la même que la phrase d'origine.

Plus d'information. règles et restrictions:

Partie 1:

  • La première entrée peut être dans n'importe quel format approprié, avec ou sans guillemets, comme argument de fonction ou depuis STDIN, avec ou sans crochets, etc.
  • La phrase d'entrée ne contiendra pas de ponctuation ou de caractères spéciaux, à l'exception d'un point / point à la fin. À l'exception du symbole de période, tous les caractères qui sont dans l'entrée seront dans la liste de mots.
  • La première lettre de la phrase sera en majuscules, le reste en minuscules.
  • La sortie de la partie 2 doit commencer par la même lettre majuscule que la phrase d'origine (il n'est donc pas recommandé de convertir l'entrée en minuscule (mais OK).
  • La sortie peut être dans n'importe quel format approprié:
    • Il doit être possible de copier-coller la sortie directement dans le prochain programme / fonction
    • Aucune modification ne peut être effectuée lors du copier-coller, la sortie entière doit être copiée et collée dans son ensemble, pas en partie.
    • Vous pouvez par exemple produire un histogramme de toutes les lettres de l'alphabet, ou seulement celles utilisées (en général, tout ce qui est nécessaire pour compléter la partie 2)
    • Vous ne pouvez pas sortir une liste de caractères où plusieurs occurrences sont répétées. Par exemple, The queuene peut pas produire une sortie: Teeehquu (3,5), il devrait être quelque chose comme: Tehqu, (1 3 1 1 2),(3 5).

Partie 2:

  • Le programme / la fonction doit accepter l'entrée exactement comme dans la partie 1 (une exception, voir le commentaire ci-dessous pour prendre le nom de fichier en entrée).
    • Si des crochets, des guillemets ou similaires sont nécessaires pour analyser l'entrée, ils doivent faire partie de la sortie de la partie 1.
  • La liste de mots peut être trouvée ici.
    • La liste de mots peut être enregistrée localement sous w.txt, ou récupérée à partir de l'URL. L'URL ne comptera que pour 5 octets, vous n'avez donc pas besoin d'un raccourcisseur d'URL.
    • Si le programme ne peut pas ouvrir un fichier sans lire le nom comme une entrée de STDIN (je crois que c'est -ce fut le cas pour Pyth au moins), le nom du fichier peut être considéré comme un argument d'entrée séparée.
  • La sortie doit être uniquement une phrase (liste de mots valides), se terminant par un point et une nouvelle ligne facultative.
    • La sortie doit avoir des mots avec le même nombre de lettres que la phrase originale dans la partie 1 (dans le bon ordre)
    • Toutes les lettres utilisées dans la phrase d'origine doivent être utilisées dans la nouvelle sortie.
    • La phrase doit commencer par la même lettre majuscule que la phrase d'entrée d'origine et se terminer par un point.

Les deux parties:

  • Aucune des parties ne devrait prendre plus de 2 minutes à exécuter (la sélection aléatoire de mots jusqu'à ce qu'une solution soit trouvée n'est pas acceptée).

Avec les règles énumérées ci-dessus, il devrait y avoir de bonnes chances que la même phrase soit reproduite, mais ce n'est pas une exigence.

Exemples:

Dans les exemples ci-dessous, quelques formats d'entrée et de sortie différents sont affichés. Beaucoup d'autres sont acceptés.

Partie 1:

Contribution:

Zulus win.

Type de sortie 1:

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

Type de sortie 2:

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

Type de sortie 3:

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

Partie 2:

Entrée: une copie exacte de la sortie de la partie 1. Sortie:

Zulus win.

Notez que d'autres combinaisons de mots sont acceptées tant qu'elles commencent par un Z, et le premier mot a 5 lettres et le second a 3.

Le code le plus court en octets gagne.

Stewie Griffin
la source
Voici le commit: github.com/isaacg1/pyth/commit/…
PurkkaKoodari
@ LegionMammal978: Oui, vous pouvez le faire sous les restrictions suivantes: La sortie de f1qui est collée dans f2doit contenir toutes les données spécifiées dans le défi. Aucune donnée supplémentaire ne peut faire partie de la sortie de f1. Aucune donnée ne peut être "stockée" pour f1rendre les informations disponibles lors de l'appel depuis f2. f1ne peut prendre qu'une seule chaîne en entrée par appel.
Stewie Griffin
1
La chance de sortir la même phrase avec plus de 3 mots est en fait assez mauvaise je pense
Eumel
En général, oui, mais il existe de nombreux cas où vous risquez de prononcer la même peine. Si votre grand-mère est fatiguée de refaire votre vieux pull, elle pourrait être: "arrêter de refitting tricoter". Je n'ai pas vérifié, mais je pense que votre grand-mère quittera toujours après la partie 2. De plus, des combinaisons de mots plus longs pourraient renvoyer la même phrase.
Stewie Griffin
1
@StewieGriffin Vous pourriez facilement obtenir "Wig ... wows." de retour avec cet exemple de phrase.
question_asker

Réponses:

5

LabVIEW, 166 primitives LabVIEW

Tout d'abord, je n'ai pas créé 2 programmes séparés parce que Labview fait le flux de données, donc il n'y a vraiment pas besoin.

Enregistre l'histogramme avec le premier élément = code ascii du reste de la première lettre de 1-26 go par montant. La longueur est simplement enregistrée dans un tableau.

Le premier mot a 3 chèques, première lettre, longueur et lettres disponibles dans l'histogramme. La vérification de la première lettre s'arrête après le premier mot.

Je vérifie l'histogramme en le décrémentant pour chaque lettre et en vérifiant s'il tomberait en dessous de 0.

Si j'ai trouvé mon Nième mot et qu'il n'y a pas de mots à construire à partir des lettres restantes, je vais commencer à supprimer les mots du dicton et refaire le Nième mot et ainsi de suite jusqu'à ce que j'aie trouvé une solution.

Cela pourrait ou non fonctionner pour les phrases, car cela prendrait une éternité à calculer (mon exemple a déjà pris quelques secondes).

Ce que j'ai essayé

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
la source
3

Python 2.7, 353 octets

Malheureusement, je ne peux pas le tester avec le véritable fichier w.txt ATM car QPython pour Android ne semble pas gérer les E / S de fichiers. Cela a fonctionné avec des données que j'ai copiées et collées.

Partie 1, 76 octets

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

Dans: 'Hi there.'

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

donc, une liste contenant:

  • une table de hachage avec l'histogramme

  • une liste des nombres de lettres

Partie 2, 277 octets

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

Je suis vraiment content d'avoir réussi à le rendre 100% fonctionnel. Je ne sais pas si cela aide au golf, mais j'ai certainement bien compris la partie obscurcie: D Voici une version plus conviviale de pt. 2 (exactement le même flux, mais avec des noms de variables):

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
la source
3

Perl, 516 504 octets

comprend 2x +1 pour -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}

Nécessite d'avoir w.txtau format Unix ( \nfins de ligne). Utilise catpour lire le fichier; changer pour typepour windows.
Enregistrez l'oneliner ci-dessus dans 534.plet exécutez sous echo Test. | perl -p 534.pl.

Assez grand, mais c'est un début - beaucoup de possibilités de golf, mais je voulais juste le poster pour rendre la réponse LabVIEW moins solitaire ;-). J'ai omis les optimisations pour l'exécution en moins d'une seconde, économisant plus de 30 octets.


Premier extrait (73 octets):

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

Il produit un histogramme et le mot longueurs dans un format compact. Pour l'entrée, Zulus win.il produit une sortie de type 2 sans le (,), qui n'est pas nécessaire ici:

s1 l1 u2 Z1 w1 i1 n1 5 3

Le voici, non golfé:

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
}

Deuxième extrait (441 octets)

Cette partie principale traite des E / S et du traitement spécial de la première lettre, en utilisant les sous g- programmes et hqui sont énumérés ci-dessous.

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

Cette fonction récursive prend une copie de l'histogramme, une copie du nombre de mots restants et le mot actuel. Si le tableau de longueur de mot est vide, renvoie true. Sinon, il diminue le nombre d'histogrammes pour les lettres du mot donné, prend la longueur de mot suivante et trouve une liste de mots appropriés dans la liste de mots. Pour chaque mot approprié, il revient.

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

Et enfin, ce sous-programme reçoit un mot et l'histogramme de la phrase. Il calcule un nouvel histogramme pour le mot et vérifie si toutes les lettres n'apparaissent pas plus souvent que ne le permet l'histogramme de phrase.

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

Vous pouvez coller les extraits non golfés ( sub i/o/g/h) dans un seul fichier et ajouter le code de test ci-dessous.

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.

  • mise à jour 504 : enregistrez 12 octets en éliminant un substret un paramètre pour sub g.
Kenney
la source
Je vois, en volant mes exemples! Je plaisante les rasults sont hilarants XD
Eumel
@Eumel Ouais, ils étaient différents des vôtres donc je les ai inclus :-)
Kenney