Stock Time Machine

35

Stock Time Machine

Vous avez accès à un ensemble de données tomorrowStockscontenant les cours des actions de votre entreprise préférée sur le NASDAQ. Cet ensemble de données est un conteneur indexé par minutes après l'ouverture. Chaque indice contient le prix du stock à ce moment.

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

Sortie

Votre tâche est de déterminer le meilleur résultat possible 1 purchaseet 1 salede 1 stockde l'ensemble de données.

Gotchas

  • Vous devez acheter et vendre exactement 1 action.
  • Vous ne pouvez pas acheter et vendre dans le même créneau horaire.
  • Vous devez acheter avant de vendre.

Données de 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

C'est un ; Soumettez la réponse la plus courte dans votre langue préférée!

MrDuk
la source
11
Bienvenue sur PPCG, belle première question! :)
FryAmTheEggman
Pouvons-nous supposer que le résultat est déterministe (c'est-à-dire qu'il existe toujours une solution qui est définitivement la meilleure, sans aucun lien)
MayorMonty
1
Dommage que l'interprète pour une langue que je suis en train de construire ne soit pas encore terminé, car il devrait pouvoir résoudre ce problème en 4 octets ... Je dois terminer ça au plus vite afin de ne pas rater autant de bonnes questions!
Steven H.
1
@SpeedyNinja C'est en fait dans les cas de test. En cas de test, [5,4,3,1]vous pouvez soit 5et vendre, 4soit acheter pour 4et vendre pour 3obtenir le résultat optimal -1.
Martin Ender
1
@Fawful Vous pouvez ajouter votre réponse non compétitive plus tard. Je serais certainement intéressé de le voir
CocoaBean

Réponses:

14

05AB1E , 4 octets

Utiliser l'approche de FryAmTheEggman . Code:

¥ŒOà

Explication:

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

Utilise le codage CP-1252 . Essayez-le en ligne! .

Adnan
la source
2
Bon sang, j'ai essayé 4 langues de golf et j'ai oublié 05AB1E. Ça m'apprendra pour la prochaine fois: P
FryAmTheEggman
19

Python 2, 46 octets

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

Testez-le sur Ideone .

Comment ça marche

Cette approche récursive tire parti des comparaisons magnifiquement perverses de Python 2.

Le meilleur résultat possible est soit la différence entre le maximum de la liste avec son premier élément supprimé et ce premier élément, soit une autre différence n'impliquant pas le premier élément.

Après avoir extrait le premier élément avec x.pop(0)(ce qui le supprime définitivement de x ), nous calculons x.pop(0)-max(x). Notez que cette différence a le "mauvais" signe.

Si la liste mise à jour x contient toujours au moins deux éléments, x[1:]génère une liste non vide et la andremplace par le négatif d'un appel récursif, calculé comme suit -f(x). Une fois qu'il y a trop peu d'éléments pour continuer, la liste est x[1:]and-f(x)évaluée.

Pour sélectionner le résultat maximal, nous prenons le minimum de la différence et le négatif de l'appel récursif (ou []). Puisque tous les entiers sont strictement inférieurs à [], minretournera simplement son argument de gauche si le bon est [].

Enfin, le moins unaire -corrige le signe du résultat calculé.

Dennis
la source
C'est étrangement beau.
MrDuk
11

MATL , 7 octets

2XN!dX>

Essayez-le en ligne! Ou vérifiez tous les cas de test .

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
Luis Mendo
la source
Il s’avère que c’est la même idée que dans la réponse de Dennis
Luis Mendo
1
Aww ... Battez-moi à elle!
DJMcMayhem
8

Gelée , 5 octets

Œcḅ-Ṁ

Essayez-le en ligne! ou vérifier tous les cas de test .

Comment ça marche

Œ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.
Dennis
la source
IŒṡS€ṀPresque la même longueur, c'est dommage de l'utiliser avant de faire la somme donne parfois la mauvaise réponse ...
FryAmTheEggman
7

Pyth, 9

eSsM.:-Vt

Essayez-le ici ou lancez une suite de tests .

Trouve les différences consécutives entre chaque élément, puis trouve chaque sous-chaîne de ce tableau. Enfin, somme les éléments et retourne le maximum.

Explication:

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

On m'a dit que le fonctionnement de cet algorithme n'était pas totalement intuitif. Espérons que cet exemple illustrera pourquoi cet algorithme fonctionne:

[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]
FryAmTheEggman
la source
5

Pyth, 9

_hS-M.cQ2

Yay 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
Ven
la source
Je crois que _hS-M.cQ2c'est équivalent.
FryAmTheEggman
@FryAmTheEggman ah, merci. Maintenant, essayant de penser comment je pourrais inverser -l'ordre des arguments ... depuis que je dois utiliser _hSet ne peux pas utilisereS
Ven
4

PowerShell v2 +, 58 octets

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

Prend les entrées $n, dirige chaque élément dans une boucle |%{...}. À chaque itération, nous découpons en $nfonction de la valeur pré-incrémentée ++$ià la fin du tableau en entrée |sort, puis prenons le maximum [-1]puis soustrayons l’élément actuel $_. Nous avons ensuite |sorttoutes ces différences et prenons à nouveau le maximum [-1].

Efface une erreur d’index de tableau commentée, car nous essayons de couper au-delà de la fin du tableau. Mais, puisque STDERR est ignoré par défaut , nous ne nous en soucions pas.

AdmBorkBork
la source
4

JavaScript (ES6), 57 54 octets

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

En JavaScript, il est plus facile de prendre le maximum du reste du tableau et de soustraire l'élément en cours. (Dans le cas du dernier élément, le résultat sera toujours -Infinity.) Edit: 3 octets enregistrés grâce à @CharlieWynn.

Neil
la source
Je pense que (M = Math.max) et utiliser M plus tard vous fera économiser 3 octets
Charlie Wynn
@CharlieWynn Merci, j'avais seulement essayé with(ce qui n'aide pas dans ce cas).
Neil
3

J, 21 octets

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

Prend un tableau de valeurs en tant qu'argument et renvoie le résultat.

Explication

[:>./@;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
milles
la source
2

Java, 141 octets

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

Le lambda accepte une ArrayList et retourne un Integer.

Code non-golfé avec cas de 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))));
    }
}

Autant que je sache, Java ne dispose d'aucun moyen de regarder dans un flux, et la manipulation de la méthode à partir de laquelle le flux est généré produit des résultats étranges. Faire ainsi à l' a.remove(0)intérieur d'une carte brise horriblement le flux.


la source
1

VBA, 154

Prend en entrée dans la colonne A à partir de A1, sorties en C1. Doit être exécuté avec la dernière cellule de A sélectionnée. Notez que Excel ajoute automatiquement les espaces entre les termes dans VBA, sinon cela pourrait être joué davantage.

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
Adam Martin
la source
1

Java, 116

Une autre solution java, j’ai utilisé celle-ci pour prouver que les jets pourraient bien paraître, mais pas toujours utiles pour le 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;}

il y a beaucoup de place pour des améliorations dans cette solution

utilisateur902383
la source
1

Clojure, 99 octets

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

Divise la liste d'entrée en première position, puis seconde et ainsi de suite, nous obtenons donc une liste qui ressemble à ceci:

[[[n1][n2 ... nk]][[n1 n2][n3 ... nk]]...[[n1...n(k-1)][nk]]]puis, pour chaque paire, soustrait le minimum des premiers éléments du maximum du second élément, puis en trouve le maximum. Ce serait plus court si Clojure min maxprenait des séquences plutôt qu'un nombre quelconque d'arguments.

Voir en ligne: https://ideone.com/b2nllT

cliffroot
la source
1

ruby, 52 octets

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

apparaît les prix de vente possibles et regarde tout le précédent pour trouver un profit. Puis obtient un profit maximum.

MegaTom
la source
1

C, 101 à 99 octets

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

Entrée: tableau terminé par zéro. Exemple: {1,2,3,4,5,0}
Sortie: renvoie le meilleur résultat.

Vous pouvez économiser 8 octets ( 93 91 au total) si vous ne voulez jamais perdre d’argent:

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;}
Riley
la source
1

R, 58 44 octets

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

non-golfé

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: fonction modifiée. original ci-dessous.

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

ou, si vous êtes prêt à recevoir un tas de messages d'avertissement, supprimez le -2 après la longueur, pour 56 octets.

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

Et si vous avez envie de ne pas trader et de perdre de l'argent alors que c'est la seule possibilité, vous pouvez vous contenter de 52

f=function(x)max(max(x-x[1]),if(length(x))f(x[-1]))
utilisateur5957401
la source
f=n'est pas nécessaire.
NoOneIsHere
@NoOneIsHere la récursivité ne fonctionnera pas sans elle. Je pourrais utiliser Rappel, mais cela ramasse plus de lettres que je n'en perds.
user5957401
Oh pardon. La récursion me manque toujours.
NoOneIsHere