Запас машини


35

Запас машини

Ви отримали доступ до набору даних, tomorrowStocksякий містить ціни акцій від вашої улюбленої справи в NASDAQ. Цей набір даних є контейнером, індексованим минулими відкриттями. Кожен індекс містить ціну акцій на той час.

// Assume the stock market opens at 9:30AM EDT
// tomorrowStocks[] contains the prices of your target stock.
// If the stock is $22 @ 10:30AM EDT
tomorrowStocks[60] == 22

Вихідні дані

Ваше завдання полягає в тому, щоб визначити найкращий можливий результат 1 purchaseі 1 saleз 1 stockз даного набору даних.

Gotchas

  • Ви повинні купувати і продавати рівно 1 акцію.
  • Ви не можете купувати та продавати в один і той же час.
  • Ви повинні придбати, перш ніж продати.

Дані тесту

[1,2,3,4,5]    # 4
[1,99,2,105]   # 104
[99,1,99,100]  # 99
[99,1,1,2,1,3] # 2
[5,4,3,3,1]    # 0
[5,4,3,1]      # -1
[5,2,1]        # -1
[5,4,1]        # -1
[55,45,20,1]   # -10
[5,1]          # -4
[10,7,5,1]     # -2
[7]            # Invalid input -- assume size >= 2

Це ; подайте найкоротшу відповідь улюбленою мовою!


11
Ласкаво просимо до PPCG, приємне перше запитання! :)
FryAmTheEggman

Чи можемо ми припустити, що результат детермінований (тобто завжди є одне рішення, яке, безумовно, є найкращим, і немає зв’язків)
MayorMonty

1
Шкода, що перекладач мови, яку я будую, ще не закінчений, тому що він повинен бути в змозі вирішити це в 4 байти ... Мені потрібно закінчити це якнайшвидше, щоб я не міг пропустити стільки хороших питань!
Стівен Х.

1
@SpeedyNinja Це насправді в тестових випадках. У тестовому випадку [5,4,3,1]ви можете або 5продати, 4або придбати 4і продати, 3щоб отримати оптимальний результат -1.
Мартін Ендер

1
@Fawful Ви можете додати свою відповідь як неконкурентну пізніше. Мені, безумовно, було б цікаво побачити це
CocoaBean

Відповіді:


14

05AB1E , 4 байти

Використовуючи підхід FryAmTheEggman в . Код:

¥ŒOà

Пояснення:

¥     # Calculate the increments of the array.
 Œ    # Get all substring of the array.
  O   # Sum the arrays in the array.
   à  # Get the largest sum and implicitly print that.

Використовує кодування CP-1252 . Спробуйте в Інтернеті! .


2
Чорт, я спробував 4 мови для гри в гольф і забув про 05AB1E. Це я дізнаюсь наступного разу: P
FryAmTheEggman

19

Python 2, 46 байт

f=lambda x:-min(x.pop(0)-max(x),x[1:]and-f(x))

Перевірте це на Ideone .

Як це працює

Це рекурсивний підхід, який використовує переваги зіпсованих порівнянь змішаного типу Python 2.

Найкращим можливим результатом є або різниця максимуму списку з вилученим його першим елементом та першим елементом, або інша різниця, яка не включає перший елемент.

Після вилучення першого елемента з x.pop(0)(який назавжди видаляє його з x ), ми обчислюємо x.pop(0)-max(x). Зауважте, що ця різниця має знак "неправильний".

Якщо оновлений список x все ще містить щонайменше два елементи, x[1:]виходить не порожній список і andзамінює його на мінус рекурсивного виклику, обчислений як -f(x). Як тільки буде занадто мало елементів для продовження, x[1:]and-f(x)оцінюється в порожній список.

Для вибору максимального результату ми беремо мінімум різниці та мінус рекурсивного виклику (або []). Оскільки всі цілі числа суворо менші [], minпросто поверне лівий аргумент, якщо правильний [].

Нарешті, одинарний мінус -виправляє ознаку обчисленого результату.


Це дивно красиво.
MrDuk

11

MATL , 7 байт

2XN!dX>

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

2XN  % Take input implicitly. Two-column 2D array with all combinations of 2 elements.
     % Each combination is a row. Elements in each row are in increasing order
!    % Transpose
d    % Difference of the two numbers in each column
X>   % Maximum value. Display implicitly

Виявляється, це та сама ідея, що і у відповіді Денніса
Луїс Мендо

1
Ау ... Побий мене!
DJMcMayhem

8

Желе , 5 байт

Œcḅ-Ṁ

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

Œcḅ-Ṁ  Main link. Argument: A (integer array)

Œc     Generate all combinations of two elements of A, in order.
  ḅ-   Convert each pair from base -1 to integer.
       This maps [a, b] to b - a.
    Ṁ  Take the maximum of all computed differences.

IŒṡS€ṀМайже такої ж довжини, це занадто погано вживання, перш ніж
підбивати підсумки,

7

Піта, 9

eSsM.:-Vt

Спробуйте тут або запустіть тестовий набір .

Знаходить послідовні відмінності між кожним елементом, а потім знаходить кожну підрядку цього масиву. Нарешті, підсумуйте елементи та поверніть максимальний.

Пояснення:

eSsM.:-Vt
eSsM.:-VtQQ   ## Auto-fill variables
      -VtQQ   ## Splat subtraction on each element of zip(Q[1:], Q)
    .:        ## Get all substrings
  sM          ## Sum each list
eS            ## Take the largest number

Мені було сказано, що цей алгоритм працює не зовсім інтуїтивно. Сподіваємось, цей приклад проілюструє, чому цей алгоритм працює:

[a, b, c, d]
difference between each element (reversed because of how Pyth does this)
[b-a, c-b, d-c]
"substrings" or each continuous slice
[b-a], [c-b], [d-c], [b-a, c-b], [c-b, d-c], [b-a, c-b, d-c]
sum each
[b-a], [c-b], [d-c], [b-a+c-b], [c-b+d-c], [b-a+c-b+d-c]
simplify
[b-a], [c-b], [d-c], [c-a], [d-b], [d-a]

5

Піта, 9

_hS-M.cQ2

Так, pfns!

_hS-M.cQ2

     .cQ2 # generate all 2-elements combinations of Q (argument)
   -M     # map-splat with -: for each combination, substract the elements together
  S       # tort
 h        # take the first
_         # absolute value

Я вважаю _hS-M.cQ2рівнозначним.
FryAmTheEggman

@FryAmTheEggman ах, спасибі Зараз намагаюся подумати, як я міг би змінити -порядок аргументів ... оскільки я маю використовувати _hSта не можу використовуватиeS
Вен

4

PowerShell v2 +, 58 байт

param($n)($n|%{($n[++$i..$n.count]|sort)[-1]-$_}|sort)[-1]

Займає вхід $n, труби кожного елемента в петлю |%{...}. Кожну ітерацію ми розрізаємо $nна основі попередньо збільшеного ++$iдо кінця вхідного масиву, |sortякий, і беремо максимум [-1], а потім віднімаємо поточний елемент $_. Потім ми |sortвсі ці відмінності і знову приймаємо максимум [-1].

Видаляє помилкову помилку з індексом масиву, оскільки ми намагаємося прорізати кінець масиву. Але, оскільки STDERR за замовчуванням ігнорується , нас це не хвилює.


4

JavaScript (ES6), 57 54 байти

a=>(m=Math.max)(...a.map((x,i)=>m(...a.slice(i+1))-x))

У JavaScript простіше взяти максимум залишку масиву і відняти поточний елемент. (У випадку останнього елемента результат все одно буде -Infinity.) Редагувати: Збережено 3 байти завдяки @CharlieWynn.


Я думаю, що (M = Math.max) і використання M пізніше заощадить 3 байти
Charlie Wynn

@CharlieWynn Спасибі, я б тільки спробував with(що не допомагає в цьому випадку).
Ніл

3

J, 21 байт

[:>./@;i.@#<@{."_1-/~

Бере масив значень як аргумент і повертає результат.

Пояснення

[:>./@;i.@#<@{."_1-/~  Input: p
                  -/~  Make a table of all differences between every pair
          #            Get the count of values in p
       i.@             Create a range [0, 1, ..., len(p)-1]
             {."_1     Take that many values from each row of the table
           <@          Box each row of selected values
[:    ;                Unbox and concatenate them
  >./@                 Reduce it by the max and return

2

Java, 141 байт

a->java.util.stream.IntStream.range(0,a.size()-1).map(i->a.subList(i+1,a.size()).stream().reduce(Math::max).get()-a.get(i)).max().getAsInt();

Лямбда приймає список ArrayList і повертає цілий номер.

Невикольований код з тестовими випадками:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.IntStream;

class Test {

    public static void main(String[] args) {
        Function<ArrayList<Integer>, Integer> f = a -> IntStream
            .range(0, a.size()-1)
            .map(i -> a.subList(i+1, a.size()).stream().reduce(Math::max).get() - a.get(i))
            .max()
            .getAsInt();

        System.out.println(f.apply(new ArrayList<>(Arrays.asList(1,2,3,4,5))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(1,99,2,105))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(99,1,99,100))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(99,1,1,2,1,3))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(5,4,3,3,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(5,4,3,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(5,2,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(5,4,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(55,45,20,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(5,1))));
        System.out.println(f.apply(new ArrayList<>(Arrays.asList(10,7,5,1))));
    }
}

Наскільки я знаю, у Java немає способу дивитися вперед у потоці, а маніпулювання методом, з якого генерується потік, дає дивні результати. Так що a.remove(0)всередині карти страшенно порушується потік.


1

VBA, 154

Приймає на вхід у стовпчик А, починаючи з A1, виводить у C1. Потрібно запустити з останньою коміркою у вибраній. Зауважте, що Excel автоматично додає пробіли між термінами в VBA, інакше це може бути додатково розіграно.

Sub s
i = Selection.Row
r = "B1:B" + i-1
Range(r).FormulaArray = "MAX(A2:A$" + i + "-A1)"
Range(r).FillDown
Range("C1").Formula = "MAX(" + r + ")"
End Sub

1

Ява, 116

Ще одне рішення Java, я використав це для доказу, що потоки можуть виглядати красиво, але не завжди корисно для гри в гольф.

int a(int[]a){int t,d=a[1]-a[0],i,j,l=a.length;for(i=0;i<l;i++)for(j=i+1;j<l;j++){t=a[j]-a[i];d=d<t?t:d;}return d;}

в цьому рішенні є багато місця для вдосконалень


1

Clojure, 99 байт

(fn[x](apply max(map #(-(apply max(% 1))(apply min(% 0)))(map #(split-at % x)(range 1(count x))))))

Розбиває список вводу на першу позицію, потім на другу і так далі, тому ми отримуємо такий список, який виглядає приблизно так:

[[[n1][n2 ... nk]][[n1 n2][n3 ... nk]]...[[n1...n(k-1)][nk]]]потім для кожної пари віднімають мінімум перших елементів від max другого елемента, а потім знаходять max від них. Було б коротше, якби Clojure min maxбрали послідовності, а не будь-яку кількість аргументів.

Дивіться це в Інтернеті: https://ideone.com/b2nllT


1

рубін, 52 байти

->a{b=[];(x=a.pop;b+=a.map{|v|x-v})while a[0];b.max}

можливі продажні ціни і перегляньте всі попередні, щоб знайти прибуток. Тоді отримує максимум прибутку.


1

C, 101 99 байт

int i,j,m,h;int f(int*a){m=1<<31;for(;a[i];i++){for(j=i+1;a[j];h=a[j++]-a[i],m=h<m?m:h);}return m;}

Вхід: нульовий завершений масив. Напр. {1,2,3,4,5,0}
Вихід: повертає найкращий результат

Ви можете заощадити 8 байт (всього 93 91), якщо ніколи не хочете втрачати гроші:

int i,j,m,h;int f(int*a){for(;a[i];i++){for(j=i+1;a[j];h=a[j++]-a[i],m=h<m?m:h);}return m;}

1

R, 58 44 байт

max(unlist(sapply(seq(y<-scan()),diff,x=y)))

неозорий

y=scan()                #input
s=1:length(y)           #sequence of same length from 1
l = sapply(s,diff,x=y)  #applies the function diff to each 'lag' in sequence s
                        #and differencing on y
max(unlist(l))          #reforms as vector and finds maximum

EDIT: змінена функція. оригінал нижче.

f=function(x)max(max(x[-1]-x[1]),if(length(x)-2)f(x[-1]))

або, якщо ви готові змиритися з купою попереджувальних повідомлень, позбавтеся від -2 за довжиною, на 56 байт.

f=function(x)max(max(x[-1]-x[1]),if(length(x))f(x[-1]))

І якщо ви відчуваєте, що не торгуєте і не втрачаєте гроші, коли це єдина можливість, ви можете знизитися до 52

f=function(x)max(max(x-x[1]),if(length(x))f(x[-1]))

f=не потрібна.
NoOneIsHere

@NoOneIsHere без нього не буде працювати рекурсія. Я міг би використати Recall, але він набирає більше листів, ніж я втрачаю.
користувач5957401

Ой, вибачте. Я завжди сумую за рекурсією.
NoOneIsHere
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.