Tìm số gần nhất trong một mảng nhất định


21

Điều này được lấy cảm hứng từ một vấn đề thế giới thực mà tôi đã có. Tôi tò mò muốn xem liệu có cách nào thông minh để làm điều này không.

Bạn được cung cấp hai mảng chưa được sắp xếp là A và B, mỗi mảng chứa một số lượng float tùy ý. A và B không nhất thiết phải có cùng độ dài. Viết hàm lấy các phần tử của A một cách tuần tự và tìm giá trị gần nhất trong mảng B. Kết quả phải được chứa trong một mảng mới.

Điều kiện thắng

Mã ngắn nhất sẽ thắng (như thường lệ).


1
Làm tròn đến số nguyên gần nhất?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Tôi đọc rằng "làm tròn từng phần tử của A đến phần tử B gần nhất"
John Dvorak

@JanDvorak: Chà, tôi hiểu phần về hướng làm tròn, nhưng vấn đề không chỉ rõ có bao nhiêu chữ số.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Làm tròn đến phao gần nhất. Câu trả lời phải xuất ra số float từ mảng / danh sách B.
Orhym

1
Mảng A và B sẽ được sắp xếp?
Cấp sông St

Câu trả lời:


17

APL, 13 17

(21 byte trong UTF-8)

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

Nếu bạn muốn lambda đúng (A là đối số bên trái và B là bên phải):

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

Làm thế nào nó hoạt động:

{...}¨Agọi hàm lambda {...}với mọi giá trị A (thay vì gọi A là mảng), thu thập kết quả thành mảng có cùng hình dạng

|⍵-B tính các giá trị tuyệt đối của sự khác biệt giữa đối số và tất cả trong B (- là phép trừ, | là abs).

↑⍋ lấy chỉ mục của phần tử nhỏ nhất (⍋ sắp xếp các chỉ mục trả về mảng, ↑ lấy phần tử đầu tiên)

B[...] chỉ là tìm nạp các phần tử theo chỉ mục (es).

Giải pháp khá rõ ràng, tuy nhiên, nó sử dụng tính năng tuyệt vời của hàm sắp xếp của APL trả về vectơ hoán vị (các chỉ số của phần tử được sắp xếp trong mảng ban đầu) thay vì chính mảng được sắp xếp.


Cái này hoạt động ra sao?
John Dvorak

Giải thích trong câu trả lời
Vovanium

Làm thế nào trên trái đất bạn biết làm thế nào để viết này?
Martijn

Điều này giống như viết tiếng Trung Quốc. Đối với tôi, không có sự khác biệt lớn khi viết từ người ngoài hành tinh hoặc nhân vật ngoài hành tinh ...
Vovanium

17

Toán học - 17

#&@@@Nearest@A/@B

Làm thế nào nó hoạt động? Vâng, tôi thừa nhận rằng có một chút gian lận ở đây vì Mathicala đã tích hợp chức năng gần nhất . Phần còn lại là đơn giản và liên quan đến việc sắp xếp kết quả trong mảng 1D. Nó trông xấu xí chỉ vì nỗ lực thêm để làm cho nó ngắn.


1
Hà! Chào mừng bạn :)
Tiến sĩ belisarius

6

C # - 103 97 87 byte

Tôi không chắc lắm nếu tôi hiểu chính xác câu hỏi này nhưng dù sao đây cũng là giải pháp của tôi. Tôi đã sử dụng Danh sách thay vì mảng, vì nó cho phép tôi viết mã ngắn hơn.

Một mảng số nguyên ngắn hơn một danh sách số nguyên.

Đầu vào:

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

Phương pháp:

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

Đầu ra:

2, 22, 15, 49

Nếu câu trả lời của tôi không chính xác, xin vui lòng để lại nhận xét bên dưới nó.

EDIT: AS @grax chỉ ra, câu hỏi bây giờ là về phao. Vì vậy, tôi cũng muốn bao gồm câu trả lời của anh ấy.

95 byte (câu trả lời của Grax)

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

Danh sách cũng tốt.
Orhym

1
Đổi tên itemthành ivà bạn sẽ an toàn thêm 6 ký tự;)
Aschratt

@Aschratt cảm ơn bạn rất nhiều!
tsavinho

3
1. Hàm không nói cụ thể để trả về giá trị mới, nhưng tôi nghĩ bạn nên làm vậy. 2. Vì câu hỏi được gọi là float, tôi nghĩ bạn nên sử dụng floatfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32

@Grax Khi tôi viết câu trả lời đầu tiên của mình, câu hỏi không phải là về phao. Vì câu hỏi đã được cập nhật, tôi cũng bao gồm câu trả lời của bạn. Cảm ơn nhiều.
tsavinho

5

R, 41 ký tự

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

Giải trình:

outer(A,B,`-`)tính toán cho mỗi phần tử x của A sự khác biệt x-Bvà đưa ra kết quả dưới dạng ma trận (có chiều dài (A) x chiều dài (B)).
which.minchọn chỉ số của số lượng tối thiểu.
apply(x, 1, f)áp dụng hàm ftrên mỗi hàng của ma trận x.
Vì vậy, apply(abs(outer(A,B,`-`)),1,which.min)trả về các chỉ số của sự khác biệt tuyệt đối tối thiểu giữa mỗi phần tử của A và các phần tử của vectơ B.

Sử dụng:

> 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

Mã chính nằm trên dòng thứ hai, phần còn lại là để sử dụng đầu vào tiêu chuẩn và đầu ra đẹp.

Dùng thử tại http://cjam.aditsu.net/

Giải trình:

q~đọc và đánh giá đầu vào
f{...}thực thi khối cho từng phần tử của mảng đầu tiên và đối tượng tiếp theo (là mảng thứ hai), thu thập kết quả trong một mảng
{...}$sắp xếp mảng thứ hai bằng cách sử dụng khối để tính một khóa cho mỗi mục
1$sao chép dòng mục từ
-zphép trừ mảng đầu tiên sau đó lấy giá trị tuyệt đối
0=lấy giá trị đầu tiên của mảng được sắp xếp (mảng có khóa tối thiểu)
\;loại bỏ mục từ mảng đầu tiên
pin biểu diễn chuỗi kết quả

Ví dụ (lấy cảm hứng từ các câu trả lời khác):

Đầu vào: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Đầu ra:[10 12 12 14 10]

Đầu vào: [0 25 10 38] [3 22 15 49 2]
Đầu ra:[2 22 15 49]


4

Javascript (E6) 54 56 59

Giảm thiểu khoảng cách. Sử dụng hình vuông thay vì abs chỉ để tiết kiệm ký tự.
Chỉnh sửa đại số ...
Chỉnh sửa sửa bài tập vô dụng (phần còn lại của bài kiểm tra với định nghĩa hàm)

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

Kiểm tra

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

Kết quả: [10, 12, 12, 14, 10]


1
D=không cần thiết, vì maptrả về một mảng mới. Chức năng sắp xếp thay thế (cùng chiều dài):(x,y)=>(x-=a)*x-(y-=a)*y
nderscore

4

Python 3.x - 55 ký tự

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

ablà các mảng đầu vào và mảng mong muốn là kết quả của biểu thức.


Tôi đã chỉnh sửa câu trả lời để biến nó thành một hàm vì câu hỏi yêu cầu một hàm.
dùng80551

3

Haskell, 55

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

Lúc đầu, tôi nghĩ sẽ sử dụng minimumBycomparing, nhưng vì những thứ đó không có trong Prelude, nên phải mất rất nhiều nhân vật để đủ điều kiện cho họ. Cũng đánh cắp ý tưởng bình phương từ một số câu trả lời khác để cạo sạch một nhân vật.


3

PowerShell - 44

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

Thí dụ

Với $a$bđặt thành:

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

Đầu ra là

40.5, 10, 40.5, 10, 20, 30

bạn có thể sử dụng phao nổi trong ví dụ này để làm cho nó rõ ràng nó xử lý nổi quá
bebe

@bebe - Cảm ơn, cập nhật để làm rõ điều đó.
Rynant

-3 byte:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy 23/12/18

2

Hồng ngọc, 40

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

Giống như câu trả lời của Python, nhưng bình phương hơi phức tạp hơn bất kỳ cách nào tôi có thể nghĩ ra để lấy giá trị tuyệt đối.


2

Bình thường - 12 11 byte

Lưu ý: Pyth trẻ hơn nhiều so với thử thách này, vì vậy câu trả lời này không đủ điều kiện để giành chiến thắng.

Phương pháp đơn giản, sử dụng ochức năng đặt hàng để có được khoảng cách tối thiểu và maps trên danh sách 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

Hãy thử trực tuyến tại đây .


@Jakube oh yeah, xin lỗi.
Maltysen

2

TI-BASIC, 24

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

Không đến gần với APL, nhưng sử dụng các hàm ít mạnh hơn-- điều này không sử dụng chức năng "được sắp xếp theo" hoặc "chỉ số ít nhất". Nhược điểm của TI-BASIC ở đây là thiếu các chức năng và mảng đa chiều.

Ung dung:

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

Hàm min (hàm có hai hành vi: khi được sử dụng với số hoặc danh sách thực, nó cho giá trị nhỏ nhất; tuy nhiên, khi được sử dụng với số hoặc danh sách phức, nó mang lại giá trị với giá trị tuyệt đối nhỏ nhất. Thêm 0ihoặc nhân với i^2trình thông dịch sử dụng hành vi thứ hai, vì vậy min(1,-2)trả về -2trong khi min(1+0i,-2+0i)trả về 1.


1

Pháo đài 90: 88

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

Điều này đòi hỏi nó phải được chỉnh sửa containtrong một chương trình đầy đủ:

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

Các dấu ngoặc vuông khai báo một mảng trong khi (...,i=)biểu thị một dovòng lặp ngụ ý ; Sau đó tôi trả về giá trị của bphần tử nào a(i)-bđược giảm thiểu.


1

Matlab: 48

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

Giả sử rằng ABlà ma trận 1D trong không gian làm việc, kết quả cuối cùng là Ctrong không gian làm việc. Điều này có khả năng cũng sẽ làm việc trong Octave là tốt. Lập chỉ mục có điều kiện làm cho việc này khá tầm thường.


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

Được rồi ... Tôi nghĩ rằng mã nhỏ này cần giải thích.

Lúc đầu, tôi đã cố gắng thực hiện công việc với hai cấp độ vòng lặp để tìm chênh lệch tối thiểu và đặt giá trị hiện tại thành tối thiểu của giá trị B. Điều đó rất cơ bản.

Điều tương tự có thể đạt được với qsort và chức năng so sánh. Tôi làm cho nó sắp xếp B theo sự khác biệt thay vì các yếu tố của B. Quá nhiều chức năng cho một thuật toán nhỏ như vậy. Vì vậy, chức năng q bây giờ phục vụ hai mục đích. Đầu tiên, nó là thuật toán, thứ hai (khi qsort gọi nó) một bộ so sánh. Để liên lạc giữa hai quốc gia, tôi đã phải tuyên bố toàn cầu.

m là viết tắt của nó cho dù nó ở trạng thái so sánh hay chính .

thí dụ:

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

Liệu 166/163 có tính khoảng trắng hay không?
Kyle Kanos

Tất nhiên là không. Không gian và dòng mới là để dễ hiểu.
bebe

0

GolfScript, 49 byte

Lưu ý: đây là một giải pháp một phần. Tôi đang làm việc để làm cho nó một giải pháp hoàn chỉnh

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

Vâng. GolfScript không hỗ trợ điểm nổi. Hãy thử nó ở đây . Thí dụ:

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

Đầu ra:

[2.2 2.2 10.3 -20.1]

0

C # 262

Chương trình tìm thấy sự khác biệt tối thiểu và lưu giá trị gần nhất từ ​​Mảng B. Tôi sẽ sớm chơi golf.

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

Chương trình đầy đủ với mã kiểm tra

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 thật tuyệt vời:

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();}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.