Zbieraj i umieszczaj przedmioty

13

Celem tego wyzwania jest zebranie wybranych pozycji z listy i przeniesienie ich do określonego miejsca na liście.

Jako wizualny przykład weź wartości wejściowe (reprezentowane przez liczby całkowite w czarnych polach) i odpowiadającą im listę prawdziwych wartości, gdzie prawda oznacza, że ​​element został wybrany (reprezentowany przez niebieskie pola, gdzie Tjest prawdą i Fjest fałszem):

wprowadź opis zdjęcia tutaj

Pierwszym logicznym krokiem jest rozdzielenie pozycji oznaczonych jako prawdziwe i niezgodne z prawdą na odpowiadające im listy. Zauważ, że względna kolejność na każdej liście musi być zachowana (tzn. Kolejność wybranych pozycji musi być 1,4,5, a kolejność niezaznaczonych pozycji musi być 2,3,6,7)!

wprowadź opis zdjęcia tutaj

Drugi logiczny krok otrzymuje indeks na pozostałej liście niewybranych elementów, wstaw wszystkie wybrane elementy przed pozycją o danym indeksie. Zakładając, że indeksowanie rozpoczyna się od 0, załóżmy, że chcesz wstawić zaznaczenie o indeksie 3. To odpowiada miejscu przed 7polem, więc wybrane elementy należy wstawić przed 7.

wprowadź opis zdjęcia tutaj

Tak więc ostateczne rozwiązanie 2,3,6,1,4,5,7.

Zauważ, że ten logiczny schemat przedstawia jeden ze sposobów, w jaki można to zrobić; twój program nie musi wykonywać tych samych logicznych kroków, o ile dane wyjściowe zawsze dają taki sam możliwy do zaobserwowania wynik.

Wejście

Twój program ma 3 wejścia:

  1. Lista liczb całkowitych reprezentujących elementy. To może być pusta lista. Ta lista zawsze będzie się składać z unikalnych dodatnich liczb całkowitych, niekoniecznie w posortowanej kolejności (tj. 5 nie będzie na liście dwa razy).
  2. Lista wartości prawdy / fałszu o tej samej długości co lista przedmiotów, przy czym wartość prawdy oznacza, że ​​wybrano element o tym samym indeksie.
  3. Liczba całkowita reprezentująca miejsce wstawienia zaznaczenia. Możesz wybrać, jaki jest indeks pierwszego elementu listy, o ile jest on stały w każdym uruchomieniu programu (np. Pierwszym elementem może być indeks 0 lub indeks 1). Określ konwencję, której przestrzega Twój program. Indeks ten powinien mieścić się w zakresie [starting_idx, ending_idx+1], tzn. Zawsze będzie prawidłowym indeksem. W przypadku indeksu sprawy ending_idx+1wybór należy wstawić na końcu listy. Możesz założyć, że ta liczba całkowita będzie pasować do rodzimego typu liczb całkowitych twojego języka.

Dane wejściowe mogą pochodzić z dowolnego żądanego źródła (standard, parametr funkcji itp.)

Wynik

Dane wyjściowe to lista reprezentująca końcową sekwencję elementów. Może to być dowolne źródło (standardowe, zwracana wartość, parametr wyjściowy funkcji itp.). Możesz modyfikować dowolne dane wejściowe w miejscu (na przykład, biorąc pod uwagę listę modyfikowalną jako parametr funkcji i pozwalając twojej funkcji działać w miejscu na tej liście).

Przypadki testowe

Wszystkie poniższe przypadki testowe zakładają indeksowanie w oparciu o 0. Użyłem 0 i 1, aby wskazać odpowiednio wartości fałszu / prawdy dla maski wyboru.

Przypadki testowe mają tak sformatowane listy [a,b,c], ale tak długo, jak długo listy wejściowe reprezentują skończoną uporządkowaną sekwencję, jest w porządku.

Wejście:

[]
[]
0

Wynik:

[]

Wejście:

[1,2,3,4,5,6,7]
[1,0,0,1,1,0,0]
3

Wynik:

[2,3,6,1,4,5,7]

Wejście:

[1,2,3,4,5,6,7]
[1,0,0,1,1,0,0]
0

Wynik:

[1,4,5,2,3,6,7]

Wejście:

[1,2,3,4,5,6,7]
[1,0,0,1,1,0,0]
4

Wynik:

[2,3,6,7,1,4,5]

Wejście:

[1,2,3,4,5,6,7]
[1,1,1,1,1,1,1]
0

Wynik:

[1,2,3,4,5,6,7]

Wejście:

[1,2,3,4,5,6,7]
[0,0,0,0,0,0,0]
5

Wynik:

[1,2,3,4,5,6,7]

Wejście:

[1,3,2,5,4,6]
[1,0,0,1,1,0]
3

Wynik:

[3,2,6,1,5,4]

Punktacja

To jest kod golfowy; najkrótsza odpowiedź w bajtach wygrywa. Standardowe luki są zabronione. Możesz używać dowolnych wbudowanych elementów.

helloworld922
źródło
Czy wejście i wyjście może być takie jak „1 2 3”, „1 0 0”, 1 ”?
betseg
Tak, wszystko, co reprezentuje dwie uporządkowane skończone sekwencje liczb całkowitych i indeks liczb całkowitych w jest w porządku.
helloworld922
Czy pierwsza tablica będzie zawierać elementy ujemne czy zero?
Leaky Nun
Chcę powiedzieć „nie”, ale intryguje mnie również, jakie masz rozwiązanie, które tego wymaga. Tak, możesz założyć, że pierwsza lista zawiera tylko dodatnią liczbę całkowitą.
helloworld922,
@PeterTaylor no. Naprawiłem to, aby przeczytać „Lista wartości prawdy / fałszu ...”. Czy istnieje dobre imię opisujące „typ” wartości prawdy / fałszu? Boolean-like?
helloworld922,

Odpowiedzi:

10

MATL, 9 bajtów

&)i:&)bwv

To rozwiązanie przyjmuje tablicę wartości T(prawda) i F(fałsz) jako drugie dane wejściowe. Również w pierwszym przypadku testowym, z pustymi tablicami, nie generuje danych wyjściowych.

Wypróbuj online! i nieco zmodyfikowana wersja dla wszystkich przypadków testowych.

Wyjaśnienie

    % Implicitly grab the first two inputs
&)  % Index into the first array using the boolean, places two items on the stack:
    % 1) The values where the boolean is TRUE and 2) the values where it is FALSE.
i   % Explicitly grab the third input (N)
:   % Create an array from 1...N
&)  % Index into the FALSE group using this array as an index. Puts two items on the stack:
    % 1) The first N elements of the FALSE group and 2) other members of the FALSE group
b   % Bubble the TRUE members up to the top of the stack
w   % Flip the top two stack elements to get things in the right order
v   % Vertically concatenate all arrays on the stack
    % Implicitly display the result
Suever
źródło
5

Mathematica, 66 62 bajtów

Zapisano 4 bajty z @MartinEnder .

a=#2~Extract~Position[#3,#4>0]&;##&@@@Insert[##~a~0,##~a~1,#]&

Funkcja anonimowa. Pobiera dane wejściowe na podstawie indeksu 1, listy i znaczników, a na liście zwraca uporządkowaną listę.

LegionMammal978
źródło
3

Haskell, 70 bajtów

m%n=[e|(e,b)<-zip m n,b]
(l#s)p|(h,t)<-splitAt p$l%(not<$>s)=h++l%s++t

Przykład użycia: ([1,2,3,4,5,6,7]#[True,False,False,True,True,False,False]) 3-> [2,3,6,1,4,5,7].

Jak to działa:

m%n=[e|(e,b)<-zip m n,b]        -- helper function, that extracts the elements of m
                                -- with corresponding True values in n
(l#s)p                          -- l: list of values
                                   s: list of booleans
                                   p: position to insert
  |                   (not<$>s) -- negate the booleans in s
                    l%          -- extract elements of l
          splitAt p             -- split this list at index p
   (h,t)<-                      -- bind h to the part before the split
                                -- t to the part after the split
     = h++l%s++t                -- insert elements at True positions between h and t
nimi
źródło
3

JavaScript (ES6), 76 bajtów

(a,b,c)=>(d=a.filter((_,i)=>!b[i]),d.splice(c,0,...a.filter((_,i)=>b[i])),d)
Neil
źródło
1

Galaretka , 10 bajtów

¬+\>⁵Ḥ³oỤị

Wypróbuj online!

Jak to działa

¬+\>⁵Ḥ³oỤị  Main link.
            Arguments: x (list of Booleans), y (list of inputs), z (index)
¬           Logical NOT; invert all Booleans in x.
 +\         Take the cumulative sum.
            This replaces each entry with the number of zeroes up to that entry.
   >⁵       Compare the results with z.
            This yields 0 for the first z zeroes, 1 for all others. The behavior
            for ones is not important.
    Ḥ       Unhalve; multiply the previous resulting by 2.
     ³o     Take the element-wise logical NOT of x and the previous result.
            This replaces all but the first z zeroes in x with twos.
       Ụ    Grade up; sort the indices of the result according to the corr. values.
        ị   Retrieve the items of y at those indices.
Dennis
źródło
0

C #, 132 bajty

int[]r(int[]a,bool[]b,int l){var x=a.Where((i,j)=>!b[j]);return x.Take(l).Concat(a.Where((i,j)=>b[j])).Concat(x.Skip(l)).ToArray();}

bez golfa:

    public static int[] r(int[] a,bool[] b,int l)
    {
        var x = a.Where((i, j) => !b[j]);
        return x.Take(l).Concat(a.Where((i, j) => b[j])).Concat(x.Skip(l)).ToArray();
    }

Doceniane pomysły na ulepszenia.

downrep_nation
źródło
0

Python 3, 91 bajtów

def f(a,x,i):b=[c for c,z in zip(a,x)if z<1];return b[:i]+[c for c in a if(c in b)<1]+b[i:]

gdzie ajest lista elementów / liczb, xjest True/Falselistą i iindeksem.

Wersja wielowierszowa dla lepszej czytelności:

def f(a,x,i):
    b=[c for c,z in zip(a,x)if z<1]
    return b[:i]+[c for c in a if(c in b)<1]+b[i:] 

Jak to działa?

Wezwanie do zip(a,x)wyników w postaci listy krotek, gdzie każdy z nich zawiera informacje o: (element,0|1). Następnie stosowane jest zrozumienie listy w celu ustalenia elementów, które mają 0/Falsepowiązaną wartość i zapisuje je w zmiennej b.

[c for c,z in zip(a,x)if z<1]Tworzy więc listę, która zawiera wszystkie elementy, które są powiązane z wartością 0( False).

Następnie lista elementów, które mają True|1wartość związaną (który poprzez sprawdzenie, które elementy anie występują w b: [c for c in a if(c in b)<1]) dodaje się do wykazu wszystkich elementów, które mają 0( Falsewartości) związany (lista b) w określonym indeksie ii wynikowa lista jest zwracana.

Ioannes
źródło
0

Python 3, 106 93 bajtów

def f(x,y,z):
 t,f=[],[]
 for n in range(len(x)):(f,t)[y[n]].append(x[n])
 f[z:z]=t
 return f

Starsza wersja:

def f(x,y,z):
 t,f=[],[]
 for n in range(len(x)):
  if y[n]:t+=[x[n]]
  else:f+=[x[n]]
 f[z:z]=t
 return f
Daniel
źródło