เคล็ดลับสำหรับการเล่นกอล์ฟใน <ทุกภาษา>


81

จุดประสงค์ของโพสต์นี้คือการรวบรวมเคล็ดลับการเล่นกอล์ฟทั้งหมดที่สามารถนำไปใช้อย่างง่ายดาย<all languages>มากกว่าที่เฉพาะเจาะจง

โพสต์คำตอบเท่านั้นว่าตรรกะสามารถนำไปใช้กับส่วนใหญ่ของภาษา

กรุณาหนึ่งเคล็ดลับต่อคำตอบ


5
"ส่วนใหญ่" โดยตัวชี้วัดอะไร?
หยุดหมุนทวนเข็มนาฬิกา

2
@leftaroundabout โดยตัวชี้วัดของคำเดียวกัน
ajax333221

8
ปัญหาคือมีหลายภาษาที่มักจะเป็นภาษาทดลอง (อายุสั้น) ที่มีกระบวนทัศน์ที่ผิดปกติมากซึ่งการแสดงออกของการเขียนโปรแกรมทั่วไปไม่สมเหตุสมผลเลย ดังนั้น "เสียงส่วนใหญ่ของทุกภาษา" จึงเป็นไปไม่ได้ที่จะเติมเต็ม คุณควร จำกัด บางอย่างเช่น "ส่วนใหญ่ของภาษาที่ใช้เป็นประจำใน codegolf.SE" ในขณะที่คำตอบที่ดูค่อนข้างมากเช่น "ส่วนใหญ่ของภาษา C-ระยะไกลที่ได้รับ" แต่ผู้ที่แม้ว่าส่วนใหญ่ของทั้งหมดที่เขียนรหัสถูกเขียนในพวกเขาไม่ได้เป็นส่วนใหญ่ของภาษา
หยุดหมุนทวนเข็มนาฬิกา

3
รอบซ้ายฉันเดาว่าเราทุกคนรู้ว่าพวกเขาหมายถึงอะไร นี่เป็นเรื่องเกี่ยวกับการปรับให้เหมาะสมกับภาษาโดยส่วนใหญ่นั่นคือไม่เพียง แต่มีประโยชน์ใน Brainfuck แต่อาจจะเป็น Python, C, Java และ Fortran พร้อมกัน แนวคิดทั่วไปที่คุณสามารถนำไปใช้ในหลายภาษาที่ทำงานคล้ายกัน ฉันไม่คิดว่าจำเป็นต้องแม่นยำและเฉพาะเจาะจงในเคล็ดลับและคำถาม CW นี่เป็นเรื่องเกี่ยวกับการช่วยเหลือผู้อื่นในการเล่นกอล์ฟ
Joey

14
หวังว่าจะไม่มีใครสร้างภาษาที่เรียกว่า<all languages>...
mbomb007

คำตอบ:


72

ผสานลูป

โดยปกติคุณสามารถรวมลูปสองอันที่ตามมาหรือสองลูปซ้อนกันเป็นหนึ่งเดียว

ก่อน:

for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();

หลังจาก:

for (i=0; i<a+b; i++) i<a?foo():bar();

ugoren ห่วงยังคงไม่เหมือนเดิม @Gaffi ถูกต้อง
kaoD

5
@kaoD ในทั้งสองกรณีfooเรียกว่าaเวลาbarเรียกว่าbครั้ง นี้เป็นเพราะใน "หลัง" ห่วงวิ่งa+bครั้งแรกaโทรคนถัดไปเรียกfoo bar
ugoren

ฉันดูที่นี่อีกครั้ง (มากไปมากภายหลัง) และฉันไม่เข้าใจคำถามของฉันตอนนี้ ฉันอาจไม่เข้าใจการดำเนินการที่สามมาก่อนหรือไม่ วิธีที่ฉันเห็นตอนนี้มันสมเหตุสมผลแล้ว
Gaffi

1
ว้าวฉันอ่านตอนดึกมาก คุณถูก!
kaoD

3
คล้ายกันมาก: for(y=0;y<Y;++y)for(x=0;x<X;++x)มักจะกลายเป็นfor(i=0;i<X*Y;++i)กับxแทนที่ด้วยi%Xและแทนที่ด้วยy i/X
ลินน์

62

เพียงพูดถึงชัดเจน:

ตั้งคำถามกับอัลกอริทึมที่คุณเลือกและลองสิ่งใหม่ทั้งหมด

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

นี่เป็นสิ่งที่เห็นได้ชัดเจนในHitting 495 (Kaprekar)ซึ่งเบี่ยงเบนจากอัลกอริทึมจริงและมองหารูปแบบที่คุณสามารถนำไปใช้เพื่อให้ได้ผลลัพธ์เดียวกันนั้นสั้นลงในหลายภาษา (ไม่ใช่ J)

ข้อเสียคือคุณอาจแก้ปัญหาเดียวกันครึ่งโหลครั้ง แต่มันใช้งานได้จริงในทุกภาษายกเว้น HQ9 + (การหาวิธีอื่นในการส่งออกHello Worldจะไร้ประโยชน์เล็กน้อย)


12
+1 นอกจากจะดีสำหรับการเล่นกอล์ฟแล้วนี่เป็นแบบฝึกหัดที่ดีสำหรับโปรแกรมเมอร์ในสถานการณ์จริง!
Gaffi

52

ใช้การพัฒนาที่ขับเคลื่อนด้วยการทดสอบ

หากรหัสต้องจัดการอินพุตที่หลากหลายให้เขียนการทดสอบที่ครอบคลุมและทำให้ง่ายต่อการเรียกใช้ทั้งหมดอย่างรวดเร็ว วิธีนี้ช่วยให้คุณลองเปลี่ยนขั้นตอนที่มีความเสี่ยงได้ทีละขั้น การเล่นกอล์ฟจึงกลายเป็นเหมือนการปรับโครงสร้างใหม่โดยมีเจตนาที่ผิดปกติ


4
ฉันใช้ spinoff ของวิธีนี้ เนื่องจากปัญหาของตัวเองมักจะค่อนข้างง่ายฉันจึงเขียนโปรแกรมที่ทำงานได้ โดยปกติแล้วนี่คือ "golfed ที่อ่านได้ง่าย" เพื่อให้รวบรัด แต่มีการขึ้นบรรทัดใหม่และอื่น ๆ ฉันคัดลอกไฟล์นี้ไปยังตำแหน่งใหม่แล้วทำการตรวจสอบทุก ๆ ตอนแล้วโปรแกรมจะส่งคืนค่าเดียวกันสำหรับอินพุตที่เลือก ถ้าฉันทำผิดพลาดโดยทิ้งโปรแกรมที่ขาดหายไม่มีความทรงจำเกี่ยวกับสิ่งที่ฉันเปลี่ยนไปและไม่เข้าใจชิ้นส่วนกอล์ฟของฉันฉันมี "ข้อมูลจำเพาะ" บันทึกไว้เป็นแหล่งอ้างอิง
shiona

2
ฉันชอบวิธีนี้ซึ่งเป็นเหตุผลหนึ่งที่ฉันมักจะรวมถึงชุดทดสอบที่ครอบคลุมสำหรับปัญหาทั้งหมดที่ฉันเขียน
Joey

@RubberDuck หลักการห้ามทำซ้ำตัวเองมักจะปฏิบัติตามอย่างเคร่งครัด
Jonathan Frech

48

พยายามลดคำแถลงเชิงตรรกะ

ตัวอย่างเช่นหากAและBเป็นบูลีนและภาษาของคุณจะถือว่าบูลีนเหมือนตัวเลขในระดับหนึ่งA and (not B)และA>Bเทียบเท่า ตัวอย่างเช่นใน Python

if A and not B:
    foo()

เหมือนกับ:

if A>B:
    foo()

3
ฉันไม่เคยคิดอย่างนั้น
cjfaure

27
B>A or foo()จะเป็นวิธีที่สั้นกว่าในการแสดงสิ่งนี้ใช้ประโยชน์จากการประเมินผลแบบนิพจน์ที่ขี้เกียจเพื่อให้แน่ใจว่ามันจะคำนวณสิ่งต่าง ๆ เมื่อจำเป็นเท่านั้น
scragar

5
@scragar: ถูกต้อง แต่นี่ไม่ใช่จุดของเคล็ดลับนี้ (มันเป็นเคล็ดลับอิสระที่มีค่าแม้ว่า)
Wrzlprmft

3
@scragar B>A or fooจะประเมินfooว่าB==Aไม่ใช่สิ่งที่เราต้องการ (ใช่ไหม)
msh210

2
นอกจากนี้หากคุณมีเงื่อนไขที่ยาวมาก (พูดด้วยพารามิเตอร์ 5/6) คุณสามารถใช้ตาราง Truth และแผนที่ Karnaughเพื่อค้นหานิพจน์บูลีนที่สั้นที่สุดสำหรับมัน
Katenkyo

33

เริ่มต้นตัวแปรโดยใช้ค่าที่คุณมีอยู่แล้ว

แทนการx=1พยายามที่จะมองหาสิ่งที่มีอยู่แล้วเท่ากับ 1
ตัวอย่างเช่นค่าตอบแทนการทำงานที่: ->printf("..");x=0; x=!printf("..");ง่ายที่สุดคือ 0 เพราะคุณสามารถปฏิเสธได้ตลอดเวลาหรือเมื่อคุณต้องการมีค่าความจริงที่ถูกต้อง (และไม่สนใจว่ามันจะเป็น 1 หรือ 19)


4
ใน C คุณสามารถใช้ argc ได้จาก main เป็น 1. ดู: codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/ ......
std''OrgnlDave

1
@ std''OrgnlDave จริง แต่คำถามนี้เกี่ยวกับสิ่งที่พบได้ทั่วไปในทุกภาษา
ugoren

33

ใช้เอก~สำหรับx+1และx-1

เคล็ดลับนี้จะนำไปใช้ภาษาที่มีผู้ประกอบการระดับบิตปฏิเสธเอกและผู้ประกอบการปฏิเสธปกติเอก~-

หากโปรแกรมของคุณมีนิพจน์-x-1คุณสามารถแทนที่ด้วย~xเพื่อบันทึกไบต์ สิ่งนี้ไม่ได้เกิดขึ้นบ่อยเกินไป แต่ดูว่าจะเกิดอะไรขึ้นถ้าเราคัดค้าน ( -) การแสดงออกทั้งสอง: x+1เท่ากับ-~x! ในทำนองเดียวกันเท่ากับx-1 ~-x(ลองคิดดูว่าคะแนนตัวหนอน: ทางขวาคือ+ซ้ายคือ-อะไร)

สิ่งนี้มีประโยชน์เพราะในทุกภาษาที่ฉันคิดว่ามีตัวดำเนินการเหล่านี้พวกเขามีความสำคัญมากกว่าตัวดำเนินการส่วนใหญ่ สิ่งนี้ช่วยให้คุณสามารถบันทึกในวงเล็บ ดูวิธีที่เราบันทึกสี่ไบต์ที่นี่:

(x+1)*(y-1)     ==>    -~x*~-y

30

บีบช่องว่าง

รู้กฎสำหรับพื้นที่ว่างในภาษาของคุณ เครื่องหมายวรรคตอนบางตัวหรือตัวอักษรอื่นอาจไม่ต้องการช่องว่างโดยรอบ พิจารณาฟังก์ชันเชลล์เป้าหมายนี้:

f () { echo a; echo b; }

ใน Bourne shell ();เป็น metacharacters และไม่ต้องการช่องว่างโดยรอบ อย่างไรก็ตาม{}เป็นคำและต้องการช่องว่างเว้นเสียแต่ว่ามันจะอยู่ถัดจาก metacharacters เราสามารถกอล์ฟออกไป 4 พื้นที่ติดกับ();แต่ต้องให้ช่องว่างระหว่างและ{echo

f(){ echo a;echo b;}

ในCommon เสียงกระเพื่อมและPicoLisp , ()มี metacharacters พิจารณารหัสนี้เพื่อหาค่าเฉลี่ยของตัวเลขสองตัว:

(/ (+ a b) 2)

เราสามารถเล่นกอล์ฟได้ 2 ที่

(/(+ a b)2)

บางภาษามีกฎที่แปลกและละเอียดอ่อนสำหรับช่องว่าง พิจารณาโปรแกรม Ruby นี้ซึ่งพิมพ์ผลรวมและผลคูณของจำนวนเต็ม

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

แต่ละคน&ต้องการพื้นที่ก่อนหน้านั้น ใน Ruby i=$F.map &:to_iหมายถึงi=$F.map(&:to_i)ตำแหน่งที่&ส่งพารามิเตอร์บล็อก แต่i=$F.map&:to_iหมายถึงการi=$F.map.&(:to_i)ที่&เป็นผู้ประกอบการไบนารี

ความประหลาดนี้เกิดขึ้นในภาษาเช่น Perl หรือ Ruby ที่ใช้เครื่องหมายวรรคตอนที่ไม่ชัดเจน หากมีข้อสงสัยให้ใช้ REPL หรือเขียนโปรแกรมสั้น ๆ เพื่อทดสอบกฏช่องว่าง


1
ทำไมต้องมีช่องว่างระหว่าง "{" และ "echo" แต่ไม่ใช่ระหว่าง ";" และ "echo"?
Ryan

3
ฉันใช้คำศัพท์จากคู่มือสำหรับ OpenBSD sh (1) ซึ่งบอกว่า "{" เป็นคำที่สงวนไว้และ ";" เป็นเมตาอักขระ ด้วยเหตุนี้ "{echo" เป็นหนึ่งคำ แต่ "; echo" เป็นสองคำ คู่มืออื่น ๆ อาจอธิบายสิ่งนี้แตกต่างกัน นอกจากนี้ Z shell zsh ยังมีกฎที่แตกต่างกัน
kernigh


28

ชื่อตัวแปรตัวอักษรเดียว

คุณมี 52 ของพวกเขา; ใช้พวกเขาทั้งหมด! อย่ากลัวที่จะลองวิธีการที่แตกต่างและเปรียบเทียบความยาว รู้ภาษาและฟังก์ชั่นทางลัด / ไลบรารีเฉพาะที่มีให้


8
26 สำหรับภาษาที่ไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก :-)
Gaffi

12
บ่อยครั้ง$และ_สามารถใช้เป็นตัวระบุ
Griffin

4
@Gaffi: และอื่น ๆ อีกมากพอสำหรับภาษาที่อนุญาตให้ใช้ตัวระบุ Unicode ยกเว้นว่างานจะ จำกัด ให้คุณเป็น ASCII หรือนับจำนวนไบต์แทนที่จะเป็นตัวอักษร
hammar

หากคุณนับไบต์แทน unicode การใช้ ascii แบบขยายอาจเป็นวิธีที่จะบีบตัวระบุอีกประมาณ 120 ตัวหากคุณต้องการ (ไม่ใช่สำหรับสคริปต์กอล์ฟคุณควรต้องการมากกว่า 26 ตัวต่อไป)
scragar

2
@เป็นชื่อตัวแปรที่ถูกต้องใน T-SQL @aใช้มันแทน
BradC

25

ใช้โอเปอเรเตอร์ที่มีเงื่อนไข

ผู้ประกอบการตามเงื่อนไข

bool ? condition_true : condition_false

เป็นประโยชน์มากขึ้นตัวละครฉลาดกว่าถ้าคำสั่ง

if(a>b){r=a;}else{r=b;}

สามารถเขียนเป็น

r=a>b?a:b;

25
ภาษาที่ไม่มี ternary สามารถใช้a&&b||cแทนได้ อีกเล็กน้อย ifแต่ก็ยังสั้นกว่า
Michael Kohl

จากนั้นอีกครั้งบางคนไม่สามารถใช้ตัวเลือกอย่างใดอย่างหนึ่ง (VBA มาถึงใจ) แต่ทั้งสองยังคงเป็นคำแนะนำที่ดี :-)
Gaffi

1
Gaffi: VBA มีIffแม้ว่ามันจะเป็นฟังก์ชั่นดังนั้นก็ขึ้นอยู่กับการประเมินผลการขัดแย้งทั้งหมด
Joey

การใช้ ternary ในกรณีที่ statement สามารถช่วยได้มากif(a ? b : c)
Jojodmo

4
@MichaelKohl ทราบว่าa&&b||cสามารถกลับมาcเมื่อaiff จริงbเป็นเท็จกรณีขอบเล็กน้อย แต่เราไม่ควรลืมว่า ^^
Katenkyo

24

เขียนคำอธิบายรหัสของคุณ

การเขียนคำอธิบายบังคับให้คุณมองที่แต่ละส่วนของรหัสอีกครั้งอย่างละเอียดและทำให้ความคิดและตัวเลือกของคุณในการเขียนข้อความบางอย่างชัดเจน ในการทำเช่นนั้นคุณอาจพบว่าวิธีการที่แตกต่างกันนั้นเป็นไปได้ซึ่งอาจบันทึกบางไบต์หรือว่าคุณตั้งสมมติฐานโดยไม่รู้ตัว

เคล็ดลับนี้จะคล้ายกับคำถามทางเลือกของอัลกอริทึมและลองสิ่งใหม่ทั้งหมด ; อย่างไรก็ตามฉันพบว่าขั้นตอนในการจดบันทึกว่าแต่ละส่วนควรทำงานอย่างไรเป็นสิ่งสำคัญในการตระหนักถึงทางเลือกต่างๆ

ในฐานะโบนัสคำตอบรวมถึงคำอธิบายน่าสนใจยิ่งขึ้นสำหรับผู้ใช้รายอื่นและมีแนวโน้มที่จะถูกถอนออก


23

ตรวจสอบจำนวนตัวละครของคุณอีกครั้ง

ฟังดูเหมือนไม่ใช่เกมง่ายๆ แต่ระวังให้ดีคุณอาจ "บันทึก" ตัวละครสองสามตัวโดยไม่ทำอะไรเลย!

หากคุณใช้ Windows คุณอาจกำลังป้อนข้อมูล\r\nแทน\rหรือ\nเมื่อคุณกดย้อนกลับ - เพิ่มไบต์พิเศษต่อบรรทัด! เปลี่ยนอักขระควบคุมเพื่อตรวจสอบอีกครั้งว่าคุณไม่ได้ทำสิ่งนี้

ใน Notepad ++ คุณสามารถแปลงทุก\r\nปลายสายที่จะเพียงแค่ได้โดยไปที่\rEdit > EOL Conversion > UNIX/OSX Format

ตรวจสอบให้แน่ใจว่าคุณไม่ได้รวมช่องว่างต่อท้ายในการนับตัวละครของคุณ! ฟีดบรรทัดในบรรทัดล่างในรหัสของคุณก็ไม่สำคัญดังนั้นจึงไม่จำเป็นต้องนับเช่นกัน


ฉันไม่คิดว่าฉันเคยเห็นกรณีที่นี้ได้นับจริง ...
ยาโคบ

4
ฉันเพิ่งมีปัญหานี้ด้วยตัวเอง (เพราะเหตุใดฉันจึงเพิ่ม)
Sean Latham

21

อ่านคำถามอย่างระมัดระวัง

การเล่นรหัสเป็นสิ่งที่เกี่ยวกับการทำความเข้าใจคำถาม (สิ่งที่ถูกถามและสิ่งที่ไม่ถูกถามถึงแม้ว่ามันจะมีนัยโดยนัยในการตั้งค่าอื่น ๆ ) เป็นการผลิตรหัสที่ (อาจ) ตอบสนองสิ่งที่ถูกถามเท่านั้น

ข้อมูลอื่นใดนอกเหนือจากที่ระบุไว้อย่างชัดเจนว่าไม่จำเป็นต้องได้รับการจัดการ หากมีบางกรณีทดสอบและไม่มีข้อกำหนดทั่วไปรหัสของคุณอาจใช้ได้เฉพาะในกรณีเหล่านั้น เป็นต้น


15
ฉันคิดว่าพาดหัวที่ดีกว่าที่นี่จะเป็น "อย่าจัดการกับกรณีขอบที่ไม่จำเป็น" วลี "พยายามหาช่องโหว่" ทำให้นึกถึงวิธีที่จะหลีกเลี่ยงการทำสิ่งที่ระบุไว้ผ่านการตีความกฎอย่างมีศิลปะในขณะที่สิ่งที่คุณเสนอเป็นเพียงคำแนะนำที่ดีไม่ควรใช้วิธีแก้ปัญหาของคุณมากเกินไป
Jonathan Van Matre

1
ใช่ แต่การตีความกฎอย่างชาญฉลาดนั้นเป็นส่วนหนึ่งของการตีกอล์ฟด้วยเช่นกัน! (0 วิธีแก้ปัญหาถ่าน ฯลฯ )
Tobia

8
แม้ว่าจะ / ควรเป็นคำตอบที่ต่างออกไป ยกตัวอย่างเช่นมีความแตกต่างพื้นฐานระหว่างการใช้งานโซลูชันที่ใช้งานได้กับ ints เท่านั้นเนื่องจาก OP ไม่ต้องการการสนับสนุนแบบลอยตัวและคำตอบที่พิมพ์ข้อความ "ยิ่งใหญ่กว่า 100" เพราะ "คุณไม่ได้บอกว่ามันต้อง เป็นจำนวนเฉพาะจริง "
Jonathan Van Matre

ฉันคิดว่า OPs บางประเภทมี "การแจ้งเตือนเรื่องการเปลี่ยนแปลงซึ่งอาจมีการแจ้งให้ทราบรหัสของคุณยังคงใช้งานได้หลังจากการเปลี่ยนแปลง" และจริง ๆ แล้วเปลี่ยนพวกเขาหากพวกเขาเห็นคำตอบเพียงครั้งเดียว
Erik the Outgolfer

20

ใช้การดำเนินการระดับบิตเพื่อตรวจสอบตัวเลขระหว่าง 0 ถึง 2 n -1

อาจเป็นเรื่องเล็กน้อย แต่อาจมีประโยชน์ในบางครั้ง มันขึ้นอยู่กับความจริงที่ว่าตัวเลขทั้งหมดที่ m = 2 n -1 ใช้นั้นมี n บิตที่ถูกต้องที่สุดตั้งค่าเป็น 1

ดังนั้น 7 10 == 00000111 2 , 15 10 == 00001111 2 , 31 10 == 00011111 2และอื่น ๆ

x&~mเคล็ดลับคือ นี้จะกลับจริงเมื่อใดก็ตามที่xเป็นไม่ได้ระหว่าง 0 และm(รวม) และเท็จอย่างอื่น จะช่วยประหยัด 6 ไบต์จากการแสดงออกเทียบเท่าสั้นที่สุดต่อไป: x>=0&&x<=mแต่เห็นได้ชัดว่าทำงานได้เฉพาะเมื่อmตอบสนอง 2 n -1


18

นำพารามิเตอร์ฟังก์ชันมาใช้ใหม่แทนตัวแปรใหม่


1
ตัวอย่างเช่นใน C ฟังก์ชันหลักของคุณจะถูกส่งผ่านจำนวนอาร์กิวเมนต์ที่กำหนดให้กับโปรแกรมเสมอ (ซึ่งคือ 1 - ชื่อโปรแกรม - โดย 'default') ดังนั้นเมื่อmain(i){...คุณมีตัวแปรที่มีค่า 1 โดยไม่ต้อง ทำงานที่ได้รับมอบหมาย 2 ตัวอักษรบันทึกไว้ที่นั่น ..
กริฟ

6
ฉันคิดว่ามันค่อนข้างเฉพาะกับภาษา C. Script ที่ไม่จำเป็นต้องมีการประกาศและในภาษาที่คอมไพล์ส่วนใหญ่การกำหนดตัวแปรไม่นานกว่าการกำหนดพารามิเตอร์
ugoren

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

18

มากกว่า / น้อยกว่าเพื่อบันทึกตัวเลข:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

เพียงจำไว้ว่าให้สลับโค้ดจากifไปยังelseและพวกเขาจะทำสิ่งเดียวกัน (หรือสลับข้างของความไม่เท่าเทียมกัน)!

หมายเหตุ:สิ่งนี้สามารถใช้กับพลังใด ๆ ของ 10 และเชิงลบของพวกเขา:...-100, -10, 10, 100...

(ลิงค์แหล่งที่มา)


ฉันไม่แน่ใจว่าฉันเข้าใจประเด็นนี้ สิ่งนี้ลดจากอะไร
Gaffi

@Gaffi คุณประหยัดอักขระหนึ่งตัวและพวกเขาก็ทำสิ่งเดียวกัน
ajax333221

เทียบกับทางเลือกอะไร? ขอโทษที่ไม่พยายามดื้อรั้นฉันไม่เข้าใจ (newb, here, apparently ... )
Gaffi

1
อ่าฉันเข้าใจแล้ว ใช้งานได้กับการเปลี่ยนเลขจำนวนเต็มตั้งแต่ 9 ถึง 10, 99 ถึง 100 เป็นต้นขออภัยที่ใช้เวลานานมาก! (ฉันพูดจำนวนเต็มเท่านั้นเพราะฉันสามารถดูปัญหากับ n = 9.5 ... )
Gaffi

8
นอกจากนี้ในบางภาษา (หากรองรับ) หากตัวเลขของคุณมีขนาดใหญ่ / เล็กพอสัญลักษณ์ทางวิทยาศาสตร์อาจช่วยให้คุณประหยัดตัวอักษรบางตัวแทน: if(n>99999)vsif(n<1e5)
scragar

16

ใช้> และ <แทน> = และ <=

เมื่อตรวจสอบกับค่าจำนวนเต็มตายตัวใช้>และ<แทน>=และ<=เป็นไปได้ ตัวอย่างเช่นการใช้

if(x>24&&x<51)

สั้นกว่าการใช้ 2 ไบต์

if(x>=25&&x<=50)

3
ที่เกี่ยวข้อง: หากคุณแน่ใจว่าผลลัพธ์จะไม่เป็นลบคุณสามารถใช้<1แทนการ==0ตรวจสอบที่ไม่ใช่ศูนย์ (หรือ>0แทน!=0การตรวจสอบแบบมิเรอร์)
Kevin Cruijssen

1
คุณไม่ควรเพิ่มบันทึกเกี่ยวกับxการเป็นจำนวนเต็มหรือ
Zacharý

15

หลีกเลี่ยงการแบ่งวงก่อนวัยอันควร

หากเรียกใช้การวนซ้ำเพื่อตรวจสอบอินสแตนซ์ของการตรวจสอบบูลีนอย่างน้อย 1 รายการอาจทำให้โปรแกรมมีประสิทธิภาพมากขึ้นเพื่อออกจากลูปในค่าที่แท้จริงแรก อย่างไรก็ตามการลบตัวแบ่งและการวนซ้ำผ่านการวนซ้ำทั้งหมดทำให้โค้ดสั้นลง

int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
} 
return 0;
}

5
นอกจากนี้คุณยังสามารถลดความซับซ้อนของคำสั่งที่ออกไปในกรณีเหล่านี้:if m|=i>=100(และคุณยังสามารถลดความซับซ้อนของi>=100การi>99ในกรณีนี้ แต่ที่ไม่เกี่ยวข้องมากที่นี่)
marinus

15

ใช้-แทน!=

สำหรับการเปรียบเทียบเชิงตัวเลข:

หาก a เท่ากับ b a-bผลลัพธ์0จะเป็นเท็จ สิ่งอื่นใดนอกจากความ0จริง ดังนั้น
หากใช้ในบริบทบูลีนa-b<=>a!=b

หากคุณใช้กับif/elseผู้ประกอบการที่ประกอบไปด้วยสิ่งนี้สามารถช่วยคุณหนึ่งไบต์เพื่อความเท่าเทียม:
a==b?c:d<=>a-b?d:c


12

แยกสตริงสำหรับอาร์เรย์ที่มีความยาว

ภาษาส่วนใหญ่มีวิธีในการแบ่งสตริงเป็นอาร์เรย์ของสตริงรอบ ๆ โทเค็นบางชนิด สิ่งนี้จะสั้นกว่าอาร์เรย์ตามตัวอักษรอย่างหลีกเลี่ยงไม่ได้เมื่อความยาวถึงขีด จำกัด ภาษาขึ้นอยู่กับเพราะค่าใช้จ่ายเพิ่มเติมต่อสตริงจะเป็นสำเนาหนึ่งของโทเค็นแบบอักขระเดียวแทนที่จะเป็นตัวคั่นสตริงสองตัว

เช่นใน GolfScript

["Foo""Bar""Baz""Quux"]  # 23 chars

กลายเป็น

"Foo
Bar
Baz
Quux"n/  # 20 chars

สำหรับบางภาษาเกณฑ์จะต่ำกว่าหนึ่งสตริง เช่นใน Java

new String[]{"Foo"}  // 19 chars

กลายเป็น

"Foo".split("~")  // 16 chars

6
%w{Foo Bar Baz Quux}ที่โดดเด่นเป็นพิเศษคือทับทิมซึ่งมีอาร์เรย์ของสตริงตัวอักษรที่แยกโดยอัตโนมัติในช่องว่างที่ค่าใช้จ่ายของทั้งสองไบต์:
Martin Ender

1
Perl ให้สิ่งที่คล้ายกัน: qw(Foo Bar Baz Quux)กลายเป็นรายการของสตริง
BenGoldberg

12

ทำความเข้าใจกับสิ่งที่คนอื่นทำ

นอกจากความสนุกแล้วถ้าคุณตรวจสอบรหัสของคนอื่นคุณสามารถค้นพบอัลกอริทึมที่ดีที่คุณไม่ได้คิดหรือเป็นกลอุบาย (บางครั้งก็ชัดเจน) ที่คุณมองข้าม

บางครั้งมีคำตอบที่มีอยู่ที่คุณสามารถแปลเป็นภาษาอื่นและได้รับประโยชน์จากสารพัดภาษา


10

รู้ถึงความสำคัญของผู้ให้บริการ

เมื่อใดก็ตามที่คุณรวมหลายนิพจน์ให้ตรวจสอบตารางลำดับความสำคัญของโอเปอเรเตอร์สำหรับภาษาของคุณเพื่อดูว่าคุณสามารถเรียงลำดับรายการใหม่เพื่อบันทึกวงเล็บหรือไม่

ตัวอย่าง:

  • ในทุกภาษาที่ฉันรู้ตัวดำเนินการระดับบิตมีความสำคัญมากกว่าตัวดำเนินการบูลีน: (a&b)&&cไม่จำเป็นต้องใช้วงเล็บ: a&b&&cเช่นเดียวกับ(a*b)+cไม่
  • a+(b<<c)a+b*2**cสามารถเขียนเป็น
    นั่นไม่ได้บันทึกอะไรสำหรับตัวอย่างนี้ แต่มันจะถ้าcเป็นตัวอักษรจำนวนเต็มขนาดเล็ก (<14)
  • การดำเนินการระดับบิตมีลำดับความสำคัญต่ำกว่าการดำเนินการทางคณิตศาสตร์ส่วนใหญ่ดังนั้นหากภาษาของคุณปลดบูลีนเป็น int คุณสามารถบันทึกไบต์a<b&&c<dด้วยa<b&c<d(ยกเว้นกรณีที่คุณต้องการการประเมินการลัดวงจร)

7

สั้นกว่าสำหรับลูป

หากคุณมีXคำสั่ง{อยู่ใน}for-loop คุณสามารถย้ายX-1คำสั่ง(ภายใน)for-loop หลังจากเครื่องหมายอัฒภาคที่สองfor(blah;blah;HERE)เพื่อบันทึก 3 ไบต์ (แยกข้อความโดยใช้เครื่องหมายจุลภาค, )

แทน

for(int i=0;i<9;){s+=s.length();println(i++);}

คุณสามารถย้ายข้อความใดข้อความหนึ่งไปยัง(เครื่องหมายวงเล็บปีกกาของ for-loop )ขณะที่ปล่อยข้อความอื่นออก

for(int i=0;i<9;println(i++))s+=s.length();

และบันทึก 3 ไบต์ (บันทึกอีก 1 ไบต์ต้องขอบคุณ @ETHProductions)


พูดง่ายๆ

แทน

for(blah;blah;){blah 1;blah 2;...;blah X}

ย้ายข้อความไปรอบ ๆ เพื่อที่คุณจะได้จบเรื่องนี้

for(blah;blah;blah 2,...,blah X)blah 1;

และบันทึก 3 ไบต์


@ETHproductions ขอขอบคุณสำหรับการเล่นกอล์ฟ
เกร็ดน่ารู้

และถ้าforเป็นประโยคสุดท้ายคำสั่ง;จะกลายเป็นตัวเลือก
elipszilon

7

ใช้เอก~สำหรับa-b-1และa+b+1

นอกจากคำแนะนำของ@Lynnเกี่ยวกับx+1-~x; และx-1~-xคุณยังสามารถกอล์ฟและa-b-1a+b+1

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

อาจดูเหมือนว่าเคล็ดลับที่คุณจะไม่ใช้ทั้งหมดที่มักจะชอบใช้~xแทน-x-1ไม่เกิดขึ้นบ่อย แต่ฉันใช้มันพอเวลาเพื่อดูว่าเป็นเคล็ดลับที่มีประโยชน์ที่นี่ โดยเฉพาะอย่างยิ่งกับการทำดัชนีอาเรย์คุณอาจใช้สิ่งเหล่านี้ด้านบนในบางกรณี


6

บีบอัดหรือ / และลายเส้น

เคล็ดลับง่าย ๆ ที่ฉันคิดขึ้นมาเมื่อพยายามบีบเงื่อนไขอันยาวเหยียดที่ถูกล่ามโซ่โดย ands (หรือ ors ในกรณีนี้เพียงแทนที่ 'all' ด้วย 'any')

เช่น:

if a>0 and a<10 and a+b==4 and a+3<1:

กลายเป็น

if all([a>0,a<10,a+b==4,a+3<1]):

นั่นเป็นสิ่งที่ยอดเยี่ยมฉันจะต้องลองดู!
stokastic

4
มีภาษาใดall(array-of-Booleans)บ้างในตัว
Peter Taylor

3
รูบี้ก็มี [a>0,a<10,a+b==4,a+3<1].all?
kernigh

4
แม้ว่านี่จะเป็นงูหลาม แต่คุณก็ชอบใช้if 10>a>0 and a+b==4>1>a+3:
Sp3000

@PeterTaylor Haskell มีเหมือนกัน
ภูมิใจ haskeller

6

พึ่งพาคอมไพเลอร์เพื่อให้มีประสิทธิภาพตามที่ต้องการ

ตรวจสอบให้แน่ใจว่าได้รับการปรับให้เหมาะสมซึ่งคอมไพเลอร์และระดับการเพิ่มประสิทธิภาพและใช้อย่างอิสระ และแม้ว่าประสิทธิภาพการทำงานไม่ได้เป็นข้อกำหนดที่เกี่ยวข้องคุณยังสามารถทดสอบด้วยการปรับให้เหมาะสมและจากนั้นให้ลดอักขระเพียงตัวเดียวเนื่องจากรหัสของคุณยังใช้งานได้ทางเทคนิคหากไม่มีแฟล็กคอมไพเลอร์

พิจารณาฟังก์ชัน Haskell ต่อไปนี้เพื่อคำนวณ 2 ^ n (โดยไม่สนใจข้อเท็จจริงที่ว่า Haskell มีตัวดำเนินการการยกกำลังในตัวอยู่แล้วหรือสาม) (23 ตัวอักษร):

p 0=1;p x=p(x-1)+p(x-1)

ปัญหาคือ - มันช้าอย่างน่ากลัวมันทำงานในเวลาที่ชี้แจง สิ่งนี้อาจทำให้รหัสของคุณไม่สามารถทดสอบได้หรือทำให้ข้อ จำกัด ด้านประสิทธิภาพใด ๆ ที่เกิดจากคำถามนั้นล้มเหลว คุณอาจถูกล่อลวงให้ใช้ตัวแปรชั่วคราวหรือเรียกใช้ฟังก์ชันตามตัวอักษรทันทีเพื่อหลีกเลี่ยงการเรียกใช้ฟังก์ชันซ้ำ (25 อักขระ):

p 0=1;p x=(\y->y+y)$p$x-1

แต่คอมไพเลอร์สามารถทำสิ่งนั้นให้คุณได้แล้วคุณต้องตั้งค่า-Oเป็นธงคอมไพเลอร์! แทนที่จะใช้อักขระพิเศษสองสามตัวต่อไซต์เพื่อกำจัดนิพจน์ย่อยทั่วไปด้วยตนเองเพียงแค่บอกคอมไพเลอร์ให้ทำออพติไมซ์พื้นฐานสำหรับคุณโดยรวมทั้งหมดหนึ่งตัวอักษรหรือสองตัวตลอดทั้งโปรแกรม


@ETHproductions อ๋อขอโทษฉันทำแล้ว
John Dvorak

ตัวอย่างแรกไม่ควรp(x-1)*2ใช่หรือไม่
Cyoce

5

อาจจะค่อนข้างชัดเจน แต่ ...

ใช้ประโยชน์จากค่าคืนของโอเปอเรเตอร์

โปรดทราบว่าผู้ดำเนินการที่ได้รับมอบหมายคืนค่า!

ตัวอย่างเช่นหากคุณต้องการเพิ่ม y เป็น x แล้วตรวจสอบว่า x มากกว่าสิ่งที่คุณทำหรือไม่

if(25<x+=y)

แทน

x+=y;if(x>25)

หรือบางทีคุณต้องการค้นหาความยาวของสตริงหลังจากตัดแต่ง:

strlen(s=trim(s))

ค่อนข้างมากกว่า

s=trim(s);strlen(s)

คุณสามารถมอบหมายการโทรภายในภาษาใดได้บ้าง? หรือว่าเป็นคำหลักหาเรื่อง?
แมว

2
ฉันคิดว่าการมอบหมายนั้นเป็นนิพจน์ (ด้วยค่าใหม่ของตัวแปรที่กำหนดเป็นค่านิพจน์) อย่างน้อย C, C ++, C # และ Java a = (b=c)+1;ชุดbไปcแล้วชุดที่จะa b+1
ลินน์

@Lynn a=1+b=cลอง และคุณสามารถเพิ่ม PHP และ JavaScript ในรายการของคุณ
ติตัส

2
รูบี้ทำสิ่งนี้ได้ดีที่สุด มันให้=ผู้ประกอบการมีความสำคัญสูงกว่าทางด้านซ้ายกว่าด้านขวาดังนั้น1+x=2ถูกต้องและประเมินถึง3
Cyoce

@Cyoce afaik เป็นวิธีนั้นในทุกภาษาที่มีการมอบหมายการแสดงออก
ติตัส

5

ใช้ประโยชน์จากรุ่นภาษา / คอมไพเลอร์ / สภาพแวดล้อมนิสัยใจคอ / คุณสมบัติใหม่

สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับแต่สามารถนำไปใช้กับความท้าทายอื่น ๆ ได้ บางครั้งข้อผิดพลาดของคอมไพเลอร์อาจทำให้เกิดข้อผิดพลาดในการติดตั้งไบต์ข้อผิดพลาดในการใช้งานอาจช่วยให้คุณประหยัดได้ไม่กี่ตัวอักษรหรือคุณลักษณะที่ทันสมัย


4

รวมหลาย / ซ้อนกันถ้าตรวจสอบการใช้และ / หรือเมื่อเป็นไปได้

เช่น:

if (a && (b || c)) {

}

แทน:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}

5
นอกจากนี้ให้ใช้เงื่อนไข bitty ( &, `|) เพื่อลบอักขระเพิ่มเติม
FUZxxl

2
แม้ว่าการใช้ bitwise &แทนการ&&ลบ 1 ตัวอักษรในบางกรณีมันเลอะความสำคัญของโอเปอเรเตอร์และคุณจะต้องใส่วงเล็บเพื่อให้มันใช้งานได้ใช้มันอย่างชาญฉลาด
DollarAkshay

4

ค้นหาวิธีที่ดีกว่าในการเริ่มต้นตัวแปรของคุณ

บางคำตอบอื่น ๆ ใกล้จะพูดถึงสิ่งนี้อยู่แล้ว แต่ในหลาย ๆ ภาษา (พิมพ์อย่างเคร่งครัด?) มันสั้นกว่าที่จะเริ่มต้นxเป็นสตริงว่างเช่น:

x:=""

หรือxว่างเปล่า rune (char) เช่น:

x:=''

กว่า

var x string

และ

var x rune

การใช้ค่าที่มีอยู่ก่อนหน้านั้นเป็นที่ต้องการอย่างเห็นได้ชัด แต่ไม่ใช่เรื่องง่าย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.