Извлечь локальные максимумы

19

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

Вы можете предположить, что массив содержит как минимум два элемента.

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

Input               | Output
[4,2,6,12,4,5,4,3]  | [4,12,5]
[1,2]               | [2]
[1,2,3,2,1]         | [3]
[3,2,1,2,3]         | [3,3]
[4,4]               | [4,4]
[2,4,4,4,1]         | [4,4,4]
[2,3,3,4]           | [3,4]
[4,3,3,4]           | [4,4]

Это , самый короткий код выигрывает!

Павел
источник
1
@PeterTaylor Я думаю, что имеется в виду «Для первого или последнего элемента, который будет включен в вывод, ...»
xnor
@PeterTaylor xnor правильно.
Павел
Связанные
Питер Тейлор
Могу ли я предложить [4,3,3,4]в качестве тестового примера. Мое решение не очень хорошо с этим справилось.
JAD

Ответы:

5

Желе ,  13 12  11 байт

0;;0»3\f"⁸Ẏ

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

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


Предыдущие 12 байтов :

0;INżI>0ḄNMị

Предыдущие 13 байтов :

0;;0ṡ3M€ċ€2Tị

Как?

0;;0»3\f"⁸Ẏ - Link: list of positive integers, A
0;          - a zero concatenated with A
  ;0        - concatenate a zero
     3\     - 3-wise reduce with:
    »       -   maximum (yields a list of the maximums in each overlapping window of 3)
         ⁸  - chain's left argument, A
        "   - zip with:
       f    -   filter keep (i.e. keep the maximal if it is [in] the [length 1 list 
            -                     of the] respective original element)
          Ẏ - flatten by one level
Джонатан Аллан
источник
Ну, я думаю, что может быть способ использовать 3-мудрое сокращение, но я не разработал его.
Джонатан Аллан
Я был прав - 3-х кратное уменьшение с максимальной диадой, »- как насчет 10, хотя ..?
Джонатан Аллан
7

Mathematica 22 байта

Pick[#,MaxDetect@#,1]&
Келли Лоудер
источник
1
Между прочим, это также будет работать на массивах более высоких измерений.
Келли Лоудер
6

Хаскелл, 50 49 42 байта

f l=[j|i:j:k:_<-scanr(:)[0]$0:l,k<=j,i<=j]

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

scanr(:)[0]составляет список хвостов (0:l), каждый с окончательным 0, например , для l = [4,3,3,4]: [[0,4,3,3,4,0],[4,3,3,4,0],[3,3,4,0],[3,4,0],[4,0],[0]]что шаблон соответствует Agains i:j:k:_извлечь все списки по крайней мере , 3 -х элементов , которые называются i, jи k. Сохранить, jесли его> =i и j.

Редактировать: Эрджан Йохансен спас 7 байтов. Благодарность!

Ними
источник
2
i:j:k:_<-scanr(:)[0]$0:lкороче (Немного подкорректировав «стандартный» tails=scanr(:)[]трюк.)
Орджан Йохансен
@ ØrjanJohansen: о, я использовал этот трюк перед собой, но как-то пропустил его здесь. Большое спасибо!
Ними
4

Dyalog APL, 31 30 28 22 21 байтов

{⍵/⍨(⌈/=2⌷⊢)¨3,/∊0⍵0}

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

Объяснение (я плохо разбираюсь в вещах):

0⍵0       - [0,input,0]   (it looks like a face!)
∊         - flatten
3,/       - split into overlapping sections of length 3.
(⌈/=2⌷⊢)¨ - Whether the middle element is the maximum (applied to every section)
⍵/⍨       - index
Zachary
источник
3

JavaScript (ES6), 40 байт

a=>a.filter((e,i)=>!(e<a[i-1]|e<a[i+1]))
Нил
источник
3

Python 3 , 84 75 * 71 байт

lambda l,k=[0]:[j for x,j in enumerate(l)if(k+l+k)[x+2]<=j>=(k+l+k)[x]]

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


* @ LeakyNun сэкономил 9 байт, используя хитрый операторский прием.

Мистер Xcoder
источник
lambda l,k=[0]:[l[i]for i in range(len(l))if(k+l+k)[i+2]<=l[i]>=(k+l+k)[i]]
Утренняя монахиня
2

05AB1E , 15  14  13 байт

ü‹0¸«sĆÁü›+_Ï

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

объяснение

ü‹             # pairwise comparison for less than
  0¸«          # append 0
     s         # swap input to top of stack
      Ć        # enclose, append the head of the list
       Á       # rotate right
        ü›     # pairwise comparison for greater than
          +    # add the two boolean lists
           _   # logical negate
            Ï  # keep only elements of input that are true in the resulting list

Предыдущее 15-байтовое решение

¬s¤)˜Œ3ùεZQ1è}Ï

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

объяснение

¬                # get head of input
 s¤              # get tail of input
   )˜            # wrap stack in flattened list
                 # produces the input list with the first and last element duplicated
     Œ3ù         # push sublists of length 3
        ε        # apply transformation on each triple
         ZQ      # ... check each element for equality to the max
          1è     # ... get the middle element
            }    # end transform
             Ï   # keep only elements of input that are true in the resulting list
Emigna
источник
2

R, 44 байта

pryr::f(x[(x>=c(0,x)&x>=x[-1])[1:sum(x|1)]])

который оценивает функцию:

function (x) 
x[(x >= c(0, x) & x >= x[-1])[1:sum(x | 1)]]

Сравнивает xс c(0,x), так что со xсмещением на одну позицию вправо. Также сравнивается xс x[-1], так что одна позиция сдвинута влево. Это оба, TRUEесли есть максимум там. &взять И этих булевых. Из-за природы обертывания векторов R, когда они не имеют одинаковую длину, мы должны обрезать результат до длины x, которая определяется путемsum(x|1) . Затем мы подключаем логический вектор, беря только истинные индексы xи возвращаем его.

Обратите внимание, поскольку эти логические операции выполняются с векторами неравной длины, R будет жаловаться. Много. Но правильный вывод будет там среди предупреждений:

> pryr::f(x[(x>=c(0,x)&x>=x[-1])[1:sum(x|1)]])(c(4,2,6,12,4,5,4,3))
[1]  4 12  5
Warning messages:
1: In x >= c(0, x) :
  longer object length is not a multiple of shorter object length
2: In x >= x[-1] :
  longer object length is not a multiple of shorter object length
3: In x >= c(0, x) & x >= x[-1] :
  longer object length is not a multiple of shorter object length
JAD
источник
2

R , 42 байта

function(x)x[c(d<-diff(x),0)<=0&c(0,d)>=0]

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

На 2 байта короче, чем решение JAD . diffвычисляет последовательные различия; тогда оставляйте только записи больше, чем оба соседа.

Робин Райдер
источник
1

R , 68 байт

function(a)a[a==sapply(1:length(a),function(i)max(c(0,a,0)[i+0:2]))]

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

Дрянная Монахиня
источник
pryr::f(expression)это более короткий способ объявления функции, чем function(a)expression.
JAD
Кроме того, sum(a|1)это ярлык для length(a).
JAD
Смотрите мое решение для более короткого подхода.
JAD
1

q, 39 байт

{x where x = -1 _ next 3 mmax x,last x}
skeevey
источник
Я никогда не слышал об этом языке раньше. Знаете ли вы, где я могу попробовать или скачать?
Павел
Конечно, kx.com , документы: code.kx.com
Skeevey
1

Stax , 10 байт

úâH◄(☼bM•Å

Запустите и отладьте его

Он производит вывод в виде значений, разделенных новой строкой, на стандартном выводе.

Распакованный, размазанный и прокомментированный, это выглядит так.

f       filter each value in input using the rest of the program; implicitly printing kept values
  x0|S  input pre- and post-pended with zero
  3B    split into batches of 3
  i@    get the i-th batch, where i is the iteration index
  |M=   is the current value equal to the max from the batch?

Запустите этот

Обновлено: только что найдено 9-байтовое решение. Обновлю объяснение позже:

Stax , 9 байт

▀▓ûa¥╓╧↨⌐

Запустите и отладьте его

рекурсивный
источник