Обобщенный массив Riffle


22

Простой гольф, чтобы начать неделю! Вам даны три массива: базовый массив B , массив значений V и индексный массив I . Вы должны создать другой массив, в который Vвставляются значения из Bиндексов, указанных в I. Вот пример:

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

Индексы указывают на следующие позиции в базовом массиве:

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

Таким образом, вставляя соответствующие элементы из массива значений, результат должен быть:

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

правила

Вы можете написать программу или функцию, используя ввод через STDIN (или ближайшую альтернативу), аргументы командной строки или аргументы функции, и выводить результат через STDOUT (или ближайшую альтернативу), возвращаемое значение функции или изменяя массив, заданный как B параметра. ,

Если ваше представление является функцией Iи Vможет быть изменено любым способом, а такжеB если оно не используется для вывода.

Вы можете сделать следующие предположения относительно ввода:

  • Все элементы массива base и value будут неотрицательными целыми числами.
  • Массив значений будет иметь не более одного элемента больше, чем базовый массив.
  • Массив значений и индексный массив будут иметь одинаковое количество элементов.
  • Массив индекса не будет содержать повторяющихся индексов, и все индексы будут в диапазоне.
  • Массивы базы и значения могут содержать повторяющиеся элементы.
  • Любой или все массивы могут быть пустыми.
  • Вы не должны предполагать, что индексы даны в каком-то определенном порядке.
  • Вы можете получать ввод и производить вывод в любой удобной, однозначной строке или формате списка. Вы также можете получить три массива в другом порядке.
  • Вы можете выбрать индексацию от 0 до 1.

Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.

Тестовые случаи

Задано в формате B V I => Resultдля индексации на основе 0. Если вы используете индексирование на основе 1, увеличьте элементы третьего массива на 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]

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

Leaderboard

Вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

# Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

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


4
Как вы относитесь NULLк пустому массиву для языков, где есть пустой массив NULL?
Алекс А.

@AlexA. Если это общее / представление пустого массива в указанном языке (ах), я хорошо с этим.
Мартин Эндер

3
Просто гольф ? Это самое сложное, что я делал в CJam за всю неделю. : P
Деннис

Ответы:


13

Pyth, 14 байт

s.icFPQmedSCtQ

Демонстрация.

Эта программа принимает входные данные в виде трех наборов списков в следующем порядке: База, Индексы, Значения.

Пояснение к примеру [5, 1, 4, 1, 3], [5, 0, 3], [0, 0, 7]:

  1. Возьмите вход: неявный, Q является входом.

  2. Составьте индекс, пары значений: CtQ=[(5, 0), (0, 0), (3, 7)]

  3. Сортируйте пары в порядке возрастания индекса: SCtQ=[(0, 0), (3, 7), (5, 0)]

  4. Возьмите значение из каждой пары: medSCtQ=[0, 7, 0]

  5. Разделите базовый список по месту нахождения признаков: cFPQ=[[], [5, 1, 4], [1, 3], []]

  6. Чередование 3 и 4: .icFPQmedSCtQ=[[], 0, [5, 1, 4], 7, [1, 3], 0, []]

  7. Объединить в один список: s.icFPQmedSCtQ=[0, 5, 1, 4, 7, 1, 3, 0]


Черт. С каких это пор у нас есть метод чередования? Просто хотел опубликовать ssC,cFPQamedSCtQ].
Якуб

5
@Jakube Исаак украдкой совершил это 6 дней назад.
orlp


3
@Jakube, так как Pyth может расти, чтобы решить любую проблему. Вот в чем проблема с языками игры в гольф. Эзотерические языки существуют ради эзотерических языков; как они разработаны * впоследствии.
Sentiao

@sentiao Честно говоря, язык хоста (Python) некоторое время перемежался под другим именем .
Мего

16

Python 2, 54

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

Принимает вход как B,I,V. Модифицирует вводB при вызове (спасибо Мартину Бюттнеру за напоминание, что это возможно).

Используется mapдля вызова B.insertкаждой пары индекс / элемент. Чтобы избежать смещения индексов списков при вставке элементов, сортирует пары в порядке убывания индекса по безобразному zip / sort / unzip. Если бы не смещение вопроса, мы могли бы просто сделать map(B.insert,*X).

Старый метод (65):

B,V,I=input()
for i,v in sorted(zip(I,V))[::-1]:B[i:i]=v,
print B

5

Haskell, 62 байта

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

Пример использования: f [5,1,4,1,3] [0,0,7] [5,0,3]-> [0,5,1,4,7,1,3,0].

Как это работает: дополнить базовый список индексами «полтора», начиная с 0.5(например [(0.5,5),(1.5,1),(2.5,4),(3.5,1),(4.5,3)]), и объединить его с парами индекс-значение. Сортировка и удаление индекса.

Замечание : не знаю, жульничаю ли я здесь. С математической точки зрения это нормально, но программист может утверждать, что список индексов [5,0,3]- это не список по Integersзапросу, а список Fractionals(точнее, тип полиморфный, но должен принадлежать Fractionalклассу, например, Floatили Double).


5

Рубин, 60 59 53 байта

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

И негольфированная версия

def riffle(array, values, indices)
    indices.zip(values).sort.reverse.each do |index, value|
        array.insert(index, value)
    end
end

2
Вы можете сократить это, что делает его неназванный функцию вместо: ->a,b,c{...}. Также есть вероятность, insertчто скобки не нужны.
Мартин Эндер

@ MartinBüttner Я знал о безымянной функции с лямбдой, но я не чувствовал, что это соответствует духу задачи (которая обычно требует именованной функции). Спасибо за то, что заметили паренов.
Дилан Фрезе

Если задача не требует конкретно именованной функции, безымянные функции всегда приемлемы . И я не просил именованную функцию (я никогда не делаю;)).
Мартин Эндер

5

CJam, 34 23 18 байт

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

Моя первая подача CJam. Советы приветствуются, я уверен, что есть много в гольф.

16 байтов сохранено с помощью @ MartinBüttner и @Dennis.

Функция ожидает ввода в стеке по порядку B V I(я самый верхний).

Пример использования:

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

Метод:

  • Сопоставить iэлемент массива сi+0.5
  • сопряжение вставки значений с позициями вставки
  • объединить получившиеся два массива
  • сортировать массив по позиционным элементам
  • сохранить элементы значения

Этот подход с плавающей запятой очень умный и (к сожалению) лучше, чем мой. Вы можете получить до 19 байтов с q~.5fm.\2/\ee+$1f=pи до 18 байтов, используя анонимную функцию:{.5fm.\2/\ee+$1f=}
Деннис

Та же идея без уловки с плавающей запятой: {.\2/\ee+{0=}$1f=}(все еще 18 байтов)
Деннис

@ Денис Спасибо, я не мог найти get array elementоператора для 1f=. Я оставлю это как полную программу, хотя.
Рандомра

Ваш звонок. Вы не возражаете, чтобы я спросил, почему вы против публикации функции?
Деннис

@Dennis Я только начал CJam и не знал, как использовать функции. Теперь я понял это, поэтому я изменил ответ на это.
Рандомра

5

К, 22 21 байт

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

Определим функцию 3 аргумента {…}с неявных переменных x, yи zпредставляющий начальный список, список значений и список индексов, соответственно. Оператор «cut» ( _) используется для разделения начального списка на отсортированный список заданных индексов ( (z@<z)). Мы чередуем значения (после их соответствующей сортировки) с разделенными фрагментами исходного массива, формируя список ( (a;b)), беря его transpose ( +) и выравнивая результат (,// ).

Пример использования:

  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

Пробелы вокруг подчеркивания необходимы, потому что K допускает подчеркивание в идентификаторах. K5 устраняет эту потенциальную неоднозначность. Если бы мы могли рассчитывать на индексы, поступающие в порядке возрастания, а подчеркивания не были действительными идентификаторами, мы могли бы использовать гораздо более приятную 13-байтовую программу:

{,//+(y;z_x)}

(вздох.)

редактировать:

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

Нарушает симметрию, но мы можем сохранить байт, используя скобку-индексацию ( […]) вместо @оператора индексации инфикса . Обычно это делает программы длиннее, но в этом случае нам нужно было все равно сортировать парены zперед выполнением вырезания.


4

Pyth, 17 байт

ssC,cFPQamedSCtQ]

@isaacg опередил мое решение. Но так как моя документация закончена, я все равно ее опубликую.

Это принимает входные данные в формате B, I, V. Вы можете попробовать это здесь: Демонстрация или Test Suite

Объяснение:

Я использую пример B = [5,1,4,1,3], I = [5,0,3], V = [0,0,7]из ОП.

                    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]

4

JavaScript (ES6), 75

Функция с 3 параметрами массива, возвращающая массив. Как ни странно, эта функция изменяет свой iпараметр (как любезно разрешено OP)

Попробуйте запустить фрагмент, Firefox только в обычном режиме.

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>


Из любопытства, как насчет кода, который делает его специфичным для Firefox? Это потому что это ES6?
Алекс А.

@ AlexA.it потому что это ES6, да. В частности, fat arrow functionэто не реализовано даже в девелоперской версии Chrome (AFAIK)
edc65

Действительно, даже Canary-сборка Chrome не поддерживает это.
DocMax

4

Mathematica, 52 51 байт

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

Пример:

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}

Объяснение:

Используя пример выше.

  • 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}
  • Затем возьмите (отсортированный) объединение этих двух списков. (=>{0.5 -> 0, 1 -> 5, 2 -> 1, 3 -> 4, 3.5 -> 7, 4 -> 1, 5 -> 3, 5.5 -> 0} )
  • А затем возьмите последний элемент каждой пары. (=> {0, 5, 1, 4, 7, 1, 3, 0})


3

R 75 байт

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}

Это создает безымянную функцию. Чтобы назвать его, дайте ему имя, напримерf=function... . Обратите внимание, что массивы должны быть 1-индексированы, потому что именно так катится R.

Ungolfed + объяснение:

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
}

Примеры:

> 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

Предложения приветствуются как всегда!


2

CJam, 19 байтов

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

Это полная программа, которая читает массивы B , I и V (по одному на строку в указанном порядке) из STDIN.

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

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 байтов

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

Это анонимная функция, которая выскакивает B , V и I (сверху вниз) из стека и оставляет один массив в стеке взамен.

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

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.

1

Рубин, 48 байтов

Я думаю, что это соответствует правилам, но, пожалуйста, проверьте.

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

Безымянная функция, принимающая три массива в качестве входных данных. Выводит строку, которая может быть однозначно проанализирована в массив чисел с выражением rubyx.split(/:+/).map(&:to_i) .

Тестовые случаи на ideone .

Я мог бы сохранить еще 3 байта, но формат вывода [1,2,[nil,5]]слишком растягивает правила, но это однозначно.


Я думаю, что текущий формат в порядке. Вложенные массивы со nilзначениями чередования немного растянуты. Но в любом случае это не победа в конкурсе, так что я не очень беспокоюсь об этом в любом случае.
Мартин Эндер

1

R, 60

В качестве неназванной функции, которая принимает b, v и i

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

Расширяет b с помощью NA. Заполняет пробелы, где это необходимо, с помощью v Возвращает вектор без 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

1

Ява, 253, 226, 219, 209

не совсем победитель, ну да ладно.

Предполагая, что B, V и я не равны нулю. v (нижний регистр v) - длина массивов значений / показателей. R - возвращенный массив. r - длина возвращаемого массива. х, у и я все временные целые числа.

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;}

расширен:

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;
}

1

APL, 22 байта

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

В ⎕IO ← 0, чтобы соответствовать тестам.

Это стандартный алгоритм: индексный вектор первого аргумента добавляется к указанным индексам (3-й аргумент). вычисляет перестановку, которая сортирует индексы в порядке возрастания. Поскольку алгоритм сортировки APL по определению стабилен, вычисленная перестановка помещает элемент объединения второго и первого аргументов в нужное место.

Например :

    {(∊⌽2↑⍵)[⍋(2⊃⍵),⍳≢⊃⍵]}(5 1 4 1 3)(0 0 7)(5 0 3)
0 5 1 4 7 1 3 0
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.