เวลาเดินทางผู้ค้าหุ้น


21

เรื่องราว
นานมาแล้ว Bobby สร้างกระเป๋าเงิน Bitcoin ด้วย 1 Satoshi (1e-8 BTC หน่วยสกุลเงินที่เล็กที่สุด) และลืมมันไป เหมือนกับคนอื่น ๆ อีกหลายคนเขาในภายหลังว่า "ประณามถ้าฉันลงทุนไปมากกว่านั้น ... "
เขาไม่ได้อุทิศเวลาและเงินทั้งหมดให้กับการสร้างไทม์แมชชีน เขาใช้เวลาส่วนใหญ่ในโรงรถของเขาไม่รู้เรื่องทางโลกและมีข่าวลือแพร่สะพัดเกี่ยวกับเขา เขาเสร็จต้นแบบหนึ่งวันก่อนที่ไฟฟ้าของเขาจะถูกปิดเนื่องจากการชำระเงินที่ไม่ได้รับ เงยหน้าขึ้นมองจากโต๊ะทำงานของเขาเขาเห็นรถตู้ตำรวจดึงขึ้นไปที่บ้านของเขาดูเหมือนกับเพื่อนบ้านที่มีจมูกยาวคิดว่าเขาทำงานห้องปฏิบัติการปรุงยาในโรงรถของเขาและเรียกตำรวจ
เมื่อไม่มีเวลาทำการทดสอบเขาคว้าแท่ง USB ที่มีข้อมูลอัตราแลกเปลี่ยนของปีที่ผ่านมาเชื่อมต่อ Flux Capacitor กับ Quantum Discombobulator และพบว่าตัวเองเคลื่อนย้ายกลับมาทั้งวันเมื่อเขาสร้างกระเป๋าเงินของเขา

ภารกิจ
จากข้อมูลอัตราแลกเปลี่ยนให้ค้นหาว่า Bobby สามารถทำเงินได้เท่าใด เขาทำตามกฎง่าย ๆ : "ซื้อต่ำ - ขายสูง" และเมื่อเขาเริ่มด้วยทุนเล็ก ๆ น้อย ๆ เราคิดว่าการกระทำของเขาจะไม่ส่งผลกระทบต่ออัตราแลกเปลี่ยนในอนาคต

อินพุต
รายการของการลอย> 0 ไม่ว่าจะเป็นสตริงที่คั่นด้วยอักขระเดียว (ขึ้นบรรทัดใหม่, แท็บ, ช่องว่าง, อัฒภาค, อะไรก็ได้ที่คุณต้องการ) ส่งผ่านเป็นอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรมอ่านจาก textfile หรือ STDIN หรือส่งผ่านพารามิเตอร์ เพื่อฟังก์ชั่น คุณสามารถใช้ประเภทข้อมูลหรืออาร์เรย์แทนสตริงได้เพราะโดยทั่วไปแล้วมันเป็นเพียงสตริงที่มีเครื่องหมายวงเล็บ

เอาท์พุท
ปัจจัยที่ Bobbys ทุนคูณด้วยการสิ้นสุดของการซื้อขาย

ตัวอย่าง

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 เนื่องจากมันกำลังจะลดลงเราขาย Bitcoins ทั้งหมดในราคา 4.8 nanodollar ตัวคูณ = 1 อัตราแลกเปลี่ยน: 0.4, ไม่ทำอะไรเลย
อัตราแลกเปลี่ยน: 0.24 $ / BTC และเพิ่มขึ้น: แปลงทุก $ เป็น 2 Satoshis Factor = 1 (ค่าเงินดอลลาร์ยังคงไม่เปลี่ยนแปลง)
อัตราแลกเปลี่ยน: 0.39 - 2.1 $ / BTC: ไม่ทำอะไรเลย
อัตราแลกเปลี่ยน: 2.24 $ / BTC: ขายทุกอย่างก่อนที่จะลดลง 44.8 nanodollar, factor = 9.33
อัตราแลกเปลี่ยน: 2.07 $ / BTC: ซื้อ 2.164 Satoshis, factor = 9.33
อัตราแลกเปลี่ยน: 2.41 $ / BTC: ซื้อ 52.15 nanodollar, factor = 10.86

Output: 10.86

รายละเอียดเพิ่มเติม
คุณอาจเพิกเฉยกรณีขอบแปลก ๆ เช่นค่าคงที่ค่าศูนย์หรือค่าลบจำนวนอินพุตเดียวเท่านั้น ฯลฯ
คุณสามารถสร้างหมายเลขสุ่มของคุณเองสำหรับการทดสอบหรือใช้แผนภูมิหุ้นจริง นี่คืออินพุตอีกต่อไปสำหรับการทดสอบ (ผลลัพธ์ที่คาดหวังประมาณ 321903884.638)
อธิบายสั้น ๆ ว่าโค้ดของคุณทำอะไร
กราฟได้รับการชื่นชม แต่ไม่จำเป็น


หากเรารับตัวเลขผ่านอาร์กิวเมนต์ของฟังก์ชั่นมันจะต้องยังคงเป็นสตริงหรือเราจะใช้อาร์เรย์โดยตรง
Martin Ender

@ MartinBüttnerฉันไตร่ตรองเรื่องนี้ซักพักหนึ่งไม่ว่าจะเป็นสายอักขระอาร์เรย์ตัวเลขหรือตัวเลือกฟรีมีบางภาษาที่ได้เปรียบเสมอ ดูเหมือนจะไม่มีข้อตกลงทั่วไปเกี่ยวกับเรื่องนี้และการเขียนโปรแกรมสองโปรแกรมหนึ่งรายการสำหรับตัวเลขและอีกรายการหนึ่งสำหรับอินพุตสตริงและค่าเฉลี่ยของคะแนนทั้งสองดูเหมือนว่าเกินความจริง
DenDenDo

สิ่งที่เกี่ยวกับไดรฟ์ที่เป็นไปไม่ได้ไม่มีที่สิ้นสุด :)
Doorknob

2
กลับไปที่ปัญหาเราจำเป็นต้องปัดเศษค่า BTC และ / หรือ $ ที่ความแม่นยำที่กำหนดในทุกรอบซ้ำหรือไม่ ตัวอย่างเช่นในกระเป๋าเงิน BTC ของโลกแห่งความจริงจะต้องถูกปัดเศษให้กับ Satoshi สิ่งนี้สร้างความแตกต่างเนื่องจากในตัวอย่างของคุณที่ 2.07 คุณสามารถซื้อ 2s เท่านั้น (ไม่ใช่ 2.164) 2.41 ของคุณคุณซื้อ 48.2 n $ (ไม่ใช่ 52.15) ดังนั้นปัจจัยคือ 10.04 (ไม่ใช่ 10.86) นอกจากว่าคุณจะเก็บเงิน $ wallet แยกต่างหากพร้อมกับการเปลี่ยนแปลงและจำเป็นต้องเพิ่มกลับในแต่ละครั้ง แล้วดอลลาร์ล่ะ ทุกคนในวันนี้สามารถเรียกร้องให้มี nanodollar ได้หรือไม่? ฉันเชื่อว่าจำนวนที่เล็กที่สุดที่สามารถถือได้คือ 1 ¢
Tobia

1
@CortAmmon: คุณกำลังบอกว่าการซื้อขาย BTC นั้นไม่วุ่นวายใช่มั้ย ;-)
Steve Jessop

คำตอบ:


10

APL, 16 ตัวอักษร

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

รุ่นนี้ใช้@Frxstremของขั้นตอนวิธีการที่เรียบง่ายและ@xnorของmax(r,1)ความคิด

นอกจากนี้สมมติว่าซีรีส์โดยรวมเพิ่มขึ้นนั่นคือค่า bitcoin แรกนั้นเล็กกว่าค่าสุดท้าย สิ่งนี้สอดคล้องกับคำอธิบายปัญหา เพื่อให้ได้สูตรทั่วไปที่กว้างขึ้นต้องลดอัตราสองครั้งแรกโดยเพิ่ม 2 ตัวอักษร:{×/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 ให้ผลการทดสอบกับเราสองสามกรณี!
เบีย

1
ฉันชอบโซลูชัน APL ที่ดีเพราะเมื่อใดก็ตามที่ฉันดูพวกเขาพวกเขาเรียกตัวกรอง "นี่คือไฟล์ไบนารีซึ่งพูดพล่อยๆ" และฉันเริ่มมองหานามสกุลไฟล์เพื่อหาวิธีเปิดมัน
Cort Ammon - Reinstate Monica

@CortAmmon ที่ไม่ได้ไม่มีที่ใดเลย: APL ใช้ตัวดำเนินการกราฟิกหลายโหล บนพื้นผิวพวกเขาสามารถเตือนคุณถึงสัญลักษณ์จากชุดอักขระ 8 บิต DOS นอกจากนี้ยังเป็นภาษาที่สั้นมากซึ่งหมายความว่า APL มีข้อมูลจำนวนมาก คุณสมบัติทั้งสองนี้รวมกันเพื่อกระตุ้นความรู้สึกของไฟล์ไบนารีที่ถูกทิ้งลงในหน้าต่าง DOS แต่จะคงอยู่จนกระทั่งคุณเรียนรู้ที่จะชื่นชมความงามของสัญลักษณ์และไวยากรณ์ของ APL
Tobia

6

Python 47

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

ตัวอย่างการทำงานเกี่ยวกับกรณีการทดสอบ

ใช้รายการของลอย ทวีคูณคูณกับปัจจัยกำไรจากองค์ประกอบสองรายการแรกจนกระทั่งมีองค์ประกอบน้อยกว่าสองรายการ สำหรับกรณีฐานให้ที่เท่าเทียมกันTrue1

การใช้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ให้เรากำหนดองค์ประกอบทั้งสองเข้าด้วยกันและเราลบมันกลับมาฟรีก่อนพิมพ์


testcase ที่ยาวเกินกว่าค่า จำกัด การเรียกซ้ำเริ่มต้นที่ 1 f (x [: 999]) ยังคงให้ผลลัพธ์ที่ถูกต้อง สำหรับการป้อนข้อมูลที่นานขึ้นคุณสามารถแยกเป็นส่วน ๆ([n:(n+1)*500 + 1] for n in range(N_elem/500) )และคูณปัจจัยบางส่วนได้
DenDenDo

ขีด จำกัด การเรียกซ้ำขึ้นอยู่กับการใช้งาน คุณสามารถใช้Stackless Pythonเพื่อหลีกเลี่ยงได้
xnor

หรือเพียงแค่ใช้sys.setrecursionlimit(ใน CPython)
253751

3

Python, 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เป็นอินพุตที่เข้ารหัสเป็นรายการ ฟังก์ชันส่งคืนปัจจัย


อาจเป็นเพียงรุ่น Python ของฉัน แต่ฉันต้องใช้1.แทน1ตอนท้ายของฟังก์ชันมิฉะนั้นฉันจะได้รับ TypeError: descriptor ' mul ' ต้องใช้วัตถุ 'float' แต่ได้รับ 'int'
Tobia

BTW อัลกอริธึมอัจฉริยะ!
เบีย

คุณไม่ต้องการf=ส่วนนั้น
wizzwizz4


1

Pyth , 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 เพื่อปัดเศษและใช้ int แทนการใช้บูลเพื่อตัดตัวอักษร จะจำได้ว่าสำหรับปริศนาในอนาคต!


เฮ้ขอบคุณสำหรับคำแนะนำ ฉันปรับปรุงตามที่แนะนำ
Darren Breen

ดูเหมือนว่าคุณกำลังปัดเลขสองหลักMath.Floor(...)ซึ่งไม่จำเป็นต้องใช้ นอกจากนี้ฉันไม่ทราบว่าเป็นไปได้ใน C # แต่มักจะคุณสามารถใช้ 1 คนและ 0 สำหรับและtrue false
DenDenDo

ขออภัยต้องใช้การปัดเศษคิดเป็น 2 ทำให้ทุกคนกำลังพิมพ์ 10.86 และฉันได้รับ 10.866 แล้วปัดเศษขึ้น คุณสามารถใช้ภาษาอื่น ๆ ได้ แต่ไม่ใช่ภาษา C # แม้ว่านั่นจะทำให้ฉันมีความคิดดังนั้นตอนนี้ฉันใช้ 1 และ 0 สำหรับการตรวจสอบบูลีนของฉัน ลดลงอีกเล็กน้อย ขอบคุณ!
Darren Breen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.