Trouver le nombre le plus proche dans un tableau donné

21

Ceci est inspiré par un problème réel que j'ai eu. Je suis curieux de voir s'il existe un moyen intelligent d'y parvenir.

Vous disposez de deux tableaux non triés, A et B, contenant chacun un nombre arbitraire de flottants. A et B n'ont pas nécessairement les mêmes longueurs. Écrivez une fonction qui prend les éléments de A séquentiellement et trouve la valeur la plus proche dans le tableau B. Le résultat doit être contenu dans un nouveau tableau.

Condition de victoire

Le code le plus court gagne (comme d'habitude).

Orhym
la source
1
Arrondir à l'entier le plus proche?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ J'ai lu que "arrondir chaque élément de A à l'élément le plus proche de B"
John Dvorak
@JanDvorak: Eh bien, je comprends la partie sur la direction d'arrondi, mais le problème n'a pas précisé le nombre de chiffres.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ Arrondir au flotteur le plus proche. La réponse doit générer des flottants à partir du tableau / de la liste B.
Orhym
1
Les tableaux A et B seront-ils triés?
Level River St

Réponses:

17

APL, 13 17

(21 octets en UTF-8)

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

Si vous voulez un vrai lambda (A comme argument de gauche et B comme droit):

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

Comment ça marche:

{...}¨Ainvoque la fonction lambda {...}avec chaque valeur A (au lieu d'invoquer avec A comme tableau), rassemblant les résultats dans un tableau de même forme

|⍵-B calcule les valeurs absolues de différence entre l'argument ⍵ et tout dans B (- est la soustraction, | est abs).

↑⍋ prend l'index du plus petit élément (⍋ trie le tableau renvoyant les indices, ↑ récupère le premier élément)

B[...] ne fait que récupérer les éléments par index (s).

La solution est assez simple, bien qu'elle utilise une fonction merveilleuse de la fonction de tri d'APL renvoyant le vecteur de permutation (les indices des éléments triés dans le tableau d'origine) plutôt que le tableau trié lui-même.

Vovanium
la source
Comment cela marche-t-il?
John Dvorak
Expliqué en réponse
Vovanium
Comment diable savez-vous comment écrire cela?
Martijn
C'est comme écrire du chinois. Pour moi, il n'y a pas de grande différence à écrire des mots ou des caractères étrangers ...
Vovanium
17

Mathematica - 17

#&@@@Nearest@A/@B

Comment ça marche? Oui, j'avoue qu'il y a un peu de tricherie ici parce que Mathematica a la fonctionnalité la plus proche intégrée. Le reste est simple et concerne l'organisation du résultat dans un tableau 1D. Il a l'air moche uniquement en raison de l'effort supplémentaire pour le raccourcir.

Szabolcs
la source
1
Ha! Bienvenue! :)
Dr belisarius
6

C # - 103 97 87 octets

Je ne suis pas sûr d'avoir bien compris cette question mais voici ma solution quand même. J'ai utilisé des listes au lieu de tableaux, car cela me permet d'écrire du code plus court.

Un tableau d'entiers est plus court qu'une liste d'entiers.

Contribution:

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

Méthode:

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

Sortie:

2, 22, 15, 49

Si ma réponse n'est pas correcte, veuillez laisser un commentaire en dessous.

EDIT: Comme l'a souligné @grax, la question concerne maintenant les flotteurs. Par conséquent, j'aimerais également inclure sa réponse.

95 octets (réponse de Grax)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
tsavinho
la source
Les listes sont bien aussi.
Orhym
1
Renommez- itemle iet vous protégerez 6 personnages supplémentaires;)
Aschratt
@Aschratt merci beaucoup!
tsavinho
3
1. La fonction ne dit pas spécifiquement de retourner la nouvelle valeur, mais je pense que vous devriez. 2. Puisque la question appelait float, je pense que vous devriez utiliser floatfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32
@Grax Comme j'ai écrit ma première réponse, la question n'était pas sur les flotteurs. Depuis que la question a été mise à jour, j'ai également inclus votre réponse. Merci beaucoup.
tsavinho
5

R, 41 caractères

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

Explication:

outer(A,B,`-`)calcule pour chaque élément x de A la différence x-Bet produit le résultat sous forme de matrice (de dimension longueur (A) x longueur (B)).
which.minsélectionne l'index du nombre minimal.
apply(x, 1, f)applique la fonction fsur chaque ligne de la matrice x. Retourne
donc apply(abs(outer(A,B,`-`)),1,which.min)les indices de la différence absolue minimale entre chaque élément de A et les éléments du vecteur B.

Usage:

> 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
la source
5

CJam - 14

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

Le code principal est sur la deuxième ligne, le reste est pour utiliser l'entrée standard et la jolie sortie.

Essayez-le sur http://cjam.aditsu.net/

Explication:

q~lit et évalue l'entrée
f{...}exécute le bloc pour chaque élément du premier tableau et l'objet suivant (qui est le deuxième tableau), la collecte des résultats dans un tableau
{...}$trie le deuxième tableau en utilisant le bloc pour calculer une clé pour chaque élément
1$copie le courant l'élément du premier tableau
-zsoustrait puis prend la valeur absolue
0=prend la première valeur du tableau trié (celui avec la clé minimale)
\;rejette l'élément du premier tableau
pimprime la représentation sous forme de chaîne du résultat

Exemples (inspirés d'autres réponses):

Entrée: [10.1 11.2 12.3 13.4 9.5] [10 12 14]
Sortie:[10 12 12 14 10]

Entrée: [0 25 10 38] [3 22 15 49 2]
Sortie:[2 22 15 49]

aditsu
la source
4

Javascript (E6) 54 56 59

Minimisez la distance. Utilisez carré au lieu d'abs pour économiser les caractères.
Modifier l' algèbre ...
Modifier corriger l'affectation inutile (un reste d'un test sans la définition de la fonction)

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

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

Tester

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

Résultat: [10, 12, 12, 14, 10]

edc65
la source
1
D=n'est pas nécessaire, car maprenvoie un nouveau tableau. Fonction de tri alternative (même longueur):(x,y)=>(x-=a)*x-(y-=a)*y
nderscore
4

Python 3.x - 55 caractères

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

aet bsont les tableaux d'entrée, et le tableau souhaité est le résultat de l'expression.

Tal
la source
J'ai édité la réponse pour en faire une fonction puisque la question nécessite une fonction.
user80551
3

Haskell, 55

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

Au début, j'ai pensé à utiliser minimumByet comparing, mais comme ceux-ci ne sont pas dans Prelude, il a fallu une tonne de personnages pour les qualifier. J'ai également volé l'idée de la quadrature à d'autres réponses pour raser un personnage.

YawarRaza7349
la source
3

PowerShell - 44

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

Exemple

Avec $aet $bréglé sur:

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

La sortie est

40.5, 10, 40.5, 10, 20, 30
Rynant
la source
vous pouvez utiliser des flotteurs dans l'exemple pour qu'il soit clair qu'il gère également les flotteurs
bebe
@bebe - Merci, mis à jour pour que ce soit clair.
Rynant
-3 octets:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy
2

Rubis, 40

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

Identique à la réponse Python, mais la quadrature est un peu plus tordue que toute autre façon à laquelle je pourrais penser pour prendre une valeur absolue.

histocrate
la source
2

Pyth - 12 11 octets

Remarque: Pyth est beaucoup plus jeune que ce défi, donc cette réponse n'est pas éligible pour gagner.

Méthode simple, utilise la ofonction d'ordre pour obtenir une distance minimale et l' maffiche sur la liste 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

Essayez-le en ligne ici .

Maltysen
la source
@Jakube oh ouais, désolé.
Maltysen
2

TI-BASIC, 24

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

Ne se rapproche pas d'APL, mais utilise des fonctions moins puissantes - cela n'utilise aucune fonction "trié par" ou "index du moins". L'inconvénient de TI-BASIC ici est son manque de ces fonctions et tableaux multidimensionnels.

Non 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 fonction min (a deux comportements: lorsqu'elle est utilisée avec des nombres réels ou des listes, elle donne la plus petite valeur; cependant, lorsqu'elle est utilisée avec des nombres ou des listes complexes, elle donne la valeur avec la plus petite valeur absolue. L'ajout 0iou la multiplication par i^2provoque l'interpréteur à utilisez le deuxième comportement, donc min(1,-2)renvoie -2alors que min(1+0i,-2+0i)renvoie 1.

lirtosiast
la source
1

Fortran 90: 88

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

Cela nécessite qu'il soit containédité dans un programme complet:

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

Les accolades carrées déclarent un tableau tandis que (...,i=)représente une doboucle implicite ; Je retourne ensuite la valeur de bquel élément a(i)-best minimisé.

Kyle Kanos
la source
1

Matlab: 48

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

Suppose que Aet Bsont des matrices 1D dans l'espace de travail, le résultat final est Cdans l'espace de travail. Cela fonctionnerait probablement aussi dans Octave. L'indexation conditionnelle rend cela assez trivial.

Godric Seer
la source
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;
}

D'accord ... Je pense que ce petit code a besoin d'explications.

Au début, j'ai essayé de faire le travail avec deux niveaux de boucle pour trouver la différence min et régler la valeur actuelle sur min de la valeur de B. C'est très basique.

La même chose peut être atteinte avec qsort et une fonction de comparaison. Je le fais trier B par différence au lieu des éléments de B. Trop de fonctions pour un si petit algorithme. La fonction q a donc deux fonctions. Au début, c'est l'algorithme lui-même, ensuite (quand qsort l'appelle) un comparateur. Pour la communication entre les deux états, j'ai dû déclarer des globaux.

m signifie que ce soit dans un état de comparaison ou le principal .

exemple:

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
être
la source
Le 166/163 compte-t-il ou non l'espace blanc?
Kyle Kanos
Bien sûr que non. Les espaces et les nouvelles lignes sont pour faciliter la compréhension.
bebe
0

GolfScript, 49 octets

Remarque: il s'agit d'une solution partielle. Je travaille pour en faire une solution complète

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

Oui. GolfScript prend en charge la virgule flottante. Essayez-le ici . Exemple:

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

Sortie:

[2.2 2.2 10.3 -20.1]
Justin
la source
0

C # 262

Le programme détecte les différences min et enregistre la valeur la plus proche de la baie B. Je vais travailler sur le golf sous peu.

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

Programme complet avec code de test

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
la source
0

C #: 120

Linq est génial:

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
la source