Воссоздайте предложение


12

Эта задача состоит из двух частей. Победителем станет решение с самым низким общим количеством байтов. Один и тот же язык должен использоваться для обеих задач.

Часть 1:

Напишите функцию или программу, которая принимает предложение с использованием только допустимых слов в качестве входных данных и выводит список использованных символов, количество раз, которое используется каждая буква, и количество букв в каждом из слов в исходном предложении. Выходные данные из этой программы должны быть действительными входными данными для следующей программы (в точности так, как они выводятся)

Я добавлю примеры и подробные правила ниже.

Часть 2:

Напишите функцию или программу, которая принимает выходные данные из первой программы в качестве входных данных и использует этот список английских слов и воссоздает предложение с информацией из выходных данных. Предложение не должно совпадать с исходным предложением.

Дополнительная информация. правила и ограничения:

Часть 1:

  • Первый ввод может быть в любом подходящем формате, с кавычками или без них, в качестве аргумента функции или из STDIN, с или без скобок и т. Д.
  • Входное предложение не будет содержать знаков препинания или специальных символов, за исключением точки / точки в конце. За исключением символа точки, все символы, которые находятся на входе, будут в списке слов.
  • Первая буква предложения будет прописной, остальные - строчными.
  • Вывод части 2 должен начинаться с той же буквы верхнего регистра, что и исходное предложение (поэтому преобразование ввода в нижний регистр не рекомендуется (но хорошо).
  • Вывод может быть в любом подходящем формате:
    • Должна быть возможность скопировать и вставить вывод непосредственно в следующую программу / функцию.
    • Никакие изменения не могут быть сделаны при копировании, весь вывод должен быть скопирован и вставлен целиком, а не по частям.
    • Например, вы можете вывести гистограмму всех букв алфавита или только используемых (в общем, все, что необходимо для завершения части 2)
    • Вы не можете вывести список символов, где повторяются несколько вхождений. Например, The queueне может дать выход: Teeehquu (3,5)он должен быть что - то вроде: Tehqu, (1 3 1 1 2),(3 5).

Часть 2:

  • Программа / функция должна принимать ввод точно так же, как и в части 1 (одно исключение, см. Комментарий ниже о принятии имени файла в качестве ввода.).
    • Если для анализа входных данных необходимы окружающие скобки, кавычки и т. П., То они должны быть частью выходных данных части 1.
  • Список слов можно найти здесь.
    • Список слов может быть сохранен как локально w.txt, так и извлечен из URL. URL будет считаться только 5 байтами, поэтому вам не нужно сокращать URL.
    • Если программа не может открыть файл , не читая имя в качестве входных данных из STDIN (я считаю , что это есть и в случае Pyth , по крайней мере), то имя файла может быть принято в качестве отдельного входного аргумента.
  • Выводом должно быть только предложение (список допустимых слов), заканчивающееся точкой и необязательным переводом строки.
    • Вывод должен содержать слова с тем же количеством букв, что и в оригинальном предложении в части 1 (в правильном порядке).
    • Все буквы, которые использовались в исходном предложении, должны использоваться в новом выводе.
    • Предложение должно начинаться с той же буквы в верхнем регистре, что и исходное предложение, и заканчиваться точкой.

Обе части:

  • Ни одна из частей не должна выполняться более 2 минут (случайный выбор слов до тех пор, пока не будет найдено решение, не принимается).

При соблюдении правил, перечисленных выше, должна быть реальная вероятность того, что воспроизводится точно такое же предложение, однако это не является обязательным требованием.

Примеры:

В приведенных ниже примерах показаны несколько различных форматов ввода и вывода. Многие другие принимаются.

Часть 1:

Входные данные:

Zulus win.

Тип выхода 1:

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

Тип выхода 2:

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

Тип выхода 3:

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

Часть 2:

Вход: точная копия вывода из части 1. Выход:

Zulus win.

Обратите внимание, что другие словосочетания принимаются до тех пор, пока они начинаются с Zбуквы « a» , а первое слово состоит из 5 букв, а второе - из 3.

Самый короткий код в байтах побеждает.



@ LegionMammal978: Да, вы можете сделать это при следующих ограничениях: вывод, f1который вставлен в, f2должен содержать все данные, указанные в задании. Никакие дополнительные данные не могут быть частью вывода f1. Никакие данные не могут быть "сохранены", f1чтобы сделать информацию доступной при ее вызове f2. f1может принимать только одну строку в качестве ввода для вызова.
Стьюи Гриффин

1
Я думаю, что шанс выпустить одно и то же предложение с более чем 3 словами на самом деле очень плохой
Eumel

В общем, да, но во многих случаях вы можете получить одно и то же предложение. Если вашей бабушке надоело переделывать свой старый свитер, она может быть: «бросить перевязывать». Я не проверял, но я думаю, что ваша бабушка все еще будет уходить после второй части. Кроме того, комбинации более длинных слов могут вернуть одно и то же предложение.
Стьюи Гриффин

1
@ StewieGriffin Вы могли бы легко получить "Парик ... вау". вернуться с этим примером предложения.
question_asker

Ответы:


5

LabVIEW, 166 примитивов LabVIEW

Во-первых, я не создавал 2 отдельные программы, потому что Labview выполняет поток данных, поэтому в этом нет необходимости.

Сохраняет гистограмму с первым элементом = ascii, код первой буквы покоится из 1-26 ходов по количеству. Длина просто сохраняется в массиве.

У первого слова есть 3 проверки, первая буква, длина и доступные буквы в гистограмме. Проверка первой буквы прекращается после первого слова.

Я проверяю гистограмму, уменьшая ее для каждой буквы и проверяя, не опустится ли она ниже 0.

Если я нашел свое N-е слово и нет слов, которые можно построить из оставшихся букв, то я начну удалять слова из диктонары и повторять N-е слово и так далее, пока не найду решение.

Это может или не может работать для предложений, которые есть, так как это займет целую вечность (мой пример занял несколько секунд).

Что я пробовал

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 байта

К сожалению, я не могу проверить это с фактическим w.txt файлом ATM, потому что QPython для Android не может обрабатывать файловый ввод / вывод. Это работало с данными, которые я скопировал и вставил все же.

Часть 1, 76 байт

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

В: 'Hi there.'

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

Итак, список, содержащий:

  • хэш-карта с гистограммой

  • список букв

Часть 2, 277 байт

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

Я очень рад, что мне удалось сделать его на 100% чисто функциональным. Не уверен, поможет ли это с фактическим игрой в гольф, но я, конечно, получил правильную часть обфускации: D Вот более дружелюбная версия pt. 2 (точно такой же поток, но с именами переменных):

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 байта

включает 2x +1 для -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}

Требуется иметь w.txtв формате unix ( \nокончания строк). Использует catдля чтения файла; изменить typeдля Windows.
Сохраните oneliner выше в 534.plи запустите как echo Test. | perl -p 534.pl.

Довольно большой, но это только начало - множество возможностей для игры в гольф, но я просто хотел опубликовать его, чтобы сделать ответ LabVIEW менее одиноким ;-). Я пропустил оптимизацию для выполнения менее чем за секунду, экономя более 30 байт.


Первый фрагмент (73 байта):

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

Он производит гистограмму и слово длины в компактном формате. Для ввода Zulus win.он производит вывод типа 2 без (,), которые здесь не нужны:

s1 l1 u2 Z1 w1 i1 n1 5 3

Вот он, бездельник

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
}

Второй фрагмент (441 байт)

Эта основная часть касается ввода-вывода и специальной обработки первой буквы, с использованием подпрограмм gи hперечисленных ниже.

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

Эта рекурсивная функция берет копию гистограммы, копию количества оставшихся слов и текущего слова. Если массив длины слова пуст, возвращает true. В противном случае он уменьшает количество гистограмм для букв в данном слове, берет следующую длину слова и находит список подходящих слов из списка слов. Для каждого подходящего слова оно повторяется.

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

И наконец, этой подпрограмме дают слово и гистограмму предложения. Он рассчитывает новую гистограмму для слова и проверяет, встречаются ли все буквы чаще, чем это разрешено гистограммой предложения.

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

Вы можете вставить фрагменты ungolfed ( sub i/o/g/h) в один файл и добавить приведенный ниже тестовый код.

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.

  • обновление 504 : сохранить 12 байтов, исключив substrи параметр для sub g.

Я вижу, краду мои примеры! Шутки о том, что это смешные веселья XD
Eumel

@Eumel Да, они отличались от ваших, поэтому я включил их :-)
Кенни
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.