Скорочення чисел


10

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

Ваше завдання полягає в тому, щоб скоротити число від «лінійно картографування» їх від 0.0до 1.0. Це означає, що найменше число в масиві буде відображено до 0,0, найбільше - до 1,0.

Ви отримуєте масив як параметр (всередині функції) або аргументи stdin / program (ви можете вибрати). Виведіть результат у форматі double1;double2;double3;.... Вихід повинен мати той самий порядок, що і вхідний .

Якщо ви хочете, ви можете округлити вихід до двох цифр після десяткової крапки. Після десяткової коми має бути не менше 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

"використання вбудованих функцій (наприклад, matematias 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

Оновлено. Хоча отримати принаймні одну цифру після десяткових - важко
Оптимізатор

If you want, you can round the output to 2 digits after the decimal pointце найпростіший спосіб, на який я думаю
edc65

@ Edc65 Але немає ніякого способу , щоб перетворити 1в 1.0те , що я зробив , за винятком.
Оптимізатор

Ні. Чи можу я натякнути?
edc65

4

Пітон 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 представляє подвійний 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 Вибачте за це, я це виправив.
isaacg

Чи не створює свою власну мову, яку ви змінюєте з часом, трохи розтягуючи правила? Ви, очевидно, можете просто додати нову функцію, щоб скоротити програму?
Кріс Джефферсон

3
@ChrisJefferson Я завжди використовую найновішу версію мови, яка вийшла до того, як поставили проблему. Оскільки це все підштовхується до Github, можна перевірити, що я нічого не додаю після публікації проблеми. Це стандартне правило CG.SE - мова повинна бути старшою за питання, і я її дотримуюся.
isaacg

2

Октава 25

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

Передбачається, що введення входить, lі оскільки це інтерактивна оболонка, результат друкується автоматично (чи це дозволено?)


2
inputХоча Octave / Matlab повинен отримати введення користувача та імітувати STDIN. Ви також можете написати функцію. Також, чи друкує результат у правильному форматі?
Мартін Ендер

І ні, просто повернення та надрукування оболонки зазвичай не враховується. Гольфскрипт тощо подібні тому, що мова визначає, що стек друкується в кінці кінців. Але це не стосується, наприклад, Javascript. І я не думаю про Matlab / Octave.
Інго Бюрк

2

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

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

Старий код без цифр після коми:

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

Візьміть мінімум вектора, візьміть різницю між максимумом і мінімумом вектора, відніміть мінімум від кожного елемента і розділіть на різницю між min і max.

Відредагований код для друку двох цифр після десяткової крапки:


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 байти при застосуванні до min та max).

Трохи застаріле пояснення: (буде змінено пізніше)

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 байт

Безголівки:

(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

Q (31) ФОРМУВАННЯ ВИХІДНОГО ВИКОРИСТАННЯ

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

вхід

1 2 3

вихід

0 .5 1


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

Невикористаний і тестовий код:

Спробуйте тут.

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.