ค้นหาจำนวนที่ใกล้เคียงที่สุด


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 องค์ประกอบในระยะทางเท่ากันคุณสามารถส่งคืนได้ทั้งคู่

คู่ I / O

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

คุณสามารถเพิ่มกรณีทดสอบเพื่อดูผลลัพธ์ทางซ้ายแทนที่จะไปทางขวาได้ไหม ie1; [7,1,-4,2]
Kevin Cruijssen

ฉันคิดว่า2; [3,-1,-3,-2,5]เป็นกรณีทดสอบที่ดี มีตัวเลขบวก แต่ผลลัพธ์เป็นลบ
Stewie Griffin

ฉันสามารถใช้ 2 ดัชนีได้หรือไม่
ติตัส

@Titus ฉันหมายความว่าถ้าคุณต้องการ
Graviton

คำตอบ:


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
คุณมีคำอธิบายไหม?
Nick Clifford

@ NickClifford แน่นอน! ฉันกำลังรอคำชี้แจง OP เพิ่มคำอธิบาย
Luis Mendo


5

เจลลี่ , 11 12 ไบต์

+1 ไบต์ - ไม่ห่อหุ้ม

Jạż⁸ṢZṪ»\Q2ị

1 การจัดทำดัชนี

ลองออนไลน์!


11 byter ก่อนหน้า (การทำดัชนีการห่อ), 0-indexed:

ṙżU$Fµ>ḢTḢị

0 [1,0,2,3]นี้ล้มเหลวบนเช่น
Ørjan Johansen

@ ØrjanJohansen Ah - มันส่งคืน3ซึ่งเป็น 1 ห่างดังนั้นอืมใช่ "ไม่ใกล้" ใช่ ...
Jonathan Allan

1
ฉันขอให้ OP เพิ่มกรณีทดสอบ
Ørjan Johansen

4

JavaScript (ES6), 57 55 ไบต์

ใช้เวลาอาร์เรย์aและดัชนีในไวยากรณ์i currying(a)(i)

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

กรณีทดสอบ


คุณไม่สามารถใช้|แทนได้||หรือไม่?
Neil

@ ไม่มีเลยเราไม่ต้องการxถูกเขียนทับเมื่อเงื่อนไขแรกเสร็จสมบูรณ์
Arnauld

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

เวอร์ชั่นออนไลน์


ดูเหมือนว่าสิ่งเหล่านี้ใช้ไม่ได้กับกรณีทดสอบครั้งแรก
Nick Clifford

@NickClifford ตอนนี้มันควรจะทำงาน ฉันใช้วิธีที่ผิด
JörgHülsermann

3

Haskell , 48 ไบต์

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

ลองออนไลน์! กรอบการทดสอบจากØrjan Johansen


คุณสามารถบันทึกไบต์โดยใช้รายการและ!!1แทน (เพียงแค่เปลี่ยนIntegerไปIntในส่วนหัว)
Ørjan Johansen

@ ØrjanJohansenขอบคุณฉันได้ลองแล้วและไม่แน่ใจว่าทำไมมันถึงบ่นเกี่ยวกับประเภท
xnor

2

x86-64 Assembly, 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เป็น list / "array" ที่กำหนด
  • iรับค่าตั้งแต่ 1 ขึ้นไปคือระยะทางจากnการทดสอบในปัจจุบัน
  • สำหรับแต่ละiเราจะตรวจสอบดัชนีและn-in+i
  • xเป็นองค์ประกอบของlการทดสอบ ถ้ามันผ่านการทดสอบมันจะเป็นองค์ประกอบของรายการความเข้าใจที่เกิดขึ้น
    • การจัดทำดัชนีโดยพลการด้วย!!อาจทำให้เกิดข้อผิดพลาดนอกขอบเขตในขณะที่dropส่งกลับรายการทั้งหมดหรือรายการเปล่าในกรณีนั้นแทน รูปแบบตรงกันกับการx:_ตรวจสอบว่าผลลัพธ์ไม่ว่างเปล่า
    • x>l!!nทดสอบว่าองค์ประกอบของเรามากกว่าองค์ประกอบที่ดัชนีn(ซึ่งรับประกันได้ว่ามีอยู่)
    • !!0 ในตอนท้ายส่งกลับการแข่งขันครั้งแรก / องค์ประกอบของรายการความเข้าใจ

ลองออนไลน์!




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 + ...

ฉันเพิ่งอ่านคำถามและต้องการเริ่มเขียนคำตอบ .. Btw ทำไมs=1,และ,s=-sไม่มีประโยชน์ในคำตอบของคุณ .. คุณลืมที่จะลบมันออกจากวิธีการเก่าหรือไม่?
Kevin Cruijssen

1
@KevinCruijssen มันเป็นความผิดพลาดและตอนนี้ฉันกำลังแก้ไขอยู่ มันผ่านการทดสอบเพราะในการทดสอบเหล่านั้นจำนวนที่ใกล้ที่สุดคือทางขวา
Leun Nun

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

อาร์กิวเมนต์แรกคืออาร์กิวเมนต์เข้า / ออก เอาต์พุตถูกเก็บไว้ในองค์ประกอบแรก

เห็นมันทำงานแบบออนไลน์


1

R, 59 ไบต์

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

ส่งคืนฟังก์ชั่นที่ไม่ระบุชื่อ ในกรณีที่มีองค์ประกอบสองอย่างที่มากกว่าในระยะทางเท่ากันจะส่งคืนแรก (ดัชนีน้อยกว่า)

ลองออนไลน์!



1

PHP, 73 ไบต์

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

การปิดจะใช้ดัชนีและอาร์เรย์จาก 0 อาร์กิวเมนต์ ตรวจสอบกรณีทดสอบทั้งหมด


ไม่ใช่ค่าที่สูงกว่าถัดไป คุณต้องการค่าที่มีระยะทางต่ำสุดที่สูงกว่า
JörgHülsermann

@ 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-condition (เสียสละเซมิโคลอนเพิ่มเติม) โคลอนถูกลบออกโดยการย้ายส่วนที่เพิ่มขึ้นไปสู่สภาพ (ดังนั้นวงเล็บของคำสั่ง if ก่อนหน้านี้จริง "ย้าย") - เปลี่ยน & เป็น | ไม่ส่งผลกระทบต่อจำนวนตัวอักษร


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 %))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.