Magazyn czasu


35

Magazyn czasu

Masz dostęp do zestawu danych, tomorrowStocksktóry zawiera ceny akcji z Twojej ulubionej firmy na NASDAQ. Ten zestaw danych to kontener indeksowany minutami po otwarciu. Każdy indeks zawiera cenę akcji w tym czasie.

// 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

Wydajność

Twoim zadaniem jest, aby ustalić najlepszy możliwy wynik 1 purchasei 1 salesię 1 stockz danego zbioru danych.

Gotchas

  • Musisz kupić i sprzedać dokładnie 1 akcję.
  • Nie możesz kupować i sprzedawać w tym samym przedziale czasowym.
  • Musisz kupić przed sprzedażą.

Dane testowe

[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

To jest ; prześlij najkrótszą odpowiedź w swoim ulubionym języku!


11
Witamy w PPCG, fajne pierwsze pytanie! :)
FryAmTheEggman

Czy możemy założyć, że wynik jest deterministyczny (tzn. Zawsze istnieje jedno rozwiązanie, które jest zdecydowanie najlepsze i nie ma powiązań)
MayorMonty

1
Szkoda, że ​​tłumacz dla języka, który buduję, nie jest jeszcze ukończony, ponieważ powinien być w stanie rozwiązać ten problem w 4 bajtach ... Muszę skończyć jak najszybciej, żeby nie przegapić tylu dobrych pytań!
Steven H.,

1
@SpeedyNinja To jest faktycznie w przypadkach testowych. W przypadku testowym [5,4,3,1]możesz albo 5sprzedać 4lub sprzedać lub kupić 4i sprzedać, 3aby uzyskać optymalny wynik -1.
Martin Ender

1
@Fawful Możesz dodać swoją odpowiedź jako niekonkurującą później. Na pewno byłbym zainteresowany jego obejrzeniem
CocoaBean

Odpowiedzi:


14

05AB1E , 4 bajty

Korzystanie z podejścia FryAmTheEggman . Kod:

¥ŒOà

Wyjaśnienie:

¥     # 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.

Wykorzystuje kodowanie CP-1252 . Wypróbuj online! .


2
Cholera, próbowałem 4 języków golfowych i zapomniałem o 05AB1E.
Nauczy

19

Python 2, 46 bajtów

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

Przetestuj na Ideone .

Jak to działa

Jest to podejście rekurencyjne, które wykorzystuje pięknie perwersyjne porównania Pythona 2 typu mieszanego.

Najlepszy możliwy wynik to albo różnica maksimum listy z usuniętym pierwszym elementem i tym pierwszym elementem, albo inna różnica, która nie obejmuje pierwszego elementu.

Po wyodrębnieniu pierwszego elementu za pomocą x.pop(0)(który trwale usuwa go z x ), obliczamy x.pop(0)-max(x). Zauważ, że ta różnica ma „zły” znak.

Jeśli zaktualizowana lista x nadal zawiera co najmniej dwa elementy, x[1:]zwraca niepustą listę i andzastępuje ją negatywem wywołania rekurencyjnego, obliczonego jako -f(x). Gdy jest już za mało elementów, aby kontynuować, przechodzi x[1:]and-f(x)do pustej listy.

Aby wybrać maksymalny wynik, bierzemy minimalną różnicę i minus wywołania rekurencyjnego (lub []). Ponieważ wszystkie liczby całkowite są ściśle mniejsze niż [], minpo prostu zwróci lewy argument, jeśli prawy [].

Wreszcie, jednostkowy minus -koryguje znak obliczonego wyniku.


To jest dziwnie piękne.
MrDuk


8

Galaretka , 5 bajtów

Œcḅ-Ṁ

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

Jak to działa

Œ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€ṀPrawie tej samej długości, szkoda, że ​​używasz, zanim od czasu do czasu daje złą odpowiedź ...
FryAmTheEggman

7

Pyth, 9

eSsM.:-Vt

Wypróbuj tutaj lub uruchom pakiet testowy .

Znajduje kolejne różnice między poszczególnymi elementami, a następnie wyszukuje każdy podciąg tej tablicy. Na koniec zsumuj elementy i zwróć maksymalny.

Wyjaśnienie:

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

Wspomniano mi, że ten algorytm działa, nie jest całkowicie intuicyjny. Mam nadzieję, że ten przykład ilustruje, dlaczego ten algorytm działa:

[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

Pyth, 9

_hS-M.cQ2

Tak 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

Uważam, że _hS-M.cQ2jest równoważny.
FryAmTheEggman

@FryAmTheEggman ah, dzięki. Teraz próbuję wymyślić, jak mogę odwrócić -kolejność argumentów ... ponieważ muszę używać _hSi nie mogę używaćeS
Ven

4

PowerShell v2 +, 58 bajtów

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

Pobiera dane wejściowe $n, potokuje każdy element w pętli |%{...}. Każdą iterację kroimy $nna podstawie wstępnie zwiększonej ++$ido końca tablicy wejściowej, |sortktóra i bierze maksimum [-1], a następnie odejmuje bieżący element $_. Następnie |sortwszystkie te różnice i ponownie przyjmujemy maksimum [-1].

Usuwa pełny błąd indeksu tablic, ponieważ próbujemy przeciąć koniec tablicy. Ale ponieważ STDERR jest domyślnie ignorowany , nie obchodzi nas to.


4

JavaScript (ES6), 57 54 bajtów

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

W JavaScript łatwiej jest wziąć maksimum reszty tablicy i odjąć bieżący element. (W przypadku ostatniego elementu wynikiem będzie nadal -Infinity.) Edycja: Zapisano 3 bajty dzięki @CharlieWynn.


Myślę, że (M = Math.max) i użycie M później pozwoli ci zaoszczędzić 3 bajty
Charlie Wynn

@CharlieWynn Dzięki, tylko próbowałem with(co nie pomaga w tym przypadku).
Neil,

3

J, 21 bajtów

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

Bierze tablicę wartości jako argument i zwraca wynik.

Wyjaśnienie

[:>./@;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 bajtów

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();

Lambda akceptuje ArrayList i zwraca liczbę całkowitą.

Nieskluczony kod z przypadkami testowymi:

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

O ile mi wiadomo, Java nie ma sposobu patrzenia w przyszłość w strumieniu, a manipulowanie metodą, z której generowany jest strumień, daje dziwne wyniki. Tak więc robienie a.remove(0)wewnątrz mapy strasznie przerywa strumień.


1

VBA, 154

Pobiera dane wejściowe w kolumnie A, zaczynając od A1, dane wyjściowe w C1. Musi być uruchamiany z wybraną ostatnią komórką w A. Należy pamiętać, że program Excel automatycznie dodaje spacje między terminami w języku VBA, w przeciwnym razie można by dalej zagrać w golfa.

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

Java, 116

Inne rozwiązanie Java, wykorzystałem to, aby udowodnić, że strumienie mogą wyglądać ładnie, ale nie zawsze są przydatne w golfie.

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

w tym rozwiązaniu jest dużo miejsca na ulepszenia


1

Clojure, 99 bajtów

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

Dzieli listę wejściową na pierwszej pozycji, a następnie na drugiej itd., Więc otrzymujemy listę, która wygląda następująco:

[[[n1][n2 ... nk]][[n1 n2][n3 ... nk]]...[[n1...n(k-1)][nk]]]następnie dla każdej pary odejmuje minimum pierwszych pierwiastków od maksimum drugiego elementu, a następnie znajduje maksimum od nich. Byłoby to krótsze, gdyby Clojure min maxbrał sekwencje zamiast jakiejkolwiek liczby argumentów.

Zobacz online: https://ideone.com/b2nllT


1

rubin, 52 bajty

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

wyskakuje możliwe ceny sprzedaży i spójrz na wszystkie poprzednie, aby znaleźć zysk. Wtedy dostaje maksymalny zysk.


1

C, 101 99 bajtów

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

Dane wejściowe: tablica zakończona zerem. Np. {1,2,3,4,5,0}
Wyjście: zwraca najlepszy wynik

Możesz zaoszczędzić 8 bajtów ( 93 91 ogółem), jeśli nigdy nie chcesz stracić pieniędzy:

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 bajtów

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

bez golfa

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

EDYCJA: zmieniona funkcja. oryginał poniżej.

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

lub, jeśli chcesz znieść kilka ostrzeżeń, pozbądź się -2 po długości, na 56 bajtów.

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

A jeśli masz ochotę nie handlować i tracić pieniędzy, gdy jest to jedyna możliwość, możesz zejść do 52

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

f=nie jest potrzebne.
NoOneIsHere

@NoOneIsHere rekursja nie będzie działać bez niego. Mógłbym użyć Przypomnienia, ale zbiera więcej liter niż tracę.
user5957401,

Przepraszam. Zawsze tęsknię za rekurencją.
NoOneIsHere
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.