Pleasanortmanteaus

32

Контаминация слово представляет собой сочетание двух слов , которые принимают участие каждого слова и делают их в единое новое слово. Например, лев + тигр => лигер .

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

(Примеры здесь показаны с разделителем между префиксом и суффиксом для ясности:. li|gerОднако фактические выходные данные программы не должны иметь разделитель:. liger)

  • Каждое портманто будет состоять из непустого префикса первого слова, соединенного с непустым суффиксом второго слова: да li|ger, нет, нет |iger.
  • Если префикс оканчивается гласным, суффикс должен начинаться с согласного, и наоборот: да lio|gerили l|er, нет lio|igerили или l|ger. Вы можете решить, считать yли вас гласным или согласным. Ваше решение должно выбрать один вариант и придерживаться его, однако.
  • Полученное слово не должно содержать ни одно из исходных слов полностью: да lio|ger, нет lion|igerили или li|tiger.
    • Это правило сохраняется, даже если рассматриваемая часть сформирована из частей обоих слов: при вводе two+ wordsвывод tw|ordsпо-прежнему недопустим, поскольку содержит подстроку words. (Единственный действительный выход для этой пары будет t|ords.)

Ваша программа или функция должны взять два слова и вывести / вернуть список всех приятных портмантеев, которые могут быть сформированы из этих слов в указанном порядке.

Детали

  • Применяются стандартные методы ввода и вывода . Стандартные лазейки запрещены.
  • Слова будут состоять только из строчных букв (или, если хотите, только из заглавных букв).
  • Вы можете взять два входных слова в виде списка, кортежа, двух отдельных входов, одной строки с разделителем без букв и т. Д.
  • Формат вывода также гибкий; если вы возвращаете или выводите строку, она должна быть разделена так, чтобы было ясно, где заканчивается одно слово portmanteau и начинается следующее.
  • Внутри слова портманто не должно быть разделителей.
  • Ничего страшного, если ваш список вывода содержит повторяющиеся результаты; также можно удалить дубликаты.

Контрольные примеры

> lion, tiger
< liger, ler, liger, lir, lioger, lior

> tiger, lion
< tion, ton, tin, tigion, tigon, tigen

> spoon, fork
< sork, spork, spork, spok, spoork, spook

> smoke, fog
< sog, smog, smog, smokog

> gallop, triumph
< giumph, gumph, gariumph, gamph, gaph, gah, galiumph, galumph, galliumph, gallumph, galloriumph, gallomph, galloh

> breakfast, lunch
< bunch, brunch, brench, brech, breh, breanch, breach, breah, breakunch, breakfunch, breakfanch, breakfach, breakfah, breakfasunch

> two, words
< tords

> harry, ginny (if y is treated as a consonant)
< hinny, hanny, hany, hay, harinny, harrinny

> harry, ginny (if y is treated as a vowel)
> hinny, hy, hanny, hany, harinny, hary, harrinny

Эталонное решение

Вот эталонное решение в Пипе (рассматривается yкак согласная).


Это : выигрывает самый короткий ответ на каждом языке!

DLosc
источник
должен ли разделитель быть постоянным или я могу поставить кучу пробелов между словами?
Asone Tuhid
@AsoneTuhid Конечно, переменные количества пробелов будут приемлемым разделителем. Единственное требование - «ясно, где заканчивается одно слово portmanteau и начинается следующее».
DLosc

Ответы:

5

05AB1E , 28 байт

y является гласным (тем же количеством байтов, что и согласный).

нη¨sθ.s¨âʒ`нsθ‚žOsåË_}Jʒs¢Z_

Попробуйте онлайн! или как слегка измененный набор тестов

Emigna
источник
2
Хороший ответ! Забавно, как есть довольно много вариантов для последнего фильтра, но, к сожалению, все тот же счетчик байтов .. ʒs¢Z_; ʒsåO_; ʒsм__; и т. д.
Кевин Круйссен,
4

Сетчатка , 72 байта

L$w`(?<=[aeiou]()|.())((.+),(.+))\B(?!\4)(?<!\5\3)(?([aeiou])\2|\1)
$`$'

Попробуйте онлайн!

Мартин Эндер
источник
Бах, я так далеко, Lw$`(?<=[aeiou])(.+),(.+)(?<!^\2\1,\2)(?!\1)(?=[^aeiou])|(?<=[^aeiou])(.+),(.+)(?<!^\4\3,\4)(?!\3)(?=[aeiou])но я не мог сосредоточиться на игре в гольф из-за головной боли.
Нил
Моя первая попытка была довольно схожей, хотя я избегал повторения центральной части, проверяя гласную / согласную вещь в конце с чем-то вроде этого, (?=.(?<=[aeiou]\1[^aeiou]|[^aeiou]\1[aeiou]))а затем, вероятно, потребовалось, по крайней мере, шесть итераций, чтобы привести его туда, где он сейчас находится.
Мартин Эндер
( ^S в моем предыдущем комментарии ошибочны) Действительно, я бы никогда не подумал об этом ()|.()трюке, на котором я бы, наверное, остановился Lw$`(?<=([aeiou])|.)((.+),(.+))(?<!\4\2)(?!\3)(?=(?(1)[^aeiou]|[aeiou])).
Нил
3

Pyth , 38 байт

f!s}RTQm+hd_edfxFm}ed"aeiou"T*._hQ.__e

Ввод - это список двух слов, а у не рассматривается как согласный.

Попробуйте онлайн здесь или проверьте все тестовые примеры сразу здесь .

f!s}RTQm+hd_edfxFm}ed"aeiou"T*._hQ.__e   Implicit: Q=eval(input())
                                hQ       First input word
                              ._         All prefixes of the above
                                     e   Second input word (Q inferred)
                                  .__    Reverse, take all prefixes
                             *           Cartesian product of the above
              f                          Filter the above using:
                 m          T              Map d in the current element using:
                   ed                        The last letter of the word part
                  }  "aeiou"                 Is it contained in the vowel list?
               xF                          Take the XOR of the list
                                         (This ensures that the word parts meet at one consonant)
       m                                 Map d in the filtered set using:
        +hd_ed                             Add the first part to the reversed second part
f                                        Filter the above using:
  s}RTQ                                    Does the portmanteau contain either of the input words?
 !                                         Logical NOT (remove from list if the above is true)
Sok
источник
3

Ява 8, 228 225 215 байт

v->w->{String r="",t,p=" aeiou";for(int i=w.length(),j;--i>0;)for(j=1;j<v.length();)r+=(t=v.substring(0,j)+w.substring(i)).matches(v+".*|.*"+w)|p.indexOf(t.charAt(j-1))*p.indexOf(t.charAt(j++))>0?"":t+" ";return r;}

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

Благодаря DLosc за игру в гольф 2 байта.

Ungolfed:

v -> w -> { // lambda taking two String parameters in currying syntax
    String r = "", // result
    t, // temporary variable used for storing
       // the portmanteau candidate currently being evaluated
    p = " aeiou"; // vowels for the purposes of this function;
                  // the leading space is so that they all have a positive index
    for(int i = w.length(), j; --i > 0; ) // loop over all proper suffixes
                                          // of the second word
        for(j = 1; j < v.length(); )      // loop over all proper prefixes
                                          // of the first word
            r += // construct the portmanteau candidate
                 (t = v.substring(0, j) + w.substring(i))
                 // if it contains one of the input words ...
                 .matches(v + ".*|.*" + w)
                 // ... or the boundary is consonant-consonant 
                 // or vowel-vowel (here we make use of the facts
                 // that all the vowels have a positive index, and
                 // indexOf() returns -1 in case of no match) ...
                 | p.indexOf(t.charAt(j-1)) * p.indexOf(t.charAt(j++)) > 0
                 ? "" // ... reject it ...
                 : t + " "; // ... else add it to the result
    return r; // return the result
}
OOBalance
источник
3

Japt , 32 байта

å+ ïVw å+)f_xè"%v$" uÃmrÈ+YwÃkøN

Japt Переводчик

Сохранено 10 байт благодаря более ясному пониманию синтаксиса Джапта Шегги.

Сохранено 8 байт благодаря новой языковой функции

Сохранено 2 байта благодаря некоторым предложениям от ETHproductions

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

Объяснение:

   ï     )       Cartesian product of...
å+                prefixes of first input
    Vw å+         and suffixes of second input.

f_         Ã     Remove the ones where...
  xè"%v$"         the number of vowels at the joining point
          u       is not 1.

m     Ã          Replace each pair with...
 rÈ+Yw            the prefix and suffix joined together
       køN       then remove the ones that contain either input
Камил Дракари
источник
Добро пожаловать в Japt (снова!). Я определенно вижу некоторый потенциал для большего количества игры в гольф здесь; Я правильно посмотрю на это, когда вернусь к компьютеру.
Лохматый
1
Несколько быстрых сбережений для тебя с моего телефона.
Лохматый
3

Python 3 , 156 150 байт

Я считаю yсогласной.

lambda a,b:{a[:i]+b[j:]for i in range(1,len(a))for j in range(1,len(b))if((a[i-1]in'aeiou')^(b[j]in'aeiou'))*0**(a in a[:i]+b[j:]or b in a[:i]+b[j:])}

-6 байт благодаря Джонатану Фреху

Попробуйте онлайн!

PieCot
источник
Возможно 150 байт .
Джонатан Фрех
@JonathanFrech спасибо за то, что заметили его
PieCot
Вы можете использовать аргументы по умолчанию lambda x=0, чтобы сохранить ... 0 символов, досадно. lambda a,b,v='aeiou',r=range:{a[:i]+b[j:]for i in r(1,len(a))for j in r(1,len(b))if((a[i-1]in v)^(b[j]in v))*0**(a in a[:i]+b[j:]or b in a[:i]+b[j:])}(Все еще 150)
Мэтт
2

JavaScript (ES6), 124 байта

Принимает 2 слова в синтаксисе карри (a)(b)и печатает результаты с alert(). Предполагается, что у согласная.

a=>b=>[...a].map(c=>[...b].map((C,j)=>!(w=s+b.slice(j)).match(a+'|'+b)&v.test(c)-v.test(C)&&alert(w),s+=c),s='',v=/[aeiou]/)

Попробуйте онлайн!

Arnauld
источник
1

Желе , 27 байт

¹Ƥp¹ÐƤ}Ø.ị"e€Øc⁻/ƲƇẎ€wÐḟƒ@,

Попробуйте онлайн!

Уу согласная. Оба случая поддерживаются. Возвращает дубликаты.

Вывод был предварительно проверен на TIO. Удалить +/€из нижнего колонтитула, чтобы увидеть фактический результат.

Эрик Outgolfer
источник
1

C ++ 11, 217 202 байта

[](auto v,auto w){auto r=v,t=v,p=v;r="",p="aeiou";for(int i=w.size(),j;--i;)for(j=v.size();j;)(t=v.substr(0,j)+w.substr(i)).find(v)+1|t.find(w)+1|p.find(t[j-1])<5==p.find(t[j--])<5?v:r+=t+" ";return r;}

Делает интенсивное использование std::string#find. Относится yкак согласная. Попробуйте это онлайн здесь .

Ungolfed:

// lambda; relies on auto to keep declarations short
[] (auto v, auto w) {
    // let's declare some strings. To keep it terse, we're using auto and the type of the arguments.
    auto r = v, // result string
    t = v,      // temporary string for storing the portmanteau candidate
    p = v;      // vowels string
    // now assign them their values
    r = "",    // result starts empty
    p = "aeiou"; // vowels don't include 'y'
    for(int i = w.size(), j; --i; ) // suffixes of the second word
        for(j = v.size(); j; ) // prefixes of the first word
            // create the portmanteau candidate
            (t = v.substr(0, j) + w.substr(i))
            // if it includes one of the input words ...
            .find(v) + 1 | t.find(w) + 1
            // ... or the boundary is consonant-consonant or vowel-vowel ...
            | p.find(t[j - 1]) < 5 == p.find(t[j--]) < 5
            ? v // ... discard it ...
            : r += t + " "; // ... else add it to the result.
    return r; // return the result
}
OOBalance
источник
1

Python 2 , 179 176 166 162 байта

lambda s,t:[w for w in g(s,t)if(s in w)<1>(t in w)]
g=lambda s,t:s[:-1]and[s[:-1]+t[j:]for j in range(1,len(t))if(s[-2]in'aeiou')^(t[j]in'aeiou')]+g(s[:-1],t)or[]

Попробуйте онлайн!

3 байта от Джонатана Фреха . И 10 байтов, спасибо Мэтту .

В моем мире yнет гласного. (Это вопль!)

Час Браун
источник
Есть беспризорные места в t) ifи t) or [].
Джонатан Фрех
@ Джонатон Фрех: Спасибо! Там немного поленился ...
Час Браун
Понятно
* Джонатан: Д'Ох! Ну, по крайней мере, я был последовательным! :)
Час Браун
1
@ Мэтт: Спасибо! На самом деле, я выдавил еще 2 байта через (s in w)<1>(t in w).
Час Браун
0

Рубин , 113 112 109 104 байта

y согласная

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

->a,b,i=j=1{r=a[0,i]+b[j..-1];g=:aeiou;!g[a[i-1]]^g[b[j]]|r[a]|r[b]||z=[*z,r];b[j+=1]||a[i+=j=1]?redo:z}

Попробуйте онлайн!

Асоне Тухид
источник
0

Emacs Lisp , 306 + 13 = 319 байт

+13 за (require'seq)

(require'seq)(lambda(a b)(dotimes(i(1-(length b)))(dotimes(j(1-(length a)))(progn(setq w(substring a 0(1+ j))x(substring b(1+ i))c(concat w x))(defun V(c)(seq-contains"aeiou"(elt c 0)'char-equal))(if(not(or(string-prefix-p a c)(string-suffix-p b c)))(if(V(substring w -1))(if(not(V x))(print c))(if(V x)(print c))))))))

Попробуйте онлайн!

Определяет анонимную лямбда-функцию. Выводит последовательность разделенных символом новой строки portmanteaus, каждый из которых заключен в кавычки. Гольф советы приветствуются. Письмоy считается согласной.

Ungolfed

(require 'seq)                                                                                                                                                           
(defun Portmanteus(word1 word2)
  "Find all valid portmanteus of the two given words"
  (dotimes (i (1- (length word2)))
    (dotimes (j (1- (length word1)))
      (progn
        (setq w (substring word1 0 (1+ j)) w2 (substring word2 (1+ i)) comb (concat w w2))
        (defun isVowel (c) (seq-contains "aeiou" (elt c 0) 'char-equal))
        (if (not (or (string-prefix-p word1 comb) (string-suffix-p word2 comb)))
          (if (isVowel (substring w -1))
            (if (not (isVowel w2))
              (princ (format "%s\n" comb))
            )
            (if (isVowel w2)
              (princ (format "%s\n" comb))
            )
          )
        )
      )
    )
  )
)
Р. Кап
источник