指定された配列で最も近い数を見つける


21

これは、私が抱えていた現実の問題に触発されました。これについて賢明な方法があるかどうか見てみたい。

並べ替えられていない2つの配列AとBが与えられ、それぞれに任意の数のfloatが含まれています。AとBは必ずしも同じ長さではありません。Aの要素を順番に受け取り、配列Bで最も近い値を見つける関数を作成します。結果は新しい配列に含まれる必要があります。

勝利条件

最短のコードが勝ちます(通常どおり)。


1
最も近い整数に丸めますか?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳私はそれを「Aの各要素を最も近いBの要素に丸める」と読みました
ジョン・ドヴォラック

@JanDvorak:まあ、丸め方向に関する部分は理解していますが、問題は桁数を指定しませんでした。
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳最も近い浮動小数点数に丸めます。答えは、配列/リストBからフロートを出力する必要があります。
Orhym14年

1
配列AとBはソートされますか?
レベルリバーセント

回答:


17

APL、13 17

(UTF-8で21バイト)

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

真のラムダが必要な場合(Aは左引数、Bは右引数):

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

使い方:

{...}¨A{...}(配列としてAを呼び出す代わりに)すべてのA値でラムダ関数を呼び出し、結果を同じ形状の配列に収集します

|⍵-B 引数⍵とBのすべての差の絶対値を計算します(-は減算、|はabs)。

↑⍋ 最小要素のインデックスを取ります(⍋インデックスを返す配列をソートし、↑最初の要素を取得します)

B[...] インデックスによって要素を取得しているだけです。

このソリューションは、ソートされた配列自体ではなく、順列ベクトル(元の配列内のソートされた要素のインデックス)を返すAPLのソート関数の素晴らしい機能を使用していますが、非常に簡単です。


これはどのように作動しますか?
ジョンドヴォルザーク

答えで説明
Vovanium

一体どうやってこれを書くのか知っていますか?
マーティン14年

これは中国語を書くようなものです。私にとっては、外国人の単語や外国人の文字のいずれかを書いては大きな違いが...ありません
Vovanium

17

Mathematica-17

#&@@@Nearest@A/@B

どのように機能しますか?はい、Mathematicaには最も近い機能が組み込まれているため、ここで少しごまかしがあります。残りは簡単で、結果を1D配列に配置することに関係しています。それは短くするための余分な努力のためにのみいように見えます。


1
ハ!ようこそ!:)
ベリサリウス博士14年

6

C#-103 97 87バイト

この質問を正しく理解したかどうかはわかりませんが、とにかくここに私の解決策があります。 短いコードを書くことができるので、配列の代わりにリストを使用しました。

整数配列は整数リストよりも短いです。

入力:

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

方法:

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

出力:

2, 22, 15, 49

私の答えが正しくない場合は、その下にコメントを残してください。

編集: @graxが指摘したように、問題はフロートに関するものです。したがって、彼の答えも含めたいと思います。

95バイト(Graxの答え)

float[]t(float[]a,float[]b){return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}

リストも大丈夫です。
オーリズム

1
名前itemを変更するiと、追加の6文字が安全になります;)
Aschratt 14年

@Aschrattありがとうございます!
tsavinho

3
1.この関数は、新しい値を返すことを具体的に言っていませんが、そうすべきだと思います。2.質問はフロートを要求しているので、フロートを使用すべきだと思うfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32 14年

@Grax最初の答えを書いたとき、問題はフロートに関するものではありませんでした。質問が更新されたので、私もあなたの答えを含めました。どうもありがとうございました。
tsavinho 14年

5

R、41文字

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

説明:

outer(A,B,`-`)Aの各要素xの差x-Bを計算し、結果を(次元length(A)x length(B)の)行列として出力します。
which.min最小数のインデックスを選択します。matrixの各行に
apply(x, 1, f)関数fを適用しますx
したがってapply(abs(outer(A,B,`-`)),1,which.min)、Aの各要素とベクトルBの要素間の最小絶対差のインデックスを返します。

使用法:

> 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

5

CJam-14

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

メインコードは2行目にあり、残りは標準入力ときれいな出力を使用するためのものです。

http://cjam.aditsu.net/で試してください

説明:

q~入力
f{...}を読み取り、評価して、最初の配列の各要素と次のオブジェクト(2番目の配列)の各要素のブロックを実行し、配列で結果を収集し
{...}$て、ブロックを使用して2番目の配列をソートし、各項目のキーを計算し
1$て現在の最初の配列から項目を
-z減算してから、絶対値
0=を取得し、ソートされた配列(最小キーを持つもの)の最初の値を取得します。
\;最初の配列から項目を破棄し
p、結果の文字列表現を出力します

(他の回答からヒントを得た):

入力:[10.1 11.2 12.3 13.4 9.5] [10 12 14]
出力:[10 12 12 14 10]

入力:[0 25 10 38] [3 22 15 49 2]
出力:[2 22 15 49]


4

Javascript(E6)54 56 59

距離を最小化します。absの代わりにsquareを使用して、文字を保存します。代数を
編集 ... 修正役に立たない割り当てを
編集(テストの残りの関数定義なし)

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

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

テスト

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

結果: [10, 12, 12, 14, 10]


1
D=map新しい配列を返すため、必要ありません。代替(同じ長さ)ソート関数:(x,y)=>(x-=a)*x-(y-=a)*y
nderscore 14年

4

Python 3.x-55文字

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

aおよびbは入力配列であり、目的の配列は式の結果です。


質問には関数が必要なので、答えを編集して関数にしました。
user80551 14年

3

ハスケル、55

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

最初は、私が使用することを考えたminimumBycomparing、しかしそれらはプレリュードではないので、それはそれらを修飾する文字のトンを取りました。また、他のいくつかの回答から二乗アイデアを盗み、キャラクターを剃り落としました。


3

PowerShell-44

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

$aし、$b次のように設定します。

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

出力は

40.5, 10, 40.5, 10, 20, 30

あなたはそれがあまりにもフロートを取り扱う明確にする例では、浮動小数点数を使用することができます
BEBE

@bebe-ありがとう、それを明確にするために更新されました。
リナント14年

-3バイト:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy

2

ルビー、40

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

Pythonの答えと同じですが、二乗は絶対値を取るために私が考えることができるどんな方法よりも少し簡潔です。


2

パイス-12 11バイト

注:Pythはこのチャレンジよりもはるかに若いため、この答えは勝ちません。

単純な方法で、o順序関数を使用して最小距離を取得mし、listでそれをapsします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

こちらからオンラインでお試しください


@ジャクベああそう、ごめんなさい。
マルティセン

2

TI-BASIC、24

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

APLには近づきませんが、あまり強力ではない関数を使用します。これは、「並べ替え」または「最小のインデックス」関数を使用しません。ここでのTI-BASICの欠点は、これらの関数と多次元配列がないことです。

ゴルフをしていない:

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

分(関数は、2つの動作を有している:実数またはリストを使用する場合には、最小値を与える、複素数またはリストを使用した場合しかし、それは最も小さい絶対値の値を与える追加。0iによって又は乗算i^2原因インタプリタへ2番目の動作を使用するため、をmin(1,-2)返しますが-2、をmin(1+0i,-2+0i)返します1


1

Fortran 90:88

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

これにはcontain、完全なプログラム内で編集する必要があります。

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

角括弧は配列を宣言しますが(...,i=)、暗黙のdoループを表します。次に、b要素a(i)-bが最小化されている値を返します。


1

Matlab:48

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

AおよびBがワークスペースの1D行列であると仮定すると、最終結果はCワークスペースにあります。これは、Octaveでも機能する可能性があります。条件付きインデックスにより、これはかなり簡単になります。


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

さて...この小さなコードには説明が必要だと思います。

最初に、2つのレベルのforループでジョブを実行して最小差を見つけ、現在の値をBの値の最小値に設定しようとしました。それは非常に基本的なことです。

同じことは、qsortとコンパレータ関数で達成できます。Bの要素ではなく、差でBをソートします。このような小さなアルゴリズムには関数が多すぎます。そのため、関数qは2つの目的を果たします。最初はアルゴリズムそのものであり、2番目(qsortが呼び出すとき)はコンパレータです。2つの状態間の通信では、グローバルを宣言する必要がありました。

mは、コンパレーター状態かメイン状態かを表します。

例:

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

166/163は空白をカウントしますか?
カイルカノス14年

もちろん違います。スペースと改行は理解を容易にするためのものです。
ベベ14年

0

GolfScript、49バイト

注:これは部分的な解決策です。私はそれを完全なソリューションにすることに取り組んでいます

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

はい。GolfScriptは浮動小数点をサポートします。ここで試してみてください。例:

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

出力:

[2.2 2.2 10.3 -20.1]

0

C#262

プログラムは最小の違いを見つけて、配列Bから最も近い値を保存します。ゴルフについては、まもなく作業します。

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

テストコード付きの完全なプログラム

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

0

C#:120

Linqは素晴らしい:

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();}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.