Найти ближайшее большее число

30

Задание

Дан любой массив целых чисел, например:

[-1,476,578,27,0,1,-1,1,2]

и индекс этого массива (в этом примере используется индексация на основе 0 , хотя можно также использовать индексацию на основе 1 ).

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]

Затем верните ближайшее число больше, чем элемент с этим индексом . В этом примере самое близкое число больше 1 - 27 (на расстоянии 2 индексов).

         index = 5
                 v
[-1,476,578,27,0,1,-1,1,2]
            ^
Nearest greater number

Output = 27

Предположения

  • Ближайший не включает в себя упаковку.
  • Программа никогда не получит массив длиной 1 (например; [55]).
  • Вы должны предположить, что всегда есть число больше, чем данный элемент.
  • Если есть 2 числа больше, чем элемент на равных расстояниях, вы можете вернуть либо одно .

Пары ввода / вывода

Input:
Index = 45
Array = [69, 43, 89, 93, 62, 25, 4, 11, 115, 87, 174, 60, 84, 58, 28, 67, 71, 157, 47, 8, 33, 192, 187, 87, 175, 32, 135, 25, 137, 92, 183, 151, 147, 7, 133, 7, 41, 12, 96, 147, 9, 134, 197, 3, 107, 164, 90, 199, 21, 71, 77, 62, 190, 122, 33, 127, 185, 58, 92, 106, 26, 24, 56, 79, 71, 24, 24, 114, 17, 84, 121, 188, 6, 177, 114, 159, 159, 102, 50, 136, 47, 32, 1, 199, 74, 141, 125, 23, 118, 9, 12, 100, 94, 166, 12, 9, 179, 147, 149, 178, 90, 71, 141, 49, 74, 100, 199, 160, 120, 14, 195, 112, 176, 164, 68, 88, 108, 72, 124, 173, 155, 146, 193, 30, 2, 186, 102, 45, 147, 99, 178, 84, 83, 93, 153, 11, 171, 186, 157, 32, 90, 57, 181, 5, 157, 106, 20, 5, 194, 130, 100, 97, 3, 87, 116, 57, 125, 157, 190, 83, 148, 90, 44, 156, 167, 131, 100, 58, 139, 183, 53, 91, 151, 65, 121, 61, 40, 80, 40, 68, 73, 20, 135, 197, 124, 190, 108, 66, 21, 27, 147, 118, 192, 29, 193, 27, 155, 93, 33, 129]
Output = 199

Input:
Index = 2
Array = [4,-2,1,-3,5]
Output = 4 OR 5

Input:
Index = 0
Array = [2124, -173, -155, 146, 193, -30, 2, 186, 102, 4545]
Output = 4545

Input:
Index = 0
Array = [1,0,2,3]
Output = 2

Input:
Index = 2
Array = [3,-1,-3,-2,5]
Output = -1 OR -2
Гравитон
источник
Не могли бы вы добавить тестовый пример, в котором он ищет результат слева, а не справа? т.е.1; [7,1,-4,2]
Кевин Круйссен
Я думаю 2; [3,-1,-3,-2,5], это хороший тестовый пример. Есть положительные числа, но результат отрицательный.
Стьюи Гриффин
Можно ли использовать 2-х индексированный?
Тит
@ Titus Я имею в виду, если вы действительно хотите
Гравитон

Ответы:

7

MATL , 10 байт

yt&y)>fYk)

При этом используется индексирование на основе 1. Попробуйте онлайн!

объяснение

Рассмотрим входы [4,-2,1,-3,5], в 3качестве примера.

y     % Take two inputs implicitly. Duplicate 2nd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5]
t     % Duplicate top of the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5]
&y    % Duplicate 3rd-top element in the stack
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], [4,-2,1,-3,5], 3
)     % Index: select elements from first input as indicated by second input
      % STACK: [4,-2,1,-3,5], 3, [4,-2,1,-3,5], 1
>     % Greater than, element-wise
      % STACK: [4,-2,1,-3,5], 3, [1,0,0,0,1]
f     % Find: gives indices of non-zero entries
      % STACK: [4,-2,1,-3,5], 3, [1,5]
Yk    % Closest element: gives closest element of each entry in second input
      % ([1,5]) to each entry in the first input (3). In case of a tie it 
      % gives the left-most one
      % STACK: [4,-2,1,-3,5], 1
)     % Index: select elements from first input as indicated by second input
      % STACK: 4
      % Implicitly display
Луис Мендо
источник
2
У вас есть объяснение?
Ник Клиффорд
@NickClifford Конечно! Я ждал разъяснений по ОП. Объяснение добавлено
Луис Мендо
6

Желе , 10 байт

ị<ṛTạ⁸$ÞḢị

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

Деннис
источник
Я возился целую вечность, пытаясь заставить сортировку работать с абсолютным значением :(
Джонатан Аллан
5

Желе , 11 12 байт

+1 байт - упаковка не допускается.

Jạż⁸ṢZṪ»\Q2ị

1-индексироваться.

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


Предыдущие 11 байтов (индексирование с переносом), 0 проиндексированы:

ṙżU$Fµ>ḢTḢị
Джонатан Аллан
источник
Это не удается, например 0 [1,0,2,3].
Орджан Йохансен
@ ØrjanJohansen Ах - он возвращается 3, а это 1, так что, да, «ближайшее» не определено ...
Джонатан Аллан
1
Я попросил OP добавить этот контрольный пример.
Орджан Йохансен
4

JavaScript (ES6), 57 55 байт

Принимает массив aи индекс iв карри синтаксисе (a)(i).

a=>g=(i,p)=>(x=a[i-p])>a[i]||(x=a[i+p])>a[i]?x:g(i,-~p)

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

Arnauld
источник
Вы не можете использовать |вместо ||?
Нейл
@Neil Нет, мы не хотим xперезаписываться при выполнении первого условия.
Арно
3

PHP, 106 байт

<?for($y=($a=$_GET[0])[$x=$_GET[1]];$y>=$a[$x-++$i]&&$y>=$a[$x+$i];);echo$y<$a[$x+$i]?$a[$x+$i]:$a[$x-$i];

Онлайн версия

Йорг Хюльсерманн
источник
Похоже, они не работают для первого теста.
Ник Клиффорд
@NickClifford Теперь это должно работать. Я
выбрал
3

Haskell , 48 байтов

i%l=minimum[[j*j,x]|(j,x)<-zip[-i..]l,x>l!!i]!!1

Попробуйте онлайн! Тестовый фреймворк от Эрджана Йохансена.

XNOR
источник
Вы можете сохранить байт, используя список и !!1вместо этого (просто измените Integerна Intв заголовке).
Орджан Йохансен
@ ØrjanJohansen Спасибо, я попробовал это и не был уверен, почему он жаловался на типы.
xnor
2

Сборка x86-64, 40 байт

Вдохновленный анализом Johan du Toit и решений C на 2501 , ниже приводится функция, которая может быть собрана с MASM для платформ x86-64.

Он соответствует соглашению о вызовах Microsoft x64 для передачи параметров, поэтому передается общая длина массива, передается ECXинтересующая позиция EDXи указатель на массив целых чисел R8(это 64-битная платформа, поэтому 64-битный указатель).

Возвращает результат («ближайшее большее число») в EAX.

             FindNearestGreater PROC      
8B F2       \    mov     esi, edx     ; move pos parameter to preferred register
8B D9       |    mov     ebx, ecx     ; make copy of count (ecx == i; ebx == count)
            | MainLoop:
8B C6       |    mov     eax, esi     ; temp  = pos
2B C1       |    sub     eax, ecx     ; temp -= i
99          |    cdq
33 C2       |    xor     eax, edx
2B C2       |    sub     eax, edx     ; temp = AbsValue(temp)
            | 
41 8B 14 B0 |    mov     edx, DWORD PTR [r8+rsi*4]
41 39 14 88 |    cmp     DWORD PTR [r8+rcx*4], edx
7E 04       |    jle     KeepGoing    ; jump if (pValues[i] <= pValues[pos])
3B D8       |    cmp     ebx, eax
77 02       |    ja      Next         ; jump if (count > temp)
            | KeepGoing:
8B C3       |     mov     eax, ebx    ; temp = count
            | Next:
8B D8       |     mov     ebx, eax    ; count = temp
E2 E3       |     loop    MainLoop    ; equivalent to dec ecx + jnz, but smaller (and slower)
            | 
            |     ; Return pValues[temp + pos]
03 C6       |     add     eax, esi
41 8B 04 80 |     mov     eax, DWORD PTR [r8+rax*4]
C3          /     ret
             FindNearestGreater ENDP

Если вы хотите вызвать его из кода C, прототип будет:

extern int FindNearestGreater(unsigned int count,
                              unsigned int pos,
                              const    int *pValues);
Коди Грей
источник
1

Haskell , 53 байта

(#)принимает Intи список Ints или Integers (фактически любого Ordтипа) и возвращает элемент списка.

n#l=[x|i<-[1..],x:_<-(`drop`l)<$>[n-i,n+i],x>l!!n]!!0

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

  • nявляется указанным индексом и lзаданным списком / «массивом».
  • iПринимая значения от 1 и выше, это расстояние от nтестируемого в данный момент.
  • Для каждого iмы проверяем индексы n-iи n+i.
  • xэто элемент lтестирования. Если он пройдет тесты, он станет элементом понимания списка.
    • Индексирование произвольных индексов !!может привести к ошибке «вне границ», в то время dropкак в этом случае возвращается либо весь список, либо пустой список. Шаблон соответствует x:_проверке того, что результат не пустой.
    • x>l!!nпроверяет, что наш элемент больше, чем элемент в индексе n(который гарантированно существует).
    • !!0 в конце возвращает первое совпадение / элемент понимания списка.

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

Орджан Йохансен
источник
1

Brachylog , 17 байт

hH&∋₎<.&t:I≜+:H∋₍

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

объяснение

hH                      Call the list H
  &∋₎<.                 Output is greater than the number at the specified index
       &t:I≜            Label I (0, then 1, then -1, then 2, then -2, …)
            +           Sum I with the input Index
             :H∋₍       Output is the element of H at index <the sum>
Fatalize
источник
1

Java (OpenJDK 8) , 98 байт

int f(int n,int[]a){for(int s=1,i=1,x=a[n];;n+=i++*s,s=-s)if(0<=n&n<a.length&&a[n]>x)return a[n];}

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

Проверяет индексы в порядке, указанном частичными суммами следующей суммы:

initial value + 1 - 2 + 3 - 4 + 5 - 6 + ...
Дрянная Монахиня
источник
Я просто читал вопрос и хотел начать писать ответ. Кстати, почему s=1,и ,s=-s, он не имеет смысла в вашем ответе. Вы забыли удалить его из старого подхода?
Кевин Круйссен
1
@KevinCruijssen это ошибка, и я исправляю это сейчас. Он прошел тестовые случаи, потому что во всех этих тестовых случаях ближайший больший номер находится справа.
Утренняя монахиня
1

C 69 байтов

t;b;f(*d,c,p){for(b=c;c--;)d[c]>d[p]&(t=abs(p-c))<b?b=t:0;*d=d[p+b];}

Первый аргумент - это аргумент in / out. Вывод сохраняется в его первом элементе.

Посмотрите, как это работает онлайн .

2501
источник
1

R, 59 байт

function(l,i)l[j<-l>l[i]][which.min(abs(1:length(l)-i)[j])]

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

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

Giuseppe
источник
1

PHP, 73 байта

function($i,$a){for(;$b<=$a[$i];)$b=max($a[++$d+$i],$a[$i-$d]);return$b;}

Закрытие принимает на основе 0 индекс и массив из аргументов. Проверьте все контрольные примеры .

Titus
источник
Не следующее более высокое значение. Вам нужно значение с наименьшим расстоянием, которое выше
Йорг Хюльсерманн
@ JörgHülsermann Спасибо за указание.
Тит
0

Java, 96 байт

int f(int n,int[]a){for(int s=1,i=1,x=a[n];0>(n+=i++*s)|n>=a.length||a[n]<=x;s=-s);return a[n];}

Идентификаторы названы как ответ @Leaky Nun. Кроме того, большинство частей были выровнены, чтобы быть в основном одинаковыми: для сравнения, ifбыло заменено forусловием (жертвуя дополнительной точкой с запятой). Двоеточие было удалено путем перемещения части-инкремента в условие (поэтому круглые скобки предыдущего оператора if практически «переместились») - изменив & на | не влияет на количество персонажей.

Johannes
источник
0

Clojure, 95 байт

#(%(nth(nth(sort-by first(for[i(range(count %)):when(>(% i)(% %2))][(Math/abs(- i %2))i]))0)1))

Это самое короткое, что я мог придумать :( Я тоже пытался поиграть с этим, но не смог довести его до финиша:

#(map(fn[f c](f c))[reverse rest](split-at %2 %))
NikoNyrh
источник