LINUX.ORG.RU

Сумма квадратов двух максимальных чисел

 ,


2

5

Дали задачу на собеседовании, написать в функциональном стиле на скале функцию, которая принимает три целых числа и возвращает для них сумму квадратов двух максимальных чисел. Корявенько получилось придумать такое:

  def twoMaxSquareSum(a: Int, b: Int, c: Int): Int =
    {
      def min(): Int =
        {
          if (a < b && a < c) {
            return a;
          } else if (b < c) {
            return b;
          } else return c;
        }
      def square(x:Int):Int=
      {
        return x*x;
      }
      
      return List(a,b,c).map (square(_)).foldLeft(0)(_ + _)-square(min)
    }
Гуру программирования, как можно сделать красивее? И по-сути не обязательно на скале, решение на других языках тоже с удовольствием гляну

Добавление: А какой вариант вы бы безоговорочно приняли на собеседовании как оптимальный?



Последнее исправление: by_zero (всего исправлений: 1)
Ответ на: комментарий от ieeya

А как я хочу?

До меня просто дошло, что большинство решений (не говорю, что все, т.к. некоторые не смогу распарсить), в т.ч. и моё, будут неверными в общем случае, если на вход могут подаваться отрицательные числа.

Ceiling_QB ★★★★
()
Последнее исправление: Ceiling_QB (всего исправлений: 1)
Ответ на: комментарий от Ceiling_QB

числа только неотрицательные?

ну скажи зачем тебе такое условие, кроме как если ты сразу квадраты всех 3 чисел будешь получать.

ieeya
()
Ответ на: комментарий от ieeya

И правда, забыл, что нужно найти сумму квадратов максимальных чисел, а не сумму максимальных квадратов.

Ceiling_QB ★★★★
()
Последнее исправление: Ceiling_QB (всего исправлений: 2)

ты просто не умеешь в арифметику

find(a,b,c) is max2(a*a,b*b,c*c)

where max2(a,b,c) is sum(a,b,c)-min(a,b,c)

зы. квадрат меньшего может быть больше квадрата большего.

поэтому выбирать

anonymous
()
int sum = 0;
if(a<b)
  sum += b*b, b = a; /* b not minimum */
else
  sum += a*a; /* a not minimum */
if(b<c)
  sum += c*c; /* c not minimum */
else
  sum += b*b; /* b (or a if a<b) not minimum */

я думаю, вы видите тут список (a, b, c), да?

emulek
()
Ответ на: комментарий от slovazap

На C я бы, наверное, принял без претензий только такой вариант

слишком топорно ИМХО. Но за то читаемо и понятно любому дебилу.

emulek
()
Ответ на: комментарий от vertexua

Нужно именно красивее? Ну тогда в список, потом sort descending, потом take(2), потом map, потом sum

таких как вы надо убивать ИМХО.

emulek
()
Ответ на: комментарий от emulek

лоровские погромисты горячи и скоры на расправу!

anonymous
()
def sq(x: Int): Int = x * x
sq(a) + sq(b) + sq(c) -  sq(a.min(b).min(c)) 
anonymous
()

Tcl

proc p {a b c} {lmap {x y} [lrange [lsort [list $a $b $c]] 1 2] {expr $x*$x+$y*$y}}
p 3 1 2
13

gorky ★★
()

Тихий ужас.

def twoMaxSquareSum(a : Int, b : Int, c : Int) : Int = List(a,b,c).sorted.tail.map(x => x * x).sum

Miguel ★★★★★
()

sicp, первая глава

на скакалку сам переведёшь, раз претендуешь получать за это деньги

тред не читал

anonymous
()
Ответ на: комментарий от Legioner

Единственный нормальный вариант. Задача была - написать функцию, возвращаюсь сумму квадратов максимальных двух чисел. Безоговорочно годится только тот вариант, в котором эта идея максимально понятно выражается. Видишь выражение, сразу понимаешь что оно делает.

bogus_result
()
Ответ на: комментарий от anonymous

Суть понята, только выше уже два раза предлагали такое решение

ieeya
()
Ответ на: комментарий от slovazap

Если бы не имя функции, то хрен проссышь за одну секунду чтения, что твой код делает. А в варианте с sort - drop - map - sum - меньше секунды на понимание надо.

anonymous
()
Ответ на: комментарий от by_zero

Уже разобрались выше, это ни на что не влияет, я просто условие подзабыл тогда.

Ceiling_QB ★★★★
()
Ответ на: комментарий от anonymous

фишка этого варианта: обработка списка, потому он хорошо должен лечь на всякую функциональщину. Наверное этого и ждали от ТСа. А скалу я не очень знаю, потому пусть ТС сам пишет.

Да, это всё тривиально расширяется на «сумму N-1 квадратов кроме одного минимума», или чуть сложнее на «сумму N-M квадратов кроме M минимумов».

emulek
()
Ответ на: комментарий от emulek

да, там как раз мутабельные переменные и четыре ветки условного оператора - идеально функциональный код. и расширяется тривиально, нужно только макрос написать, чтоб ветки хуярил, если нужно выбрать 5000 из 10000

anonymous
()
Ответ на: комментарий от anonymous

да, там как раз мутабельные переменные и четыре ветки условного оператора - идеально функциональный код.

это PoC рабочего алгоритма. Реализация на C. Причём развёрнутая для частного случая N=3.

нужно только макрос написать

нет. Нужно язык учить, что-бы уметь на нём выражать алгоритмы. Мне учить скалу лень, она мне ненужна.

emulek
()
Ответ на: комментарий от bogus_result

не уверен, что сторонний человек сразу поймёт, что она вычисляет

Функцию телом которой является, очевидно (twoMaxSquareSum(a: Int, b: Int, c: Int): Int).

motto
()
Ответ на: комментарий от emulek

расскажи лучше, как эта задача «ложится на фп» (что это за бред вообще?) и как ее отмасштабировать для произвольного к-ва аргументов?

anonymous
()
Ответ на: комментарий от by_zero

А если без использования списков, тогда как?

В скале что, нельзя получить список переданных аргументов?

loz ★★★★★
()
Ответ на: комментарий от qnikst

(\a b c -> uncurry (+) $ bimap (^2) (^2) $ first (snd . f c) $ f a b)

а я про что-то другое?

Без понятия. Это вообще предполагался псевдокод (std::minmax есть и в C++).

motto
()

R

sum((sort(c(a,b,c), decreasing=TRUE)[1:2])^2)

anonymous
()
Ответ на: комментарий от anonymous

Это работает так.

На некотором шаге просмотрены некоторые элементы списка L, известен текущий результат S и известен текущий минимальный элемент m.

На следующем шаге мы сравниваем X первый из непросмотренных элементов списка L с m. Если m меньше, то S=S+square(X), иначе S=S+square(m), m=X.

И переходим к следующему шагу. В функциональном стиле эту идею выразить легко, хоть рекурсивно, хоть итеративно.

bogus_result
()
Ответ на: Haskell от sevenredlines
Prelude> let twoMaxSquareSum xs = sum . map (^2) $ filter (/= minimum xs) xs
Prelude> twoMaxSquareSum [1, 2, 3]
13
Prelude> twoMaxSquareSum [1, 1, 1]
0

Ой...

Waterlaz ★★★★★
()
Ответ на: комментарий от bogus_result

а теперь для N, M = N / 2.

будешь хранить половину всех элементов, чтоб сравнивать? сложность сам оценишь? а наивный способ отсортировать список, за который наш упореный emulek предлагал убивать - универсальное решение, которое как раз и масштабируется, и на фп ложится, и вообще - то, что нужно. так-то.

anonymous
()
Ответ на: комментарий от anonymous

Вообще как бы, если вам на собеседовании задали задачу, в которой три числа, и одно нужно исключить, а вы решаете задачу с N числами, M которых надо исключить, то что это?

bogus_result
()
Ответ на: комментарий от bogus_result

да ограничить входной список тремя числовыми элементами, не?

Deleted
()
Ответ на: комментарий от bogus_result

emulek разорялся, что его решение масштабируется на список любой длины N, где нужно оставить любые M максимальных чисел. вот видишь, ты влез в чужой разговор, а теперь не знаешь, о чем он.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.