ค้นหาตัวเลขที่ใกล้ที่สุดในอาร์เรย์ที่กำหนด


21

นี่คือแรงบันดาลใจจากปัญหาโลกแห่งความจริงที่ฉันมี ฉันอยากรู้ว่ามีวิธีที่ฉลาดที่จะไปเกี่ยวกับเรื่องนี้

คุณจะได้รับอาร์เรย์สองอันที่ไม่เรียงลำดับคือ A และ B แต่ละอันมีจำนวนลอยโดยพลการ A และ B ไม่จำเป็นต้องมีความยาวเท่ากัน เขียนฟังก์ชันที่ใช้องค์ประกอบของ A ตามลำดับและค้นหาค่าที่ใกล้ที่สุดในอาร์เรย์ B ผลลัพธ์จะต้องมีอยู่ในอาร์เรย์ใหม่

เงื่อนไขการชนะ

รหัสที่สั้นที่สุดชนะ (ตามปกติ)


1
ปัดเศษเป็นจำนวนเต็มที่ใกล้ที่สุดหรือไม่
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ฉันอ่านว่าเป็น "ปัดองค์ประกอบของ A ไปยังองค์ประกอบที่ใกล้ที่สุดของ B"
John Dvorak

@JanDvorak: ฉันเข้าใจส่วนเกี่ยวกับทิศทางการปัดเศษ แต่ปัญหาไม่ได้ระบุจำนวนหลัก
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ ปัดเศษเป็นทศนิยมที่ใกล้ที่สุด คำตอบต้องส่งออกลอยจากอาร์เรย์ / รายการ B
Orhym

1
อาร์เรย์ A และ B จะเรียงลำดับหรือไม่
เลเวลริเวอร์เซนต์

คำตอบ:


17

APL, 13 17

(21 ไบต์ใน UTF-8)

B[{↑⍋|⍵-B}¨A]

ถ้าคุณต้องการแลมบ์ดาที่แท้จริง (A เป็นอาร์กิวเมนต์ด้านซ้ายและ B ด้านขวา):

{⍵[⍺{↑⍋|⍺-⍵}¨⊂⍵]}

มันทำงานอย่างไร:

{...}¨Aเรียกใช้ฟังก์ชั่นแลมบ์ดาที่{...}มีค่า A ทุกค่า (แทนที่จะเรียกใช้ด้วย A ในฐานะอาร์เรย์) รวบรวมผลลัพธ์ไปยังอาร์เรย์ที่มีรูปร่างเดียวกัน

|⍵-B คำนวณค่าสัมบูรณ์ของความแตกต่างระหว่างการโต้แย้ง⍵และทั้งหมดใน B (- คือการลบ, | คือ abs)

↑⍋ รับดัชนีองค์ประกอบที่น้อยที่สุด (⍋เรียงลำดับดัชนีที่ส่งคืนอาร์เรย์↑รับองค์ประกอบแรก)

B[...] เป็นเพียงการดึงองค์ประกอบ (s) โดยดัชนี (es)

วิธีการแก้ปัญหาค่อนข้างแปลกใจมากมันใช้คุณสมบัติที่ยอดเยี่ยมของฟังก์ชั่นการเรียงลำดับของ APL ที่คืนค่าการเปลี่ยนแปลงของเวกเตอร์ (ดัชนีเรียงลำดับองค์ประกอบในอาร์เรย์เดิม) แทนที่จะเรียงตัวเอง


มันทำงานอย่างไร
John Dvorak

อธิบายในคำตอบ
Vovanium

คุณรู้วิธีการเขียนสิ่งนี้บนโลกได้อย่างไร?
Martijn

นี่มันเหมือนการเขียนภาษาจีน สำหรับผมไม่มีความแตกต่างที่ดีทั้งการเขียนคำพูดของมนุษย์ต่างดาวหรือตัวอักษรที่คนต่างด้าว ...
Vovanium

17

Mathematica - 17

#&@@@Nearest@A/@B

มันทำงานยังไง? ใช่ฉันยอมรับว่ามีการโกงเล็กน้อยที่นี่เพราะ Mathematica มีฟังก์ชันการทำงานที่ใกล้เคียงที่สุดในตัว ส่วนที่เหลือนั้นตรงไปตรงมาและเกี่ยวข้องกับการจัดเรียงผลลัพธ์ในอาร์เรย์ 1D มันดูน่าเกลียดเพียงเพราะความพยายามพิเศษที่จะทำให้มันสั้น


1
ฮา! ยินดีต้อนรับ! :)
ดร. เบลิซาเรียส

6

C # - 103 97 87 ไบต์

ฉันไม่แน่ใจว่าฉันเข้าใจคำถามนี้ถูกต้องหรือไม่ แต่นี่คือคำตอบของฉัน ฉันใช้รายการแทนอาร์เรย์เพราะมันทำให้ฉันสามารถเขียนรหัสที่สั้นกว่าได้

อาร์เรย์จำนวนเต็มสั้นกว่ารายการเลขจำนวนเต็ม

การป้อนข้อมูล:

t(new int[] { 0, 25, 10, 38 }, new int[] { 3, 22, 15, 49, 2 });

วิธี:

void t(int[]a,int[]b){var e=a.Select(c=>b.OrderBy(i=>Math.Abs(c-i)).First()).ToArray();

เอาท์พุท:

2, 22, 15, 49

หากคำตอบของฉันไม่ถูกต้องโปรดแสดงความคิดเห็นไว้ด้านล่าง

แก้ไข: AS @ grax ชี้ให้เห็นคำถามตอนนี้เกี่ยวกับการลอย ดังนั้นฉันต้องการรวมคำตอบของเขาด้วย

95 ไบต์ (คำตอบของ Grax)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}

รายการก็ดีเหมือนกัน
Orhym

1
เปลี่ยนชื่อitemเป็นiและคุณจะปลอดภัย 6 ตัวอักษรเพิ่มเติม;)
Aschratt

@ Aschratt ขอบคุณมาก!
tsavinho

3
1. ฟังก์ชั่นไม่ได้บอกเป็นการเฉพาะเพื่อคืนค่าใหม่ แต่ฉันคิดว่าคุณควร 2. เนื่องจากคำถามที่เรียกว่าโฟลทฉันคิดว่าคุณควรใช้โฟลตfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32

@ Grax ในขณะที่ฉันเขียนคำตอบแรกของฉันคำถามไม่ได้เกี่ยวกับลอย เนื่องจากคำถามได้รับการอัปเดตฉันจึงรวมคำตอบของคุณด้วย ขอบคุณมาก.
tsavinho

5

R, 41 ตัวอักษร

B[apply(abs(outer(A,B,`-`)),1,which.min)]

คำอธิบาย:

outer(A,B,`-`)คำนวณสำหรับแต่ละองค์ประกอบ x ของ A ความแตกต่างx-Bและแสดงผลลัพธ์เป็นเมทริกซ์ (ของความยาวมิติ (A) x ความยาว (B))
which.minเลือกดัชนีของจำนวนที่น้อยที่สุด
apply(x, 1, f)ใช้ฟังก์ชั่นบนแถวของเมทริกซ์แต่ละf ดังนั้นส่งกลับดัชนีของความแตกต่างน้อยที่สุดระหว่างแต่ละองค์ประกอบของ A และองค์ประกอบของเวกเตอร์ Bx
apply(abs(outer(A,B,`-`)),1,which.min)

การใช้งาน:

> A <- runif(10,0,50)
> B <- runif(10,0,50)
> A
[1] 10.0394987 23.4564467 19.6667152 36.7101256 47.4567670 49.8315028  2.1321263 19.2866901  0.7668489 22.5539178
> B
[1] 44.010174 32.743469  1.908891 48.222695 16.966245 23.092239 24.762485 30.793543 48.703640  6.935354
> B[apply(abs(outer(A,B,`-`)),1,which.min)]
[1]  6.935354 23.092239 16.966245 32.743469 48.222695 48.703640  1.908891 16.966245  1.908891 23.092239

5

CJam - 14

q~
f{{1$-z}$0=\;}
p

รหัสหลักอยู่บนบรรทัดที่สองส่วนที่เหลือใช้สำหรับอินพุตมาตรฐานและเอาต์พุตสวย

ลองที่http://cjam.aditsu.net/

คำอธิบาย:

q~อ่านและประเมินค่าอินพุต
f{...}ดำเนินการบล็อกสำหรับแต่ละองค์ประกอบของอาร์เรย์แรกและวัตถุถัดไป (ซึ่งเป็นอาร์เรย์ที่สอง) การรวบรวมผลลัพธ์ในอาร์เรย์
{...}$เรียงลำดับอาร์เรย์ที่สองโดยใช้บล็อกเพื่อคำนวณคีย์สำหรับแต่ละรายการ
1$คัดลอกปัจจุบัน รายการจากการ
-zลบอาเรย์แรกจากนั้นใช้ค่าสัมบูรณ์
0=ใช้ค่าแรกของอาเรย์ที่จัดเรียง (อันที่มีคีย์ต่ำสุด)
\;ทิ้งรายการจากอาเรย์แรก
pพิมพ์การแทนค่าสตริงของผลลัพธ์

ตัวอย่าง (แรงบันดาลใจจากคำตอบอื่น ๆ ):

อินพุต: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
เอาต์พุต:[10 12 12 14 10]

อินพุต: [0 25 10 38] [3 22 15 49 2]
เอาต์พุต:[2 22 15 49]


4

Javascript (E6) 54 56 59

ลดระยะทางให้สั้นที่สุด ใช้สี่เหลี่ยมแทน abs เพื่อประหยัด chars
แก้ไขพีชคณิต ...
แก้ไขการมอบหมายแก้ไขที่ไร้ประโยชน์ (ส่วนที่เหลือของการทดสอบโดยไม่มีการกำหนดฟังก์ชัน)

F=(A,B)=>A.map(a=>B.sort((x,y)=>x*x-y*y+2*a*(y-x))[0])

เป็น F=(A,B)=>D=A.map(a=>B.sort((x,y)=>((x-=a,y-=a,x*x-y*y))[0])

ทดสอบ

F([10.1, 11.2, 12.3, 13.4, 9.5],[10, 12, 14])

ผล: [10, 12, 12, 14, 10]


1
D=ไม่จำเป็นเนื่องจากmapส่งคืนอาร์เรย์ใหม่ ฟังก์ชันการเรียงลำดับทางเลือก (ความยาวเท่ากัน):(x,y)=>(x-=a)*x-(y-=a)*y
ขีดล่าง

4

Python 3.x - 55 ตัวอักษร

f=lambda a,b:[min((abs(x-n),x)for x in b)[1]for n in a]

aและbเป็นอาร์เรย์อินพุตและอาร์เรย์ที่ต้องการคือผลลัพธ์ของนิพจน์


ฉันแก้ไขคำตอบเพื่อให้เป็นฟังก์ชันเนื่องจากคำถามต้องใช้ฟังก์ชัน
user80551

3

Haskell, 55

c a b=[[y|y<-b,(y-x)^2==minimum[(z-x)^2|z<-b]]!!0|x<-a]

ตอนแรกฉันคิดว่าจะใช้minimumByและcomparingแต่เนื่องจากมันไม่ได้อยู่ในพรีลูดมันจึงต้องใช้ตัวละครมากมายในการคัดเลือกพวกเขา นอกจากนี้ยังขโมยความคิดกำลังสองจากคำตอบอื่น ๆ เพื่อกำจัดตัวละคร


3

PowerShell - 44

$a|%{$n=$_;($b|sort{[math]::abs($n-$_)})[0]}

ตัวอย่าง

กับ $aและ$bตั้งค่าเป็น:

$a = @(36.3, 9, 50, 12, 18.7, 30)
$b = @(30, 10, 40.5, 20)

ผลผลิตคือ

40.5, 10, 40.5, 10, 20, 30

คุณสามารถใช้ลอยในตัวอย่างเพื่อให้ชัดเจนว่ามันจัดการลอยด้วย
bebe

@bebe - ขอบคุณอัปเดตเพื่อให้ชัดเจน
Rynant

-3 bytes:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy

2

ทับทิม, 40

f=->a,b{a.map{|x|b.min_by{|y|(x-y)**2}}}

เช่นเดียวกับคำตอบของ Python แต่การยกกำลังสองนั้นค่อนข้างสั้นกว่าวิธีใด ๆ ที่ฉันคิดว่าให้คุณค่าที่แท้จริง


2

Pyth - 12 11 ไบต์

หมายเหตุ: Pyth อายุน้อยกว่าความท้าทายนี้มากดังนั้นคำตอบนี้จึงไม่มีสิทธิ์ชนะ

วิธีการที่ง่ายใช้oฟังก์ชั่นเพื่อให้ได้ระยะทางน้อยที่สุดและmaps aมันมากกว่ารายการ

mho.a-dNQvz

m    vz    Map over evaled first input and implicitly print
 ho Q      Minimal mapped over evaled second input
  .a-      Absolute difference
   d       Lambda param 1
   b       Lambda param 2

ลองมันออนไลน์ได้ที่นี่


@ Jakube โอ้ใช่ขอโทษ
Maltysen

2

TI-BASIC, 24

∟A+seq(min(∟B+i²∟A(N)),N,1,dim(∟A

ไม่เข้าใกล้ APL แต่ใช้ฟังก์ชั่นที่ทรงพลังน้อยกว่า - สิ่งนี้ไม่ใช้ฟังก์ชัน "เรียงตาม" หรือ "ดัชนีอย่างน้อย" ข้อเสียของ TI-BASIC ที่นี่คือการขาดฟังก์ชั่นเหล่านั้นและอาร์เรย์หลายมิติ

Ungolfed:

seq(       ,N,1,dim(∟A           #Sequence depending on the Nth element of list A
    ∟A(N)+min(   +0i)            #Number with minimum absolute value, add to ∟A(N)
              ∟B-∟A(N)           #Subtracts Nth element of ∟A from all elements of B

min (ฟังก์ชั่นมีสองพฤติกรรม: เมื่อใช้กับจำนวนจริงหรือรายการจะให้ค่าที่น้อยที่สุดอย่างไรก็ตามเมื่อใช้กับจำนวนหรือรายการที่ซับซ้อนก็ให้ค่าที่มีค่าสัมบูรณ์ที่เล็กที่สุดการเพิ่ม0iหรือทวีคูณโดยi^2ทำให้ล่าม ใช้พฤติกรรมที่สองเพื่อให้min(1,-2)ผลตอบแทน-2ในขณะที่ผลตอบแทนmin(1+0i,-2+0i)1


1

Fortran 90: 88

function f();integer::f(size(a));f(:)=[(b(minloc(abs(a(i)-b))),i=1,size(a))];endfunction

สิ่งนี้ต้องการให้แก้ไขcontainภายในโปรแกรมเต็มรูปแบบ:

program main
   real :: a(5), b(3)
   integer :: i(size(a))
   a = [10.1, 11.2, 12.3, 13.4, 9.5]
   b = [10, 12, 14]
   i = f()
   print*,i
 contains
   function f()
     integer :: f(size(a))
     f(:)=[(b(minloc(abs(a(i)-b))),i=1,size(a))]
   end function
end program main

เครื่องหมายวงเล็บเหลี่ยมจะประกาศอาร์เรย์ในขณะที่(...,i=)แทนการdoวนซ้ำโดยนัย ฉันจะคืนค่าของbองค์ประกอบที่a(i)-bถูกย่อให้เล็กสุด


1

Matlab: 48

f=@(a)B(abs(B-a)==min(abs(B-a)));C=arrayfun(f,A)

สันนิษฐานว่าAและBเป็น 1D การฝึกอบรมในพื้นที่ที่ผลสุดท้ายคือCในพื้นที่ทำงาน สิ่งนี้น่าจะใช้ได้ในอ็อกเทฟเช่นกัน การจัดทำดัชนีแบบมีเงื่อนไขทำให้การทำเช่นนี้เป็นเรื่องเล็กน้อย


0

C 144 163

#define f float
f T, *C, m;
f *q(f *A, f *B, int S, f s)
{
    if(m) 
        return abs(T - *A) - abs(T - *B);
    for ( 
        C = malloc(S * 4);
        m = S--;
        C[S] = *B
    ) 
        T = A[S], 
        qsort(B, s, 4, q);
    return C;
}

โอเค ... ฉันคิดว่ารหัสเล็กน้อยนี้ต้องการคำอธิบาย

ตอนแรกฉันพยายามทำงานด้วยสองระดับสำหรับวนรอบเพื่อค้นหาความแตกต่างขั้นต่ำและตั้งค่าปัจจุบันเป็นค่าขั้นต่ำของ B นั่นเป็นพื้นฐานมาก

สิ่งเดียวกันสามารถเข้าถึงได้ด้วยqsortและฟังก์ชันตัวเปรียบเทียบ ฉันจัดเรียง B ตามความแตกต่างแทนองค์ประกอบของ B มีฟังก์ชันมากเกินไปสำหรับอัลกอริธึมเล็กน้อย ดังนั้นตอนนี้ฟังก์ชั่น q มีจุดประสงค์สองประการ ในตอนแรกมันเป็นอัลกอริธึมที่สอง (เมื่อ qsort เรียกมันว่า) ตัวเปรียบเทียบ สำหรับการสื่อสารระหว่างสองรัฐฉันต้องประกาศกลม

mย่อมาจากไม่ว่าจะอยู่ในสถานะเปรียบเทียบหรือหนึ่งหลัก

ตัวอย่าง:

float A[] = {1.5, 5.6, 8.9, -33.1};
float B[] = {-20.1, 2.2, 10.3};
float *C;

C = q(A, B, sizeof(A)/sizeof(*A), sizeof(B)/sizeof(*B));
// C holds 2.2,2.2,10.3,-20.1

166/163 นับช่องว่างหรือไม่?
Kyle Kanos

ไม่แน่นอน ช่องว่างและบรรทัดใหม่มีไว้เพื่อให้เข้าใจง่าย
bebe

0

GolfScript, 49 ไบต์

หมายเหตุ: นี่เป็นวิธีแก้ปัญหาบางส่วน ฉันกำลังทำงานเพื่อทำให้เป็นโซลูชันที่สมบูรณ์

{{\.@\.[.,,\]zip@{[\~@-abs]}+%{~\;}$0=0==}%\;}:f;

ใช่. GolfScript รองรับจุดลอยตัว ลองที่นี่ ตัวอย่าง:

# B is [-20.1 2.2 10.3]
[-201 10 -1?*
22 10 -1?*
103 10 -1?*]

# A. No floating point numbers allowed here.
# This is because 1.5{}+ (where the 1.5 is a
# single floating point number, not 1.5,
# which would be 1 1 5) results in the block
# {1.5 }, which leads to 1 1 5 when executed
[1 5 9 -30]

เอาท์พุท:

[2.2 2.2 10.3 -20.1]

0

C # 262

โปรแกรมค้นหาความแตกต่างขั้นต่ำและประหยัดค่าที่ใกล้เคียงที่สุดจาก Array B. ฉันจะทำงานกอล์ฟในไม่ช้า

List<float> F(List<float> a, List<float> b)
{
List<float> c = new List<float>();
float diff,min;
int k;
for(int i=0; i<a.Count;i++)
{
diff=0;
min=1e6F;
k = 0;
for(int j=0; j<b.Count;j++)
{
diff = Math.Abs(a[i] - b[j]);
if (diff < min)
{
min = diff;
k = j;
}
}
c.Add(b[k]);
}
return c;
}

โปรแกรมเต็มพร้อมรหัสทดสอบ

using System;
using System.Collections.Generic;
public class JGolf
{
    static List<float> NearestValues(List<float> a, List<float> b)
    {
        List<float> c = new List<float>();
        float diff,min;
        int k;
        for(int i=0; i<a.Count;i++)
        {
            diff=0;
            min=1e6F;
            k = 0;
            for(int j=0; j<b.Count;j++)
            {
                diff = Math.Abs(a[i] - b[j]);
                if (diff < min)
                {
                    min = diff;
                    k = j;
                }
            }
            c.Add(b[k]);
        }
        return c;
    }

    public static void Main(string[] args)
    {
        List<float> A = RandF(8413);
        Console.WriteLine("A");
        Print(A);
        List<float> B = RandF(9448);
        Console.WriteLine("B");
        Print(B);

        List<float> d = JGolf.NearestValues(A, B);
        Console.WriteLine("d");
        Print(d);
        Console.ReadLine();
    }

    private static List<float> RandF(int seed)
    {
        Random r = new Random(seed);
        int n = r.Next(9) + 1;
        List<float> c = new List<float>();
        while (n-- > 0)
        {
            c.Add((float)r.NextDouble() * 100);
        }
        return c;
    }

    private static void Print(List<float> d)
    {
        foreach(float f in d)
        {
            Console.Write(f.ToString()+", ");
        }
    }
}

0

C #: 120

Linq ยอดเยี่ยม:

float[] t(float[] A, float[] B){return A.Select(a => B.First(b => Math.Abs(b-a) == B.Min(c=>Math.Abs(c-a)))).ToArray();}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.