Uogólniony Riffle Array

22

Prosty golf na początek tygodnia! Dostaniemy trzy tablice: the podstawy tablicy B The tablicy wartość V i tablicy wskaźnik I . Powinieneś stworzyć kolejną tablicę, w której wartości Vsą wstawiane Bwedług wskaźników określonych przez I. Oto przykład:

Base:    [5, 1, 4, 1, 3]
Values:  [0, 0, 7]
Indices: [5, 0, 3]

Wskaźniki wskazują na następujące pozycje w tablicy podstawowej:

[ 5, 1, 4, 1, 3 ]
 ^        ^    ^
 0        3    5

Tak więc wstawiając odpowiednie elementy z tablicy wartości, wynik powinien być:

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

Zasady

Możesz napisać program lub funkcję, przyjmując dane wejściowe przez STDIN (lub najbliższą alternatywę), argumenty wiersza poleceń lub argumenty funkcji i wypisywać wynik za pomocą STDOUT (lub najbliższej alternatywy), zwracaną wartość funkcji lub modyfikując tablicę podaną jako Bparametr .

Jeśli przesłanie jest funkcją Ii Vmoże być zmodyfikowane w jakikolwiek sposób, a także Bjeśli nie jest używane w danych wyjściowych.

Możesz przyjąć następujące założenia dotyczące danych wejściowych:

  • Wszystkie elementy tablicy podstawowej i wartości będą liczbami całkowitymi nieujemnymi.
  • Tablica wartości będzie miała najwyżej jeden element więcej niż tablica podstawowa.
  • Tablica wartości i tablica indeksu będą miały tę samą liczbę elementów.
  • Tablica indeksów nie będzie zawierać powtarzających się indeksów, a wszystkie indeksy będą w zakresie.
  • Tablice podstawowa i wartości mogą zawierać powtarzające się elementy.
  • Dowolna lub wszystkie tablice mogą być puste.
  • Nie można zakładać, że wskaźniki są podawane w określonej kolejności.
  • Możesz odbierać dane wejściowe i generować dane wyjściowe w dowolnym dogodnym, jednoznacznym łańcuchu lub formacie listy. Możesz także wybrać otrzymywanie trzech tablic w innej kolejności.
  • Możesz wybierać między indeksowaniem opartym na 0 i opartym na 1.

To jest kod golfowy, więc wygrywa najkrótsza odpowiedź (w bajtach).

Przypadki testowe

Podany w formacie B V I => Resultindeksowania 0. Jeśli korzystasz z indeksowania 1, zwiększ elementy trzeciej tablicy o 1.

[] [] [] => []
[] [1] [0] => [1]
[1,2] [] [] => [1,2]
[1,2] [3] [0] => [3,1,2]
[1,2] [3] [1] => [1,3,2]
[1,2] [3] [2] => [1,2,3]
[0,0,0] [1,1,1,1] [0,1,2,3] => [1,0,1,0,1,0,1]
[5,1,4,1,3] [0,0,7] [5,0,3] => [0,5,1,4,7,1,3,0]
[1,2,3,4] [4,3,2,1] [4,0,3,1] => [3,1,1,2,3,2,4,4]

Daj mi znać, jeśli natkniesz się na inne interesujące przypadki, a ja je dodam.

Tabela liderów

Oto fragment kodu, który pozwala wygenerować zarówno zwykłą tabelę wyników, jak i przegląd zwycięzców według języka.

Aby upewnić się, że twoja odpowiedź się pojawi, zacznij od nagłówka, korzystając z następującego szablonu Markdown:

# Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Martin Ender
źródło
4
Jak oceniasz NULLpustą tablicę dla języków, w których jest pusta tablica NULL?
Alex A.,
@AlexA. Jeśli jest to wspólne / reprezentacja pustej tablicy we wspomnianym języku (S), jestem zadowolony z tego.
Martin Ender
3
Prosty golf ? To najtrudniejsza rzecz, którą robiłem w CJam przez cały tydzień. : P
Dennis

Odpowiedzi:

13

Pyth, 14 bajtów

s.icFPQmedSCtQ

Demonstracja.

Ten program przyjmuje dane wejściowe jako trzy krotki list w kolejności Podstawa, indeksy, wartości.

Objaśnienie na przykładzie [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Weź dane wejściowe: niejawne, Q to dane wejściowe.

  2. Stwórz indeks, pary wartości: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Posortuj pary w porządku rosnącym indeksu: SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. Wyjmij wartość z każdej pary: medSCtQ=[0, 7, 0]

  5. Podziel listę bazową w miejscu wskazań: cFPQ=[[], [5, 1, 4], [1, 3], []]

  6. Przeplot 3 i 4: .icFPQmedSCtQ=[[], 0, [5, 1, 4], 7, [1, 3], 0, []]

  7. Połącz w jedną listę: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]

isaacg
źródło
Cholerny. Od kiedy mamy metodę przeplotu? Chciałem tylko opublikować ssC,cFPQamedSCtQ].
Jakube,
5
@Jakube isaac podstępnie popełnił to 6 dni temu.
lub
3
@Jakube, ponieważ Pyth może urosnąć, aby rozwiązać każdy problem. Taki jest problem z językami golfowymi. Języki ezoteryczne istnieją ze względu na języki ezoteryczne; ponieważ są one zaprojektowane * później.
sentiao
@sentiao Aby być sprawiedliwym, język hosta (Python) przeplata się pod inną nazwą od jakiegoś czasu.
Mego
16

Python 2, 54

lambda B,*X:map(B.insert,*zip(*sorted(zip(*X))[::-1]))

Pobiera dane wejściowe jako B,I,V. BPo wywołaniu modyfikuje dane wejściowe (dzięki Martin Büttner za przypomnienie, że to możliwe).

Używa mapwywoływania B.insertkażdej pary indeksu / elementu. Aby uniknąć problemu przesuwania indeksów listy podczas wstawiania elementów, sortuje pary w kolejności malejącej indeksu według brzydkiego zip / sort / unzip. Gdyby nie problem zmiany, moglibyśmy to zrobić map(B.insert,*X).

Stara metoda (65):

B,V,I=input()
for i,v in sorted(zip(I,V))[::-1]:B[i:i]=v,
print B
xnor
źródło
5

Haskell, 62 bajty

import Data.List
f b v i=map snd$sort$zip[0.5,1.5..]b++zip i v

Przykład użycia: f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0].

Jak to działa: powiększ listę bazową indeksami „półtora” zaczynającymi się od 0.5(np. [(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)]) I połącz ją z parami indeks-wartość. Posortuj i odrzuć indeks.

Uwaga : nie wiem, czy tutaj oszukuję. Z matematycznego punktu widzenia jest w porządku, ale programista może argumentować, że lista indeksów [5,0,3]nie jest listą Integerswymaganą, ale listą Fractionals(dokładnie, typ jest polimorficzny, ale musi należeć do Fractionalklasy, np. FloatLub Double).

nimi
źródło
5

Rubin, 60 59 53 bajtów

->a,b,c{c.zip(b).sort.reverse.map{|i,v|a.insert i,v}}

I wersja bez golfa

def riffle(array, values, indices)
    indices.zip(values).sort.reverse.each do |index, value|
        array.insert(index, value)
    end
end
Dylan Frese
źródło
2
Można skrócić ten dokonując jej nienazwanej funkcję zamiast: ->a,b,c{...}. Są też szanse, insertże nie trzeba nawiasów.
Martin Ender
@ MartinBüttner Wiedziałem o nienazwanej funkcji z lambda, ale nie czułem, że było to w duchu wyzwania (które zwykle prosi o nazwaną funkcję). Ale dziękuję za zauważenie parenów.
Dylan Frese
O ile wyzwanie nie wymaga konkretnej funkcji nazwanej, funkcje nienazwane są zawsze dopuszczalne . I nie prosiłem o nazwaną funkcję (nigdy tego nie robię;)).
Martin Ender
5

CJam, 34 23 18 bajtów

{.\2/\ee+{0=}$1f=}

Moje pierwsze zgłoszenie do CJam. Porady są mile widziane, jestem pewien, że jest wiele do golfa.

16 bajtów zapisanych przy pomocy @ MartinBüttner i @Dennis.

Funkcja oczekuje wejścia na stosie w kolejności B V I(I jest najwyższa).

Przykładowe użycie:

[5 1 4 1 3] [0 0 7] [5 0 3] {.\2/\ee+{0=}$1f=}~

Metoda:

  • sparuj element tablicy izi+0.5
  • sparuj wartości wstawiania z pozycjami wstawiania
  • scal powstałe dwie tablice
  • sortuj tablicę na podstawie elementów pozycji
  • zachowaj elementy wartości
randomra
źródło
To podejście zmiennoprzecinkowe jest bardzo sprytne i (niestety) lepsze niż moje. Za q~.5fm.\2/\ee+$1f=ppomocą anonimowej funkcji można uzyskać do 19 bajtów zi do 18 bajtów:{.5fm.\2/\ee+$1f=}
Dennis
Ten sam pomysł bez sztuczki zmiennoprzecinkowej: {.\2/\ee+{0=}$1f=}(wciąż 18 bajtów)
Dennis
@Dennis Dzięki, nie mogłem znaleźć get array elementoperatora 1f=. Pozostawię to jako pełny program.
randomra
Twoja decyzja. Czy przeszkadza mi, że pytam, dlaczego sprzeciwiasz się opublikowaniu funkcji?
Dennis
@Dennis Właśnie uruchomiłem CJam i nie byłem pewien, jak korzystać z funkcji. Teraz to rozgryzłem, więc zmieniłem odpowiedź na to.
randomra
5

K, 22 21 bajtów

{,//+(y@<z;(z@<z)_ x)}

Definiujemy funkcję 3 argumentów {…}ze zmiennymi ukrytymi x, ya zreprezentujący listę startową, na liście wartości i listę indeksu odpowiednio. Operator „cut” ( _) służy do podziału listy początkowej na posortowaną listę podanych indeksów ( (z@<z)). Przeplatamy wartości (po odpowiednim sortowaniu) z podzielonymi częściami oryginalnej tablicy, tworząc listę ( (a;b)), przyjmując jej transpozycję ( +) i spłaszczając wynik ( ,//).

Przykład użycia:

  f:{,//+(y@<z;(z@<z)_ x)}
{,//+(y@<z;(z@<z)_ x)}

  f[1 2 3 4;4 3 2 1;4 0 3 1]
3 1 1 2 3 2 4 4

  f[5 1 4 1 3;0 0 7;5 0 3]
0 5 1 4 7 1 3 0

Spacje wokół znaku podkreślenia są konieczne, ponieważ K pozwala na podkreślenia w identyfikatorach. K5 usuwa tę potencjalną dwuznaczność. Gdybyśmy mogli liczyć na indeksy rosnące w porządku rosnącym, a podkreślenia nie były prawidłowymi identyfikatorami, moglibyśmy użyć znacznie ładniejszego 13-bajtowego programu:

{,//+(y;z_x)}

(westchnienie.)

edytować:

{,//+(y@<z;(z@<z)_ x)} / before
{,//+(y@<z;z[<z]_ x)}  / after

Łamie symetrię, ale możemy zaoszczędzić bajt za pomocą bracketing-indexing ( […]) zamiast @operatora indeksowania infix . Zwykle powoduje to, że programy są dłuższe, ale w tym przypadku potrzebowaliśmy parens do posortowania zprzed wykonaniem cięcia.

JohnE
źródło
4

Pyth, 17 bajtów

ssC,cFPQamedSCtQ]

@isaacg pokonał już moje rozwiązanie. Ale skoro skończyłem dokumentację, i tak ją opublikuję.

To pobiera dane wejściowe w formacie B, I, V. Możesz spróbować tutaj: Demonstration lub Test Suite

Wyjaśnienie:

Korzystam z przykładu B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]z OP.

                    implicit: Q = input()
      PQ            all elements but last of Q   => [[5,1,4,1,3], [5,0,3]]
    cF              split B it the indices in I  => [[], [5,1,4], [1,3], []]

              tQ    all elements but first of Q  => [[5,0,3], [0,0,7]]
             C      zip                          => [(5,0), (0,0), (3,7)]
            S       sort                         => [(0,0), (3,7), (5,0)]
         med        extract the end of each pair => [0,7,0]
        a       ]   append an empty list         => [0,7,0,[]]

   ,                create a pair => ([[], [5,1,4], [1,3], []], [0,7,0,[]])
  C                 zip           => [([],0), ([5,1,4],7), ([1,3],0), ([],[])]
 s                  sum           => ([],0,[5,1,4],7,[1,3],0,[],[])
s                   sum           => [0,5,1,4,7,1,3,0]
Jakube
źródło
4

JavaScript (ES6), 75

Funkcja z 3 parametrami tablicy, zwracająca tablicę. Dziwnie, ta funkcja modyfikuje swój iparametr (na co pozwala OP)

Testuj uruchamianie fragmentu, Firefox tylko jak zwykle.

f=(b,v,i,j=0)=>b.concat(v).map(p=>(p=i.indexOf(j))<0?b[j++]:(i[p]=-1,v[p]))

// TEST
out=x=>O.innerHTML+=x+'\n'

test=[
{ b:[], v:[], i:[], k:[] },
{ b:[], v:[1], i:[0], k:[1] },
{ b:[1,2], v:[], i:[], k:[1,2] },
{ b:[1,2], v:[3], i:[0], k:[3,1,2] },
{ b:[1,2], v:[3], i:[1], k:[1,3,2] },
{ b:[1,2], v:[3], i:[2], k:[1,2,3] },
{ b:[0,0,0], v:[1,1,1,1], i:[0,1,2,3], k:[1,0,1,0,1,0,1] },
{ b:[5,1,4,1,3], v:[0,0,7], i:[5,0,3], k:[0,5,1,4,7,1,3,0] },
{ b:[1,2,3,4], v:[4,3,2,1], i:[4,0,3,1], k:[3,1,1,2,3,2,4,4] }
];

test.forEach(x=>{
  r = f(x.b,x.v,x.i.slice(0)) // pass a copy of i, as the function will alter it
  ok = ''+r==''+x.k
  s='Test ' + (ok?'OK':'FAIL')
  +'\n B ['+x.b
  +']\n V ['+x.v
  +']\n I ['+x.i
  +']\n Result ['+r
  +']\n Check  ['+x.k
  +']\n'
  out(s)
  
})
<pre id=O></pre>

edc65
źródło
Z ciekawości, co z kodem czyni go specyficznym dla Firefoksa? Czy to dlatego, że to ES6?
Alex A.,
@ AlexA.To dlatego, że to ES6, tak. W szczególności fat arrow functionnie jest zaimplementowany nawet w wersji dla programistów Chrome (AFAIK)
edc65
Rzeczywiście, nawet wersja Chrome dla Canary nie obsługuje tego.
DocMax,
4

Mathematica, 52 51 bajtów

Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&

Przykład:

In[1]:= f = Last/@(Tr@#2->#&~MapIndexed~#⋃Thread[#3+.5->#2])&;

In[2]:= f[{5, 1, 4, 1, 3}, {0, 0, 7}, {5, 0, 3}]

Out[2]= {0, 5, 1, 4, 7, 1, 3, 0}

Wyjaśnienie:

Korzystając z powyższego przykładu.

  • Tr@#2->#&~MapIndexed~# => {1 -> 5, 2 -> 1, 3 -> 4, 4 -> 1, 5 -> 3}
  • Thread[#3+.5->#2] => {5.5 -> 0, 0.5 -> 0, 3.5 -> 7}
  • Następnie weź (posortowane) połączenie tych dwóch list. (=> {0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0})
  • A następnie weź ostatni element każdej pary. (=> {0, 5, 1, 4, 7, 1, 3, 0})
alephalpha
źródło
3

CJam, 30 29 bajtów

q~.\2/$z~0@+2ew@f{\~@<>}.\e_p

To za długo. Wydaje mi się, że to nie jest przesłanie w golfa: |

Wypróbuj online tutaj

Optymalizator
źródło
3

R, 75 bajtów

function(b,v,i){n=b;j=0;for(g in v)n=append(n,g,i[j<-j+1]+sum(i<i[j])-1);n}

To tworzy funkcję bez nazwy. Aby to nazwać, nadaj mu nazwę, np f=function.... Zauważ, że tablice muszą być indeksowane 1, ponieważ tak właśnie się dzieje R.

Niegolfowane + wyjaśnienie:

f <- function(b, v, i) {
    # Initialize the output vector to b
    n <- b

    # Initialize an index over the indices
    j <- 0

    # Loop over the values to insert
    for(g in v) {
        # Get the index of the next given insertion index
        j <- j + 1

        # Insert g into n.
        # The position at which to insert the value is determined by
        # adding the number of indices less than the current one and
        # subtracting 1. The subtraction is because we're using the
        # `after` argument in the `append` function.

        n <- append(n, g, i[j] + sum(i < i[j]) - 1)
    }

    # Return n
    n
}

Przykłady:

> f(c(), c(), c())
[1] NULL

> f(c(0, 0, 0), c(1, 1, 1, 1), c(1, 2, 3, 4))
[1] 1 0 1 0 1 0 1

> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(6, 1, 4))
[1] 0 5 1 4 7 1 3 0

Sugestie są jak zawsze mile widziane!

Alex A.
źródło
2

CJam, 19 bajtów

l~_,)N*q~.{t}~.\N-p

Jest to pełny program, który odczytuje tablice B , I i V (jeden na linię, w tej kolejności) ze STDIN.

Wypróbuj online w interpretatorze CJam .

Jak to działa

l~    e# Evaluate the first line of input.
_,)   e# Compute the array length and add 1.
N*    e# Push a string of that many linefeeds.
q~    e# Evaluate the remaining input.
.{t}~ e# Vectorized array set: for each index in the array from line 2, replace the
      e# LF at that index by the corresponding element of the array from line 3.
.\    e# Interleave the two arrays on the stack.
N-    e# Remove the linefeeds.
p     e# Print.

CJam, 20 bajtów

{Qa+@@.{a2$2$=+t}e_}

Jest to anonimowa funkcja, która wyskakuje B , V i I (od góry do dołu) ze stosu i pozostawia w zamian pojedynczą tablicę na stosie.

Wypróbuj online w interpretatorze CJam .

Jak to działa

Qa+      e# Append [[]] to B.
@@       e# Rotate V and I on top of B.
.{       e# For each v in V and the corresponding i in I:
   a     e#     Push [v].
   2$2$= e#     Retrieve b := B[i].
   +     e#     Append to push [v b].
         e#     The stack now consists of: B i [v b]
   t     e#     Set B[i] := [v b].
}        e#
e_       e# Flatten B.
Dennis
źródło
1

Rubinowy, 48 bajtów

Myślę, że jest to zgodne z zasadami, ale proszę sprawdzić.

->b,v,i{l=-1;i.map{|j|b[j]=[v[l+=1],b[j]]};b*?:}

Nienazwana funkcja przyjmująca trzy tablice jako dane wejściowe. Zwraca ciąg znaków, który można jednoznacznie przeanalizować w tablicę liczb z wyrażeniem ruby x.split(/:+/).map(&:to_i).

Testuj przypadki na ideone .

Mógłbym zapisać jeszcze 3 bajty, ale format wyjściowy [1,2,[nil,5]]nieco przesuwa reguły zbyt mych imo, chociaż jest to jednoznaczne.

blutorange
źródło
Myślę, że obecny format jest w porządku. Zagnieżdżone tablice z nilwartościami przeplotu są nieco rozciągnięte. Ale w obu przypadkach nie wygrywa to konkursu, więc tak naprawdę nie martwię się o to.
Martin Ender
1

R 60

Jako nienazwana funkcja, która przyjmuje b, v i i

function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}

Rozszerza b za pomocą NA Wypełnia luki tam, gdzie jest to wymagane za pomocą v Zwraca wektor bez NA

> f=function(b,v,i){e=c(NA,rbind(b,NA));e[i*2+1]=v;e[!is.na(e)]}
> f(c(), c(), c())
logical(0)
> f(c(0, 0, 0), c(1, 1, 1, 1), c(0, 1, 2, 3))
[1] 1 0 1 0 1 0 1
> f(c(5, 1, 4, 1, 3), c(0, 0, 7), c(5, 0, 3))
[1] 0 5 1 4 7 1 3 0
MickyT
źródło
1

Java, 253, 226, 219, 209

nie do końca zwycięzca, ale no cóż.

Zakładając, że B, V i ja nie są zerowe. v (małe litery v) to długość tablic Wartości / Wskaźników. R jest zwróconą tablicą. r jest długością zwracanej tablicy. x, y i ja są tymczasowymi ints.

int[]f(int[]B,int[]V,int[]I){int v=V.length,r=B.length+v,x,y,i;int[]R=java.utils.Arrays.copyOf(B,r);for(x=0;x<v;x++){i=I[x];for(y=0;y<x;y++)if(I[x]>I[y])i++;for(y=r-2;y>=i;y--)R[y+1]=R[y];R[i]=V[x];}return R;}

rozszerzony:

int[]f( int[] B, int[] V, int[] I ) {
    int v = V.length, //length of Values
        r = B.length + v, //length of the result
        x, y, i; //temps
        int[] R = java.utils.Arrays.copyOf( B, r );       
        for( x = 0; x < v; x++ ) {
        i = I[x];
        for( y = 0; y < x; y++ )
            if( I[x] > I[y] )
                i++;
        for( y = r - 2; y >= i; y-- )
            R[y+1] = R[y];
        R[i] = V[x];
    }
    return R;
}
Jack Ammo
źródło
1

APL, 22 bajty

{(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}

W ⎕IO ← 0, aby dopasować przypadki testowe.

Jest to standardowy algorytm: wektor indeksu pierwszego argumentu jest dołączany do podanych indeksów (trzeci argument). oblicza permutację, która posortowałaby indeksy w porządku rosnącym. Ponieważ algorytm sortowania APL jest z definicji stabilny, obliczona permutacja umieszcza element catenacji drugiego i pierwszego argumentu we właściwym miejscu.

Na przykład :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
lstefano
źródło