Komponowanie wypełnij puste pola

18

Powiedzmy, że mamy określony zestaw funkcji na ciągach. Funkcje te przypominają wypełnianie pustych pól lub madlibów, z tym wyjątkiem, że pobierają tylko jeden wkład i używają go do wypełnienia wszystkich swoich pustych pól. Na przykład możemy mieć funkcję, która wygląda

I went to the ____ store and bought ____ today.

Jeśli zastosujemy tę funkcję do łańcucha, cheesewynikiem będzie:

I went to the cheese store and bought cheese today.

Możemy reprezentować te funkcje jako niepustą listę ciągów, gdzie puste miejsca są po prostu przerwami między ciągami. Na przykład nasza powyższa funkcja to:

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

Dzięki tej reprezentacji istnieje tylko jedna reprezentacja dla każdej funkcji tego rodzaju i tylko jedna funkcja dla każdej reprezentacji.

Naprawdę fajne jest to, że zestaw takich funkcji jest zamknięty w ramach kompozycji. To znaczy, że składanie się z dwóch naszych funkcji jest zawsze kolejną z tych funkcji. Na przykład, jeśli skomponuję naszą funkcję powyżej

["blue ", ""]

(funkcja, która przechodzi bluedo wejścia) Otrzymujemy funkcję:

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

Mogą się one jednak nieco bardziej skomplikować. Na przykład, jeśli skomponujemy pierwszą funkcję z

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

Wynik to

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

Zadanie

Twoim zadaniem jest przyjęcie dwóch funkcji opisanych jako niepuste listy ciągów i wygenerowanie ich składu jako niepustej listy ciągów.

Na potrzeby tego wyzwania listą może być dowolny uporządkowany kontener, który zezwala na duplikaty, a ciąg może być rodzimym typem ciągu, listą znaków lub listą liczb całkowitych.

To jest odpowiedź na w bajtach, przy czym mniej bajtów jest lepszych.

Przypadki testowe

["","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"]
Kreator pszenicy
źródło
1
Wszystkie 3 istniejące odpowiedzi obecnie kończą się niepowodzeniem, jeśli na wejściu zostanie użyty jakiś niedrukowalny znak ASCII (SOH, TAB lub LF, w zależności od odpowiedzi). Myślę więc, że naprawdę powinieneś zdecydować, czy dane wejściowe są ograniczone do drukowalnego ASCII, czy nie.
Arnauld
@Arnauld Ok, a teraz jest to nieograniczone i nie widziałem powodu, aby to zmienić, więc pozostanie.
Wheat Wizard
2
@ Kopalnia KevinCruijssen jest ważna, ponieważ zero nie jest znakiem. Pomocna funkcja języka szczęśliwego.
Jonathan Allan
1
@ SriotchilismO'Zaic Mój 05AB1E łączył / dzielił przez nowe linie. Odpowiedzi na JavaScript i Haskell łączą / dzielą tabulatory, odpowiedź C # drukowalnym znakiem `` (SOH), więc wszystkie one również są nieprawidłowe. Jednak nie znam wystarczająco dobrze Perla 5. Aby ten mógł być ważny.
Kevin Cruijssen
3
@Roman Nie możesz założyć, że jakikolwiek znak nie pojawi się na wejściu, więc możesz użyć go jako separatora. Musisz faktycznie rozwiązać wyzwanie.
Wheat Wizard

Odpowiedzi:

11

Galaretka , 6 bajtów

j0j@ṣ0

Dyadyczny link akceptujący pierwszą reprezentację funkcji po prawej i drugą reprezentację funkcji po lewej, która daje wynikową reprezentację funkcji. Każda reprezentacja funkcji jest listą znaków (Jelly nie ma innych ciągów znaków).

Wypróbuj online! (argumenty pełnego programu podano w notacji Pythona; ciągi stają się listami. Stopka pokazuje reprezentację wyjścia Link w Pythonie).

Oto pakiet testowy, który formatuje dane wyjściowe łącza podobnie jak dane wejściowe.

W jaki sposób?

Korzysta z list mieszanych typów Jelly, aby umożliwić całą domenę reprezentacji (dowolną listę list znaków), używając liczby całkowitej zero jako symbolu zastępczego:

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"])

Gdybyśmy musieli poradzić sobie z dowolną z mieszanych list Jelly (w tym tych o dowolnej głębokości lub kształcie), moglibyśmy użyć tego ośmiu bajtów: j,©⁹jœṣ®który używa sparowanych argumentów jako elementu zastępczego .

Jonathan Allan
źródło
5

Haskell , 78 bajtów

(a:b:r)#t@(x:s)|s>[]=(a++x):init s++((last s++b):r)#t|z<-a++x++b=(z:r)#t
x#_=x

Wypróbuj online!

Laikoni
źródło
5

Python 3.8 (wersja wstępna) ,  60  58 bajtów

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

Nienazwana funkcja akceptująca dwie listy ciągów ai b, która zwraca listę ciągów.

Wypróbuj online! Lub zobacz zestaw testowy .

W jaki sposób?

Najpierw tworzy ciąg separatora v, którego nie można znaleźć wewnątrz alub b. Następnie tworzy ciąg, łącząc ciągi bz kopiami v. Następnie tworzy ciąg, łącząc ciągi az kopiami tego. Na koniec dzieli ten ciąg w przypadkach, vaby uzyskać listę ciągów.

Zapewniając jednocześnie vnie jest alub bmusimy również zapewnić, że vprzyzwyczajenie uczynić nas podzielić wcześnie w przypadku, gdy wszystkie ciągi w ai bsą równe. Aby to zrobić, łączymy vwszystkie ciągi na obu listach z wystąpieniami ciągu (tutaj '&') i dodajemy inny, inny znak (tutaj '$'). Zauważ, że wykonanie jednego z nich osobno nie wystarczy, ponieważ wszystkie ciągi wejściowe mogą być równe wybranemu znakowi.

Jonathan Allan
źródło
Czy możesz podać przykładowe dane, gdzie &jest to wymagane? a używanie ''.join(a+b)+'$'to za mało?
Wheat Wizard
Zajęło mi to trochę czasu, ale ['$','$'] ['$','$']będzie jednym.
Wheat Wizard
Tak, jeśli wszystkie łańcuchy są równe wybranemu '$'znakowi, a wynikiem będzie więcej niż jeden ciąg, potrzebujemy tam innego znaku, aby uniknąć wcześniejszego podziału.
Jonathan Allan
2

05AB1E , 4 15 19 9 11 bajtów

«TýR©ý¹sý®¡

W przeciwieństwie do odpowiedzi Jelly, ciąg 05AB1E "0", liczba całkowita 0i liczba zmiennoprzecinkowa 0.0są (nieco) równe, więc nie mogę podzielić / dołączyć liczby całkowitej. Właśnie dlatego mieliśmy obejście +15 bajtów jako obejście, chociaż teraz grałem w golfa z powrotem do 9 bajtów. Dzięki @JonathanAllan za znalezienie 2 błędów.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

«            # 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)
Kevin Cruijssen
źródło
2
Nie powiedzie się to, jeśli dane wejściowe mają znaki nowej linii (OP stwierdził, że dane wejściowe są obecnie nieograniczone).
Erik the Outgolfer
@EriktheOutgolfer Każda inna odpowiedź ma ten sam problem btw.
Kevin Cruijssen
@EriktheOutgolfer Zdecydowanie można jeszcze zagrać w golfa, ale na razie dokonał szybkiej i brudnej naprawy.
Kevin Cruijssen
1
Przepraszam za to ... to nie zadziała, jeśli listy wejściowe zawierają ciągi zawierające tylko znaki nowej linii :( (wcześniej się rozdzieli)
Jonathan Allan
1
@JonathanAllan Lol .. No cóż, chyba mogę ci tylko podziękować za znalezienie tych błędów .. Mam nadzieję, że to już zostało naprawione i nie znajdziesz nic innego .. Chociaż mam wrażenie, że możesz ...
Kevin Cruijssen
2

Japt , 8 bajtów

Dostosowuje podejście Jonathana .

qVqN²)qN

Spróbuj

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"
Kudłaty
źródło
Co jest Nw tym przypadku? Jeśli dobrze to rozumiem (używając funkcji wyszukiwania łącza TryIt), powtarza się Ndwa razy ( ). Następnie używa tego, aby połączyć drugie wejście V( VqN²), a następnie używa tego całego łańcucha, aby dołączyć pierwsze (niejawne) wejście U( q...)). I na koniec dzieli wynikowy ciąg znaków na N( qN). Ale co jest Nw tym przypadku?
Kevin Cruijssen
Ach, czekaj, chyba szukałem niewłaściwej p(...)metody wyszukiwania. Dodaje 2oba sparowane wejścia razem, prawda? Tylko wyniki [["w","x","y","z"],["ab","cd","e"],2]i używa całej listy do dołączenia. Dlaczego w takim przypadku finał qNnie pozostawia 2listy wyników? Czy modyfikuje oryginał N?
Kevin Cruijssen
1
@KevinCruijssen, dodał wyjaśnienie, ale właściwie to zrozumiałeś. I tak, pushing elementy do tablicy w JS modyfikuje oryginalną tablicę.
Kudłaty
1

Haskell , 62 bajty

[a]#(c:d)=(a++c):d
(a:b)#c=a:b#c
[a]%b=[a]
(a:b)%c=[a]#c#(b%c)

Wypróbuj online!

Oto moja odpowiedź Haskella. Działa na każdym typie listy.

Kreator pszenicy
źródło
1

J , 44 43 42 29 bajtów

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

Wypróbuj online!

-13 bajtów dzięki milom!

To podejście wykorzystuje liczby całkowite i wynika z mil.

oryginalne podejście ze sznurkami

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

Wypróbuj online!

Uwaga: Dostosowałem -3 do TIO, aby uwzględnić f=.

Wykorzystuje metodę Jonathana Allena, dostosowaną do J.

To było zaskakująco trudne do gry w golfa, ponieważ J nie ma wbudowanej metody „dołączenia” i byłbym ciekawy, czy można to znacznie poprawić.

g to czasownik pomocniczy, który daje nam „dołączyć”

Jonasz
źródło
Praca z listy liczb całkowitych jako wejście, znalazłem 29 char rozwiązanie , _<;._1@,(;@}:@,@,.(,_&,)&.>/)używa nieskończoności _jako wartość wartowniczego wiedzieć, gdzie do podziału <;._1. Łączenie odbywa się najpierw za pomocą funkcji zmniejsz, /aby utworzyć jedno duże pudełko, a następnie po prostu kształtowanie tablicy.
mile
To imponujące. Dzięki @miles. Ten zdecydowanie miał wrażenie, że można poprawić, ale nie widziałem, jak to zrobić.
Jonasz
@miles Czy nie należy g&.:(a.&i.&.>)liczyć się do bajtów, czy coś mi brakuje?
Jonasz
OP wspomniał, że dane wejściowe mogą być listą znaków lub listą liczb całkowitych, więc funkcja pomocnika polega na konwersji z pól tablic znaków na pola tablic int dla łatwiejszego przeglądania
mile
Ach, zapomniałem o tym, dzięki
Jonasz
0

Perl 5 (-lp ), 20 bajtów

Jak skomentował @JonathanAllan, jest to pełny program wykorzystujący, dla IO, kartę jako separator listy i nowy wiersz do oddzielenia dwóch list.

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

TIO

wybrano zakładkę i nowy wiersz, ponieważ wygodniej było sprawdzać przypadki testowe, w przeciwnym razie można je zmienić na znaki niedrukowalne \1i\2 .

( -02l012p)

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

TIO

Jak to działa,

  • -02 : aby ustawić separator rekordów wejściowych na \2
  • -l: aby usunąć separator wejściowy z domyślnego argumentu $_i dodać separator rekordu wyjściowego do domyślnego wyjścia
  • -012: aby ustawić separator rekordów wyjściowych na \012( \n), aby łatwiej było sprawdzić dane wyjściowe
  • -p : aby wydrukować domyślny argument

  • $n=<>; : aby przeczytać następny rekord i przypisać do $n

  • chop$n; : aby usunąć separator $n
  • s/\x1/$n/g: Zastąpienie wszystkich wystąpień \1z$n
Nahuel Fouilleul
źródło
2
Mój Perl prawie nie istnieje, ale wierzę, że jest to pełny program wykorzystujący, dla IO, tabulator jako separator list i nowy wiersz do oddzielenia dwóch list. Jak może zaakceptować dane wejściowe za pomocą tych znaków?
Jonathan Allan
@JonathanAllan, masz rację, nie miałem czasu na dodanie wyjaśnienia podczas przesyłania, postaram się to zrobić
Nahuel Fouilleul
0

JavaScript (ES6),  62  59 bajtów

Zaoszczędź 3 bajty dzięki @Shaggy

To jest poprawiona wersja odpowiedzi Luisa (teraz usunięta), która obsługuje wszystkie postacie.

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

Wypróbuj online!

Arnauld
źródło