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.