주어진 배열에서 가장 가까운 숫자 찾기


21

이것은 내가 가진 실제 문제에서 영감을 얻었습니다. 이것에 대해 영리한 방법이 있는지 궁금합니다.

각각 임의의 수의 부동 소수점을 포함하는 두 개의 정렬되지 않은 배열 A와 B가 제공됩니다. A와 B의 길이가 반드시 같을 필요는 없습니다. A의 요소를 순차적으로 가져 와서 배열 B에서 가장 가까운 값을 찾는 함수를 작성하십시오. 결과는 새 배열에 포함되어야합니다.

승리 조건

가장 짧은 코드가 승리합니다 (평소와 같이).


1
가장 가까운 정수로 반올림 하시겠습니까?
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

1
@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 나는 "A의 각 요소를 B의 가장 가까운 요소로 둥글게"라고 읽었습니다
John Dvorak

@ JanDvorak : 글쎄, 반올림 방향에 대한 부분을 이해하지만 문제는 몇 자릿수로 지정되지 않았습니다.
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

@ n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ 가장 가까운 플로트로 반올림합니다. 답은 배열 / 목록 B에서 수레를 출력해야합니다.
Orhym

1
배열 A와 B가 정렬됩니까?
레벨 리버 St

답변:


17

APL, 13 17

(UTF-8에서 21 바이트)

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

진정한 람다를 원한다면 (A를 왼쪽 인수로, B를 오른쪽으로) :

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

작동 방식 :

{...}¨A{...}A를 배열로 호출하는 대신 모든 A 값으로 람다 함수 를 호출하여 결과를 동일한 모양의 배열로 수집

|⍵-B 인수 ⍵와 B의 모든 차이의 절대 값을 계산합니다 (-는 빼기, |는 abs입니다).

↑⍋ 최소 원소의 인덱스를 취합니다 (⍋ 배열을 반환하는 인덱스 정렬, ↑ 첫 원소 얻기)

B[...] 인덱스로 요소를 가져 오는 것입니다.

이 솔루션은 정렬 방식 자체가 아니라 순열 벡터 (원래 배열의 정렬 된 요소 색인)를 반환하는 APL의 정렬 기능의 훌륭한 기능을 사용하기는 쉽지 않습니다.


어떻게 작동합니까?
John Dvorak

답변 설명
Vovanium

이 글을 쓰는 방법을 지구상에서 어떻게 아십니까?
Martijn 2016 년

이것은 중국어를 쓰는 것과 같습니다. 나를 위해, 외계인 단어 나 외계인 문자를 쓰는 데 큰 차이가 없습니다 ...
Vovanium

17

매스 매 티카-17

#&@@@Nearest@A/@B

어떻게 작동합니까? 예, Mathematica에는 가장 가까운 기능 이 내장되어 있기 때문에 약간의 부정 행위가 있음을 인정합니다 . 나머지는 간단하며 결과를 1D 배열로 배열하는 것과 관련이 있습니다. 짧은 노력으로 인해 추악한 것처럼 보입니다.


1
하아! 환영! :)
Dr. belisarius

6

C # -103 97 87 바이트

이 질문을 올바르게 이해했는지 확실하지 않지만 여기에 내 해결책이 있습니다. 더 짧은 코드를 작성할 수 있기 때문에 배열 대신 Lists를 사용했습니다.

정수 배열은 정수 목록보다 짧습니다.

입력:

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 's answer)

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

목록도 괜찮습니다.
Orhym

1
이름 item을 바꾸면 i6 개의 추가 캐릭터를 안전하게 보호 할 수 있습니다.)
Aschratt

@Aschratt 감사합니다!
tsavinho

3
1.이 함수는 구체적으로 새로운 값을 반환한다고 말하지 않지만 당신이해야한다고 생각합니다. 2. 질문에 float가 필요했기 때문에 float을 사용해야한다고 생각합니다.float[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
Grax32

@Grax 첫 번째 답변을 썼을 때 문제는 수레에 관한 것이 아닙니다. 질문이 업데이트되었으므로 귀하의 답변도 포함되었습니다. 대단히 감사합니다.
tsavinho

5

R, 41 자

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

설명:

outer(A,B,`-`)A의 각 요소 x에 대해 차이를 계산 x-B하고 결과를 차원 길이 (A) x 길이 (B)의 행렬로 출력합니다.
which.min최소 숫자의 인덱스를 선택합니다. 행렬의 각 행에
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

메인 코드는 두 번째 줄에 있고 나머지는 표준 입력과 예쁜 출력을 사용하기위한 것입니다.

http://cjam.aditsu.net/ 에서 시도 하십시오

설명:

q~입력을 읽고 평가하여
f{...}첫 번째 배열의 각 요소와 다음 객체 (두 번째 배열)에 대한 블록을 실행하고, 배열로 결과를 수집
{...}$하면 블록을 사용하여 두 번째 배열을 정렬하여 각 항목의 키를 계산
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

자바 스크립트 (E6) 54 56 59

거리를 최소화하십시오. abs 대신 square를 사용하면 문자를 저장하십시오.
편집 대수 ...
편집 수정 쓸모 할당 (/ O 함수 정의 w 시험의 나머지)

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

4

Python 3.x-55 자

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

ab상기 입력 배열하고, 원하는 배열 식의 결과이다.


질문에 기능이 필요하기 때문에 답변을 편집하여 기능으로 만들었습니다.
user80551

3

하스켈, 55

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

처음에는 minimumByand 을 사용 comparing하려고했지만 Prelude에 없기 때문에 자격을 갖추려면 많은 캐릭터가 필요했습니다. 또한 캐릭터를 면도하기 위해 다른 답변에서 제곱 아이디어를 훔쳤습니다.


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-고맙습니다. 명확하게 업데이트되었습니다.
Rynant

-3 바이트 :$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
mazzy

2

루비, 40

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

파이썬 답변과 동일하지만, 제곱은 절대 가치를 생각할 수있는 방법보다 약간 더 무섭습니다.


2

Pyth- 12 11 바이트

참고 : Pyth는이 ​​도전보다 훨씬 젊으 므로이 답변은 이길 수 없습니다.

간단한 방법, o차수 함수를 사용 하여 최소 거리를 가져 와서 m목록에 적용하십시오 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

여기에서 온라인으로 사용해보십시오 .


@Jakube 오 예, 죄송합니다.
Maltysen 2016 년

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

최소 (함수는 두 개의 동작을 가지고 실수 또는 목록과 함께 사용할 때, 가장 작은 값을 제공, 복소수 또는 목록으로 사용될 때, 그것은 작은 절대 값을 갖는 값을주는 추가. 0i또는 승산 i^2원인 인터프리터 두 번째 동작을 사용하므로 min(1,-2)반환 -2반면에 min(1+0i,-2+0i)반환 1.


1

포트란 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작업 공간에. 이것은 옥타브에서도 작동합니다. 조건부 인덱싱은이 작업을 매우 간단하게 만듭니다.


0

C 144163

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

좋아 ...이 작은 코드에는 설명이 필요하다고 생각합니다.

처음에는 최소 차이를 찾는 두 가지 수준의 for 루프로 작업을 시도하고 현재 값을 최소 B 값으로 설정했습니다. 매우 기본입니다.

qsort 와 비교기 함수를 사용 하여 같은 것을 얻을 수 있습니다 . B의 요소 대신 B를 차이로 정렬합니다. 그런 작은 알고리즘에는 너무 많은 기능이 있습니다. 따라서 함수 q는 이제 두 가지 목적으로 사용됩니다. 처음에는 알고리즘 자체이며, 두 번째 (qsort에서 호출 할 때) 비교기입니다. 두 국가 간의 의사 소통을 위해 전 세계를 선언해야했습니다.

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은 공백을 계산합니까?
Kyle Kanos

당연히 아니지. 공백과 줄 바꿈은 이해를 돕기위한 것입니다.
bebe

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.