Знайти найближче число в заданому масиві


21

Це натхнене реальною проблемою у мене. Мені цікаво побачити, чи є якийсь розумний шлях для цього.

Вам дано два несортованих масиви, A і B, кожен з яких містить довільну кількість плавців. 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.
Orhym

1
Чи будуть відсортовані масиви A і B?
Рівень Рівер Сент

Відповіді:


17

APL, 13 17

(21 байт у UTF-8)

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

Якщо ви хочете справжньої лямбда (A як лівий аргумент і B як правий):

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

Як це працює:

{...}¨Aвикликає функцію лямбда {...}з кожним значенням A (замість виклику з A як масив), збираючи результати для масиву тієї ж форми

|⍵-B обчислює абсолютні значення різниці між аргументом ⍵ і всім у B (- віднімання, | є абс).

↑⍋ приймає індекс найменшого елемента (⍋ сортує масив, що повертає індекси, ↑ отримує перший елемент)

B[...] це лише отримання елементів (ив) за індексами.

Рішення досить чітке, хоча воно використовує чудову особливість функції сортування APL, що повертає вектор перестановки (відсортовані індекси елемента в оригінальному масиві), а не відсортований масив.


Як це працює?
Джон Дворак

Пояснили у відповідь
Вованій

Як же ти знаєш, як це написати?
Martijn

Це як писати китайською. Для мене немає великої різниці в написанні ані чужорідних слів, ані чужорідних символів ...
Vovanium

17

Математика - 17

#&@@@Nearest@A/@B

Як це працює? Так, я визнаю, що тут є трохи обману, оскільки Mathematica має вбудований найближчий функціонал. Решта - це просто і стосується упорядкування результату в 1D масиві. Це виглядає некрасиво лише через додаткові зусилля, щоб зробити його коротким.


1
Га! Ласкаво просимо! :)
доктор belisarius

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

Якщо моя відповідь не вірна, залиште коментар під нею.

EDIT: AS @grax вказував, зараз питання про floats. Тому я хотів би включити і його відповідь.

95 байт (відповідь Гракса)

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

Списки теж прекрасні.
Орхім

1
Перейменуйте itemна, iі ви збережете 6 додаткових символів;)
Ашратт

@Aschratt дуже дякую!
tsavinho

3
1. Функція спеціально не каже повернути нове значення, але я думаю, що слід. 2. Оскільки питання вимагає float, я думаю, ви повинні використовувати floatfloat[] t(float[] a, float[] b) {return a.Select(d=>b.OrderBy(e=>Math.Abs(e-d)).First()).ToArray();}
вимагає

@Grax Коли я писав свою першу відповідь, питання було не про поплавці. Оскільки питання було оновлено, я включив і вашу відповідь. Велике спасибі.
tsavinho

5

R, 41 ч

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

Пояснення:

outer(A,B,`-`)обчислює різницю для кожного елемента x з A 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

Javascript (E6) 54 56 59

Мінімізуйте відстань. Використання квадрата замість abs просто так збережіть символи.
Редагувати алгебру ...
Редагувати непотрібне призначення виправлення (залишок тесту без визначення функції)

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]

aі bє вхідними масивами, а бажаний масив є результатом виразу.


Я відредагував відповідь, щоб зробити її функцією, оскільки питання вимагає функції.
користувач80551

3

Хаскелл, 55

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

Спочатку я думав використовувати minimumByі 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

ви можете використовувати floats у прикладі, щоб дати зрозуміти, що він також обробляє floats
bebe

@bebe - Дякую, оновлено, щоб зробити це зрозумілим.
Рінант

-3 байти:$a|%{$n=$_;($b|sort{($n-$_)*($n-$_)})[0]}
маззи

2

Рубі, 40

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

Так само, як відповідь Python, але квадратик трохи терпіший, ніж будь-який спосіб, про який я міг би придумати, щоб прийняти абсолютне значення.


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 о так, вибачте.
Мальтісен

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

Min (функція має дві поведінки: при використанні з реальними числами або списками вона дає найменше значення; однак, коли використовується зі складними числами чи списками, вона дає значення з найменшим абсолютним значенням. Додавання 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

Матлаб: 48

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

Припускаємо, що Aі Bє матрицями 1D у робочій області, остаточний результат - Cу робочій області. Це, ймовірно, буде працювати і в Октаві. Умовна індексація робить це досить тривіальним.


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

Гаразд ... Я думаю, цей маленький код потребує пояснення.

Спочатку я намагався виконати роботу з двома рівнями для циклу, знаходячи мінімальну різницю та встановивши поточне значення на min значення B. Це дуже просто.

Те саме можна досягти за допомогою qsort та функції порівняння. Я роблю це сортування B за різницею замість елементів B. Занадто багато функцій для такого маленького алгоритму. Отже функція q тепер виконує дві цілі. По-перше, це сам алгоритм, по-друге (коли qsort називає його) компаратор. Для спілкування між двома державами мені довелося декларувати глобальні точки.

м означає, що він знаходиться в порівняльному стані або основний .

приклад:

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 пробіл чи ні?
Кайл Канос

Звичайно, ні. Простіри та нові лінії для зручності розуміння.
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();}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.