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

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

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

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

5 ответов

Решение

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

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

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

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

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

Interleave←{,⍉↑⍵}

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

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

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

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

Используя Dyalog dfn:

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

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

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

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

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

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

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

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

LEN←∊⌊/⍴¨V1 V2 
V3←∊((LEN↑V1),¨LEN↑V2),LEN↓¨V1 V2

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

 1 2 3,.,40 50 60

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

Построение поверх этого порождает эту dfn:

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

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

{r←(⍴⍺)⌊⍴⍵⋄(,(r⍴⍺),⍪r⍴⍵),(r↓⍺),r↓⍵}
Другие вопросы по тегам