Есть ли удар?


39

По заданному списку положительных целых чисел определите, существует ли элемент, который больше, чем его два соседа, или меньше, чем его два соседа («удар»). Чтобы быть понятным, выпуклость никогда не может быть первым или последним элементом списка, потому что у них есть только один сосед.

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

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

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

[] -> False
[1] -> False
[1,2] -> False
[1,2,1] -> True
[1,2,2] -> False
[1,2,3] -> False
[1,2,2,1] -> False
[1,2,2,3] -> False
[1,2,1,2] -> True
[1,3,2] -> True
[3,1,2] -> True
[2,2,2] -> False

5
Запрос тестового примера: числа, отличные от 0-1-2-3, также разрешены / запрещены отрицательные значения?
Волшебная Урна Осьминога

Предлагаемый тестовый пример: [1,3,3](гарантирует, что ответы, использующие алгоритм Денниса, будут иметь знак приращений, а не только сами приращения)
ETHproductions

1
@ETHproductions Разве это уже не покрыто [1,2,2]? Или я что-то упустил?
Фонд Моники иск

2
@NicHartley, дельты [1,2,2]совпадают с признаками этих дельт, но это не так [1,3,3].
Лохматый

Ответы:


15

Желе , 5 байт

IṠIỊẠ

Возвращает 0, если есть удар, 1, если нет.

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

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

IṠIỊẠ  Main link. Argument: A (integer array)

I      Increments; take all forward differences of A.
 Ṡ     Take the signs.
       The signs indicate whether the array is increasing (1), decreasing (-1), or
       constant at the corresponding point. A 1 followed by a -1 indicates a local
       maximum, a -1 followed by a 1 a local minimum.
  I    Increments; take the forward differences again.
       Note that 1 - (-1) = 2 and (-1) - 1 = -2. All other seven combinations of
       signs map to -1, 0, or 1.
   Ị   Insignificant; map each difference d to (-1 ≤ d ≤ 1).
    Ạ  All; return 1 if all differences are insignificant, 0 if not.

1
Что такое «Приращения?». Что увеличивается и что это делает?
Пшеничный волшебник

1
@WheatWizard Я думаю, что это эквивалент команды deltaas (¥) 05AB1E: массив [n0, n1, n2, n3] всплывает, а массив [n1-n0, n2-n1, n3-n2] выдвигается.
Kaldo

10

JavaScript (ES6), 38 байт

Возвращает логическое значение.

a=>a.some(x=n=>x*(x=a<n|-(a>(a=n)))<0)

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

Как?

Мы используем для хранения предыдущего значения п . Мы устанавливаем x в 1, если a <n , -1 если a> n или 0, если a = n . И мы проверяем, является ли old_x * x <0 , что возможно, только если ( old_x = 1 и x = -1 ) или ( old_x = -1 и x = 1 ).

Поскольку x инициализируется функцией анонимного обратного вызова some () , он приводится к NaN во время первой итерации, что делает тест ложным.


Это будет бросать в строгом режиме.
Алуан Хаддад

2
@AluanHaddad Что ж, 99% кода для игры в гольф JS будут работать в строгом режиме только из-за необъявленных переменных. PPCG и codereview плохо сочетаются. : P
Арнаулд

Это справедливо, я не очень люблю гольф.
Алуан Хаддад

4
Тогда зачем это комментировать, лол
Марк С.

8

Haskell , 42 байта

any(<0).f(*).f(-)
f a b=zipWith a b$tail b

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

объяснение

Сначала у нас есть функция, fкоторая принимает двоичную функцию и список и применяет двоичную функцию к каждой соседней паре в списке.

Тогда наша основная функция применяется f(-)к списку ввода. Это вычисляет список различий. Затем мы применяем f(*)к списку умножение каждой соседней пары. Наконец, мы спрашиваем, есть ли какая-либо пара меньше нуля.

Число в конечном списке может быть отрицательным, только если оно является произведением отрицательного и положительного числа из списка разностей. Таким образом, чтобы создать отрицательную запись (и затем вернуть true), исходный список должен переключиться с увеличения на уменьшение или наоборот, то есть он должен иметь удар.


Хороший способ разобраться с пустым списком!
Лайкони


5

Октава с пакетом изображений, 34 32 байта

2 байта сохранены благодаря @StewieGriffin !

@(x)0||prod(im2col(diff(x),2))<0

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

объяснение

Вычисляет последовательные различия, упорядочивает их в скользящих блоках длиной 2, получает произведение каждого блока и проверяет, является ли какой-либо такой продукт отрицательным.


0||prod(...)экономит 2 байта. Вы также можете пропустить всю anyчасть и использовать стандартное определение «истина / ложь», чтобы сохранить 5 байтов .
Стьюи Гриффин

Черт, экономия 5 байтов сделает ваше решение короче моего :( Хорошее использование пакета изображений. Я не знал, что это было на TIO.
Стьюи Гриффин,

1
@StewieGriffin Поскольку задача требует двух последовательных значений, я не могу удалить any. Спасибо за 0||идею!
Луис Мендо

4

R, 48 байтов

function(x)any(apply(embed(diff(x),2),1,prod)<0)

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

Как это работает пошагово, используя c (1,4,1,4) в качестве примера:

> x=c(1,4,1,4)
> diff(x)
[1]  3 -3  3
> embed(diff(x),2)
     [,1] [,2]
[1,]   -3    3
[2,]    3   -3
> apply(embed(diff(x),2),1,prod)
[1] -9 -9
> any(apply(embed(diff(x),2),1,prod)<0)
[1] TRUE

В качестве бонуса, вот решение аналогичной длины и концепции с использованием пакета zoo:

function(x)any(zoo::rollapply(diff(x),2,prod)<0)

1
аккуратный! Примечание для себя: помните, что embedсуществует. Это очень плохо, rowProdsи colProdsне существует как псевдонимы в R.
Джузеппе

1
@ Giuseppe от отчаяния я на самом деле проверил, если они существуют :) но на самом деле справедливо rowSumsи rowMeans...
plannapus

1
ну, по крайней мере, просматривая документы, .colSumsизменит входные данные в матрицу, основанную на дополнительных входах, которые, вероятно, где-то есть в приложении для игры в гольф ... теперь мне просто нужно найти один!
Джузеппе

@Guiseppe: взгляните на функции в matrixStatsпакете.
Майкл М

@MichaelM К сожалению, из-за длины имени пакета это не делает его конкурентоспособным (57 байт:) function(x)any(matrixStats::colProds(embed(diff(x),2)))<0. Но для всего, кроме Code Golf, этот пакет действительно сокровищница.
plannapus


3

Perl 6 , 39 байт

{so~(.[1..*]Zcmp$_)~~/'re L'|'s M'/}

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

$_аргумент списка этой анонимной функции. .[1..*]тот же список, но с первым удаленным элементом. Zcmpобъединяет два списка вместе с cmpоператором, в результате получается список Orderзначений. Например, для списка ввода 1, 2, 2, 2, 1это привело бы к списку More, Same, Same, Less.

Теперь нам просто нужно знать, содержит ли этот список два смежных элемента More, Lessили Less, More. Уловка, которую я использовал, заключается в том, чтобы преобразовать список в строку, разделенную пробелом ~, и затем проверить, содержит ли она подстроку re Lили s M. (Первое не может быть просто e Lпотому, что Sameтакже заканчивается буквой «е».)

Оператор умного сопоставления возвращает либо Matchобъект (если совпадение выполнено), либо Nil(если это не так), поэтому он soпреобразует все, что есть, в логическое значение.



3

Рубин , 55 46 байт

->a{a.each_cons(3).any?{|x,y,z|(y-x)*(y-z)>0}}

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

Лямбда, принимающая массив и возвращающая логическое значение.

-9 байт: заменить (x<y&&y>z)||(x>y&&y<z)на (y-x)*(y-z)>0(благодаря GolfWolf )

->a{
  a.each_cons(3)              # Take each consecutive triplet
    .any?{ |x,y,z|            # Destructure to x, y, z
      (y-x)*(y-z) > 0         # Check if y is a bump
    }
}

1
Я думаю, что вы можете использовать |вместо того ||, чтобы сэкономить 1 байт.
Yytsi


Сохранить 1 байт с помощью '0 <(yx) * y- = z'
ГБ

3

PostgreSQL 173 байта

SELECT DISTINCT ON(a)a,x>j and x>k OR x<least(j,k)FROM(SELECT a,x,lag(x,1,x)OVER(w)j,lead(x,1,x)OVER(w)k FROM d WINDOW w AS(PARTITION BY rn ORDER BY xn))d ORDER BY 1,2 DESC;
     a     | c 
-----------+---
 {1}       | f
 {1,2}     | f
 {1,2,1}   | t
 {1,2,1,2} | t
 {1,2,2}   | f
 {1,2,2,1} | f
 {1,2,2,3} | f
 {1,2,3}   | f
 {1,3,2}   | t
 {2,2,2}   | f
 {3,1,2}   | t
(11 rows)

Здравствуйте и добро пожаловать на сайт. Я не знаком с PostgreSQL, но вы можете уменьшить количество используемого пробела. Как правило, большинство языков не требуют большинства используемых вами интервалов.
Пшеничный волшебник

@WheatWizard это пример данных в базу данных, это не имеет значения.
Эван Кэрролл

Какой у тебя код? Мы не разрешаем вставлять ввод непосредственно в код вместо ввода. Если это так, то вам следует переписать его так, чтобы он принимал ввод стандартным методом .
Пшеничный волшебник

@WheatWizard по предоставленной вами ссылке, codegolf.meta.stackexchange.com/a/5341/23085
Эван Кэрролл,

1
Хорошо, если это формат ввода, который вы используете, тогда все в порядке. Удачи в игре в гольф здесь, приятно видеть людей, играющих в гольф на менее часто используемых языках.
Пшеничный волшебник

3

Java 8, 108 104 101 86 84 79 72 байта

a->{int i=a.length,p=0;for(;i-->1;)i|=p*(p=a[i]-a[i-1])>>-1;return-i>1;}

-2 байта благодаря @ OlivierGrégoire .
-13 байт благодаря @Nevay .

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


1
84 байта . Я изменил порядок итераций (понижаясь), поменял местами два операнда умножения и затем смог удалить лишнее -1.
Оливье Грегуар

1
79 байтов: a->{int i=a.length;for(;i-->2;)i|=(a[i]-a[--i])*(a[i]-a[i-1])>>-1;return-~i|3;}(возвращается -1для истинных случаев, 3для ложных случаев) - или, если в качестве возвращаемого значения используется наличие / отсутствие исключения, 55 байтов:a->{for(int i=0;++i>0;)i|=(a[i-1]-a[i])*(a[i]-a[i+1]);}
Nevay

1
72 байта:a->{int i=a.length,p=0;for(;i-->1;)i|=p*(p=a[i]-a[i-1])>>-1;return-i>1;}
Невай

3

R , 58 56 байт

function(x)any(abs(diff(sign(diff(c(NA,x)))))>1,na.rm=T)

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

Сохранено 2 байта благодаря Джузеппе


3
Вы можете избавиться от фигурных скобок {}за -2 байта.
Джузеппе

Кроме того, я думаю, что вы можете портировать подход Стьюи Гриффина на 42 байта
Джузеппе

@Giuseppe, я думаю, что Стьюи перенес мой метод, с той разницей, что мой может правильно обрабатывать пустой вектор, как указано в тестовых примерах. Matlab немного мягче с пустыми векторами по сравнению с R.
NofP

c()Это NULLне то же самое, что пустой вектор целых чисел, integer(0)тогда как в MATLAB []это значение doubleпо умолчанию, но если вы хотите сохранить его таким образом, это вполне разумно.
Джузеппе

3

J , 16 15 байт

-1 байт благодаря FrownyFrog

1 e.0>2*/\2-/\]

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

Оригинал: 16 байт

0>[:<./2*/\2-/\]

2-/\] - отличия каждого соседнего предмета

2*/\ - продукты каждого смежного товара

[:<./ - минимум

0> - отрицательно?

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


Здравствуйте ! Разве это не может быть сокращено до этой более простой явной формы 0> <./ 2 * / \ 2 - / \ (13 байт)?
Матиас Долидон

@Mathias Dolidon Это работает в интерпретаторе, но здесь, в PPCG, обычно есть функция (глагол J), если есть какой-то ввод. Если глагол молчаливый, мы не считаем f=.байты присваивания . Пожалуйста, имейте ввиду, что я относительно новый пользователь :)
Гален Иванов

Я тоже, и вы разъяснили мне правило. Благодарность ! :)
Матиас Долидон

1
1 e.0>2*/\2-/\]
FrownyFrog

@ FrownyFrog Спасибо! Кажется, я редко пользуюсь е. :)
Гален Иванов



2

Атташе , 39 байт

Any&:&{_*~?Sum[__]}@Slices&2@Sign@Delta

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

Очень доволен тем, как это получилось.

объяснение

Это композиция из четырех функций:

Delta
Sign
Slices&2
Any&:&{_*~?Sum[__]}

Deltaполучает различия между элементами. знак равно

Затем Signприменяется к каждому различию, давая нам массив 1s, 0s и -1s. знак равно

Затем, Slices&2дает все куски длиной два из массива, давая все пары различий.

Наконец, Any&:&{_*~?Sum[__]}эквивалентно, для ввода x:

Any[&{_*~?Sum[__]}, x]
Any[[el] -> { el[0] and not (el[0] + el[1] = 0) }, x]

Это ищет элементы, которые суммируют в ноль, но не равны нулю. Если какая-либо такая пара элементов существует, то есть удар.




2

Октава , 33 байта

@(x)0||abs(diff(sign(diff(x))))>1

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

Объяснение:

@(x)                           % Anonymous function taking x as input
                  diff(x)       % Takes the difference between consecutive elements
             sign(diff(x))      % The sign of the differences
        diff(sign(diff(x)))     % The difference between the signs
    abs(diff(sign(diff(x)))>1   % Check if the absolute value is 2
@(x)abs(diff(sign(diff(x)))>1   % Output as matrices that are treated truthy or falsy

2

Брахилог , 10 байт

s₃.¬≤₁∧¬≥₁

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

Успех (true. ), если есть удар, и терпит неудачу (false. ), если нет удара.

объяснение

Это уже достаточно читабельно:

s₃.           There is a substring of the input…
  .¬≤₁        …which is not non-decreasing…
      ∧       …and…
       ¬≥₁    …which is not non-increasing

2

05AB1E , 7 байтов

¥ü‚P0‹Z

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

объяснение

¥         # calculate delta's
 ü‚       # pair each element with the next element
   P      # product of each pair
    0‹    # check each if less than 0
      Z   # max

Разве не было 1-байтовой альтернативы, 0‹которая в основном проверяет число на наличие отрицательного знака?
Волшебная урна осьминога

@MagicOctopusUrn: dиспользуется для проверки наличия только верхней части стека [0-9], что противоположно тому, что мы хотим здесь. Но теперь он стал более интеллектуальным, и отрицательные числа / числа с плавающей точкой также считаются числами.
Emigna

Ааааа ... можно aбылоnegative знак и вернул истину или что-то в этом роде ... Но я думаю, ты прав, я помню твой dтрюк.
Волшебная Урна Осьминога

2

Брахилог , 10 байт

s₃s₂ᶠ-ᵐ×<0

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

Не такой аккуратный и элегантный, как 10-байтовый ответ @ Fatalize, но он работает!

s₃   % There exists a substring of three elements [I,J,K] in the array such that

s₂ᶠ  % When it's split into pairs [[I,J],[J,K]]

-ᵐ   % And each difference is taken [I-J, J-K]

×    % And those differences are multiplied (I-J)*(J-K)
     % (At a bump, one of those will be negative and the other positive. 
     % At other places, both differences will be positive, or both negative, 
     %  or one of them 0 - ultimately resulting in a non-negative product.)

<0   % The product is negative





1

Wolfram Language (Mathematica) , 37 36 байт

FreeQ[(d=Differences)@Sign@d@#,-2|2]&

Дает противоположные ответы тестового примера (False и True поменялись местами). Добавить! чтобы перейти к нормальной форме.

ИЛИ

Abs@(d=Differences)@Sign@d@#~FreeQ~2&

Также обратный вывод, поэтому заменить FreeQнаMatchQ для нормальной формы.

Пояснение: Возьмите знак различий в последовательности. Если результирующая последовательность включает в себя {1, -1} или {-1,1}, есть выпуклость. Абсолютное значение разности {1, -1} или {-1,1} равно 2 в любом случае.

Сбрейте еще один байт, возведя в квадрат окончательный список вместо того, чтобы принимать абсолютное значение:

FreeQ[(d=Differences)@Sign@d@#^2,4]&

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


1

Perl, 35 байт

Включает +3в себя для-p

bump.pl:

#!/usr/bin/perl -p
s%\S+ %$a*1*($a=$&-$')%eg;$_=/-/

Беги как:

bump.pl <<< "3 1 2"

1

Юлия 0,6 , 57 56 байт

l->any(p>c<n||p<c>n for(p,c,n)=zip(l,l[2:end],l[3:end]))

В основном просто полный ответ человека на python. -1 байт от пользователя71546

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

Юлия 0,6 , 39 байт

f(x,y,z,a...)=x>y<z||x<y>z||f(y,z,a...)

Стиль рекурсии Лиспы, ответ Питона Денниса. Возвращает, trueкогда существует удар, иначе выдает ошибку. Это может быть 42 байта, так как вы должны разделить его при вызове. Например, для a=[1,2,1]вас называют как f(a...).f(a)=f(a...)удалил бы эту потребность, но это дольше. Мне нужно улучшить рекурсию, и мне не очень нравится писать код, который выдает ошибку.

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


1
кажется, место после forне нужно;)
Шиеру Асакото
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.