Znajdź najbliższy numer w danej tablicy

21

Jest to inspirowane moim prawdziwym problemem na świecie. Jestem ciekawy, czy istnieje jakiś sprytny sposób na rozwiązanie tego problemu.

Otrzymujesz dwie nieposortowane tablice, A i B, każda zawierająca dowolną liczbę liczb zmiennoprzecinkowych. A i B niekoniecznie mają takie same długości. Napisz funkcję, która sekwencyjnie pobiera elementy A i znajduje najbliższą wartość w tablicy B. Wynik musi być zawarty w nowej tablicy.

Warunek wygranej

Najkrótszy kod wygrywa (jak zwykle).

Orhym
źródło
1
Zaokrąglić do najbliższej liczby całkowitej?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨dd Czytałem to jako „zaokrąglić każdy element A do najbliższego elementu B”
John Dvorak
@JanDvorak: Cóż, rozumiem część dotyczącą zaokrąglania kierunku, ale problem nie określał liczby cyfr.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨d̷̰̀ĥ̷̳ Zaokrąglij do najbliższego pływaka. Odpowiedź musi
wynikać z liczb zmiennoprzecinkowych
1
Czy tablice A i B zostaną posortowane?
Level River St

Odpowiedzi:

17

APL, 13 17

(21 bajtów w UTF-8)

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

Jeśli chcesz prawdziwą lambda (A jako lewy argument i B jako prawy):

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

Jak to działa:

{...}¨Awywołuje funkcję lambda {...}z każdą wartością A (zamiast wywoływać z A jako tablicą), zbierając wyniki do tablicy o tym samym kształcie

|⍵-B oblicza bezwzględne wartości różnicy między argumentem ⍵ a wszystkim w B (- to odejmowanie, | to abs).

↑⍋ pobiera indeks najmniejszego elementu (⍋ sortuje tablice zwracające indeksy, ↑ dostaje pierwszy element)

B[...] pobiera tylko elementy według indeksów.

Rozwiązanie jest dość jednoznaczne, chociaż wykorzystuje wspaniałą cechę funkcji sortującej APL zwracającej wektor permutacji (wskaźniki posortowanego elementu w oryginalnej tablicy) zamiast samej tablicy posortowanej.

Vovanium
źródło
Jak to działa?
John Dvorak,
Wyjaśniono w odpowiedzi
Vovanium
Skąd wiesz, jak to napisać?
Martijn
To jest jak pisanie po chińsku. Dla mnie nie ma wielkiej różnicy w pisaniu albo obcych słów, albo obcych znaków ...
Vovanium
17

Mathematica - 17

#&@@@Nearest@A/@B

Jak to działa? Tak, przyznaję, że jest tu trochę oszustwa, ponieważ Mathematica ma wbudowaną najbliższą funkcjonalność. Reszta jest prosta i dotyczy uporządkowania wyniku w tablicy 1D. Wygląda brzydko tylko z powodu dodatkowego wysiłku, aby go skrócić.

Szabolcs
źródło
1
Ha! Witamy! :)
Dr belisarius
6

C # - 103 97 87 bajtów

Nie jestem pewien, czy dobrze zrozumiałem to pytanie, ale oto moje rozwiązanie. Użyłem list zamiast tablic, ponieważ pozwala mi to pisać krótszy kod.

Tablica liczb całkowitych jest krótsza niż lista liczb całkowitych.

Wkład:

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

Metoda:

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

Wydajność:

2, 22, 15, 49

Jeśli moja odpowiedź jest nieprawidłowa, proszę zostawić komentarz poniżej.

EDYCJA: Jak zauważył @grax, pytanie dotyczy teraz pływaków. Dlatego chciałbym również dołączyć jego odpowiedź.

95 bajtów (odpowiedź Graxa)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
tsavinho
źródło
Listy też są w porządku.
Orhym
1
Zmień nazwę itemna, ia będziesz bezpieczny 6 dodatkowych postaci;)
Aschratt
@Aschratt dziękuję bardzo!
tsavinho,
3
1. Funkcja nie mówi specjalnie o zwróceniu nowej wartości, ale myślę, że powinieneś. 2. Ponieważ pytanie dotyczyło float, myślę, że powinieneś użyć floatfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32,
@Grax Gdy napisałem pierwszą odpowiedź, pytanie nie dotyczyło pływaków. Ponieważ pytanie zostało zaktualizowane, zamieściłem również twoją odpowiedź. Dziękuję Ci bardzo.
tsavinho
5

R, 41 znaków

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

Wyjaśnienie:

outer(A,B,`-`)oblicza dla każdego elementu x różnicy x-Bi wyprowadza wynik jako macierz (o długości wymiarowej (A) x długości (B)).
which.minwybiera indeks liczby minimalnej.
apply(x, 1, f)stosuje funkcję fw każdym rzędzie macierzy x. Zwraca
więc apply(abs(outer(A,B,`-`)),1,which.min)wskaźniki minimalnej absolutnej różnicy między każdym elementem A i elementami wektora B.

Stosowanie:

> 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
źródło
5

CJam - 14

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

Główny kod znajduje się w drugim wierszu, reszta służy do użycia standardowego wejścia i ładnego wyjścia.

Wypróbuj na http://cjam.aditsu.net/

Wyjaśnienie:

q~odczytuje i ocenia dane wejściowe
f{...}wykonuje blok dla każdego elementu pierwszej tablicy i następnego obiektu (którym jest druga tablica), zbieranie wyników w tablicy
{...}$sortuje drugą tablicę za pomocą bloku do obliczenia klucza dla każdego elementu
1$kopiuje bieżący element z pierwszej tablicy
-zodejmuje następnie przyjmuje wartość bezwzględną
0=bierze pierwszą wartość z posortowanej tablicy (ta z minimalnym kluczem)
\;odrzuca element z pierwszej tablicy
pdrukuje reprezentację ciągu wyniku

Przykłady (inspirowane innymi odpowiedziami):

Wejście: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Wyjście:[10 12 12 14 10]

Wejście: [0 25 10 38] [3 22 15 49 2]
Wyjście:[2 22 15 49]

aditsu
źródło
4

JavaScript (E6) 54 56 59

Minimalizuj odległość. Używając kwadratu zamiast abs, po prostu oszczędzaj znaki.
Edytuj algebrę ...
Edytuj poprawkę niepotrzebne przypisanie (pozostała część testu bez definicji funkcji)

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

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

Test

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

Wynik: [10, 12, 12, 14, 10]

edc65
źródło
1
D=nie jest potrzebne, ponieważ mapzwraca nową tablicę. Alternatywna funkcja sortowania (o tej samej długości):(x,y)=>(x-=a)*x-(y-=a)*y
nderscore
4

Python 3.x - 55 znaków

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

ai bsą tablicami wejściowymi, a pożądana tablica jest wynikiem wyrażenia.

Tal
źródło
Zredagowałem odpowiedź, aby stała się funkcją, ponieważ pytanie wymaga funkcji.
user80551
3

Haskell, 55

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

Na początku myślałem, używać minimumByi comparing, ale od tych, którzy nie są w Prelude, zajęło mnóstwo znaków je zakwalifikować. Ukradłem również pomysł kwadratu z kilku innych odpowiedzi, aby ogolić postać.

YawarRaza7349
źródło
3

PowerShell - 44

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

Przykład

Za pomocą $ai $bustawić na:

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

Dane wyjściowe to

40.5, 10, 40.5, 10, 20, 30
Rynant
źródło
możesz użyć pływaków w tym przykładzie, aby było jasne, że obsługuje również pływaki
bebe
@bebe - Dziękujemy, zaktualizowano, aby to wyjaśnić.
Rynant
-3 bajty:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy
2

Ruby, 40

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

Taki sam jak odpowiedź w Pythonie, ale kwadratowanie jest trochę bardziej skomplikowane niż jakikolwiek sposób, w jaki mógłbym wziąć wartość bezwzględną.

histocrat
źródło
2

Pyth - 12 11 bajtów

Uwaga: Pyth jest znacznie młodszy od tego wyzwania, więc ta odpowiedź nie kwalifikuje się do wygrania.

Prosta metoda, wykorzystuje ofunkcję porządku, aby uzyskać minimalną odległość i maps to na liście 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

Wypróbuj online tutaj .

Maltysen
źródło
@Jakube o tak, przepraszam.
Maltysen
2

TI-BASIC, 24

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

Nie jest zbliżony do APL, ale używa mniej wydajnych funkcji - nie używa to funkcji „posortowanej według” lub „indeksu najmniej”. Wadą TI-BASIC jest tutaj brak tych funkcji i tablic wielowymiarowych.

Nie golfowany:

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

Funkcja min (ma dwa zachowania: gdy jest używana z liczbami rzeczywistymi lub listami, daje najmniejszą wartość; jednak gdy jest używana z liczbami zespolonymi lub listami, daje wartość o najmniejszej wartości bezwzględnej. Dodanie 0ilub pomnożenie przez i^2powoduje, że interpreter użyj drugiego zachowania, więc min(1,-2)zwraca, -2a min(1+0i,-2+0i)zwraca 1.

lirtosiast
źródło
1

Fortran 90: 88

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

Wymaga to containedycji w pełnym programie:

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

Nawiasy kwadratowe deklarują tablicę, podczas gdy (...,i=)reprezentują domyślną dopętlę; Następnie zwracam wartość, bdla której element a(i)-bjest zminimalizowany.

Kyle Kanos
źródło
1

Matlab: 48

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

Zakłada, że Ai Bsą matrycami 1D w obszarze roboczym, końcowy wynik znajduje się Cw obszarze roboczym. Prawdopodobnie działałoby to również w Octave. Indeksowanie warunkowe czyni to dość trywialnym.

Godric Seer
źródło
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;
}

Dobra ... Myślę, że ten mały kod wymaga wyjaśnienia.

Na początku próbowałem wykonać zadanie z dwoma poziomami pętli for, znajdując różnicę minimalną i ustawiając bieżącą wartość na min wartości B. To bardzo proste.

To samo można osiągnąć dzięki qsort i funkcji komparatora. Robię to sortując B według różnicy zamiast elementów B. Zbyt wiele funkcji dla tak małego algorytmu. Zatem funkcja q służy teraz dwóm celom. Na początku jest to sam algorytm, a po drugie (gdy qsort go wywołuje) komparator. Do komunikacji między dwoma stanami musiałem ogłosić globale.

m oznacza, czy jest w stanie porównawczym, czy głównym .

przykład:

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
źródło
Czy 166/163 liczy białe znaki, czy nie?
Kyle Kanos
Oczywiście nie. Spacje i znaki nowej linii ułatwiają zrozumienie.
bebe
0

GolfScript, 49 bajtów

Uwaga: jest to częściowe rozwiązanie. Pracuję nad tym, aby było to kompletne rozwiązanie

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

Tak. GolfScript obsługuje zmiennoprzecinkowe. Wypróbuj tutaj . Przykład:

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

Wydajność:

[2.2 2.2 10.3 -20.1]
Justin
źródło
0

C # 262

Program znajduje minimalne różnice i zapisuje najbliższą wartość z tablicy B. Niedługo będę pracował nad golfem.

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

Pełny program z kodem testowym

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
źródło
0

C #: 120

Linq jest niesamowity:

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();}
DL
źródło