Mẹo chơi gôn trong Tcl


15

Bạn có lời khuyên chung nào cho việc chơi golf trong Tcl? Tôi đang tìm kiếm những ý tưởng có thể được áp dụng cho các vấn đề về golf nói chung ít nhất là cụ thể đối với Tcl (ví dụ: "xóa bình luận" không phải là một câu trả lời). Xin vui lòng gửi một lời khuyên cho mỗi câu trả lời.

Câu trả lời:


7

Sử dụng lmapthay thế foreach. Điều này đòi hỏi Tcl 8.6.

Cú pháp là như nhau, nhưng lmaptrả về một danh sách với kết quả của mỗi vòng lặp.


4

Theo câu trả lời của tôi /codegolf//a/107557/29325 tôi có thể chứng minh:

  1. Thường set j 0;while \$j<$n;{...;incr j}là ngắn hơn tương đươngfor {set j 0} {$j<$n} {incr j} {...}

  2. Khi biến vòng lặp bắt đầu từ 1, chúng ta có thể thực hiện gia số như một phần của whileđiều kiện kiểm tra, tránh viết trước khi set i 1không cần thiết: while {[incr i]<=$n} {...}thay vìset i 1;while \$i<=$n;{...;incr i}

CHÚ Ý : Người ta chỉ có thể làm 2. trong trường hợp vòng ngoài! Tôi không thể áp dụng nó cho jbiến của mình vì nó cần được đặt lại thành 1 ở bên ngoài vòng lặp bên trong của chính nó! Và incr jsẽ có được giá trị được đặt ở bước cuối cùng của vòng lặp bên trong, thay vì lấy một biến không xác địnhj để giả định 0và tăng nó lên 1!


4

Đôi khi nó đáng để sử dụng time {script} ntrong đó nsố lần lặp thay vì vòng lặp thông thường whilehoặc forvòng lặp. Mặc dù timemục đích của nó không phải là lặp, nhưng hiệu quả đạt được là như nhau.

Tôi đã thực hiện các thay đổi gần đây cho câu trả lời của riêng tôi theo hướng này.

CẬP NHẬT: Tôi vừa phát hiện ra một cạm bẫy dễ rơi: Bạn không thể thay thế một forhoặc whilemột timekhối, nếu nó chứa một breakhoặc a continue.


3

Sử dụng vỏ tương tác. Điều này cho phép bạn viết tắt tên lệnh miễn là chỉ có 1 lệnh bắt đầu bằng các chữ cái còn lại.

Thí dụ:

  • gets -> ge
  • lassign -> las
  • expr -> exp
  • puts -> pu

Và các giải pháp tương tác là miễn phí: P

Bối cảnh :

Khi tclshchạy với một thiết bị đầu cuối là thiết bị đầu vào, nó đặt biến tcl_interactivethành 1. Điều này gây ra unknown(thủ tục mặc định sẽ được gọi nếu không thể tìm thấy lệnh) để tìm kiếm các lệnh bắt đầu bằng tên đó.

Nhược điểm: nó sẽ in kết quả của mỗi dòng, sử dụng ;thay vì dòng mới.
Ồ, và nó có thể gọi các lệnh bên ngoài như w, đó là một từ viết tắt tốt while.


3

Các tiểu ban và tùy chọn có thể (thường) được viết tắt. Điều này có thể tiết kiệm khá nhiều, nhưng bạn phải kiểm tra vì không phải mọi thứ đều có thể rút ngắn theo cách này ( regsubví dụ: tùy chọn không thể).

Sau đó, bạn có thể sử dụng điều này với phép thuật namespaceđể làm một số điều thực sự xấu xa. Xem xét điều này:

namespace exp *;namespace en cr -c ?

Sau đó, ?bây giờ là một lệnh ma thuật cho phép bạn viết tắt bất kỳ lệnh Tcl toàn cầu nào, và tất cả mà không có sự không chắc chắn khó chịu khi làm rối tung unknown.


2

Tôi đang sử dụng Tcl 8.0.5, nhưng tôi tin rằng những điều sau đây có thể áp dụng cho tất cả các phiên bản gần đây.

  1. Sử dụng renameđể đổi tên rename:

    rename rename &
    

    &thể là bất kỳ định danh; &chỉ nhắc tôi về "tài liệu tham khảo" trong C.

  2. Sử dụng tên được đổi tên renameđể đổi tên set:

    & set =
    

    Một lần nữa, =có thể là bất kỳ định danh; =chỉ là trực quan với tôi.

  3. Bây giờ, đổi tên các lệnh khác có giá trị đổi tên, ví dụ:

    & regsub R
    & string S
    & while W
    

    Một lệnh có giá trị đổi tên nếu, với độ dài n và các lần xuất hiện k , k (n-1) - (n + 4)> 0 . Giải cho k , công thức trở thành k > (n+4)/(n-1). Đây là bảng tham chiếu giúp dễ dàng:

    length of       minimum         example(s)
    command         occurrences
    ------------------------------------------------
    2               6               if (consider renaming to "?")
    3               4               for, set (consider renaming to "=")
    4               3               eval, expr, incr (consider renaming to "+"), info, join, proc, puts, scan
    5               3               break, catch, lsort, split, subst, trace, unset, while
    6               3               format, lindex, lrange, regexp, regsub, rename, return, string, switch
    7               2               foreach, lappend, linsert, llength, lsearch, unknown
    .               2               lreplace
    .               2               continue
    .               2               
    
  4. Tiếp theo, các tiểu ban được sử dụng thường xuyên như

    = I index
    = L length
    

    để bạn có thể làm những việc như

    S $I $x 7
    S $L $x
    
  5. Một số miscellanea rõ ràng:

    1. lappend có thể đặt thành phần đầu tiên của danh sách nếu nó chưa tồn tại (không cần khởi tạo).
    2. Bạn có thể đặt mảng mà không cần sử dụng array, vd set doesNotExist(7) 43 .
    3. Bạn có thể sử dụng chuỗi ( "a b c") thay vì [list a b c].
    4. Bạn có thể nội suy trong các chuỗi như vậy : foo${a}bar.
    5. Bạn có thể sử dụng two\ wordschứ không phải "two words". (Nói chung, hãy nhớ rằng đối với các chuỗi liền kề không có dấu cách, có thể bỏ qua dấu ngoặc kép!)
    6. Bạn hầu như luôn có thể viết lại fors thành whiles để lưu một hoặc hai ký tự, vì whilecó thể đồng thời kiểm tra và tăng trong khi forsử dụng các khối riêng biệt.
  6. Đối với các chương trình lớn hơn, đây là một mẹo tôi nghĩ đến nhưng chưa được áp dụng:

    proc unknown {c args} {eval [info commands $c*] $args}
    

    Điều này mô phỏng viết tắt lệnh tương tác! Nó có giá 54 ký tự, nhưng bây giờ bạn có thể sử dụng jcho join, spcho split, stcho string, wcho while, v.v.


1
Nếu bạn muốn mô phỏng các chữ viết tắt tương tác, hãy sử dụnginfo script {};set tcl_interactive 1
Johannes Kuhn

Hay quá cảm ơn! Tôi đã ghi có bạn ở đây . Tuy nhiên, có một số vấn đề với kỹ thuật đó, tuy nhiên, tôi đã không gặp phải unknownlộ trình: xem tại đâyđây .
Andrew Cheong

Câu hỏi yêu cầu những lời khuyên có phần cụ thể đối với Tcl. Toán tử ternary được bao gồm trong các mẹo cho tất cả các ngôn ngữ .
Peter Taylor

@PeterTaylor - Cảm ơn, tôi đã xóa mẹo đó.
Andrew Cheong

2

khác là tùy chọn

Như đã nói trên nếu trang thủ công , elsesẽ ẩn trên ifcác cấu trúc khối. Vậy là gì

if ... {} else {}

có thể trở thành

if ... {} {}

như bạn có thể thấy trên một số câu trả lời của tôi.


1

Có thể nó nên được tích hợp vào một câu trả lời khác, nhưng ở đây nó đi:

Khi a procchỉ có một tham số, nó có thể được viết là

proc p a {DO THINGS}

thay vì

proc p {a} {DO THINGS}

Điều tương tự áp dụng cho hai tham số procsử dụng dấu gạch chéo ngược; nó có thể được viết là

proc p a\ b {DO THINGS}

thay vì

proc p {a b} {DO THINGS}

Đối với số lượng tham số cao hơn, {}kết xuất mã ngắn hơn.


1

Đôi khi, đáng để thay thế hai setcâu lệnh để nối chuỗi chỉ bằng một lappendcâu lệnh. Trên một công trình như thế, người ta có thể thay thế

set s ""

loop {
    # ...
    set s $s\X
}

bởi

loop {
    # ...
    append s X
}

Các appendlệnh cóincr hành vi như thế nào, mà khởi tạo một biến chưa được xác định.

Cẩn thận để không nhầm lẫn appendbởilappend


1

Nếu bạn đang xử lý một danh sách với một thao tác theo cú pháp là xen kẽ giữa mỗi phần tử, đôi khi bạn có thể joincác phần tử để thực hiện một thao tác cụ thể, thay vì duyệt qua nó.

Trên /codegolf//a/127042/29325 có một ví dụ:

puts \n[expr [join [split [read stdin]] +]]

read stdinđưa ra 23 214 52sau đó phân chia sẽ đưa ra danh sách {23 214 52}. Sau, [join {23 214 52} +]sẽ trả về chuỗi 23+214+52. Cuối cùng expr 23+214+52cũng làm công việc tổng kết


Trong trường hợp này, bạn có thể bỏ qua split.
Julian Kuhn

@JohannesKuhn: cảm ơn. Làm xong.
sergiol

1

Nếu bạn có mã lớn, có thể tránh sử dụng nhiều lần sử exprdụng namespace pat tcl::mathopngay từ đầu. Nó cung cấp hoạt động tiền tố-cú pháp như một fonction Tcl thông thường. Ví dụ:

namespace pat tcl::mathop
set sum [+ 1 2 3]
set prod [* {*}{1 2 3 4}]
puts $sum\ $prod

Xem trang tài liệu mathop chính thức


0

Khi bạn có một vài biến nằm settrên các dòng tiếp theo, bạn có thể sử dụng một biến lassignthay vì một vài biếnset hướng dẫn để đạt được hiệu quả tương tự.

Một ví dụ là câu trả lời của riêng tôi /codegolf//a/105789/29325

Để quyết định, người ta chỉ cần cân số lượng biến (giả sử 1 biến chữ, như dự kiến ​​khi chơi golf):

  • <5, setlà người chơi gôn

  • = 5, setlassigntạo ra số byte tương tự

  • > 5, lassign là gôn thủ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.