เคล็ดลับการเล่นกอล์ฟในลัวะ


21

คุณมีเคล็ดลับอะไรสำหรับการเล่นกอล์ฟใน Lua ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะ Lua (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ) กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ


6
คำถามเคล็ดลับควรเป็นวิกิชุมชน แต่สำหรับใครก็ตามที่ส่งเรื่องนี้อย่างใกล้ชิดว่า "ยึดหลักความคิดเห็นเป็นหลัก" เคล็ดลับสำหรับการตีกอล์ฟเป็นคำถามภาษาเป็นข้อยกเว้นที่เรายอมรับในกฎนั้น คำถามปลายเปิดเหล่านี้เป็นเหตุผลว่าทำไมพวกเขาถึงเป็นชุมชน wiki-ed
Jonathan Van Matre

คำตอบ:


9

นอกจากรายการที่โพสต์ไปแล้วนี่คือเคล็ดลับบางอย่างที่ฉันได้รวบรวมเมื่อเวลาผ่านไปโดยไม่เรียงลำดับเฉพาะ ...

  • สำหรับการเรียกฟังก์ชันที่มีเพียงหนึ่งพารามิเตอร์ที่คั่นด้วยสัญลักษณ์ ( "สำหรับสตริง{สำหรับตาราง) พารามิเตอร์ไม่จำเป็นต้องถูกล้อมรอบวงเล็บ
    ตัวอย่างเช่นแทนที่จะทำprint("hello")คุณสามารถทำได้:print"hello"

  • ลบช่องว่างให้มากที่สุดเท่าที่จะทำได้ - นี่เป็นเรื่องง่ายโดยเฉพาะอย่างยิ่งหลังจากสัญลักษณ์ที่ปิดสตริง (หรือก่อนการเปิดหนึ่งครั้ง), การเรียกใช้ฟังก์ชัน, ตาราง ...
    แทนที่จะprint(42) a=1ทำเช่นprint(42)a=1นั้น ตัวอย่างอื่น ๆ : print(a and-1 or-2).

  • ใช้ผู้ประกอบการที่ประกอบไปด้วยเมื่อคุณสามารถ! แทนที่จะชอบif a>0 then print("hello") else print("goodbye") end print(a>0 and "hello" or "goodbye")ข้อมูลเพิ่มเติมที่นี่
    (ซึ่งจริงจะได้รับที่ดียิ่งขึ้น: print(a>0 and"hello"or"goodbye"))

  • ใช้ลำไส้ใหญ่โทรน้ำตาลประโยคเมื่อคุณสามารถ: แทนการทำstring.rep(str,12) str:rep(12)ซึ่งยังทำงานกับตัวแปรที่ไม่ใช่ด้วยวิธีนี้ (และวิธีนี้เท่านั้น):("a"):rep(5)

  • แทนที่จะทำtonumber(str)แค่ทำstr+0

  • สำหรับฟังก์ชั่นที่ไม่มีพารามิเตอร์แทนที่จะกำหนดตามวิธีปกติ ( function tick() blabla() end) คุณสามารถทำได้: ticks=loadstring"blabla()"ซึ่งจะบันทึก 1 ไบต์หรือมากกว่านั้นขึ้นอยู่กับเนื้อหา นอกจากนี้หากคุณกำหนดหลายฟังก์ชั่นให้แปลloadstringเป็นตัวแปร 1 อักขระก่อนหน้าและคุณจะประหยัดได้มากเป็นไบต์;) ให้เครดิตกับ Jim Bauwens สำหรับเคล็ดลับนี้

  • Lua พิจารณาสตริงว่าง (และ0แตกต่างจากภาษาอื่น ๆ ) เป็นจริงในการทดสอบตามเงื่อนไขดังนั้นเช่นแทนที่จะทำให้while 1 do ... endบันทึก 1 ไบต์ด้วยการเขียนwhile''do ... end


(เพิ่มเคล็ดลับการโหลด)
Adriweb

2
0 การเป็นความจริงเป็นเพียงความโง่เขลา
SuperJedi224

สิ่งที่str+0เทียบเท่าอีกอย่างหนึ่งก็คือ~~strสามารถใช้ประโยชน์ได้อย่างเต็มที่สำหรับความสำคัญของมัน
Felipe Nardi Batista

@FelipeNardiBatista แต่รองรับเฉพาะใน Lua 5.3+
Adriweb

5

ฉันคิดแล้ว ฉันไม่รู้ว่ามันใช้งานได้ในภาษาอื่นบ้างไหม แต่ Lua เป็นคนเดียวที่ฉันรู้ว่าอะไรที่ทำให้คุณสามารถเก็บฟังก์ชันในตัวแปรได้ ดังนั้นถ้าเช่นถูกนำมาใช้หลายครั้งในโปรแกรมเช่นการใช้งานของคุณstring.subs=string.sub


4
มันยังทำงานได้ในหลายภาษาเช่น Python และ Ruby
nyuszika7h

4
Javascript และ Haskell สามารถมีค่าฟังก์ชันได้เช่นกัน
ภูมิใจ haskeller

นี่เทียบเท่าs=("").subหรือs=a.subสำหรับตัวแปรใด ๆaที่มีค่าสตริง
Egor Skriptunoff

สิ่งนี้เรียกว่าฟังก์ชั่นชั้นหนึ่ง
โปรแกรม Redwolf

5

มันเป็นภาษาที่ค่อนข้างสมบูรณ์สำหรับการเล่นกอล์ฟ ... แต่มีเคล็ดลับทั่วไปที่นึกถึง:

  • พยายามหลีกเลี่ยงเงื่อนไขเนื่องจากif... then... else... endเป็นของเสียที่สำคัญ
  • ให้พยายามจดจ่ออยู่กับโครงสร้างภาษาที่สั้นกว่าfor i=1,5 doแทน
  • #ผู้ประกอบการเป็นที่ดีงามสำหรับการเล่นกอล์ฟ (และทั่วไป)

5

ร่นวงไม่มีที่สิ้นสุดของคุณ

เมื่อคุณต้องใช้วงวนไม่สิ้นสุดคุณอาจคิดถึงการใช้ a whileแต่การใช้ป้ายกำกับนั้นสั้นกว่า 2 ไบต์:

while''do end
::a::goto a

ใช้พื้นที่น้อยที่สุดเท่าที่จะทำได้

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

x=0>1 and 0or 1print(x)

ความเป็นไปได้ในการลบช่องว่างขึ้นอยู่กับตัวอักษรตามหมายเลขต่อไปนี้เป็นตัวอักษรที่ไม่อนุญาตให้คุณทำเช่นนี้:

a,b,c,d,e,f            -- They would be interpreted as hexadecimal
x                      -- only fail when after a 0, other number are fine
                       -- (0x indicates the following is an hexadecimal number)

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

ยกตัวอย่างที่นี่แล้วและใช้คำแนะนำนี้ต่อไปนี้เป็นอีกหนึ่งไบต์ที่คุณสามารถสลัด :)

print(a and-1 or-2)
print(a and-1or-2)

ใช้วิธีการป้อนข้อมูลที่ถูกต้อง

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

function f(x)x end
io.read()
arg[1]

หนึ่งในวิธีการนี้อนุญาตให้เรารับ 1 อินพุทโดยที่ฟังก์ชั่นเป็นหนึ่งที่มีค่าใช้จ่ายมากที่สุด (แต่ช่วยให้เราสามารถนำตารางเป็นอินพุต)

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

arg[1]
...

...เป็นพิเศษบิตในการหลัวก็เป็นตัวแปรที่มีเนื้อหาแตกของargหรือพารามิเตอร์แตกในกรณีของฟังก์ชั่น variadic

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

a=arg[1]b=arg[2]    -- highly un-efficient, costs 8 bytes by variable
a,b=unpack(arg)     -- costs 15, but at least doesn't depends on the number of argument
a,b=...             -- only costs 7

และนี่คือการโทรที่สั้นที่สุดที่คุณสามารถทำได้โดยไม่มีตัวแปร:

...     -- using a allow a gain of 1-2 bytes at each use
arg[2]  -- using b allow a gain of 4-5 bytes at each use

จากจุดที่คุณมี 3 ข้อโต้แย้งหรือเมื่อคุณใช้ 2 ข้อโต้แย้งโดยที่มีการใช้สองครั้งคุณจะได้รับไบต์เนื่องจากa,b=...! :)

แทบไม่เคยใช้ถ้า!

ไม่มีกรณีใดที่การใช้คำสั่ง if / elseif / if จะมีค่าใช้จ่ายน้อยกว่า ternary boilerplate สำหรับคำสั่งดังกล่าวหนักจริงๆ:

-- exemple with dumb values
if 1>0then v=1 else v=0 end
v=1>0 and 1or 0

ด้วยตัวอย่างง่ายๆคุณได้ประหยัด 12 ไบต์เมื่อคุณต้องทำอย่างอื่นมันสำคัญมากขึ้นเรื่อย ๆ ดังนั้นจงระวังให้ดี!

นอกจากนี้ ternaries ใน lua ยังมีความพิเศษมีเงื่อนไขบางอย่างในการทำงานสำหรับผู้ที่สนใจฉันจะอธิบายด้านล่าง:

Ternaries ใน lua เป็นของแบบฟอร์ม <condition> and <case true: have to be a true value> or <case false: can be anything>

orครั้งแรกของทั้งหมดเรามาดูตารางความจริงของ orถือได้ว่าเป็นฟังก์ชั่น: มันก็กลับค่านี่คือค่าที่จะส่งกลับ:

x | y ||x or y
------||-------
0 | 0 ||   y
0 | 1 ||   y
1 | 0 ||   x
1 | 1 ||   x

นั่นคือสิ่งที่ช่วยให้เราสามารถสร้างไตรภาคของเรา

นี่andคือสิ่งที่ทำให้เราสามารถประเมินเงื่อนไขมันจะกลับมาเสมอyหากx and yประเมินเป็นจริง

ปัญหากับมันก็คือว่ามันจะล้มเหลวหากเราต้องการnilหรือที่จะกลับมาเมื่อเงื่อนไขเป็นfalse falseตัวอย่างเช่นค่าต่อไปนี้จะคืนค่า 5 แม้ว่าเงื่อนไขจะเป็นจริง

v = true and false or 5

ต่อไปนี้เป็นขั้นตอนการประเมินแบบไตรภาคเพื่ออธิบายวิธีการทำงาน (จะมีประโยชน์เมื่อคุณต้องซ้อนมันไว้ :))

-- let's use our dumb ternary
= true and false or 5
-- and statement will be evaluated first, leading to
= false or 5
-- and we saw how the or works
= 5

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

โปรดทราบว่าเคล็ดลับ "ใช้พื้นที่น้อยที่สุดเท่าที่จะทำได้" ใช้งานได้กับ Lua 5.2 และใหม่กว่าเท่านั้น
Adriweb

4

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


กำหนดฟังก์ชั่นซ้ำ ๆ ให้กับตัวแปร

Lua ช่วยให้คุณสามารถกำหนดฟังก์ชั่นให้กับตัวแปร แม้แต่ตัวแปรตัวละครเดียว ซึ่งหมายความว่าหากคุณทำซ้ำฟังก์ชันstring.sub(x, y)มากกว่าสองครั้งคุณจะได้รับประโยชน์จากการกำหนดให้กับตัวแปร

โดยไม่ต้องกำหนดให้กับตัวแปร (69 ตัวอักษร):

print(string.sub(x, y))
print(string.sub(x, y))
print(string.sub(x, y))

การกำหนดตัวแปร (51 ตัวอักษร):

s=string.sub
print(s(x,y))
print(s(x,y))
print(s(x,y))

มีหลายกรณีที่คุณสามารถทำสิ่งนี้ได้อีกขั้นหนึ่ง Lua อนุญาตให้ OOP จัดการสตริงเช่น: str:sub(x, y)หรือstr.sub(x, y)เปิดตัวเลือกใหม่สำหรับรหัสของเรา คุณสามารถกำหนดตัวแปรให้กับฟังก์ชันได้โดยการอ้างอิงตามที่แสดง (46 ตัวอักษร)

s=z.sub
print(s(x, y))
print(s(x, y))
print(s(x, y))

ใช้วิธีที่มีประสิทธิภาพที่สุดในการแยกวิเคราะห์สตริง

คุณอาจพบว่าตัวเองใช้forลูปและstring.subย้ำตัวละครทีละตัวใน Lua บางครั้งสิ่งนี้อาจทำงานได้ดีที่สุดทั้งนี้ขึ้นอยู่กับความต้องการของคุณ แต่บางครั้ง string.gmatch จะทำงานได้ไม่กี่ตัวอักษร นี่คือตัวอย่างของทั้งคู่:

s=io.read()
for a = 1, s:len() do
    print(s:sub(a, a))
end 

for i in io.read():gmatch('.') do
    print(i)
end

และเมื่อเล่นกอล์ฟความแตกต่างก็มีความโดดเด่นมากขึ้น:

s=io.read()for a=1,s:len()do print(s:sub(a, a))end

for i in io.read():gmatch'.'do print(i)end

ปรับโครงสร้างการมอบหมายเพื่อเพิ่มประสิทธิภาพ Whitespace

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

  • การกำหนดตัวแปร:

     x,y=io.read(),0 print(x)
     vs.
     y,x=0,io.read()print(x)
    
  • ถ้าข้อความ:

     if x:sub(1,1)==1 then
     vs
     if 1==x:sub(1,1)then
    

คืนอักขระที่น้อยที่สุดที่เป็นไปได้

หากคุณต้องส่งคืนค่าจริงหรือเท็จดูเหมือนว่าคุณต้องใช้อย่างน้อย 5 ตัวอักษรสำหรับค่าส่งคืน ในความเป็นจริงการทำงานต่อไปนี้ก็เช่นกัน:

return true
return false
vs
return 1>0
return 0>1

เคล็ดลับที่ดีฉันมีเสรีภาพที่จะแนะนำการแก้ไขโพสต์ของคุณ เท่านั้นnilและfalseประเมินเป็นเท็จในหลัวทุกอย่างอื่นเป็นความจริงดังนั้นเคล็ดลับของคุณเกี่ยวกับการเปลี่ยนx==0, x==""และx==''โดยxที่เป็นเท็จ ฉันกำลังเปลี่ยนเป็นnil:)
Katenkyo

อ่าคุณถูกต้อง ขอบคุณสำหรับการแก้ไข!
Skyl3r

2

นี่คือการเพิ่มประสิทธิภาพ Lua เท่านั้น (ฉันคิดว่า):

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

การสลับเนื้อหาของสองตัวแปรไม่จำเป็นต้องมีตัวแปรชั่วคราว a,b=b,aจะสลับค่าของ a และ b

นอกจากนี้หากต้องการขยายความตามที่กล่าวไว้ข้างต้นอักขระตัวอักษรและตัวเลขใด ๆ สามารถสัมผัสกับตัวอักษรและตัวเลข ดังนั้นจึงa,b=io.read():match"(.+)/(.+)"u,v=a,bเป็นสคริปต์ที่สมบูรณ์แบบและใช้งานได้แม้ว่าจะไม่มีช่องว่าง


2

รวมการมอบหมายตัวแปรท้องถิ่น

แทน:

local a=42
local b=17
local c=99

ใช้การมอบหมายแบบขนาน:

local a,b,c=42,17,19

บันทึก 6 ไบต์สำหรับแต่ละตัวแปร!

ประกาศตัวแปรท้องถิ่นผ่านพารามิเตอร์ฟังก์ชันที่ไม่ได้ใช้

แทน:

function foo(a,b) local c,d ... end
function bar(a,b) local c,d=42,17 ... end

ใช้

function foo(a,b,c,d) ... end
function bar(a,b,c,d) c,d=42,17 ... end

บันทึก 6 ไบต์ (ลบ 1-2 ไบต์สำหรับแต่ละตัวแปรที่อาจซ้ำกัน)


1
Downvoted เนื่องจากไม่มีกรณีใด ๆ ที่การใช้localจะพิสูจน์ได้เมื่อเล่นกอล์ฟเพราะคุณต้องใช้ชื่ออื่น เราสามารถใช้ชื่อทั้งหมดได้ถึง 7 ตัวอักษรและตารางที่มีดัชนีสตริงได้ถึง 7 ชุดตัวอักษรก่อนที่เราจะกดปุ่มบางสิ่งที่อาจได้รับประโยชน์จากการใช้คนในท้องถิ่น
Katenkyo

1

ฟังก์ชัน Variadic

ฟังก์ชันหลัก variadic print()ปัญหาที่คุณจะเป็น ตัวอย่างเช่นเมื่อคุณใช้งานพร้อมString.gsub()มันจะพิมพ์สตริงที่คุณแก้ไขและจำนวนครั้งที่ทgsubริกเกอร์

ในการแทนที่เอาต์พุตที่สองให้สรุปแค็ปของคุณgsubใน parens เพื่อบังคับให้ส่งคืนค่าเดียวเท่านั้น

print(String.gsub("aa",".","!"))    -- outputs "!!    2\n"
print((String.gsub("aa",".","!")))  -- outputs "!!\n"

1

รู้วิธีการส่งออก

มีสองวิธีหลักในการส่งออกในลัวะ

io.write()    -- outputs without trailing newline
print()       -- outputs with trailing new line and shorter by 3 bytes

เมื่อคุณต้องต่อหลาย ๆ ครั้งคุณสามารถย่อให้สั้นลงได้โดยใช้การio.write()กำหนดให้กับตัวแปรตัวอักษรหนึ่งตัวแทนการใช้ตัวต่อแบบมาตรฐาน..

i(a)    -- i was defined as io.write
s=s..a

คุณจะได้รับ 2 ไบต์ในการโทรแต่ละครั้งในขณะที่จ่ายเงินล่วงหน้า

i=io.write  -- longer by 6 bytes
s=""

คุณยังอยู่ในอันดับที่สามและเริ่มได้รับไบต์ที่สี่


3
มันเป็นprintและไม่printf!
วาลพูดว่า Reinstate Monica

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

1

เคล็ดลับในลำดับที่ไม่มี:

  • stringชื่อยาวสวย ได้อย่างมีประสิทธิภาพเป็นเช่นเดียวกับ('').char string.charผลลัพธ์ที่ดียิ่งขึ้นสามารถทำได้หากคุณใช้ร่วมกับเครื่องหมายอัฒภาคบนตัวแปร: a=...; print(a:sub(1, 5))แต่บางstringฟังก์ชั่นไม่ได้ใช้สตริงเป็นอินพุต
  • Lua มีการแปลงโดยอัตโนมัติระหว่างสตริงและตัวเลขสำหรับกรณีส่วนใหญ่ดังนั้นtonumberและ+0บ่อยครั้งที่จะเสียไบต์เท่านั้น
  • มักจะใช้แทนload'your function code here' function()your function code here endเข้าถึงฟังก์ชันอาร์กิวเมนต์โดยใช้...ด้านใน
  • ฟังก์ชั่นสตริงบางอย่างใน Lua สามารถใช้งานได้โดยไม่ตั้งใจ! ตัวอย่างเช่นa:gsub('.',load'my function')น่าจะเป็นวิธีที่สั้นที่สุดในการวนซ้ำตัวอักษรในสตริง
  • ในขณะที่เอ็นจิ้นสตริงนั้นทรงพลังจงระวังพลังของมันเมื่อใช้อินพุตของผู้ใช้เป็นรูปแบบ! ด้วยเหตุนี้คุณอาจต้องใช้a:find('.',1,1)(เพื่อทดสอบปัญหานี้ให้ลอง%ใส่ที่สถานที่ต่างๆในข้อมูลที่คุณป้อนและตรวจสอบผลลัพธ์) ความคิดนับไม่ถ้วนเกิดขึ้นเพราะ Lua พยายามแยกวิเคราะห์อินพุตเป็นรูปแบบ
  • nilคือสามไบต์_เป็นหนึ่ง (เป็นเพียงชื่อสุ่มที่ไม่มีแนวโน้มมากที่สุด) นอกจากนี้ตัวเลขใด ๆ จะทำงานเป็นค่าความจริง
  • x and i or oรู้ว่าอยู่เบื้องหลังตรรกะของคุณ มันไม่ได้เป็นเพียงผู้ประกอบการที่สาม - มันเป็นตรรกะที่สมบูรณ์ ในความเป็นจริงมันหมายถึงสิ่งต่อไปนี้: "ถ้าxเป็นจริงลองiถ้า x หรือฉันเป็นเท็จกลับ o" ดังนั้นหากiไม่ truthy oผลคือ นอกจากนี้ยังสามารถตัดทั้งสองส่วนandหรือor( x and i, x or o)
  • ใช้การหารจำนวนเต็มหนึ่งรายการแทนmath.floor: 5.3//1==5.0. โปรดทราบว่าจำนวนผลลัพธ์จะเป็นไปตามประเภทของอินพุตหนึ่งเสมอ (จำนวนเต็ม / จำนวนเต็ม)

1
"นอกจากนี้ตัวเลขใด ๆ จะทำงานเป็นค่าความจริง" แค่ต้องการอธิบายอย่างละเอียดว่าสิ่งนี้รวมถึง 0 ซึ่งอาจไม่ง่ายนักสำหรับผู้เขียนโค้ดบางคนจากพื้นหลัง C / C ++
ouflak
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.