Машина времени запаса


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

Можем ли мы предположить, что результат является детерминированным (т.
Е.

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€ṀПочти такой же длины, это очень плохо делать с использованием до суммирования иногда дает неправильный ответ ...
FryAmTheEggman

7

Пиф, 9

eSsM.:-Vt

Попробуйте здесь или запустите Test Suite .

Находит последовательные различия между каждым элементом, а затем находит каждую подстроку этого массива. Наконец, суммируйте элементы и верните максимальный.

Объяснение:

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

Уу пфнс!

_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
Ven

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 байта
Чарли Уинн

@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

Принимает входные данные в столбце A, начиная с 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)))

ungolfed

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

РЕДАКТИРОВАТЬ: изменил функцию. оригинал ниже.

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, но он собирает больше букв, чем я теряю.
user5957401

Ой, извини. Я всегда скучаю по рекурсии.
NoOneIsHere
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.