Сокращение чисел


10

Входные данные представляют собой массив из (как минимум 3, максимум 20) различных целых чисел. Каждое целое число больше -1000 и меньше 1000.

Ваша задача состоит в том, чтобы уменьшить числа, "линейно отображая" их от 0.0до 1.0. Это означает, что наименьшее число в массиве будет отображаться на 0,0, наибольшее на 1,0.

Вы получаете массив в качестве параметра (внутри функции) или аргументов стандартного ввода / программы (вы можете выбрать). Распечатайте результат в формате double1;double2;double3;.... Выходные данные должны иметь тот же порядок, что и входные .

Если вы хотите, вы можете округлить вывод до 2 цифр после десятичной точки. Должна быть как минимум 1 цифра после десятичной точки.

Использование встроенных функций (функции , которые уменьшают номера для вас, таких как mathematicas Rescale) отвергается .

Примеры:

Input              Output
[5,-20,30]         0.5;0.0;1.0
[1,2,3,4,5]        0.0;0.25;0.5;0.75;1.0
[0,5,100,400]      0.0;0.01;0.25;1.0

(Последний вывод округляется, иначе будет 0.0;0.0125;0.25;1.0)


2
Таким образом, даже если мы напишем функцию, результат должен быть напечатан? (В отличие от возвращения соответствующего массива парных чисел.)
— Мартин Эндер

@ MartinBüttner Да, они должны быть напечатаны. Встроенные функции запрещены.
— CommonGuy

«использование встроенных функций (таких как mathematicas Rescale) запрещено». - это слишком расплывчато Какие функции запрещены? Только те, которые решают полную проблему (которая была бы стандартной лазейкой)?
— Джон Дворжак

Подождите, значит, ввод может быть аргументом функции, но вывод должен быть на экране ???
— Джон Дворжак

1
@Dennis Формат должен соответствовать указанному в вопросе. Это означает, что числа разделяются точкой с запятой.
— CommonGuy

Ответы:


5

CJam, 18 байт

q~_$0=f-_$W=df/';*

Обратите внимание, что онлайн-переводчик ошибочно представляет 0dкак 0вместо 0.0.

Пример запуска

$ cjam shrink.cjam <<< '[5 -20 30]'; echo
0.5;0.0;1.0
$ cjam shrink.cjam <<< '[1 2 3 4 5]'; echo
0.0;0.25;0.5;0.75;1.0
$ cjam shrink.cjam <<< '[0 5 100 400]'; echo
0.0;0.0125;0.25;1.0

Как это работает

q~                    " P := eval(input())         ";
  _$0=                " S := sorted(P)[0]          ";
      f-              " Q := { X - S : X ∊ P }     ";
        _$W=d         " D := double(sorted(Q)[-1]) ";
             f/       " R := { X / D : X ∊ Q }     ";
               ';*    " print(join(R, ';'))        ";

Моя реакция на это, как на источник CJam: Wtf? требуется объяснение ...
— edc65

2
Хороший способ получить минимальное и максимальное значения, используя индекс массива вместо того, чтобы выталкивать, а затем обмениваться данными
— Optimizer

Это, наверное, моя холодная речь, но почему вы сортируете дважды? Разве отсортированный массив не должен оставаться отсортированным, если из каждого элемента вычитается константа?
— Инго Бюрк

@ IngoBürk Сортированный массив не переживает доступ к массиву, я думаю. Что имеет смысл, потому что окончательный результат не должен быть отсортирован.
— Мартин Эндер

@ MartinBüttner D'oh. Конечно. Нам нужно сохранить порядок для результата. Спасибо!
— Инго Бюрк

4

JavaScript, ES6, 81 байт

Спасибо @ edc65 за toFixedтрюк

F=a=>a.map(v=>((v-n)/d).toFixed(2),n=Math.min(...a),d=Math.max(...a)-n).join(';')

Запустите его в последней консоли Firefox.

Это создает функцию, fкоторую вы можете вызвать как

F([5,-20,30])

1) почему eval (подсказка), когда функция разрешена? 2) После десятичной точки должна быть как минимум 1 цифра. 3) не нужно хранить M, просто d = Mm
— edc65

Обновлено. Хотя получить хотя бы 1 цифру после десятичной дроби сложно
— Оптимизатор

If you want, you can round the output to 2 digits after the decimal pointэто более простой способ, я думаю
— edc65

@ edc65 Но нет никакого способа , чтобы преобразовать 1в 1.0то , что я сделал , за исключением.
— Оптимизатор

Нет. Можно намекнуть?
— edc65

4

Python 2, 72 68 63 56 55

Очевидно, не так кратко, как другие ответы, но в любом случае:

x=input()
m=min(x)
print[(i*1.-m)/(max(x)-m)for i in x]

Образец прогона:

[1,100,25,8,0]                  #input
[0.01, 1.0, 0.25, 0.08, 0.0]    #output

Старый (68 символов, написанный на Python 3):

x=eval(input())
y=sorted(x)
print([(i-y[0])/(y[-1]-y[0])for i in x])

Вы можете сохранить еще один символ, определив m=min(x).
— FryAmTheEggman

4

CJam, 24 23 байта

l~_$)\(:M\;-\Mf-\df/';*

Вход будет как:

[5 -20 30]

Попробуйте онлайн здесь Обратите внимание , что онлайн печатает компилятор , Double 0как 0только. Запустите интерпретатор Java, который печатает правильно.

Как это работает:

l~                      "Evaluate input and convert each element to double";
  _$                    "Copy the array and sort the copied array";
    )                   "Pop the last element out of the array. This is Max";
     \                  "Swap last two stack elements, bring sorted array on top";
      (:M               "Pop the first element of array and store it in M. This is Min";
         \;             "Bring the remaining of sorted array on top and remove it from stack";
           -\           "Subtract Max and Min and bring the original array to top of stack"
             Mf-        "Push min to stack and subtract it from each array element";
                \df/    "Bring (Double)(Max-Min) to top and divide each array element by it";
                   ';*  "Push the character ; to stack and join the array with it";

1
Ах, это гораздо лучшая идея, чтобы получить минимум и максимум.
— Мартин Эндер

Это печатает 0;0.5;1вместо 0.0;0.5;1.0.
— CommonGuy

@Manu - Да, пытаюсь это исправить. И почти все ответы делают только это.
— Оптимизатор

2
Вам не нужно исправить. Интерпретатор Java представляет Double 0 как 0.0.
— Деннис

3

C # 92

Бег внутри LinqPad

void F(int[]a)
{
   double n=a.Min(),d=a.Max()-n;
   a.Select(x=>((x-n)/d).ToString("0.00")).Dump();
}

Тест в LinqPad

void Main()
{
    F(new int[]{5,-20,30});
}
void F(int[]a){double n=a.Min(),d=a.Max()-n;a.Select(x=> ((x-n)/d).ToString("0.00")).Dump();}

Вывод

IEnumerable<String> (3 items)
0,50 
0,00 
1,00 

3

APL (15)

(2⍕+÷⌈/)(+-⌊/)⎕

(или без поездов тоже 15 персонажей :)

2⍕V÷⌈/V←V-⌊/V←⎕

Это читает аргумент с клавиатуры и выводит результат на экран.

Объяснение:

  • ⎕: прочитать строку с клавиатуры и оценить ее
  • +-⌊/: вычесть самый низкий элемент в массиве из всех элементов в массиве
  • +÷⌈/: разделить каждый элемент в массиве на самый высокий элемент массива
  • 2⍕: формат с двумя десятичными знаками

Тестовое задание:

      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
     5 ¯20 30
 0.50 0.00 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      1 2 3 4 5
 0.00 0.25 0.50 0.75 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      0 5 100 400
 0.00 0.01 0.25 1.00

Следует добавить количество байтов ...
— Оптимизатор

Что составляет всего 24 байта.
— Оптимизатор

2
@Optimizer: если в вопросе не указано иное, каждый ответ оценивается с использованием кодировки, которая дает наименьшее количество байтов. Есть кодовая страница APL, которая представляет каждый символ APL одним байтом.
— Деннис

Поправьте меня, если я что-то не так делаю, но по умолчанию код-гольф считается в байтах и mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … На странице написано 24 байта. Я что-то пропустил ?
— Оптимизатор

1
Вывод должен быть разделен точками с запятой, а не пробелами.
— CommonGuy

3

Пиф , 18

Теперь с правильным форматированием!

j\;mc-dhSQ-eSQhSQQ

Тестовое задание:

$ pyth -c 'j\;mc-dhSQ-eSQhSQQ' <<< '[0,5,100,400]'
0.0;0.0125;0.25;1.0

Объяснение:

(implicit)              Q = eval(input())
j\;                     ';'.join(
   m                             map(lambda d:
    c                                         float_div(
     -dhSQ                                              d-sorted(Q)[0],
     -eSQhSQ                                            sorted(Q)[-1]-sorted(Q)[0]),
    Q                                         Q))

Вывод не отформатирован правильно.
— CommonGuy

@Manu Извините, я исправил это.
— Исаак

Не создает ли ваш собственный язык, который вы меняете со временем, немного растягивая правила? Очевидно, вы можете просто добавить новую функцию, чтобы сделать программу короче?
— Крис Джефферсон

3
@ChrisJefferson Я всегда использую новейшую версию языка, которая появилась до того, как была задана проблема. Поскольку все это отправлено на Github, можно убедиться, что я ничего не добавляю после публикации проблемы. Это стандартное правило CG.SE - язык должен быть старше вопроса, и я соблюдаю его.
— Исаак

2

Октава 25

b=min(l);(l-b)/(max(l)-b)

Предполагается, что ввод введен, lи поскольку это интерактивная оболочка, результат печатается автоматически (это разрешено?)


2
У Octave / Matlab есть inputвозможность получить пользовательский ввод и имитировать STDIN. Вы также можете написать функцию. Кроме того, это печатает результат в правильном формате?
— Мартин Эндер

И нет, просто возвращение и печать оболочки это вообще не считается. Golfscript и тому подобное отличаются, потому что язык определяет, что стопка печатается в конце. Но это не так, например, для Javascript. И я не думаю, что для Matlab / Octave тоже.
— Инго Бюрк

2

APL, 31 символ / 55 байт

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{2⍕(⍵-b)÷c}¨⍵}

Старый код без цифр после десятичной точки:

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{(⍵-b)÷c}¨⍵}

Возьмите минимум вектора, возьмите разницу между максимумом и минимумом вектора, вычтите минимум из каждого элемента и разделите на разницу между минимумом и максимумом.

Отредактированный код для печати двух цифр после десятичной точки:


2

CJam, 30 29 байт

l~:d_{e>}*\_{e<}*:Mf-\M-f/';*

Ожидает ввода на STDIN, как [5 -20 30].

Проверьте это здесь. (Это будет печатать целое 0и 1без десятичной точки, но интерпретатор Java делает печать 0.0и 1.0.)

Из- за ошибки я не могу сократить {e>}*до:e> хотя это должно быть возможным в соответствии со спецификацией (что позволит сэкономить 4 байта , когда применяется как мин и макс).

Немного устаревшее объяснение: (исправлю позже)

l~:d_{e<}*_@_{e>}*@-\@f-\f/';* "Read and eval the input leaving an array of strings on the stack";
l~                             "Read and eval the input leaving an array of strings on the stack";
  :d                           "Convert all elements to double";
    _                          "Duplicate the array";
     {e<}*                     "Wrap the MIN function in a black and fold it onto the array";
          _                    "Duplicate the minimum";
           @                   "Rotate the stack, pulling the array to the top";
            _                  "Duplicate the array";
             {e>}*             "Same as before, now with MAX";
                  @            "Rotate the stack, pulling the minimum to the top";
                   -           "Subtract to give the total range";
                    \          "Swap range and array";
                     @         "Rotate the stack, pulling the other minimum to the top";
                      f-       "Subtract the minimum from each element in the array";
                        \      "Swap range and array";
                         f/    "Divide each element in the array by the range";
                           ';  "Push a semicolon character";
                             * "Riffle the semicolon into the array";

В конце программы содержимое стека выводится по умолчанию.

Я уверен, что есть способ сохранить половину перестановки стека, но мне пока не очень комфортно с CJam.


Это печатает 0;0.5;1вместо 0.0;0.5;1.0.
— CommonGuy

@Manu См. Комментарий Денниса к ответу Оптимизатора. Он отлично работает в интерпретаторе Java.
— Мартин Эндер

2

Xojo, 179 байт

dim x,n as double,k,z as int16,s() as string
n=1e3
x=-n
for each k in a
x=max(x,k)
n=min(n,k)
next
for k=0 to ubound(a)
s.append str((a(k)-n)/(x-n),"0.0#")
next
msgbox join(s,";")

2

R, 60 байтов

m=min(x<-scan());cat(sprintf("%f",(x-m)/(max(x)-m)),sep=";")    

При форматировании расходуется много байтов, 0и 1по умолчанию они обрезаются, чтобы ничего не отображать после целочисленной части.


1

Clojure 63

(fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) 

Не совсем следует правилам, так как возвращает двойные, а не двойные. Если это не приемлемо, добавьте 7 байтов

Ungolfed:

(fn [values]
    (let [low (apply min values)]
         (map #(/ (- % low)
                  (- (apply max values) low))
              values)))

Вызывается так:

((fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) [5 -20 30])

Вывод: (1/2 0 1)


1

Руби, 49

f=->a{$><<a.map{|x|(x-l=a.min).fdiv(a.max-l)}*?;}

Объяснение:

f=->a{}     # Define a lambda that takes one argument a
$><<        # Print the following to STDOUT
a.map{|x|}  # For each element x
(x-l=a.min) # Find the lowest element of a, assign it to l, and subtract it from x
.fdiv       # Float division (/ truncates)
(a.max - l) # Divide by the maximum minus the minimum
*?;         # Convert the resulting array into a string joined by the ';' character




0

Java 7, 149 байт

float[]c(int[]x){int b=1<<31,a=b-1,j=0,l=x.length;for(int i:x){a=i<a?i:a;b=i>b?i:b;}float[]r=new float[l];for(;j<l;r[j]=x[j++]-a)*1f/(b-a);return r;}

Ungolfed & тестовый код:

Попробуй это здесь.

import java.util.Arrays;
class M{
  static float[] c(int[] x){
    int b = Integer.MIN_VALUE,
        a = b-1, // In Java, Integer.MIN_VALUE - 1 = Integer.MAX_VALUE (and vice-versa)
        j = 0,
        l = x.length;
    for(int i : x){
      a = i < a ? i : a; // Determine min value of array
      b = i > b ? i : b; // Determine max value of array
    }
    float[] r = new float[l];
    for(; j < l; r[j] = (x[j++] - a) * 1f / (b-a));
    return r;
  }

  public static void main(String[] a){
    System.out.println(Arrays.toString(c(new int[]{ 5, -20, 30 })));
    System.out.println(Arrays.toString(c(new int[]{ 1, 2, 3, 4, 5 })));
    System.out.println(Arrays.toString(c(new int[]{ 0, 5, 100, 400 })));
  }
}

Вывод:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.