Stock Time Machine


35

Stock Time Machine

Hai ottenuto l'accesso a un set di dati, tomorrowStocksche contiene i prezzi delle azioni della tua attività preferita sul NASDAQ. Questo set di dati è un contenitore indicizzato dall'apertura dell'ultimo minuto. Ogni indice contiene il prezzo del titolo in quel momento.

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

Produzione

Il vostro compito è quello di determinare il miglior risultato possibile di 1 purchasee 1 saledel 1 stockdalla data set di dati.

gotchas

  • È necessario acquistare e vendere esattamente 1 azione.
  • Non è possibile acquistare e vendere nella stessa fascia oraria.
  • Devi comprare prima di vendere.

Dati di test

[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

Questo è un ; invia la risposta più breve nella tua lingua preferita!


11
Benvenuto in PPCG, bella prima domanda! :)
FryAmTheEggman,

Possiamo supporre che l'output sia deterministico (cioè c'è sempre una soluzione che è definitivamente la migliore, e senza legami)
MayorMonty

1
Peccato che l'interprete per una lingua che sto costruendo non sia ancora finito, in quanto dovrebbe essere in grado di risolverlo in 4 byte ... Devo finire al più presto in modo da non perdere così tante buone domande!
Steven H.

1
@SpeedyNinja Questo è in realtà nei casi di test. Nel caso di test [5,4,3,1]è possibile ma non 5vendere e vendere 4o acquistare 4e vendere per 3ottenere il risultato ottimale di -1.
Martin Ender,

1
@Fawful Potresti aggiungere la tua risposta come non competitiva in seguito. Sarei sicuramente interessato a vederlo
CocoaBean,

Risposte:


14

05AB1E , 4 byte

Utilizzando l'approccio di FryAmTheEggman . Codice:

¥ŒOà

Spiegazione:

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

Utilizza la codifica CP-1252 . Provalo online! .


2
Accidenti, ho provato 4 lingue da golf e mi sono dimenticato di 05AB1E. Questo mi imparerà per la prossima volta: P
FryAmTheEggman,

19

Python 2, 46 byte

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

Provalo su Ideone .

Come funziona

Questo è un approccio ricorsivo che sfrutta i raffinati confronti di tipo misto perverso di Python 2.

Il miglior risultato possibile è la differenza del massimo dell'elenco con il suo primo elemento rimosso e quel primo elemento o un'altra differenza che non coinvolge il primo elemento.

Dopo aver estratto il primo elemento con x.pop(0)(che lo rimuove definitivamente da x ), calcoliamo x.pop(0)-max(x). Si noti che questa differenza ha il segno "sbagliato".

Se l'elenco aggiornato x contiene ancora almeno due elementi, x[1:]produce un elenco non vuoto e lo andsostituisce con il negativo di una chiamata ricorsiva, calcolato come -f(x). Una volta che ci sono troppo pochi elementi per continuare, x[1:]and-f(x)restituisce un elenco vuoto.

Per selezionare il risultato massimo, prendiamo il minimo della differenza e il negativo della chiamata ricorsiva (o []). Poiché tutti i numeri interi sono rigorosamente inferiori a [], minrestituirà semplicemente l'argomento sinistro se è quello giusto [].

Infine, il meno unario -corregge il segno del risultato calcolato.


Questo è stranamente bello.
Mr Duk,


8

Gelatina , 5 byte

Œcḅ-Ṁ

Provalo online! o verifica tutti i casi di test .

Come funziona

Œ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€ṀQuasi della stessa lunghezza, è un
peccato

7

Pyth, 9

eSsM.:-Vt

Provalo qui o esegui una Test Suite .

Trova le differenze consecutive tra ciascun elemento, quindi trova ogni sottostringa di tale array. Infine, sommare gli elementi e restituire il massimo.

Spiegazione:

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

Mi è stato detto che questo algoritmo funziona non è del tutto intuitivo. Speriamo che questo esempio spiegherà perché questo algoritmo funziona:

[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

Sì 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

Credo _hS-M.cQ2sia equivalente.
FryAmTheEggman,

@FryAmTheEggman ah, grazie. Ora provo a pensare come potrei invertire -l'ordine degli argomenti ... dato che devo usare _hSe non posso usareeS
Ven

4

PowerShell v2 +, 58 byte

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

Accetta input $n, convoglia ogni elemento in un loop |%{...}. Ogni iterazione, suddividiamo in $nbase a pre-incrementato ++$ifino alla fine dell'array di input, |sortquello, e prendiamo il massimo [-1], quindi sottraggiamo l'elemento corrente $_. Abbiamo quindi |sorttutte queste differenze, e di nuovo prendiamo il massimo [-1].

Elimina un errore dettagliato dell'indice dell'array, poiché proviamo a tagliare oltre la fine dell'array. Ma, poiché STDERR è ignorato per impostazione predefinita , non ci interessa.


4

JavaScript (ES6), 57 54 byte

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

In JavaScript è più semplice prendere il massimo del resto dell'array e sottrarre l'elemento corrente. (Nel caso dell'ultimo elemento il risultato sarà comunque -Infinito.) Modifica: 3 byte salvati grazie a @CharlieWynn.


Penso (M = Math.max) e l'utilizzo di M in seguito ti farà risparmiare 3 byte
Charlie Wynn,

@CharlieWynn Grazie, ci avevo solo provato with(il che non aiuta in questo caso).
Neil,

3

J, 21 byte

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

Prende una matrice di valori come argomento e restituisce il risultato.

Spiegazione

[:>./@;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 byte

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 accetta un ArrayList e restituisce un numero intero.

Codice non golfato con casi di test:

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

Per quanto ne so, Java non ha modo di guardare avanti in uno stream e manipolare il metodo da cui viene generato lo stream produce strani risultati. Così facendo a.remove(0)all'interno di una mappa si interrompe orribilmente il flusso.


1

VBA, 154

Accetta l'ingresso nella colonna A a partire da A1, produce in C1. Deve essere eseguito con l'ultima cella in A selezionata. Si noti che Excel aggiunge automaticamente gli spazi tra i termini in VBA, altrimenti questo potrebbe essere ulteriormente risolto.

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

Un'altra soluzione java, l'ho usata per dimostrare che i flussi potrebbero sembrare belli, ma non sempre utili per giocare a golf.

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

c'è molto spazio per miglioramenti in questa soluzione


1

Clojure, 99 byte

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

Divide l'elenco di input in prima posizione, poi in seconda e così via, in modo da ottenere un elenco simile al seguente:

[[[n1][n2 ... nk]][[n1 n2][n3 ... nk]]...[[n1...n(k-1)][nk]]]quindi per ogni coppia sottrae il minimo dei primi elementi dal massimo del secondo elemento e quindi trova il massimo da essi. Sarebbe più breve se Clojure'smin max stesse prendendo sequenze piuttosto che un numero qualsiasi di argomenti.

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


1

rubino, 52 byte

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

mostra i possibili prezzi di vendita e guarda tutti i precedenti per trovare profitto. Quindi ottiene il massimo profitto.


1

C, 101 99 byte

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

Input: matrice terminata null. Ad esempio {1,2,3,4,5,0}
Output: restituisce il risultato migliore

Puoi risparmiare 8 byte ( 93 91 in totale) se non vuoi mai perdere denaro:

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 byte

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

EDIT: funzione cambiata. originale sotto.

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

oppure, se sei disposto a tollerare un sacco di messaggi di avviso, elimina la lunghezza -2 dopo, per 56 byte.

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

E se hai voglia di non fare trading e perdere denaro quando questa è l'unica possibilità, puoi scendere a 52

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

f=non è necessario.
NoOneIsHere

@NoOneIsHere la ricorsione non funzionerà senza di essa. Potrei usare Richiama, ma raccoglie più lettere di quelle che perdo.
user5957401

Oh scusa. Mi manca sempre la ricorsione.
NoOneIsHere
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.