시간 여행 주식 상인


21

이야기
오래 전 Bobby는 1 Satoshi (1e-8 BTC, 가장 작은 통화 단위)로 Bitcoin 지갑을 만들어 잊었습니다. 다른 많은 사람들과 마찬가지로 그는 나중에 "만약 내가 더 많은 투자를했다면 ..."
공상을 멈추지 않고 타임머신을 만드는 데 시간과 돈을 전부 바칩니다. 그는 대부분의 시간을 자신의 차고에서 보내고, 세상의 일과 그에 관한 소문을 알지 못합니다. 그는 지불금을 놓쳐서 전기가 꺼지기 직전에 프로토 타입을 완성합니다. 그는 자신의 작업대를 올려다 보면서 경찰차가 집으로 올라가는 것을 보았고 코가 막힌 이웃들이 차고에서 마약 연구소를 운영하고 있다고 생각한 것 같습니다.
그는 테스트를 실행할 시간이 없었으며 지난 몇 년간의 환율 데이터로 USB 스틱을 잡고 플럭스 커패시터를 Quantum Discombobulator에 연결하고 지갑을 만들었던 날로 돌아간 것을 발견했습니다.

작업
환율 데이터가 제공되면 Bobby가 얼마나 많은 돈을 벌 수 있는지 알아보십시오. 그는 "매수-고매 매수"라는 매우 간단한 규칙을 따르고 무한한 작은 자본으로 시작하기 때문에 그의 행동은 미래의 환율에 영향을 미치지 않을 것이라고 가정합니다.

입력
단일 문자 (줄 바꿈, 탭, 공백, 세미콜론 등)로 구분 된 문자열로서 프로그램에 명령 행 인수로 전달되거나 텍스트 파일 또는 STDIN에서 읽거나 매개 변수로 전달 된 부동 소수점> 0 함수에. 기본적으로 대괄호가있는 문자열이기 때문에 문자열 대신 숫자 데이터 유형 또는 배열을 사용할 수 있습니다.

산출
바비 자본에 거래 종료를 곱한 계수.

Input:  0.48 0.4 0.24 0.39 0.74 1.31 1.71 2.1 2.24 2.07 2.41

환율 : 0.48 $ / BTC 하락할 예정이므로 모든 비트 코인을 4.8 나노 달러에 판매합니다. 요소 = 1 환율 : 0.4, 아무것도하지 마십시오
환율 : 0.24 $ / BTC 및 상승 : 모든 $를 2 Satoshis로 변환하십시오. 요인 = 1 (달러 가치는 여전히 변하지 않음)
환율 : 0.39-2.1 $ / BTC : 아무것도하지 마십시오
환율 : 2.24 $ / BTC : 하락하기 전에 모든 것을 판매하십시오. 44.8 나노 달러, 계수 = 9.33
환율 : 2.07 $ / BTC : 2.164 사토시 구매, 요인 = 9.33
환율 : 2.41 $ / BTC : 52.15 나노 달러, 인수 = 10.86 구매

Output: 10.86

추가 세부 사항
상수 입력, 0 또는 음수 값, 하나의 입력 숫자 등과 같은 이상한 경우를 무시할 수 있습니다
. 실제 주식 차트를 테스트하거나 사용하기 위해 임의로 임의의 숫자를 생성하십시오. 다음 은 테스트를위한 더 긴 입력입니다 (예상되는 출력 약 321903884.638).
코드가 무엇을하는지 간단히 설명
하십시오.


함수 인수를 통해 숫자를 가져와도 여전히 문자열이어야합니까, 아니면 직접 배열을 취할 수 있습니까?
Martin Ender

@ MartinBüttner 입력이 문자열이든 숫자 배열이든 자유 선택이든 관계없이 한동안 그것에 대해 숙고했습니다. 이점을 얻는 언어는 항상 있습니다. 이것에 대한 일반적인 합의는없는 것 같고, 두 개의 프로그램을 작성하는 것은 하나는 숫자 입력 용이고 다른 하나는 문자열 입력 용이며 두 점수를 평균화하는 것은 과도한 것으로 보입니다.
DenDenDo

무한 불가능 드라이브는 어떻습니까? :)
Doorknob

2
문제로 돌아가서, 반복 할 때마다 주어진 정밀도로 BTC 및 / 또는 $ 값을 반올림해야합니까? 예를 들어, 실제 세계에서 BTC 지갑은 사토시로 반올림되어야합니다. 이 예에서는 2.07에서는 2 (2.164 제외) 만 구입할 수 있기 때문에 차이가 있습니다. 그런 다음 2.41에서 2는 48.2 n $ (52.15 아님)를 사서 계수는 10.04 (10.86 아님)입니다. 당신은 변경과 함께 별도의 $ 지갑을 유지하고 매번 다시 추가해야하지 않는 한. 달러는 어떻습니까? 오늘날 누구나 나노 달러를 가지고 있다고 주장 할 수 있습니까? 내가 가질 수있는 가장 작은 양은 1 ¢라고 생각합니다.
Tobia

1
@CortAmmon : 당신은 BTC 거래는 말을하는지 없는 혼란? ;-)
Steve Jessop

답변:


10

APL, 16 자

{×/1⌈÷/⊃⍵,¨¯1⌽⍵}

이 버전은 @Frxstrem 의 더 간단한 알고리즘과 @xnormax(r,1)아이디어를 사용합니다.

또한 시리즈가 전체적으로 상승한다고 가정합니다. 즉, 첫 번째 비트 코인 값이 마지막 비트 코인 값보다 작습니다. 이것은 문제 설명과 일치합니다. 보다 일반적인 공식을 얻으려면 두 문자를 추가하여 처음 몇 가지 요율을 삭제해야합니다.{×/1⌈÷/⊃1↓⍵,¨¯1⌽⍵}

예:

    {×/1⌈÷/⊃⍵,¨¯1⌽⍵}  0.48 0.4 0.24 0.39 0.74 1.31 1.71 2.1 2.24 2.07 2.41
10.86634461
    {×/1⌈÷/⊃⍵,¨¯1⌽⍵}  (the 1000 array from pastebin)
321903884.6

설명:

환율 데이터로 시작하십시오.

    A←0.48 0.4 0.24 0.39 0.74 1.31 1.71 2.1 2.24 2.07 2.41

각 숫자를 이전 숫자와 쌍을 이루고 (첫 번째는 마지막과 짝을 이루어) 행렬에 넣습니다.

    ⎕←M←⊃A,¨¯1⌽A
0.48 2.41
0.4  0.48
0.24 0.4
0.39 0.24
0.74 0.39
1.31 0.74
1.71 1.31
2.1  1.71
2.24 2.1
2.07 2.24
2.41 2.07

나누기를 기준으로 각 행을 줄이고 비율을 1보다 높게 유지 한 다음 비율을 곱셈으로 결합합니다. 이는 연속적인 환율 상승의 반복 요인과 첫 환율과 마지막 환율 사이의 스퓨리어스 비율을 제거합니다.

    ×/1⌈÷/M
10.86634461

항상 첫 번째 위치에서 판매해야한다는 가정은 더 긴 입력에 실패하고 1보다 작은 수를 반환합니다 (분명히 불가능합니다).
Frxstrem

@Frxstrem 감사합니다. 이제 스크립트와 동일한 결과를 제공합니다. OP가 결과와 함께 몇 가지 테스트 사례를 제공하면 더 도움이 될 것입니다!
Tobia

1
나는 그들이 그것을 볼 때마다 "이것은 이진 파일 횡설수설"필터를 트리거하고 그것을 여는 방법을 알아 내기 위해 파일 확장자를 찾기 시작하기 때문에 좋은 APL 솔루션을 좋아합니다.
Cort Ammon-복원 Monica Monica

전혀 근거가없는 @CortAmmon : APL은 수십 개의 그래픽 연산자를 사용합니다. 표면상에서 8 비트 DOS 문자 세트의 기호를 상기시킬 수 있습니다. 또한 매우 간결한 언어이므로 APL 라인은 정보 엔트로피가 매우 높습니다. 이 두 기능이 결합되어 DOS 창에 덤프 된 이진 파일의 느낌을 유발합니다. 그러나 APL의 기호와 구문의 아름다움을 이해하는 법을 배울 때까지 지속됩니다.
Tobia

6

파이썬, 47

f=lambda t:2>len(t)or max(t[1]/t[0],1)*f(t[1:])

테스트 사례에서 실행 예제 .

수레 목록을 작성하십시오. 두 요소보다 적을 때까지 처음 두 요소의 이익 계수에 재귀 적으로 곱합니다. 기본 사례의 경우 Truewhich is equals을 제공합니다 1.

를 사용 pop하면 동일한 수의 문자가 제공됩니다.

f=lambda t:2>len(t)or max(t[1]/t.pop(0),1)*f(t)

목록의 끝에서 시작됩니다.

f=lambda t:2>len(t)or max(t.pop()/t[-1],1)*f(t)

비교를 위해 Python 2의 반복 코드는 49 자, 2 자 더 깁니다.

p=c=-1
for x in input():p*=max(x/c,1);c=x
print-p

c=-1가상의 첫 번째 "이동"이 절대로 이익을 보이지 않도록하는 것은 시작입니다 . 제품을 시작 -1하지 않고 1두 요소를 모두 할당 할 수 있으며 인쇄하기 전에 무료로 음화 할 수 있습니다.


더 긴 테스트 케이스는 기본 재귀 한계를 1만큼 초과합니다. f (x [: 999])는 여전히 올바른 결과를 제공합니다. 더 긴 입력을 위해 그것을 덩어리 ([n:(n+1)*500 + 1] for n in range(N_elem/500) )로 나누고 부분적인 요소를 곱할 수 있습니다
DenDenDo

재귀 한계는 구현에 따라 다릅니다. Stackless Python 을 사용 하여 피할 수 있습니다.
xnor

또는 그냥 사용하십시오 sys.setrecursionlimit(CPython에서)
user253751

3

파이썬, 79 81 76 77 바이트

f=lambda x:reduce(float.__mul__,(a/b for a,b in zip(x[1:],x[:-1]) if a>b),1.)

x목록으로 인코딩 된 입력입니다. 이 함수는 계수를 반환합니다.


어쩌면 그냥 내 파이썬 버전입니다,하지만 난 사용했다 1.대신 1, 함수의 끝에서 다른 I GET 형식 오류 : 설명은 ' MUL은 'A '부동'객체를 필요로하지만, 'INT'를 받았습니다
Tobia

BTW, 스마트 알고리즘!
Tobia

f=부분 은 필요하지 않습니다 .
wizzwizz4


1

피 이스 , 18

u*GeS,1ceHhHC,QtQ1

설명:

u                 reduce, G is accumulator, H iterates over sequence
 *G               multiply G by
   eS             max(               
     ,1               1,
       ceHhH            H[1]/H[0])
 C                H iterates over zip(
  ,QtQ                                Q,Q[1:])
 1                G is initialized to 1

max(H[1]/H[0],1) @xnor 덕분에 아이디어


1

C #, 333 , 313

나의 첫 번째 시도. 아마 더 최적화 할 수는 있지만 첫 번째 시도와 마찬가지로 중단 될 것입니다!.

double a(double [] b){var c=0.0;var d=1;for(int i=0;i<b.Count();i++){c=(d==1)?(((i+1)<b.Count()&&b[i+1]<=b[i]&&d==1)?((c==0)?b[i]:b[i]*c):((i+1)>=b.Count()?(c*b[i])/b[0]:c)):((i+1)<b.Count()&&b[i+1]>b[i]&&d==0)?c/b[i]:c;d=((i+1)<b.Count()&&b[i+1]<b[i]&&d==1)?0:((i+1)<b.Count()&&b[i+1]>b[i]&&d==0)?1:d;}return c;}

입력

0.48, 0.4, 0.24, 0.39, 0.74, 1.31, 1.71, 2.1, 2.24, 2.07, 2.41

산출

10.86

편집 : DenDenDo 덕분에 math.floor를 사용하여 문자를 자르기 위해 bool 대신 int를 사용하고 반올림하지 말 것을 제안했습니다. 미래의 퍼즐을 위해 그것을 기억할 것입니다!


헤야, 팁 주셔서 감사합니다. 제안대로 업데이트했습니다.
대런 브린

Math.Floor(...)필요하지 않은 두 자리로 반올림하는 것 같습니다 . 또한, 나는 C #에서의 가능 여부를 알 수는 없지만, 일반적으로는 1과 0을 사용 true하고 false.
DenDenDo

죄송합니다, 모든 사람이 10.86을 인쇄하고 10.866을 받고 반올림했기 때문에 2로 반올림해야한다고 생각했습니다. 다른 C 언어에는 사용할 수 있지만 C #에는 사용할 수 없습니다. 그것이 나에게 아이디어를 주었으므로 이제 내 부울 검사에 1과 0을 사용하고 있습니다. 조금 더 줄였습니다. 감사!
대런 브린
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.