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


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.