Составление заполнить бланки

18

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

I went to the ____ store and bought ____ today.

Если бы мы применили эту функцию к строке, cheeseрезультат был бы:

I went to the cheese store and bought cheese today.

Мы можем представить эти функции в виде непустого списка строк, где пробелы - это просто промежутки между строками. Например, наша функция выше будет:

["I went to the ", " store and bought ", " today."]

С этим представлением есть только одно представление для каждой функции такого рода и только одна функция для каждого представления.

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

["blue ", ""]

(функция, которая предшествует blueвводу) Мы получаем функцию:

["I went to the blue ", " store and bought blue ", " today."]

Это может быть немного сложнее, хотя. Например, если мы сочиняем первую функцию с

["big ", " and ", ""]

Результат

["I went to the big ", " and ", " store and bought big ", "and", " today."]

задача

Ваша задача - взять две функции, описанные как непустые списки строк, и вывести их композицию в виде непустого списка строк.

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

Это ответы будут оцениваться в байтах с меньшим количеством байтов, тем лучше.

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

["","xy"] ["ab",""] -> ["ab","xy"]
["x","y","z"] ["a","b"] -> ["xa","bya","bz"]
["xy"] ["ab"] -> ["xy"]
["","",""] ["a",""] -> ["a","a",""]
["x",""] ["","",""] -> ["x","",""]
["x","y","z"] ["a","b","c"] -> ["xa","b","cya","b","cz"]
["x","x","x"] ["a"] -> ["xaxax"]
["w","x","y","z"] ["ab","cd","e"] -> ["wab","cd","exab","cd","eyab","cd","ez"]
Мастер пшеницы
источник
1
Все 3 существующих ответа в настоящее время терпят неудачу, если на входе используется какой-либо непечатаемый символ ASCII (SOH, TAB или LF, в зависимости от ответа). Поэтому я думаю, что вы действительно должны решить, ограничен ли ввод для печати ASCII или нет.
Арно
@Arnauld Хорошо, на данный момент это неограниченно, и я не видел причин, чтобы изменить это так, что это останется.
Пшеничный волшебник
2
Шахта @KevinCruijssen действительна, поскольку ноль не является символом. Удачная языковая особенность выручает.
Джонатан Аллан
1
@ SriotchilismO'Zaic Мой 05AB1E соединялся / раскалывался по новым строкам. Ответы JavaScript и Haskell объединяются / разбиваются по вкладкам, а ответ C # - непечатаемым символом `` (SOH), поэтому все они также недопустимы. Впрочем, я не знаю Perl 5 достаточно хорошо. Так что один может быть действительным.
Кевин Круйссен
3
@Roman Вы не можете предполагать, что какой-либо символ не появится на входе, так что вы можете использовать его в качестве разделителя. Вы должны на самом деле решить задачу.
Пшеничный волшебник

Ответы:

11

Желе , 6 байт

j0j@ṣ0

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

Попробуйте онлайн! (аргументы полной программы даны в нотации Python; строки становятся списками. Нижний колонтитул показывает представление Python для вывода Link.)

Вот набор тестов, который форматирует выходные данные Link как входные данные.

Как?

Использует списки смешанного типа Jelly, чтобы разрешить весь домен представлений (любой список списков символов), используя целое число ноль в качестве заполнителя:

j0j@ṣ0 - Link: b, a        e.g.    b = [['a','b'],['c','d'],['e']]
       -                   ...and  a = [['w'],['x'],['y'],['z']]
                             (i.e. test-case ["w","x","y","z"] ["ab","cd","e"])
j0     - join b with zeros         ['a','b',0,'c','d',0,'e']    
  j@   - join a with that          ['w','a','b',0,'c','d',0,'e','x','a','b',0,'c','d',0,'e','y','a','b',0,'c','d',0,'e','z']
    ṣ0 - split at zeros            [['w','a','b'],['c','d'],['e','x','a','b'],['c','d'],['e','y','a','b'],['c','d'],['e','z']
                             (i.e.: ["wab","cd","exab","cd","eyab","cd","ez"])

Если бы нам нужно было иметь дело с любым из смешанных списков Jelly (включая списки любой глубины или формы), мы могли бы использовать этот восемь байтов: j,©⁹jœṣ®который использует парные аргументы в качестве заполнителя.

Джонатан Аллан
источник
5

Python 3.8 (предварительная версия) ,  60  58 байт

lambda a,b:(v:='&'.join(a+b)+'$').join(b).join(a).split(v)

Безымянная функция, принимающая два списка строк, aи b, которая возвращает список строк.

Попробуйте онлайн! Или посмотрите набор тестов .

Как?

Сначала формируется строка-разделитель v, которую нельзя найти внутри aили b. Затем формирует строку, соединяя строки bс копиями v. Затем формирует строку, объединяя строки aс копиями этого. Наконец, разделяет эту строку на экземпляры, vчтобы получить список строк.

Хотя обеспечение vне входит, aили bмы должны также гарантировать, что не vзаставит нас разделиться рано в случае, когда все строки в aи bравны. Для этого мы формируем v, объединяя все строки в обоих списках с экземплярами строки (здесь '&') и добавляем дополнительный, другой символ (здесь '$'). Обратите внимание, что одного из этих действий недостаточно, поскольку все строки на входах могут быть равны выбранному символу.

Джонатан Аллан
источник
Не могли бы вы привести пример ввода, где &требуется? а использования ''.join(a+b)+'$'недостаточно?
Пшеничный волшебник
Это заняло у меня некоторое время, но ['$','$'] ['$','$']будет одним.
Пшеничный волшебник
Да, если все строки равны выбранному '$'символу, и результатом будет более одной строки, нам нужен другой символ, чтобы избежать раннего разделения.
Джонатан Аллан
2

05AB1E , 4 15 19 9 11 байт

«TýR©ý¹sý®¡

В отличие от ответа Jelly, строка 05AB1E "0", целое число 0и число с плавающей точкой 0.0все (несколько) равны, поэтому я не могу разделить / объединить целым числом. Вот почему у нас было +15 байт в качестве обходного пути, хотя я сейчас вернул его до 9 байт. Спасибо @JonathanAllan за то, что нашли 2 ошибки.

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

Объяснение:

«            # Merge the two (implicit) input-lists together
 Tý          # Then using a "10" delimiter join all strings together
   R         # Reverse this string
    ©        # Store this string in variable `®` (without popping)
     ý       # Use this string as delimiter to join the second (implicit) input-list
      ¹sý    # Then join the first input-list by this entire string
         ®¡  # And split it back on variable `®` so it's the expected list of strings
             # (after which this result is output implicitly)
Кевин Круйссен
источник
2
Это терпит неудачу, если у входа есть новые строки (OP сказал, что ввод в настоящее время неограничен).
Эрик Outgolfer
@EriktheOutgolfer Кстати, у каждого другого ответа такая же проблема.
Кевин Круйссен
@EriktheOutgolfer Определенно можно еще поиграть в гольф, но сейчас сделаем быстрое и грязное решение.
Кевин Круйссен
1
Э-э, извините за это ... это не сработает, если входные списки содержат строки, содержащие только переводы строк :( (рано разделятся)
Джонатан Аллан
1
@JonathanAllan Lol .. Ну, я думаю, я могу только поблагодарить вас за то, что вы нашли эти ошибки .. Я надеюсь, что это исправлено сейчас, и вы не найдете ничего больше .. Хотя у меня есть ощущение, что вы могли бы ...
Кевин Круйссен
2

Wolfram Language (Mathematica) , 62 61 байт

""<>#&/@Flatten[#~(R=Riffle)~I/.I->#2~R~I]~SequenceSplit~{I}&

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

-1 спасибо Роману


Хотя это неверный вывод, он возвращает функцию, которая на самом деле выполняет работу .. (34 байта)

(g=a""<>a~Riffle~#&)[#]@*g[#2]&

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

attinat
источник
1
61 байт при утилизации Riffle.
Роман
2

Japt , 8 байт

Адаптирует подход Джонатана .

qVqN²)qN

Попытайся

qVqN²)qN     :Implicit input of arrays U & V (N=[U,V])
q            :Join U with
 Vq          :  V joined with
   N²        :    Push 2 to N (modifying the original), which gets coerced to a string
             >     e.g., N=[["a","b"],["c","d"]] -> N=[["a","b"],["c","d"],2] -> "a,b,c,d,2"
     )       :End join
      qN     :Split on the modified N, which, again, gets coerced to a string
             > e.g., N=[["a","b"],["c","d"],2] -> "a,b,c,d,2"
мохнатый
источник
Что Nв этом случае? Если я правильно понимаю (используя функцию поиска по ссылке TryIt), это повторяется Nдва раза ( ). Затем он использует это для присоединения ко второму input V( VqN²), а затем использует всю эту строку для присоединения к первому (неявному) input U( q...)). И, наконец, разбивает полученную строку на N( qN). Но что Nв этом случае?
Кевин Круйссен
Ах, подождите, я думаю, что я искал неправильный p(...)метод в поиске. Это добавляет 2к обоим входам, соединенным вместе, не так ли. Только результаты [["w","x","y","z"],["ab","cd","e"],2], и он использует весь этот список, чтобы присоединиться. Почему финал qNне оставляет 2список результатов в этом случае? Или изменить оригинал N?
Кевин Круйссен
1
@KevinCruijssen, добавил объяснение, но вы в значительной степени поняли его. И, да, pushдобавление элементов в массив в JS изменяет исходный массив.
Мохнатый
1

J , 44 43 42 29 байт

_<;._1@,(;@}:@,@,.(,_&,)&.>/)

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

-13 байт благодаря милям!

Этот подход использует целые числа и обусловлен милями.

оригинальный подход со строками

g=.[:}.@,,.
f=.(<@0<@;;._1@,];@g<"0@[)<@0<@g]

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

Примечание: я настроил -3 от TIO для учета f=.

Использует метод Джонатана Аллена, адаптированный для Дж.

Это было удивительно сложно для гольфа, поскольку у J нет встроенного метода «соединения», и мне было бы любопытно посмотреть, можно ли его значительно улучшить.

g это вспомогательный глагол, который дает нам «присоединиться»

Ион
источник
Работая со списком целых чисел в качестве входных данных, я нашел решение с 29 символами , _<;._1@,(;@}:@,@,.(,_&,)&.>/)использующее бесконечность _в качестве значения часового, чтобы знать, где делить <;._1. Соединение сначала выполняется с использованием метода Reduce, /чтобы сформировать один большой блок, а затем - просто формирование массива.
миль
Это поразительно. Спасибо @ миль. Этот определенно чувствовал, что есть место для улучшения, но я не видел как.
Иона
@ Мили Не должно ли g&.:(a.&i.&.>)считаться с байтами или я что-то упустил?
Иона
ОП упоминал, что входные данные могут быть в виде списка символов или в виде списка целых чисел, так что вспомогательная функция - это просто преобразование из блоков массивов символов в блоки массивов int для более удобного просмотра
мили
Ах, я забыл это, спасибо
Иона
0

Perl 5 ( -lp), 20 байт

Как прокомментировал @JonathanAllan, это полная программа, использующая для ввода-вывода вкладку в качестве разделителя списка и новую строку для разделения двух списков.

chop($n=<>);s/  /$n/g

TIO

Вкладка и новая строка были выбраны, потому что удобнее проверять контрольные примеры, в противном случае их можно изменить на непечатные символы \1и \2.

( -02l012p)

chop($n=<>);s//$n/g

TIO

Как это устроено,

  • -02 : установить разделитель входной записи на \2
  • -l: удалить входной разделитель из аргумента по умолчанию $_и добавить выходной разделитель записей в вывод по умолчанию
  • -012: установить разделитель выходной записи на \012( \n), чтобы легче было проверить вывод
  • -p : напечатать аргумент по умолчанию

  • $n=<>; : прочитать следующую запись и назначить $n

  • chop$n; : снять разделитель с $n
  • s/\x1/$n/g: заменить все случаи \1с$n
Науэль Фуйе
источник
2
Мой Perl почти не существует, но я считаю, что это полная программа, использующая для ввода-вывода вкладку в качестве разделителя списков и новую строку для разделения двух списков. Как он может принять ввод с этими символами?
Джонатан Аллан
@JonathanAllan, вы правы, у меня не было времени, чтобы добавить объяснение при отправке, я постараюсь сделать
Науэль Фуийо
0

JavaScript (ES6),  62  59 байт

Сохранено 3 байта благодаря @Shaggy

Это исправленная версия ответа Луиса (теперь удалена) для поддержки всех персонажей.

a=>b=>a.map(e=escape).join(b.map(e)).split`,`.map(unescape)

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

Arnauld
источник