En yakın sayıyı bulun


30

Görev

Herhangi bir tamsayı dizisi verildiğinde, örneğin:

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

ve bu dizinin bir dizini (bu örnek 0 tabanlı dizinleme kullanır , ancak 1 tabanlı dizinleme de kullanabilirsiniz .):

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

Ardından , bu dizindeki öğeden daha büyük olan en yakın sayıyı döndürün . Örnekte, 1'den büyük olan en yakın sayı 27'dir (2 indeks uzakta).

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

Output = 27

Varsayımlar

  • En yakın sarma içermez.
  • Programa asla bir uzunluk 1 dizisi (örneğin; [55]) verilmez .
  • Her zaman verilen öğeden daha büyük bir sayı olduğunu varsaymalısınız .
  • Elementten eşit mesafelerde 2 sayı daha büyükse, ikisinden de dönebilirsiniz .

G / Ç çiftleri

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

Sağa değil sola doğru bir sonuç aradığı bir test senaryosu ekleyebilir misiniz? yani1; [7,1,-4,2]
Kevin Cruijssen

Bence 2; [3,-1,-3,-2,5]güzel bir test davası. Olumlu sayılar var ama sonuç olumsuz.
Stewie Griffin,

2 indeksli kullanabilir miyim?
Titus,

@Titus Gerçekten istersen demek istiyorum
Graviton

Yanıtlar:


7

MATL , 10 bayt

yt&y)>fYk)

Bu 1 tabanlı indeksleme kullanır. Çevrimiçi deneyin!

açıklama

Giriş göz önünde [4,-2,1,-3,5], 3bir örnek olarak.

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
Bir açıklamanız var mı?
Nick Clifford

@NickClifford Tabii! OP açıklamasını bekliyordum. Açıklama eklendi
Luis Mendo



4

JavaScript (ES6), 57 55 bayt

Küme sözdizimi dizisini ave dizini alır .i(a)(i)

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

Test durumları


Kullanmak Can |yerine ||?
Neil,

@Neil Hayır, xilk koşul yerine getirildiğinde üzerine yazmak istemeyiz .
Arnauld

3

PHP, 106 Bayt

<?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];

Çevrimiçi sürüm


Bunlar ilk test durumu için işe yaramıyor gibi görünüyor.
Nick Clifford

@NickClifford Şimdi çalışması gerekiyor. Yanlış bir yaklaşıma
girdim

3

Haskell , 48 bayt

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

Çevrimiçi deneyin! Ørjan Johansen'den test çerçevesi.


Bir listeyi kullanarak ve bir bayt kaydedebilirsiniz !!1yerine (sadece değiştirmek Integeriçin Intbaşlığında).
Ørjan Johansen

@ ØrjanJohansen Teşekkürler, denedim ve neden türlerden şikayet ettiğinden emin değildim.
xnor

2

x86-64 Derleme, 40 bayt

Johan du Toit ve 2501'in C çözümlerini analiz ederek , aşağıdakiler MAS86 ile x86-64 platformları için birleştirilebilecek bir fonksiyondur.

Parametrelerin geçirilmesi için Microsoft x64 çağrı kuralını izler , böylece dizinin toplam uzunluğu iletilir ECX, ilgilenilen konum girilir EDXve tam sayı dizisine gösterici girilirR8 (bu 64 bitlik bir platformdur, bu nedenle 64 bitlik bir işaretçi).

İçindeki sonucu ("en yakın sayı") döndürür 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

Eğer onu C kodundan çağırmak istersen, prototip şöyle olurdu:

extern int FindNearestGreater(unsigned int count,
                              unsigned int pos,
                              const    int *pValues);



1

Haskell , 53 bayt

(#)bir Intve Ints veya Integers listesini alır (aslında herhangi bir Ordtür) ve listenin bir öğesini döndürür.

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

Nasıl çalışır

  • nverilen dizin ve lverilen liste / "dizi" dir.
  • i1'den yukarı olan değerleri alarak, nşu anda test edilene olan mesafedir .
  • Her biri için iendeksleri n-ive n+i.
  • xltest edilen unsurdur . Testleri geçerse, sonuçta elde edilen listenin kavranmasının bir unsuru olacaktır.
    • İsteğe bağlı dizinleri dizine ekleme !!, sınırların dışında bir hataya neden olabilir, dropbunun yerine ya tüm listeyi ya da bu durumda boş bir listeyi döndürür. Desen x:_, sonucun boş olmadığını kontrol eder.
    • x>l!!nelementimizin indeksindeki elementten daha büyük olduğunu test eder n(var olması garantilidir).
    • !!0 sonunda liste anlama ilk eşleme / elemanını verir.

Çevrimiçi deneyin!



1

Brachylog , 17 bayt

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

Çevrimiçi deneyin!

açıklama

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>

1

Java (OpenJDK 8) , 98 bayt

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];}

Çevrimiçi deneyin!

Endeksleri aşağıdaki toplamın kısmi toplamları tarafından belirtilen sıraya göre kontrol eder:

initial value + 1 - 2 + 3 - 4 + 5 - 6 + ...

Ben sadece soruyu okuyordum ve bir cevap yazmaya başlamak istedim .. Btw, neden s=1,ve ,s=-s, cevabınızda bir faydası yok. Eski bir yaklaşımdan çıkarmayı unuttunuz mu?
Kevin Cruijssen

1
@KevinCruijssen bu bir hatadır ve şimdi düzeltiyorum. Test evrelerini geçti çünkü tüm bu test evrelerinde, en yakın sayı sağa doğru.
Sızdıran Rahibe,

1

C, 69 bayt

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];}

İlk argüman bir giriş / çıkış argümanıdır. Çıkış, ilk elemanında saklanır.

Çevrimiçi çalıştığını görün .


1

R, 59 bayt

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

isimsiz bir işlev döndürür. Eşit mesafelerde daha büyük iki element olması durumunda, ilk (daha küçük endeks) döndürür.

Çevrimiçi deneyin!



1

PHP, 73 bayt

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

kapatma 0-tabanlı indeksi ve argümanlardan diziyi alır. Tüm test durumlarını doğrulayın .


Bir sonraki daha yüksek değer değil. En düşük mesafeye sahip bir değere ihtiyacınız var
Jörg Hülsermann

@ JörgHülsermann Gösterdiğiniz için teşekkürler.
Titus,



0

Java, 96 Bayt

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];}

Tanımlayıcılar @Leaky Nun'un cevabı gibi adlandırılır. Ayrıca, çoğu bölüm temelde aynı olacak şekilde ayarlanmıştır: Buna karşılık, ifyerine for(ek noktalı virgül kurban ederek) yerine geçmiştir . Bir kolon, artım kısmını koşula getirerek kaldırıldı (böylece önceki if ifadesinin parantezleri pratikte "taşındı") - değiştirildi & | karakter sayısı üzerinde etkisi yoktu.


0

Clojure, 95 bayt

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

Bu bulabildiğim en kısa şey :( Ben de bununla oynamayı denedim ama bitiş çizgisine getiremedim:

#(map(fn[f c](f c))[reverse rest](split-at %2 %))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.