Как чередовать два заданных вектора в APL

Я пытаюсь решить проблему с помощью APL, для которого у меня есть два вектора v1 и v2 с относительной длиной не более +1, в зависимости от ввода. Это означает, что ((≢v1)-(≢v2))∊¯1 0 1.

Как лучше всего чередовать указанные векторы, чтобы создать третий вектор v3, такой что v3=v1[0],v2[0],v1[1],v2[1],...?

(Если актуально, я использую Dyalog APL версии 16.0)


person J. Sallé    schedule 11.01.2018    source источник
comment
Я думаю, вы могли бы сделать этот вопрос немного более общим, удалив часть относительной длины, учитывая, что все ответы до сих пор не учитывают это (и поддерживают любую разницу) или применяют только для равной длины   -  person Uriel    schedule 14.01.2018


Ответы (6)


Это должно работать практически в каждом APL.

(v0,v1)[⍋(⍳⍴v0),⍳⍴v1]

Если вы хотите беспокоиться о том, что v0 или v1 являются скалярами, то

(v0,v1)[⍋(⍳⍴,v0),⍳⍴,v1]
person Lobachevsky    schedule 12.01.2018
comment
Это настолько классика, насколько это возможно. Очень полезная идиоматика. - person Lobachevsky; 12.01.2018

Если вы не возражаете против получения элемента заливки прототипа, когда векторы имеют неравную длину, тогда

Interleave←{,⍉↑⍵}

Сделаю. Попробуйте онлайн!

В противном случае вы можете чередовать совпадающие части, а затем добавить отсутствующие элементы — это работает и для разностей длин больше единицы:

Interleave←{
    lengths←⌊/≢¨⍵
    main←,⍉↑lengths↑¨⍵
    tail←⊃,/lengths↓¨⍵
    main,tail
}

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

person Adám    schedule 11.01.2018

Использование диалога dfn:

zip ← {
    mix ← ,⍉↑ ⍺ ⍵
    mask ← ,⍉↑ 1⊣¨¨ ⍺ ⍵
    mask / mix
}

Идея здесь состоит в том, чтобы смешать оба аргумента, затем транспонировать результат и, наконец, сгладить его (mix).

Затем мы применяем то же самое к массиву 1s, соответствующем длине заданных массивов (mask), и используем его в качестве маски для фильтрации прототипов, добавленных смешанным примитивом.

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

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

person Uriel    schedule 11.01.2018

Поскольку я не знаю Dyalog APL, отвечаю на старом ISO APL 1970-х годов:
(v1,v2)[⍋((0.5×(⍴v1)<⍴v2)+⍳⍴v1),((0.5×(⍴v2)<⍴v1)+⍳⍴v2]

Первым элементом будет самый длинный вектор, если они имеют одинаковую длину, первый элемент будет первым элементом v1.

person GilVib    schedule 11.01.2018
comment
Чтобы узнать, как вводить символы APL, посмотрите здесь и здесь и здесь. - person Adám; 14.01.2018

Вот как я решил бы исходный вопрос в APL2:

LEN←∊⌊/⍴¨V1 V2 
V3←∊((LEN↑V1),¨LEN↑V2),LEN↓¨V1 V2
person mappo    schedule 12.01.2018

С векторами одинаковой длины используйте внутренний продукт:

 1 2 3,.,40 50 60

┌──────────────┐
│1 40 2 50 3 60│
└──────────────┘

Надстройка над этим порождает этот dfn :

{r←(⍴⍺)⌊⍴⍵⋄(∊(r⍴⍺),.,r⍴⍵),(r↓⍺),r↓⍵}

в качестве альтернативы мы можем ламинировать (сохраняя ту же общую логику):

{r←(⍴⍺)⌊⍴⍵⋄(,(r⍴⍺),⍪r⍴⍵),(r↓⍺),r↓⍵}
person Jimmy Gauvin    schedule 23.08.2019