คุณมีเคล็ดลับทั่วไปอะไรสำหรับการเล่นกอล์ฟในจูเลีย ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ Julia (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
คุณมีเคล็ดลับทั่วไปอะไรสำหรับการเล่นกอล์ฟในจูเลีย ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ Julia (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
คำตอบ:
หมายเหตุ: ด้านล่างอาจมีเคล็ดลับที่ล้าสมัยเนื่องจาก Julia ยังไม่เสถียรในแง่ของโครงสร้าง แต่อย่างใด
เทคนิคเล็กน้อยในการบันทึกอักขระบางตัว
\ =divและคุณสามารถพิมพ์a\bแทนdiv(a,b)ได้ สังเกตพื้นที่ - นี่เป็นสิ่งจำเป็นเพื่อหลีกเลี่ยงการแยกวิเคราะห์เป็นตัวดำเนินการ "\ =" โปรดทราบด้วยว่าหากโอเวอร์โหลดที่ระดับพรอมต์ของ REPL ให้ใช้(\)=Base.(\)หรือ\ =Base. \เพื่อรีเซ็ต หมายเหตุ: บางฟังก์ชั่นมีตัวดำเนินการที่กำหนดไว้ล่วงหน้าของ UTF-8 เช่น÷for divตามที่ Alex A.a>0?"Hi":""ใช้"Hi"^(a>0)เพื่อบันทึกหนึ่งไบต์หรือสำหรับบูลีน a ใช้"Hi"^aเพื่อบันทึกสามไบต์a=split("Hi there"," ")คุณอาจหลีกเลี่ยงa[1]และa[2]โดยการใช้a,b=split("Hi there"," ")ซึ่งสามารถอ้างอิงเป็นaและbบันทึกสามไบต์สำหรับการใช้งานแต่ละครั้งในราคาเพียงอักขระพิเศษสองตัวที่ได้รับมอบหมาย เห็นได้ชัดว่าอย่าทำเช่นนี้หากคุณสามารถทำงานกับการดำเนินการเวกเตอร์ได้[] - สำหรับอาร์เรย์แสดงออกเทียบเท่ากับA[] A[1]โปรดทราบว่าสิ่งนี้ใช้ไม่ได้กับ Strings หากคุณต้องการได้ตัวอักษรตัวแรกหรือ Tuples==[]สำหรับอาร์เรย์และ==()สำหรับ tuples; ในทำนองเดียวกันสำหรับการลบ, การใช้งานและ!=[] !=()สำหรับสตริงใช้==""สำหรับที่ว่างเปล่า แต่ใช้>""สำหรับที่ไม่ว่างเปล่าเนื่องจาก "" เป็นคำศัพท์ก่อนหน้าสตริงอื่น ๆx<=1&&"Hi"สามารถเขียนเป็นx>1||"Hi"บันทึกอักขระ (ตราบใดที่การส่งคืนบูลีนไม่สำคัญ)in('^',s) contains(s,"^")หากคุณสามารถใช้อักขระอื่นคุณสามารถบันทึกได้อีกเล็กน้อย'^'∈sแต่โปรดทราบว่า∈มีขนาด 3 ไบต์ใน UTF-8minimum(x)หรือmaximum(x)ใช้min(x...)หรือmax(x...)เพื่อโกนอักขระหนึ่งตัวออกจากรหัสของคุณหากคุณรู้ว่าxจะมีองค์ประกอบอย่างน้อยสององค์ประกอบ หรือถ้าคุณรู้ว่าองค์ประกอบทั้งหมดxจะไม่เป็นลบให้ใช้minabs(x)หรือmaxabs(x)r"(?m)match^ this"พิมพ์r"match^ this"mบันทึกตัวอักษรสามตัวreverse(x)ยาวกว่าหนึ่งไบต์flipud(x)และจะทำงานแบบเดียวกันดังนั้นหลังจึงดีกว่า{[1,2]}ไม่ได้{1,2}) - จูเลีย 0.4 Any[[1,2]]คุณจะต้องendภายในการทำดัชนีอาเรย์มันจะถูกแปลงโดยอัตโนมัติตามความยาวของอาเรย์ / สตริง ดังนั้นแทนที่จะk=length(A)ใช้A[k=end]เพื่อบันทึก 3 ตัวอักษร โปรดทราบว่าสิ่งนี้อาจไม่เป็นประโยชน์หากคุณต้องการใช้ k ทันที วิธีนี้ยังใช้งานได้ในหลายมิติกรณี - A[k=end,l=end]จะได้ขนาดของแต่ละมิติของA- อย่างไรก็ตาม(k,l)=size(A)จะสั้นกว่าหนึ่งไบต์ในกรณีนี้ดังนั้นให้ใช้เฉพาะเมื่อคุณต้องการเข้าถึงองค์ประกอบสุดท้ายในเวลาเดียวกันทันทีA[k=1:end]ซึ่งในกรณีนี้จะถือการจับคู่k iterator 1:length(A)สิ่งนี้มีประโยชน์เมื่อคุณต้องการใช้อาร์เรย์Aในเวลาเดียวกันcollect(A)ใช้[A...]ซึ่งจะทำสิ่งเดียวกันและบันทึก 4 ไบต์"$(s[i])"หรือdec(s[i])สำหรับนิพจน์หรือตัวแปรหลายตัวอักษรและ"$i"สำหรับตัวแปรอักขระเดี่ยว?:แทน&&หรือ||สำหรับการกำหนดเงื่อนไข - นั่นคือถ้าคุณต้องการที่จะดำเนินการได้รับมอบหมายเท่านั้นบนเงื่อนไขบางอย่างที่คุณสามารถบันทึกหนึ่งไบต์โดยการเขียนcond?A=B:1มากกว่าcond&&(A=B)หรือมากกว่าcond?1:A=B cond||(A=B)โปรดทราบว่าที่1นี่เป็นค่าตัวอย่างunionหรือ∪แทนunique - union(s)จะทำเช่นเดียวกับunique(s)และบันทึกไบต์ในกระบวนการ หากคุณสามารถใช้อักขระที่ไม่ใช่ ASCII แล้ว∪(s)จะทำสิ่งเดียวกันและ∪มีค่าใช้จ่ายเพียง 3 ไบต์แทน 5 unionไบต์ในsplit("Hi there")เพราะอาร์กิวเมนต์รูปแบบเริ่มต้นที่ช่องว่าง
                    การกำหนดตัวดำเนินการใหม่สามารถบันทึกไบต์จำนวนมากในวงเล็บและเครื่องหมายจุลภาค
สำหรับตัวอย่างที่ไม่แตกต่างกันให้เปรียบเทียบการประยุกต์ใช้แบบเรียกซ้ำต่อไปนี้ของลำดับ Fibonacci:
F(n)=n>1?F(n-1)+F(n-2):n # 24 bytes
!n=n>1?!~-n+!(n-2):n     # 20 bytes
!n=n>1?!~-n+!~-~-n:n     # 20 bytesตัวดำเนินการที่นิยามใหม่ยังคงมีความสำคัญเริ่มต้น
โปรดทราบว่าเราไม่สามารถเพียงแค่สลับออก!ในความโปรดปรานของ~ตั้งแต่~ถูกกำหนดไว้แล้วสำหรับจำนวนเต็มในขณะที่!ถูกกำหนดไว้เฉพาะสำหรับ Booleans
แม้ไม่มีการเรียกซ้ำการกำหนดตัวดำเนินการใหม่จะสั้นกว่าการกำหนดฟังก์ชันไบนารี เปรียบเทียบคำจำกัดความต่อไปนี้ของการทดสอบการหารอย่างง่าย
f(x,y)=x==0?y==0:y%x==0 # 23 bytes
(x,y)->x==0?y==0:y%x==0 # 23 bytes
x->y->x==0?y==0:y%x==0  # 22 bytes
x\y=x==0?y==0:y%x==0    # 20 bytesต่อไปนี้แสดงวิธีการกำหนดตัวดำเนินการไบนารีใหม่เพื่อคำนวณฟังก์ชัน Ackermann:
A(m,n)=m>0?A(m-1,n<1||A(m,n-1)):n+1    # 35 bytes
^ =(m,n)->m>0?(m-1)^(n<1||m^~-n):n+1   # 36 bytes
| =(m,n)->m>0?m-1|(n<1||m|~-n):n+1     # 34 bytes
m\n=m>0?~-m\(n<1||m\~-n):n+1           # 28 bytesโปรดทราบว่า^ยิ่งใช้เวลานานกว่าการใช้ตัวระบุทั่วไปเนื่องจากลำดับความสำคัญสูงเกินไป
ดังที่ได้กล่าวมาก่อน
m|n=m>0?m-1|(n<1||m|~-n):n+1           # 28 bytesจะไม่ทำงานสำหรับอาร์กิวเมนต์จำนวนเต็มเนื่องจาก|มีการกำหนดไว้แล้วในกรณีนี้ คำจำกัดความของจำนวนเต็มสามารถเปลี่ยนแปลงได้ด้วย
m::Int|n::Int=m>0?m-1|(n<1||m|~-n):n+1 # 38 bytesแต่นั่นยาวยาว อย่างไรก็ตามมันใช้งานได้ถ้าเราผ่านการลอยตัวเป็นอาร์กิวเมนต์ซ้ายและจำนวนเต็มเป็นอาร์กิวเมนต์ที่ถูกต้อง
อย่าล่อลวงด้วยปัจจัย (n)ฟังก์ชั่นไลบรารี่พื้นฐานที่ล่อลวงfactor(n)มีข้อบกพร่องร้ายแรง: มันจะคืนค่าการแยกตัวประกอบของจำนวนเต็มของคุณในรูปแบบที่ไม่เรียงลำดับ Dictดังนั้นจึงจำเป็นต้องมีค่าใช้จ่ายสูงcollect(keys())และcollect(values())อาจcatเป็นsortไปได้ที่จะได้รับข้อมูลที่คุณต้องการ ในหลายกรณีอาจมีราคาถูกกว่าที่จะพิจารณาจากแผนกการทดลอง เศร้า แต่จริง
ใช้แผนที่ mapเป็นทางเลือกที่ดีในการวนซ้ำ ระวังความแตกต่างระหว่างmapและmap!และใช้ประโยชน์จากฟังก์ชั่นแบบแทนที่เมื่อคุณทำได้
ใช้ mapreduce ช่วย mapreduceขยายการทำงานของแผนที่ให้ดียิ่งขึ้นและสามารถเป็นตัวช่วยประหยัดไบต์ที่สำคัญได้
ฟังก์ชั่นนิรนามนั้นยอดเยี่ยมมาก! .. โดยเฉพาะเมื่อผ่านไปยังmapฟังก์ชั่นดังกล่าว
ฟังก์ชันอาเรย์สะสม cumprod , ฟังก์ชันที่cumsumมีรสชาติcumminและชื่ออื่นที่คล้ายกันเปิดใช้งานการดำเนินการสะสมตามมิติที่ระบุของอาเรย์ n-Dim (หรือ * un * ถูกระบุหากอาร์เรย์เป็น 1-d)
สัญกรณ์สั้น ๆ สำหรับใด ๆเมื่อคุณต้องการเลือกทุกมิติของอาเรย์หลายมิติ (หรือ Dict) เช่นA[Any,2]คุณสามารถบันทึกไบต์โดยใช้A[:,2]
ใช้สัญกรณ์บรรทัดเดียวสำหรับฟังก์ชั่นแทนคุณfunction f(x) begin ... endมักจะทำให้ง่ายขึ้นf(x)=(...)
ใช้ผู้ประกอบการที่สามมันสามารถประหยัดพื้นที่สำหรับการแสดงออก If-Then-Else คำเตือน:ในขณะที่เป็นไปได้ในบางภาษาคุณไม่สามารถตัดส่วนหลังลำไส้ใหญ่ในจูเลียได้ นอกจากนี้ตัวดำเนินการเป็นระดับนิพจน์ใน Julia ดังนั้นคุณไม่สามารถใช้เพื่อดำเนินการตามเงื่อนไขของรหัสทั้งหมดได้ 
if x<10 then true else false endVS
x<10?true:false
สิ่งนี้อาจเป็นไปได้ในภาษาอื่น ๆ แต่มักจะยาวกว่าวิธีที่ตรงไปตรงมา อย่างไรก็ตามความสามารถของจูเลียในการกำหนดผู้ประกอบการที่ไม่เป็นเอกภาพและไบนารีทำให้มันค่อนข้างกอล์ฟ
ตัวอย่างเช่นหากต้องการสร้างตารางการบวกการลบการคูณและการหารสำหรับตัวเลขธรรมชาติตั้งแต่ 1 ถึง 10 เราสามารถใช้
[x|y for x=1:10,y=1:10,| =(+,-,*,÷)]ซึ่งนิยามใหม่ของไบนารีประกอบการ|เป็น+, -, *และ÷จากนั้นคำนวณx|yสำหรับการดำเนินงานแต่ละคนและxและyในช่วงที่ต้องการ
มันใช้งานได้กับผู้ประกอบการเอก ตัวอย่างเช่นในการคำนวณจำนวนเชิงซ้อน1 + 2i , 3-4i , -5 + 6iและ-7-8i , ค่าลบ, ค่าคอนจูเกตคอมเพล็กซ์และค่าผกผันคูณ
[~x for~=(+,-,conj,inv),x=(1+2im,3-4im,-5+6im,-7-8im)]ซึ่งนิยามใหม่ของเอกภาคผู้ประกอบการ~เป็น+, -, conjและinvจากนั้นคำนวณ~xตัวเลขที่ซับซ้อนที่ต้องการทั้งหมด
ลำดับหญิงและชาย (ไบนารี)
การเปลี่ยน Case (unary)
บางครั้งคำหลักสามารถติดตามค่าคงที่ได้ทันทีโดยไม่จำเป็นต้องเว้นวรรคหรืออัฒภาค ตัวอย่างเช่น:
n->(for i=1:n n-=1end;n)หมายเหตุการขาดพื้นที่ระหว่างที่และ1 endนี้ยังเป็นจริงสำหรับที่เกิดขึ้นหลังจากที่มีการวงเล็บใกล้คือend)end
ดำเนินการหารจำนวนเต็มโดยใช้÷มากกว่าdiv()หรือมากเกินไปตัวดำเนินการ โปรดทราบว่า÷มีค่า 2 ไบต์ใน UTF-8
ใช้vec()หรือA[:](สำหรับบางอาร์เรย์A) แทนที่จะreshape()เป็นไปได้
สร้างฟังก์ชั่นแทนโปรแกรมเต็มรูปแบบเมื่อได้รับอนุญาตในกฎการท้าทาย มันสั้นกว่าที่จะกำหนดฟังก์ชั่นที่รับอินพุตมากกว่าการกำหนดตัวแปรโดยการอ่านจาก stdin ตัวอย่างเช่น:
n->(n^2-1)
n=read(STDIN,Int);n^2-1ตัวแปรสามารถเพิ่มขึ้นภายในอาร์กิวเมนต์ไปยังฟังก์ชัน ตัวอย่างเช่นต่อไปนี้คือคำตอบของฉันสำหรับการค้นหาเลขฐานสองแบบ 1 เบาบางถัดไป :
n->(while contains(bin(n+=1),"11")end;n)ซึ่งสั้นกว่าการเพิ่มขึ้นnภายในวง
return  f(x)=x+4เป็นเหมือน f(x)=return x+4แต่สั้นกว่า Julia จะส่งคืนผลลัพธ์ของคำสั่งล่าสุดเสมอ[x for x in 1:4]มีความยาวเกิน 3 อักขระ แต่เทียบเท่า[x for x=1:4]   เปิดตัวใน Julia 0.5 มันเป็นเหมือนแผนที่ แต่ใช้ตัวอักษรน้อยลงและออกอากาศพฤติกรรมเหนือสิ่งอื่น - ซึ่งหมายความว่าคุณสามารถเขียนแลมบ์ดาน้อยลงเพื่อจัดการกับสิ่งต่าง ๆ
ค่อนข้างมากกว่า:
map(f,x) - 8 ตัวอักษรf.(x) - 5 ตัวอักษรยังดีกว่า:
map(a->g(a,y),x) - 16 ตัวอักษรg.(x,[y]) - 9 ตัวอักษร