Собирайте и размещайте предметы


13

Цель этой задачи - собрать выбранные элементы в списке и переместить их в определенное место в списке.

В качестве наглядного примера возьмем входные значения (представленные целыми числами в черных ящиках) и соответствующий список истинных значений, где true означает, что выбран элемент (представлен голубыми полями, где Ttrue и Fis falses):

введите описание изображения здесь

Первый логический шаг - разделить элементы, помеченные как правдивые и не правдивые, в соответствующие списки. Обратите внимание, что относительный порядок в каждом списке должен поддерживаться (то есть порядок выбранных элементов должен быть 1,4,5, а порядок невыбранных элементов должен быть 2,3,6,7)!

введите описание изображения здесь

Второй логический шаг - указание индекса в оставшемся списке невыбранных элементов, вставка всех выбранных элементов перед элементом с указанным индексом. Предполагая, что индексирование начинается с 0, предположим, что вы хотите вставить выборку с индексом 3. Это соответствует месту перед 7полем, поэтому выбранные элементы должны быть вставлены перед 7.

введите описание изображения здесь

Окончательное решение тогда 2,3,6,1,4,5,7.

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

вход

Ваша программа имеет 3 входа:

  1. Список целых чисел, представляющих элементы. Это может быть пустой список. Этот список всегда будет состоять из уникальных натуральных чисел, не обязательно в отсортированном порядке (т.е. 5 не будет в списке дважды).
  2. Список истинных / ложных значений такой же длины, что и список элементов, где истинное значение означает, что был выбран элемент с тем же индексом.
  3. Целое число, представляющее, куда вставить выбор. Вы можете выбрать индекс первого элемента списка, если он постоянен при каждом запуске вашей программы (например, первым элементом может быть индекс 0 или индекс 1). Пожалуйста, укажите, какой конвенции придерживается ваша программа. Этот индекс должен находиться в диапазоне [starting_idx, ending_idx+1], т.е. он всегда будет действительным индексом. Для индекса случая ending_idx+1, выбор должен быть вставлен в конец списка. Вы можете предположить, что это целое число будет соответствовать типу целого числа вашего языка.

Вход может поступать из любого желаемого источника (stdio, параметр функции и т. Д.)

Выход

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

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

Все следующие тестовые примеры предполагают индексирование на основе 0. Я использовал 0 и 1, чтобы указать ложные / истинные значения соответственно для маски выбора.

В тестовых примерах списки отформатированы как [a,b,c], но пока ваши входные списки представляют собой конечную упорядоченную последовательность, это нормально.

Входные данные:

[]
[]
0

Выход:

[]

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

Входные данные:

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

Выход:

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

счет

Это код гольф; кратчайший ответ в байтах побеждает. Стандартные лазейки запрещены. Вам разрешено использовать любые встроенные модули по вашему желанию.


Может ли вход и выход быть похожими на «1 2 3», «1 0 0», 1 '?
Betseg

Да, все, что представляет две конечные упорядоченные целочисленные последовательности и целочисленный индекс в порядке.
helloworld922

Будет ли первый массив содержать отрицательные элементы или ноль?
Дрянная Монахиня

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

@PeterTaylor нет. Я исправил это, чтобы прочитать "Список истинных / ложных ценностей ...". Есть ли хорошее название для описания «типа» истинных / ложных значений? Boolean-как?
helloworld922

Ответы:


10

MATL, 9 байт

&)i:&)bwv

Это решение принимает массив значений T(true) и F(false) в качестве второго ввода. Также для первого тестового примера, с пустыми массивами, он не производит вывод.

Попробуйте онлайн! и немного измененная версия для всех тестовых случаев.

объяснение

    % 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

5

Mathematica, 66 62 байта

Сохранено 4 байта из @MartinEnder .

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

Анонимная функция. Принимает индекс на основе 1, список и маркеры в качестве входных данных и возвращает переупорядоченный список в качестве выходных данных.


3

Haskell, 70 байт

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

Пример использования: ([1,2,3,4,5,6,7]#[True,False,False,True,True,False,False]) 3-> [2,3,6,1,4,5,7].

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

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

3

JavaScript (ES6), 76 байт

(a,b,c)=>(d=a.filter((_,i)=>!b[i]),d.splice(c,0,...a.filter((_,i)=>b[i])),d)

1

Желе , 10 байт

¬+\>⁵Ḥ³oỤị

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

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

¬+\>⁵Ḥ³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.

0

C #, 132 байта

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

ungolfed:

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

Идеи по улучшению приветствуются.


0

Python 3, 91 байт

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:]

где aсписок элементов / номера, xявляется True/Falseсписок и iявляется индексом.

Многострочная версия для улучшения читаемости:

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:] 

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

Вызов zip(a,x)результатов в виде списка кортежей , где каждый из них содержит информацию: (element,0|1). Затем используется понимание списка, чтобы определить элементы, которым присвоено 0/Falseзначение, и сохранить их в переменной b.

Таким образом, [c for c,z in zip(a,x)if z<1]создается список, который содержит все элементы, с которыми связано значение 0( False).

После этого, список элементов , которые имеют True|1значение , связанное (которая определяется проверкой , какие элементы aне присутствуют в b: [c for c in a if(c in b)<1]) вставляется в списке со всеми элементами , которые имеют 0( Falseзначение) , связанное (список b) по указанному индексу iи полученный список возвращается.


0

Python 3, 106 93 байта

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

Старая версия:

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.