Как чередовать два заданных вектора в 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
).
Затем мы применяем то же самое к массиву 1
s, соответствующий длине заданных массивов (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↓⍵}