Finde die nächste Nummer in einem bestimmten Array

21

Dies ist inspiriert von einem realen Problem, das ich hatte. Ich bin gespannt, ob es dafür einen klugen Weg gibt.

Sie erhalten zwei unsortierte Arrays, A und B, die jeweils eine beliebige Anzahl von Floats enthalten. A und B müssen nicht unbedingt gleich lang sein. Schreiben Sie eine Funktion, die die Elemente von A nacheinander aufnimmt und den nächsten Wert in Array B findet. Das Ergebnis muss in einem neuen Array enthalten sein.

Gewinnbedingung

Der kürzeste Code gewinnt (wie üblich).

Orhym
quelle
1
Rund auf die nächste ganze Zahl?
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳ Ich las das als "runde jedes Element von A zum nächsten Element von B"
John Dvorak
@JanDvorak: Nun, ich verstehe den Teil über die Rundungsrichtung, aber das Problem hat nicht angegeben, wie viele Stellen.
n̴̖̋h̷͉̃a̷̭̿h̷̭̿d̷̰̀ĥ̷̳
@ n̴̖̋h̴̖̋a̷̭̿h̷̭̿d̷̰̀ĥ̷̳ Runde bis zum nächsten Schwimmer. Die Antwort muss
Gleitkommazahlen
1
Werden die Arrays A und B sortiert?
Level River St

Antworten:

17

APL, 13-17

(21 Byte in UTF-8)

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

Wenn Sie wahres Lambda wollen (A als linkes Argument und B als rechtes):

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

Wie es funktioniert:

{...}¨ARuft die Lambda-Funktion {...}mit jedem A-Wert auf (anstatt mit A als Array aufzurufen) und sammelt die Ergebnisse in Arrays derselben Form

|⍵-B Berechnet die absoluten Differenzwerte zwischen dem Argument ⍵ und all in B (- ist Subtraktion, | ist abs).

↑⍋ Nimmt den Index des kleinsten Elements (⍋ sortiert das Array, das die Indizes zurückgibt, ↑ erhält das erste Element)

B[...] ruft nur Elemente nach Index (en) ab.

Die Lösung ist recht unkompliziert, obwohl sie die wunderbare Funktion der APL-Sortierfunktion verwendet, die den Permutationsvektor (die Indizes der sortierten Elemente im ursprünglichen Array) zurückgibt, anstatt das Array selbst zu sortieren.

Vovanium
quelle
Wie funktioniert das?
John Dvorak
In der Antwort erklärt
Vovanium
Wie um alles in der Welt weißt du, wie man das schreibt?
Martijn
Das ist wie Chinesisch schreiben. Für mich gibt es keinen großen Unterschied, ob ich fremde Wörter oder fremde Zeichen schreibe ...
Vovanium,
17

Mathematica - 17

#&@@@Nearest@A/@B

Wie funktioniert es? Ja, ich gebe zu, dass hier ein bisschen geschummelt wird, weil Mathematica die nächstgelegene Funktionalität eingebaut hat . Der Rest ist unkompliziert und befasst sich mit der Anordnung des Ergebnisses in einem 1D-Array. Es sieht nur wegen des zusätzlichen Aufwands, es kurz zu machen, hässlich aus.

Szabolcs
quelle
1
Ha! Herzlich willkommen! :)
Dr. belisarius
6

C # - 103 97 87 Bytes

Ich bin mir nicht ganz sicher, ob ich diese Frage richtig verstanden habe, aber hier ist trotzdem meine Lösung. Ich habe Listen anstelle von Arrays verwendet, weil ich damit kürzeren Code schreiben kann.

Ein Integer-Array ist kürzer als eine Integer-Liste.

Eingang:

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

Methode:

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

Ausgabe:

2, 22, 15, 49

Wenn meine Antwort nicht korrekt ist, hinterlassen Sie bitte einen Kommentar darunter.

EDIT: Wie @grax betonte, geht es jetzt um Floats. Deshalb möchte ich auch seine Antwort aufnehmen.

95 Bytes (Grax Antwort)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Tsavinho
quelle
Listen sind auch in Ordnung.
Orhym
1
Umbenennen itemin iund Sie
sparen
@ Schratt vielen Dank!
Tsavinho
3
1. Die Funktion sagt nicht ausdrücklich, dass der neue Wert zurückgegeben werden soll, aber ich denke, Sie sollten es tun. 2. Da die Frage nach float float[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
lautete,
@Grax Als ich meine erste Antwort schrieb, ging es bei der Frage nicht um Schwimmer. Da die Frage aktualisiert wurde, habe ich auch Ihre Antwort hinzugefügt. Vielen Dank.
Tsavinho
5

R, 41 Zeichen

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

Erläuterung:

outer(A,B,`-`)berechnet für jedes Element x von A die Differenz x-Bund gibt das Ergebnis als Matrix (der Dimension Länge (A) x Länge (B)) aus.
which.minwählt den Index der minimalen Zahl.
apply(x, 1, f)Wendet die Funktion fauf jede Matrixzeile an x.
So apply(abs(outer(A,B,`-`)),1,which.min)gibt die Indizes der minimalen absoluten Differenz zwischen jedem Element von A und die Elemente des Vektors B.

Verwendung:

> 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
quelle
5

CJam - 14

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

Der Hauptcode steht in der zweiten Zeile, der Rest dient der Verwendung der Standardeingabe und der hübschen Ausgabe.

Versuchen Sie es unter http://cjam.aditsu.net/

Erläuterung:

q~liest und bewertet die Eingabe
f{...}des Blocks für jedes Element der ersten Anordnung und dem nächsten Objekt (das das zweite Array ist) ausführt, die in einem Array um die Ergebnisse zu sammeln
{...}$den Block sortiert die zweite Anordnung mit einem Schlüssel für jeden Artikel zu berechnen ,
1$kopiert die aktuelle item vom ersten Array
-zsubtrahiert dann den absoluten Wert
0=nimmt den ersten Wert des sortierten Arrays (der mit dem minimalen Schlüssel)
\;verwirft das Item vom ersten Array
pdruckt die String-Darstellung des Ergebnisses

Beispiele (inspiriert von anderen Antworten):

Eingabe: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Ausgabe:[10 12 12 14 10]

Eingabe: [0 25 10 38] [3 22 15 49 2]
Ausgabe:[2 22 15 49]

aditsu
quelle
4

Javascript (E6) 54 56 59

Abstand minimieren. Verwenden Sie Quadrat anstelle von Bauchmuskeln, um Zeichen zu sparen. Algebra
bearbeiten ... Fix unbrauchbare Zuordnung
bearbeiten (Rest eines Tests ohne Funktionsdefinition)

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

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

Prüfung

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

Ergebnis: [10, 12, 12, 14, 10]

edc65
quelle
1
D=wird nicht benötigt, da mapein neues Array zurückgegeben wird. Alternative (gleiche Länge) (x,y)=>(x-=a)*x-(y-=a)*y
Sortierfunktion
4

Python 3.x - 55 Zeichen

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

aund bsind die Eingabearrays, und das gewünschte Array ist das Ergebnis des Ausdrucks.

Tal
quelle
Ich habe die Antwort bearbeitet, um sie zu einer Funktion zu machen, da für die Frage eine Funktion erforderlich ist.
user80551
3

Haskell, 55

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

Zuerst dachte ich verwenden minimumByund comparing, aber da diese nicht in Prelude sind, dauerte es eine Tonne Zeichen , sie zu qualifizieren. Habe auch die Quadraturidee aus anderen Antworten gestohlen, um einen Charakter abzuschaben.

YawarRaza7349
quelle
3

PowerShell - 44

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

Beispiel

Mit $aund $beingestellt auf:

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

Ausgabe ist

40.5, 10, 40.5, 10, 20, 30
Rynant
quelle
In diesem Beispiel können Sie floats verwenden, um zu verdeutlichen, dass auch floats behandelt werden
bebe
@bebe - Danke, aktualisiert, um das klar zu machen.
Rynant
-3 Bytes:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy
2

Rubin, 40

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

Wie die Python-Antwort, aber das Quadrieren ist ein wenig schärfer als ich es mir vorstellen kann, um einen absoluten Wert zu erhalten.

Histokrat
quelle
2

Pyth - 12 11 Bytes

Hinweis: Pyth ist viel jünger als diese Herausforderung, daher ist diese Antwort nicht gewinnberechtigt.

Einfache Methode, benutzt die Bestellfunktion o, um die minimale Distanz zu ermitteln und mdie Liste zu überschreiben 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

Probieren Sie es hier online aus .

Maltysen
quelle
@ Jakube oh yeah, sorry.
Maltysen
2

TI-BASIC, 24

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

Kommt nicht an APL heran, verwendet aber weniger leistungsfähige Funktionen - dies verwendet keine Funktion "sortiert nach" oder "Index der wenigsten". Der Nachteil von TI-BASIC ist das Fehlen dieser Funktionen und mehrdimensionaler Arrays.

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

Die min (Funktion zwei Verhalten hat: wenn mit reellen Zahlen oder Listen verwendet, gibt es den kleinsten Wert, aber wenn mit komplexen Zahlen oder Listen verwenden, wird den Wert mit dem kleinsten Absolutwert gibt Hinzufügen. 0iOder Multiplikation mit i^2Ursachen der Dolmetscher verwende das zweite Verhalten, also min(1,-2)kehre zurück, -2wohingegen min(1+0i,-2+0i)kehre zurück 1.

Lirtosiast
quelle
1

Fortran 90: 88

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

Dies setzt voraus, dass es containin einem vollständigen Programm bearbeitet wird:

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

Die eckigen Klammern deklarieren ein Array, während (...,i=)sie eine implizite doSchleife darstellen. Ich gebe dann den Wert zurück, bfür den das Element a(i)-bminimiert ist.

Kyle Kanos
quelle
1

Matlab: 48

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

Geht davon aus, dass Aund B1D Matrizen im Arbeitsbereich sind, ist endgültig Cin dem Arbeitsbereich. Dies würde wahrscheinlich auch in Octave funktionieren. Die bedingte Indizierung macht dies ziemlich trivial.

Godric Seher
quelle
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;
}

Okay ... Ich denke, dieser kleine Code muss erklärt werden.

Zuerst habe ich versucht, die Arbeit mit zwei Ebenen von for loop zu erledigen, um die minimale Differenz zu ermitteln und den aktuellen Wert auf min von B's Wert zu setzen. Das ist sehr einfach.

Dasselbe kann mit qsort und einer Komparatorfunktion erreicht werden. Ich sorge dafür, dass B nach dem Unterschied sortiert wird und nicht nach den Elementen von B. Zu viele Funktionen für einen so kleinen Algorithmus. Die Funktion q dient also nun zwei Zwecken. Erstens ist es der Algorithmus selbst, zweitens (wenn qsort ihn aufruft) ein Komparator. Für die Kommunikation zwischen den beiden Staaten musste ich Globals deklarieren.

m steht für, ob es im Komparatorzustand oder im Hauptzustand ist .

Beispiel:

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
quelle
Zählt der 166/163 das Leerzeichen oder nicht?
Kyle Kanos
Natürlich nicht. Leerzeichen und Zeilenumbrüche dienen dem besseren Verständnis.
Bebe
0

GolfScript, 49 Bytes

Hinweis: Dies ist eine Teillösung. Ich arbeite daran, daraus eine Komplettlösung zu machen

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

Ja. GolfScript unterstützt Gleitkommazahlen. Probieren Sie es hier aus . Beispiel:

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

Ausgabe:

[2.2 2.2 10.3 -20.1]
Justin
quelle
0

C # 262

Das Programm findet minimale Unterschiede und speichert den nächsten Wert von Array B. Ich werde in Kürze mit dem Golfen beginnen.

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

Volles Programm mit Testcode

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
quelle
0

C #: 120

Linq ist großartig:

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
quelle