Stock Time Machine


35

Stock Time Machine

Você obteve acesso a um conjunto de dados, tomorrowStocksque contém os preços das ações da sua empresa favorita na NASDAQ. Este conjunto de dados é um contêiner indexado por minutos após a abertura. Cada índice contém o preço das ações naquele 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

Saída

Sua tarefa é determinar o melhor resultado possível de 1 purchasee da partir do conjunto de dados fornecido.1 sale1 stock

Gotchas

  • Você deve comprar e vender exatamente 1 ação.
  • Você não pode comprar e vender no mesmo horário.
  • Você deve comprar antes de vender.

Dados de teste

[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

Este é um ; envie a resposta mais curta no seu idioma favorito!


11
Bem-vindo ao PPCG, boa primeira pergunta! :)
FryAmTheEggman

Podemos supor que a saída é determinística (isto Há sempre uma solução que é definitivamente o melhor, e sem vínculos)
MayorMonty

11
Pena que o intérprete para um idioma que estou construindo ainda não terminou, pois deve ser capaz de resolver isso em 4 bytes ... Preciso terminar o mais rápido possível para não perder tantas perguntas boas!
Steven H.

11
@SpeedyNinja Na verdade, isso está nos casos de teste. Em caso de teste [5,4,3,1]você pode mas para 5e vender para 4ou comprar para 4e vender para 3obter o resultado ideal de -1.
Martin Ender

11
@ Fawful Você pode adicionar sua resposta como não concorrente posteriormente. Eu definitivamente estar interessado em vê-lo
CocoaBean

Respostas:


14

05AB1E , 4 bytes

Usando a abordagem de FryAmTheEggman . Código:

¥ŒOà

Explicaçã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.

Usa a codificação CP-1252 . Experimente online! .


2
Droga, tentei 4 idiomas de golfe e esqueci o 05AB1E. Isso vai me aprender da próxima vez: P
FryAmTheEggman

19

Python 2, 46 bytes

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

Teste em Ideone .

Como funciona

Essa é uma abordagem recursiva que tira proveito das comparações de tipo misto maravilhosamente perversas do Python 2.

O melhor resultado possível é a diferença do máximo da lista com o primeiro elemento removido e o primeiro elemento, ou outra diferença que não envolve o primeiro elemento.

Depois de extrair o primeiro elemento com x.pop(0)(que o remove permanentemente de x ), calculamos x.pop(0)-max(x). Observe que essa diferença tem o sinal "errado".

Se a lista atualizada x ainda contém pelo menos dois elementos, x[1:]gera uma lista não vazia e a andsubstitui pelo negativo de uma chamada recursiva, calculada como -f(x). Quando houver muito poucos elementos para continuar, ele será x[1:]and-f(x)avaliado como uma lista vazia.

Para selecionar o resultado máximo, assumimos o mínimo da diferença e o negativo da chamada recursiva (ou []). Como todos os números inteiros são estritamente menores que [], minsimplesmente retornará seu argumento à esquerda se o direito for [].

Finalmente, o unário menos -corrige o sinal do resultado calculado.


Isso é estranhamente bonito.
MrDuk


8

Gelatina , 5 bytes

Œcḅ-Ṁ

Experimente online! ou verifique todos os casos de teste .

Como funciona

Œ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€ṀQuase do mesmo tamanho, é muito ruim fazer o uso antes de somar, às vezes, dá a resposta errada ...
FryAmTheEggman

7

Pitão, 9

eSsM.:-Vt

Experimente aqui ou execute um conjunto de testes .

Localiza as diferenças consecutivas entre cada elemento e localiza cada substring dessa matriz. Por fim, some os elementos e retorne o máximo.

Explicação:

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

Foi mencionado para mim que esse algoritmo funciona não é totalmente intuitivo. Espero que este exemplo ilustre por que esse algoritmo funciona:

[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

Pitão, 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

Eu acredito que _hS-M.cQ2é equivalente.
FryAmTheEggman

@FryAmTheEggman ah, obrigado. Agora, tentando pensar em como eu poderia reverter -a ordem dos argumentos ... já que tenho que usar _hSe não posso usar #eS
1520 Ven Ven

4

PowerShell v2 +, 58 bytes

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

Recebe entrada $n, canaliza cada elemento em um loop |%{...}. A cada iteração, dividimos com $nbase no pré-incrementado ++$iaté o final da matriz de entrada, |sortque , pegamos o máximo [-1]e subtraímos o elemento atual $_. Em seguida, |sorttodas essas diferenças e, novamente, tomamos o máximo [-1].

Lança um erro detalhado do índice da matriz, porque tentamos passar além do final da matriz. Mas, como STDERR é ignorado por padrão , não nos importamos.


4

JavaScript (ES6), 57 54 bytes

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

No JavaScript, é mais fácil tirar o máximo do restante da matriz e subtrair o elemento atual. (No caso do último elemento, o resultado ainda será -Infinity.) Editar: salvou 3 bytes graças a @CharlieWynn.


Eu acho que (M = Math.max) e usar M depois poupará 3 bytes
Charlie Wynn

@CharlieWynn Obrigado, eu só tentei with(o que não ajuda neste caso).
Neil

3

J, 21 bytes

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

Pega uma matriz de valores como argumento e retorna o resultado.

Explicação

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

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

O lambda aceita um ArrayList e retorna um número inteiro.

Código não protegido com casos de teste:

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

Até onde eu sei, Java não tem uma maneira de olhar adiante em um fluxo, e manipular o método a partir do qual o fluxo é gerado produz resultados estranhos. Assim, fazer a.remove(0)dentro de um mapa interrompe terrivelmente o fluxo.


1

VBA, 154

Recebe a entrada na coluna A começando em A1, sai em C1. Deve ser executado com a última célula em A selecionada. Observe que o Excel adiciona automaticamente os espaços entre os termos no VBA; caso contrário, isso pode ser mais prejudicado.

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

Outra solução java, usei esta para provar que, os fluxos podem parecer bons, mas nem sempre são úteis para jogar golfe.

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

há muito espaço para melhorias nesta solução


1

Clojure, 99 bytes

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

Divide a lista de entrada na primeira posição, depois na segunda e assim por diante, para obter uma lista parecida com esta:

[[[n1][n2 ... nk]][[n1 n2][n3 ... nk]]...[[n1...n(k-1)][nk]]]em seguida, para cada par, subtraia o mínimo dos primeiros elementos do máximo do segundo elemento e encontre o máximo deles. Seria mais curto se o Clojure min maxestivesse pegando seqüências em vez de qualquer número de argumentos.

Veja on-line: https://ideone.com/b2nllT


1

rubi, 52 bytes

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

aparece os preços de venda possíveis e analisa todos os itens anteriores para encontrar lucro. Então obtém lucro máximo.


1

C, 101 99 bytes

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

Entrada: matriz terminada nula. Por exemplo: {1,2,3,4,5,0}
Saída: retorna o melhor resultado

Você pode salvar 8 bytes ( 93 91 total) se nunca quiser perder dinheiro:

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 bytes

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

destroçado

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: função alterada. original abaixo.

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

ou, se você estiver disposto a aceitar várias mensagens de aviso, livre-se do -2 após o comprimento, por 56 bytes.

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

E se você sentir vontade de não negociar e perder dinheiro quando essa é a única possibilidade, você pode chegar a 52

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

f=não é necessário.
NoOneIsHere

A recursão @NoOneIsHere não funcionará sem ela. Eu poderia usar o Recall, mas ele pega mais letras do que eu perco.
precisa saber é o seguinte

Oh, desculpe. Eu sempre sinto falta da recursão.
NoOneIsHere 8/08/16
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.