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

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)

CommonGuy
источник
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 
edc65
источник
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))
isaacg
источник
Вывод не отформатирован правильно.
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}¨⍵}

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

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

Shujal
источник
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,";")
silverpie
источник
2

R, 60 байтов

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

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

Billywob
источник
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)

resueman
источник
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
histocrat
источник
0

Q (31) ФОРМАТ НЕПРАВИЛЬНОГО ВЫХОДА

{(%/)(x;max x)-min x}(.:)(0::)0

вход

1 2 3

вывод

0 .5 1
протисты
источник
0

Perl - 60

my@a=sort@ARGV;print map{($_-$a[0])/($a[-1]-$a[0])." "}@ARGV
KSFT
источник
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]
Кевин Круйссен
источник