Tcl에서의 골프 팁


15

Tcl에서 골프를 치기위한 일반적인 팁은 무엇입니까? 나는 적어도 Tcl에 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고있다 (예 : "댓글 제거"는 답이 아니다). 답변 당 팁 하나를 게시하십시오.

답변:


7

lmap대신 사용하십시오 foreach. 이를 위해서는 Tcl 8.6이 필요합니다.

구문은 동일하지만 lmap각 루프의 결과가 포함 된 목록을 반환합니다.


4

내 대답 /codegolf//a/107557/29325에서 다음 을 보여줄 수 있습니다.

  1. 일반적으로 set j 0;while \$j<$n;{...;incr j}동등한 것보다 짧습니다for {set j 0} {$j<$n} {incr j} {...}

  2. 루핑 변수가 1로 시작하면, 우리는의 한 부분으로 증가 할 수 있습니다 while전에 쓰기 방지 시험 조건 set i 1불필요 : while {[incr i]<=$n} {...}대신set i 1;while \$i<=$n;{...;incr i}

주의 : 외부 루프의 경우 2 개만 할 수 있습니다! j자체 내부 루프 외부에서 1로 재설정해야하므로 변수에 적용 할 수 없습니다 ! 그리고 정의되지 않은 변수 를 incr j잡아서 증가시키는 대신 내부 루프의 마지막 단계에서 설정된 값을 얻습니다 !j01


4

때때로 노멀 또는 루프 대신 반복 횟수가있는 time {script} n곳 을 사용 하는 n것이 좋습니다 . 하지만 의 목적은 반복되지 않는, 달성 된 효과는 동일합니다.whilefortime

이 방향에 따라 최근에 내 자신의 답변을 변경했습니다.

업데이트 : 난 그냥 쉬운 함정 떨어질 발견했습니다 당신은 대체 할 수 없습니다 for또는를 whilea로 time그것이 포함되어있는 경우, 블록 break또는를 continue.


3

대화식 쉘을 사용하십시오. 이렇게하면 하나의 명령 만 나머지 문자로 시작하는 한 명령 이름을 축약 할 수 있습니다.

예:

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

대화 형 솔루션은 무료입니다 .P

배경 :

경우 tclsh입력 장치로 실행 단자는, 상기 변수 설정 tcl_interactive에이 1. 이로 인해 unknown(명령을 찾을 수없는 경우 호출되는 기본 프로 시저) 해당 이름으로 시작하는 명령을 검색합니다.

단점 : 모든 줄의 결과를 인쇄하고 줄 ;바꿈 대신 사용 합니다.
같은 오, 그것은 외부 명령을 호출 할 수있는 w좋은 약자 인 while.


3

부속 명령 및 옵션은 (대개) 축약 될 수 있습니다. 이것은 상당히 절약 할 수 있지만 모든 방법을 단축 할 수있는 것은 아니므로 테스트 해야합니다 ( regsub예 : 옵션은 할 수 없습니다).

그런 다음 이것을 namespace진정으로 악한 일을 하는 마법과 함께 사용할 수 있습니다 . 이걸 고려하세요:

namespace exp *;namespace en cr -c ?

그 후, ?이제 모든 글로벌 Tcl 명령을 축약 할 수있는 마법 명령이되었습니다 unknown.


2

Tcl 8.0.5를 사용하고 있지만 다음은 모든 최신 버전에 적용됩니다.

  1. rename이름을 바꾸는 데 사용 rename:

    rename rename &
    

    &임의의 식별자 일 수있다; &C에서 "참조"를 상기시켜줍니다.

  2. 이름 rename을 바꾼 이름 을 사용하여 이름 을 바꿉니다 set.

    & set =
    

    다시 말하지만,는 =식별자 일 수 있습니다. =나에게 직관적입니다.

  3. 이제 가치 이름 바꾸기 다른 명령, 이름 바꾸기 등을

    & regsub R
    & string S
    & while W
    

    길이가 n 이고 발생 k , k (n-1)-(n + 4)> 0 이면 명령의 이름을 바꿀 가치가 있습니다. k를 풀면 식이됩니다 k > (n+4)/(n-1). 다음은 쉬운 참조 테이블입니다.

    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. 다음으로 자주 사용되는 소형 부속 명령

    = I index
    = L length
    

    그래서 당신은 같은 일을 할 수 있습니다

    S $I $x 7
    S $L $x
    
  5. 몇 가지 명백한 기타 :

    1. lappend 목록의 첫 번째 요소가 아직 없으면 (초기화하지 않아도) 설정할 수 있습니다.
    2. 당신은 사용하지 않고 배열을 설정할 수 있습니다 array, 예를 set doesNotExist(7) 43 .
    3. "a b c"대신 문자열 ( )을 사용할 수 있습니다 [list a b c].
    4. 다음과 같이 문자열을 보간 할 수 있습니다 foo${a}bar.
    5. two\ words대신 사용할 수 있습니다 "two words". (공백이없는 연속 된 문자열의 경우 큰 따옴표를 생략 할 수 있음을 일반적으로 기억하십시오.)
    6. 문자 는 별도의 블록을 사용 하는 동안 동시에 확인하고 증가시킬 수 있기 때문에 문자를 두 개 저장하기 위해 s를 거의 항상 fors로 다시 쓸 수 있습니다 .whilewhilefor
  6. 더 큰 프로그램의 경우 여기에 내가 생각했지만 아직 적용하지 않은 트릭이 있습니다.

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

    이것은 대화식 명령 약어를 에뮬레이트합니다! 그것은 54 개 문자 비용,하지만 지금은 당신이 사용할 수 j에 대한 join, sp대한 split, st대한 string, w대한 while, 등등.


1
대화 형 약어를 에뮬레이션하려면info script {};set tcl_interactive 1
Johannes Kuhn

감사합니다! 나는 당신을 여기에서 인정 했습니다 . 그러나이 기술과 관련하여 몇 가지 문제가 있었지만 unknown경로에서 발생하지 않았습니다 . herehere 참조 .
Andrew Cheong

이 질문은 Tcl에 특정한 팁을 요구합니다. 삼항 연산자는 모든 언어 에 대한 팁에 포함되어 있습니다 .
피터 테일러

@PeterTaylor-고맙습니다. 팁을 삭제했습니다.
Andrew Cheong

2

그렇지 않으면 선택 사항입니다

가에 말했다됨에 경우 매뉴얼 페이지를 , else에 암시 적 if블록 구축합니다. 그래서 무엇입니까

if ... {} else {}

될 수있다

if ... {} {}

내 대답 중 일부에서 볼 수 있듯이.


1

다른 답변에 통합되어야 할 수도 있지만 여기에 있습니다.

A는 때 proc하나 개의 매개 변수가 다음과 같이 작성 될 수있다

proc p a {DO THINGS}

대신에

proc p {a} {DO THINGS}

proc백 슬래시를 사용하는 두 매개 변수에도 동일하게 적용됩니다 . 그것은 다음과 같이 쓸 수 있습니다

proc p a\ b {DO THINGS}

대신에

proc p {a b} {DO THINGS}

더 많은 수의 매개 변수의 경우 {}더 짧은 코드를 렌더링합니다.


1

때로는 두 개의 set명령문 을 대체하여 문자열을 하나의 lappend명령문 으로 연결하는 것이 좋습니다. 같은 구조에서 대체 할 수 있습니다

set s ""

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

으로

loop {
    # ...
    append s X
}

append명령에는 incr아직 정의되지 않은 변수를 초기화 하는 유사한 동작이 있습니다.

없는 실수에주의 append하여lappend


1

구문 적으로 각 요소 사이에 인터리브되는 오퍼레이션으로 목록을 처리하는 경우 때때로 join트래버스하지 않고 요소가 특정 오퍼레이션을 수행 할 수 있습니다 .

/codegolf//a/127042/29325 예제가있다 :

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

그것은 read stdin부여합니다 23 214 52다음 목록을 줄 것이다 분할 {23 214 52}. 이후에 [join {23 214 52} +]문자열을 반환합니다 23+214+52. 마지막으로 expr 23+214+52합산 작업을 수행


이 경우을 생략 할 수 있습니다 split.
Johannes Kuhn

@JohannesKuhn : 감사합니다. 끝난.
sergiol

1

당신이 큰 코드가 있다면, 그것은 여러 용도 회피하는 것이 가능 expr하여 namespace pat tcl::mathop시작 부분에 있습니다. 일반적인 Tcl 기능으로 접두사 구문 작업을 제공합니다. 예를 들면 다음과 같습니다.

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

공식 mathop 문서 페이지 참조


0

set다음 줄에 여러 변수가 있으면 하나를 사용할 수 있습니다lassignset 경우 동일한 효과를 얻기 위해 여러 명령 대신 를 .

하나의 예는 내 자신의 답변입니다 /codegolf//a/105789/29325

결정하려면 변수 수에 가중치를 부여하면됩니다 (골프 할 때 예상되는 1 개의 문자 변수로 가정).

  • <5, set골퍼입니다

  • = 5 setlassign동일한 바이트 수를 생성

  • > 5, lassign골퍼입니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.