Temukan nomor terdekat dalam array yang diberikan

21

Ini terinspirasi oleh masalah dunia nyata yang saya miliki. Saya ingin tahu apakah ada cara cerdas untuk melakukannya.

Anda diberi dua array yang tidak disortir, A dan B, masing-masing berisi jumlah float yang sewenang-wenang. A dan B tidak harus memiliki panjang yang sama. Tulis fungsi yang mengambil elemen-elemen A secara berurutan dan temukan nilai terdekat dalam array B. Hasilnya harus dimuat dalam array baru.

Kondisi menang

Kode terpendek menang (seperti biasa).

Orym
sumber
1
Membulatkan ke bilangan bulat terdekat?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Saya membaca itu sebagai "putaran setiap elemen A ke elemen B terdekat"
John Dvorak
@ JanDvorak: Yah, saya mengerti bagian tentang arah pembulatan, tetapi masalahnya tidak menentukan berapa banyak digit.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Putaran ke pelampung terdekat. Jawabannya harus keluaran mengapung dari array / daftar B.
Orhym
1
Apakah array A dan B akan disortir?
Level River St

Jawaban:

17

APL, 13 17

(21 byte dalam UTF-8)

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

Jika Anda ingin benar lambda (A sebagai argumen kiri dan B sebagai kanan):

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

Bagaimana itu bekerja:

{...}¨Amemanggil fungsi lambda {...}dengan setiap nilai A (alih-alih memanggil dengan array A), mengumpulkan hasil ke array dengan bentuk yang sama

|⍵-B menghitung nilai absolut dari perbedaan antara argumen ⍵ dan semua dalam B (- adalah pengurangan, | adalah abs).

↑⍋ mengambil indeks elemen terkecil (⍋ macam indeks pengembalian array, ↑ dapatkan elemen pertama)

B[...] hanya mengambil elemen berdasarkan indeks.

Solusinya cukup lurus ke depan, meskipun menggunakan fitur luar biasa dari fungsi sortasi APL yang mengembalikan vektor permutasi (indeks elemen yang diurutkan dalam array asli) daripada array yang diurutkan sendiri.

Vovanium
sumber
Bagaimana cara kerjanya?
John Dvorak
Dijelaskan dalam jawaban
Vovanium
Bagaimana kamu bisa menulis ini?
Martijn
Ini seperti menulis bahasa Cina. Bagi saya, tidak ada perbedaan besar menulis kata-kata asing atau karakter alien ...
Vovanium
17

Mathematica - 17

#&@@@Nearest@A/@B

Bagaimana cara kerjanya? Ya, saya akui ada sedikit kecurangan di sini karena Mathematica memiliki fungsi terdekat yang ada di dalamnya . Sisanya mudah dan berkaitan dengan mengatur hasilnya dalam array 1D. Itu terlihat jelek hanya karena upaya ekstra untuk membuatnya pendek.

Szabolcs
sumber
1
Ha! Selamat datang! :)
Dr. belisarius
6

C # - 103 97 87 Bytes

Saya tidak begitu yakin apakah saya memahami pertanyaan ini dengan benar tetapi ini solusinya. Saya menggunakan Daftar daripada array, karena memungkinkan saya untuk menulis kode yang lebih pendek.

Array integer lebih pendek dari daftar integer.

Memasukkan:

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

Metode:

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

Keluaran:

2, 22, 15, 49

Jika jawaban saya tidak benar, silakan tinggalkan komentar di bawahnya.

EDIT: AS @grax menunjukkan, pertanyaannya sekarang tentang mengapung. Karena itu saya ingin memasukkan jawabannya juga.

95 Bytes (jawaban Grax)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
tsavinho
sumber
Daftar juga baik-baik saja.
Orhym
1
Ganti nama itemmenjadi idan Anda akan mengamankan 6 karakter tambahan;)
Aschratt
@ Asrat terima kasih banyak!
tsavinho
3
1. Fungsi tidak secara khusus mengatakan untuk mengembalikan nilai baru, tetapi saya pikir Anda harus melakukannya. 2. Karena pertanyaannya adalah float, saya pikir Anda harus menggunakan floatfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32
@ Galx Ketika saya menulis jawaban pertama saya, pertanyaannya bukan tentang mengapung. Karena pertanyaan telah diperbarui, saya memasukkan jawaban Anda juga. Terima kasih banyak.
tsavinho
5

R, 41 karakter

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

Penjelasan:

outer(A,B,`-`)menghitung untuk setiap elemen x dari A perbedaan x-Bdan mengeluarkan hasilnya sebagai matriks (panjang dimensi (A) x panjang (B)).
which.minmemilih indeks dari angka minimal.
apply(x, 1, f)menerapkan fungsi fpada setiap baris matriks x.
Jadi apply(abs(outer(A,B,`-`)),1,which.min)mengembalikan indeks perbedaan absolut minimal antara setiap elemen A dan elemen vektor B.

Pemakaian:

> 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
plannapus
sumber
5

CJam - 14

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

Kode utama ada di baris kedua, sisanya untuk menggunakan input standar dan output cantik.

Cobalah di http://cjam.aditsu.net/

Penjelasan:

q~membaca dan mengevaluasi input
f{...}mengeksekusi blok untuk setiap elemen dari array pertama dan objek berikutnya (yang merupakan array kedua), mengumpulkan hasil dalam array
{...}$mengurutkan array kedua menggunakan blok untuk menghitung kunci untuk setiap item
1$menyalin salinan saat ini item dari array pertama
-zmengurangi kemudian mengambil nilai absolut
0=mengambil nilai pertama dari array yang diurutkan (yang dengan kunci minimum)
\;membuang item dari array pertama
pmencetak representasi string dari hasil

Contoh (terinspirasi dari jawaban lain):

Input: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Keluaran:[10 12 12 14 10]

Input: [0 25 10 38] [3 22 15 49 2]
Keluaran:[2 22 15 49]

aditsu
sumber
4

Javascript (E6) 54 56 59

Minimalkan jarak. Menggunakan persegi alih-alih abs hanya menghemat chars.
Edit aljabar ...
Edit perbaiki tugas yang tidak berguna (sisa tes tanpa definisi fungsi)

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

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

Uji

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

Hasil: [10, 12, 12, 14, 10]

edc65
sumber
1
D=tidak diperlukan, karena mapmengembalikan array baru. Fungsi sortir alternatif (sama panjang):(x,y)=>(x-=a)*x-(y-=a)*y
nderscore
4

Python 3.x - 55 karakter

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

adan badalah array input, dan array yang diinginkan adalah hasil ekspresi.

Tal
sumber
Saya mengedit jawaban untuk membuatnya berfungsi karena pertanyaannya membutuhkan fungsi.
user80551
3

Haskell, 55

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

Pada awalnya, saya berpikir untuk menggunakan minimumBydan comparing, tetapi karena mereka tidak di Prelude, butuh satu ton karakter untuk memenuhi syarat mereka. Juga mencuri ide kuadrat dari beberapa jawaban lain untuk mengurangi karakter.

YawarRaza7349
sumber
3

PowerShell - 44

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

Contoh

Dengan $adan $bdiatur ke:

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

Output adalah

40.5, 10, 40.5, 10, 20, 30
Rynant
sumber
Anda bisa menggunakan pelampung dalam contoh untuk membuatnya jelas itu menangani pelampung juga
bebe
@ bebe - Terima kasih, diperbarui untuk memperjelasnya.
Rynant
-3 byte:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy
2

Ruby, 40

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

Sama seperti jawaban Python, tetapi mengkuadratkan sedikit terser daripada cara apa pun yang bisa saya pikirkan untuk mengambil nilai absolut.

histokrat
sumber
2

Pyth - 12 11 byte

Catatan: Pyth jauh lebih muda dari tantangan ini, jadi jawaban ini tidak memenuhi syarat untuk menang.

Metode sederhana, menggunakan ofungsi pesanan untuk mendapatkan jarak minimal dan mmenambahkannya pada daftar 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

Cobalah online di sini .

Maltysen
sumber
@ Jakube oh ya, maaf.
Maltysen
2

TI-BASIC, 24

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

Tidak mendekati APL, tetapi menggunakan fungsi yang kurang kuat - ini tidak menggunakan fungsi "diurutkan berdasarkan" atau "indeks paling tidak". Kerugian dari TI-BASIC di sini adalah kurangnya fungsi dan array multidimensi.

Tidak Disatukan:

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 (fungsi memiliki dua perilaku: ketika digunakan dengan bilangan real atau daftar, ia memberikan nilai terkecil; namun, ketika digunakan dengan bilangan atau daftar kompleks, ia memberikan nilai dengan nilai absolut terkecil. Menambah 0iatau mengalikan dengan i^2menyebabkan penerjemah menjadi gunakan perilaku kedua, jadi min(1,-2)kembalikan -2sedangkan min(1+0i,-2+0i)pengembalian 1.

lirtosiast
sumber
1

Fortran 90: 88

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

Ini mengharuskannya containdiedit dalam program lengkap:

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

Kurung kurawal mendeklarasikan array sementara (...,i=)mewakili doloop tersirat ; Saya kemudian mengembalikan nilai belemen a(i)-byang diminimalkan.

Kyle Kanos
sumber
1

Matlab: 48

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

Mengasumsikan bahwa Adan Badalah matriks 1D di ruang kerja, hasil akhir adalah Cdi ruang kerja. Ini kemungkinan juga akan bekerja di Octave. Pengindeksan bersyarat membuat melakukan ini cukup sepele.

Pelihat Godric
sumber
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;
}

Oke ... Saya rasa kode kecil ini perlu penjelasan.

Pada awalnya saya mencoba melakukan pekerjaan dengan dua level untuk loop menemukan perbedaan min dan mengatur nilai saat ini ke nilai min B. Itu sangat mendasar.

Hal yang sama dapat dicapai dengan fungsi qsort dan komparator. Saya membuatnya menjadi B berdasarkan perbedaan, bukan elemen B. Terlalu banyak fungsi untuk algoritma sekecil itu. Jadi fungsi q sekarang melayani dua tujuan. Pada awalnya, ini adalah algoritma itu sendiri, kedua (ketika qsort menyebutnya) komparator. Untuk komunikasi antara kedua negara, saya harus menyatakan global.

m adalah singkatan dari apakah itu dalam keadaan komparator atau yang utama .

contoh:

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
bebe
sumber
Apakah 166/163 menghitung spasi putih atau tidak?
Kyle Kanos
Tentu saja tidak. Ruang dan baris baru adalah untuk memudahkan pemahaman.
bebe
0

GolfScript, 49 byte

Catatan: ini adalah solusi parsial. Saya sedang berupaya menjadikannya solusi yang lengkap

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

Iya nih. GolfScript mendukung floating point. Cobalah di sini . Contoh:

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

Keluaran:

[2.2 2.2 10.3 -20.1]
Justin
sumber
0

C # 262

Program menemukan perbedaan minimal dan menyimpan nilai terdekat dari Array B. Saya akan bekerja di golf segera.

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

Program lengkap dengan kode uji

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()+", ");
        }
    }
}
bacchusbeale
sumber
0

C #: 120

Linq mengagumkan:

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();}
DLeh
sumber