Encuentra el número más cercano en una matriz dada

21

Esto está inspirado en un problema del mundo real que tuve. Tengo curiosidad por ver si hay alguna manera inteligente de hacer esto.

Se le dan dos matrices sin clasificar, A y B, cada una con un número arbitrario de flotantes. A y B no necesariamente tienen las mismas longitudes. Escriba una función que tome los elementos de A secuencialmente y encuentre el valor más cercano en la matriz B. El resultado debe estar contenido en una nueva matriz.

Condición de victoria

El código más corto gana (como de costumbre).

Orhym
fuente
1
Redondear al entero más cercano?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Lo leí como "redondear cada elemento de A al elemento más cercano de B"
John Dvorak
@ JanDvorak: Bueno, entiendo la parte sobre la dirección del redondeo, pero el problema no especificó cuántos dígitos.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Redondear al flotador más cercano. La respuesta tiene que salir flotantes de la matriz / lista B.
Orhym
1
¿Se ordenarán las matrices A y B?
Level River St

Respuestas:

17

APL, 13 17

(21 bytes en UTF-8)

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

Si quieres una verdadera lambda (A como argumento izquierdo y B como derecho):

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

Cómo funciona:

{...}¨Ainvoca la función lambda {...}con cada valor A (en lugar de invocar con A como matriz), reuniendo los resultados en una matriz de la misma forma

|⍵-B calcula valores absolutos de diferencia entre el argumento ⍵ y todo en B (- es resta, | es abs).

↑⍋ toma el índice del elemento mínimo (⍋ ordena la matriz que devuelve índices, ↑ obtiene el primer elemento)

B[...] solo busca elementos por índice (es).

La solución es bastante sencilla, aunque utiliza una característica maravillosa de la función de clasificación de APL que devuelve el vector de permutación (índices del elemento ordenado en la matriz original) en lugar de la matriz ordenada en sí.

Vovanium
fuente
¿Como funciona esto?
John Dvorak
Explicado en respuesta
Vovanium
¿Cómo sabes escribir esto?
Martijn
Esto es como escribir en chino. Para mí, no hay una gran diferencia al escribir palabras extrañas o caracteres extraños ...
Vovanium
17

Mathematica - 17

#&@@@Nearest@A/@B

¿Como funciona? Sí, admito que hay un poco de trampa aquí porque Mathematica tiene la funcionalidad más cercana incorporada. El resto es sencillo y se ocupa de organizar el resultado en una matriz 1D. Se ve feo solo por el esfuerzo extra de hacerlo corto.

Szabolcs
fuente
1
¡Decir ah! ¡Bienvenido! :)
Dr. belisarius
6

C# - 103 97 87 Bytes

No estoy muy seguro de haber entendido esta pregunta correctamente, pero de todos modos esta es mi solución. Usé Listas en lugar de matrices, porque me permite escribir código más corto.

Una matriz de enteros es más corta que una lista de enteros.

Entrada:

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

Método:

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

Salida:

2, 22, 15, 49

Si mi respuesta no es correcta, deje un comentario debajo.

EDITAR: Como señaló @grax, la pregunta ahora es sobre flotadores. Por lo tanto, me gustaría incluir su respuesta también.

95 bytes (respuesta de Grax)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
tsavinho
fuente
Las listas también están bien.
Orhym
1
Cambiar el nombre itemde iy usted será seguro 6 caracteres adicionales;)
Aschratt
@Aschratt muchas gracias!
tsavinho
3
1. La función no dice específicamente que devuelva el nuevo valor, pero creo que debería hacerlo. 2. Dado que la pregunta requería flotación, creo que debería usar flotaciónfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32
@Grax Mientras escribía mi primera respuesta, la pregunta no era sobre carrozas. Como la pregunta se ha actualizado, también incluí tu respuesta. Muchas gracias.
tsavinho
5

R, 41 caracteres

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

Explicación:

outer(A,B,`-`)calcula para cada elemento x de A la diferencia x-By genera el resultado como una matriz (de dimensión longitud (A) x longitud (B)).
which.minselecciona el índice del número mínimo.
apply(x, 1, f)aplica la función fen cada fila de la matriz x.
Entonces apply(abs(outer(A,B,`-`)),1,which.min)devuelve los índices de la diferencia absoluta mínima entre cada elemento de A y los elementos del vector B.

Uso:

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

CJam - 14

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

El código principal está en la segunda línea, el resto es para usar la entrada estándar y la salida bonita.

Pruébalo en http://cjam.aditsu.net/

Explicación:

q~lee y evalúa la entrada,
f{...}ejecuta el bloque para cada elemento de la primera matriz y el siguiente objeto (que es la segunda matriz), recogiendo los resultados en una matriz
{...}$clasifica la segunda matriz usando el bloque para calcular una clave para cada elemento que
1$copia el actual el elemento de la primera matriz
-zresta y luego toma el valor absoluto
0=toma el primer valor de la matriz ordenada (el que tiene la clave mínima)
\;descarta el elemento de la primera matriz
pimprime la representación de cadena del resultado

Ejemplos (inspirados en otras respuestas):

Entrada: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Salida:[10 12 12 14 10]

Entrada: [0 25 10 38] [3 22 15 49 2]
Salida:[2 22 15 49]

aditsu
fuente
4

Javascript (E6) 54 56 59

Minimiza la distancia. Usando cuadrado en lugar de abdominales solo para guardar caracteres.
Editar álgebra ...
Editar asignación inútil fija (el resto de una prueba sin la definición de la función)

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

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

Prueba

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

Resultado: [10, 12, 12, 14, 10]

edc65
fuente
1
D=no es necesario, ya que mapdevuelve una nueva matriz. Alternativa función (misma longitud) para ordenar:(x,y)=>(x-=a)*x-(y-=a)*y
nderscore
4

Python 3.x - 55 caracteres

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

ay bson las matrices de entrada, y la matriz deseada es el resultado de la expresión.

Tal
fuente
Edité la respuesta para que sea una función, ya que la pregunta requiere una función.
user80551
3

Haskell, 55

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

Al principio, pensé en usar minimumByy comparing, pero como no están en Prelude, se necesitaron muchos personajes para calificarlos. También robó la idea de cuadratura de algunas otras respuestas para afeitar a un personaje.

YawarRaza7349
fuente
3

PowerShell - 44

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

Ejemplo

Con $ay $bconfigurado en:

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

La salida es

40.5, 10, 40.5, 10, 20, 30
Rynant
fuente
usted podría utilizar flotadores en el ejemplo para que quede claro que maneja demasiado FloAts
bebe
@bebe - Gracias, actualizado para que quede claro.
Rynant
-3 bytes:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy
2

Rubí, 40

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

Igual que la respuesta de Python, pero la cuadratura es un poco más tersa que cualquier otra forma en que se me ocurra tomar un valor absoluto.

histocrat
fuente
2

Pyth - 12 11 bytes

Nota: Pyth es mucho más joven que este desafío, por lo que esta respuesta no es elegible para ganar.

Método simple, utiliza la ofunción de orden para obtener una distancia mínima y la maplica sobre la lista 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

Pruébelo en línea aquí .

Maltysen
fuente
@Jakube oh sí, lo siento.
Maltysen
2

TI-BASIC, 24

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

No se acerca a APL, pero utiliza funciones menos potentes; esto no utiliza la función "ordenado por" o "índice de menor importancia". La desventaja de TI-BASIC aquí es su falta de esas funciones y matrices multidimensionales.

Sin golf:

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

La función min (tiene dos comportamientos: cuando se usa con números o listas reales, da el valor más pequeño; sin embargo, cuando se usa con números o listas complejas, da el valor con el valor absoluto más pequeño. Agregar 0io multiplicar por i^2hace que el intérprete usa el segundo comportamiento, entonces min(1,-2)retorna -2mientras que min(1+0i,-2+0i)regresa 1.

lirtosiast
fuente
1

Fortran 90: 88

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

Esto requiere que se containedite dentro de un programa completo:

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

Los corchetes declaran una matriz mientras (...,i=)representa un dobucle implícito ; Luego devuelvo el valor de bpara qué elemento a(i)-bse minimiza.

Kyle Kanos
fuente
1

Matlab: 48

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

Asume que Ay Bson matrices 1D en el espacio de trabajo, el resultado final está Cen el espacio de trabajo. Esto probablemente también funcionaría en Octave. La indexación condicional hace que esto sea bastante trivial.

Vidente de Godric
fuente
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;
}

De acuerdo ... creo que este pequeño código necesita explicación.

Al principio intenté hacer el trabajo con dos niveles de bucle for para encontrar la diferencia mínima y establecer el valor actual en min del valor de B. Eso es muy básico.

Se puede alcanzar lo mismo con qsort y una función de comparación. Hago que clasifique B por la diferencia en lugar de los elementos de B. Demasiadas funciones para un algoritmo tan pequeño. Entonces, la función q ahora tiene dos propósitos. Al principio, es el algoritmo mismo, en segundo lugar (cuando qsort lo llama) un comparador. Para la comunicación entre los dos estados, tuve que declarar globales.

m significa si está en estado de comparación o el principal .

ejemplo:

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
fuente
¿El 166/163 cuenta el espacio en blanco o no?
Kyle Kanos
Por supuesto no. Los espacios y las nuevas líneas son para facilitar la comprensión.
bebe
0

GolfScript, 49 bytes

Nota: esta es una solución parcial. Estoy trabajando para que sea una solución completa

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

Sí. GolfScript admite punto flotante. Pruébalo aquí . Ejemplo:

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

Salida:

[2.2 2.2 10.3 -20.1]
Justin
fuente
0

C # 262

El programa encuentra diferencias mínimas y guarda el valor más cercano de Array B. Trabajaré en el golf en breve.

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

Programa completo con código de prueba

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

C #: 120

Linq es asombroso:

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
fuente