라켓 / 스킴에서의 골프 팁


15

Racket / Scheme 에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 나는 일반적으로 Racket / Scheme에 다소 특정한 코드 골프 문제에 적용될 수있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).


SchemeRacket (이전의 PLT Scheme)은 기술적으로 다른 언어이지만 많은면에서 상당히 유사하며 많은 코드 (의심)가 대부분 의도 된대로 실행될 것이라고 알고 있습니다. 팁이 위에서 언급 한 언어 중 하나에 만 적용되는 경우 참고하십시오.

답변:


3

식은 'x, `x, ,x,가 ,@x자동으로 확장 (quote x), (quasiquote x), (unquote x),와 (unquote-splicing x), 각각. 이것은 순전히 구문 변환이며 어디에서나 적용 할 수 있습니다. 이것은 한 변수 함수에 대한 편리한 표기법을 제공합니다.

; Defining a function:
(define ,x (+ x x))
; Calling a function:
(display ,2)

어느쪽으로 확장

; Defining a function:
(define (unquote x) (+ x x))
; Calling a function:
(display (unquote 2))

위와 같은 코드가 테스트 한 인터프리터에서 작동 했지만 두 문자 약어가 있기 때문에 이상적이지는 않지만 구문 변수 를 사용 quote하거나 quasiquote바인딩 된 변수 로 구문 키워드를 음영 처리하는 의미가 무엇인지 확실하지 unquote-splicing않지만 unquote한 문자 약어가있는 보조 구문이므로이 핵에 이상적입니다.


8

에서 라켓 , λ그리고 lambda익명 함수를 구성하는 동의어 키워드가 있지만, λ2 바이트 lambda6입니다.

에서 계획 , 거기에 그런 키워드 없습니다 λ당신은에 붙어있어 lambda.


6

~a숫자와 기호를 문자열로 변환하는 데 사용 합니다.


5

Racket을 사용할 때는 λ몇 바이트를 사용하여 변수를 바인드하십시오 . 에서 계획 , lambda하나의 4 개 이상의 변수를 바인딩하지 않는 한,이 트릭가 적용되지 수 있습니다.

예 : 하나의 변수는 let/define

(define n 55)(* n n) ; 20 bytes

(let([n 55])(* n n)) ; 20 bytes

((λ(n)(* n n))55) ; 18 bytes

나는 그 바인딩을 부르지 않을 것입니다. 다른 기능을 사용하고 있습니다. 경우에 따라 익명 함수를 사용하는 것이 변수를 바인딩하는 것보다 짧습니다.
Michael Vehrs

나는 당신의 의견이 계획 서클에서 사용되는 일반적인 용어 와 어떤 관련이 있는지 잘 모르겠습니다 . 변수를 어휘 범위에 바인딩하는 두 가지 방법을 보장하며 let종종의 관점에서 구현됩니다 lambda.
Winny

5

에서 라켓 , require형태는 여러 인수를 가질 수 있습니다.

(require net/url net/uri-codec)

보다 짧은 방법

(require net/url)(require net/uri-codec)

Scheme에 대해 많이 알지 못하지만 require내장 기능 이없는 것 같습니다 .


5

짧은 동의어 사용

라켓에는 대부분 짧은 버전의 절차가 있습니다. (일반적으로 동일하지 않습니다. 예를 들어, 실패한 (car (cons 1 2))곳 에서 작동 (first (cons 1 2))합니다. 그러나 귀하의 경우 동의어 인 경우 대체 할 수 있습니다.)

이 목록은 아마도 불완전합니다. 아마도이 목록에 들어갈 수있는 대부분의 것들을 알지 못할 것입니다.

  • (= a b)(equal? a b)숫자를 비교할 때가 아니라
  • '(1 2)대신에 (list 1 2).
  • car, cadr, cdr대한 first, secondrest.
  • null? 대신에 empty?
  • moduloremainder계수가 양수일 때가 아니라
  • floortruncate논쟁이 긍정적일 때가 아니라

4

불필요한 공간 생략

이것은 "사소한"팁으로 간주 될 수 있지만 어딘가에 지적되어야합니다.

평범한 사람들이 작성한 라켓 코드 (예 : 라켓 문서 ) 를 읽을 때마다 모든 공백이 들어 갑니다 . 예를 들어,

(append (list 1 2) (list 3 4) (list 5 6) (list 7 8))

사실, 이후 ()변수 이름의 일부가 될 수 없습니다, 우리는 어떤 모호성을 잃고 그들 주위의 모든 공간을 삭제하고 할 수없는 (그리고, 더 중요한 것은 여전히 유효 코드를 얻을). 따라서 위의 표현은 다음과 같습니다.

(append(list 1 2)(list 3 4)(list 5 6)(list 7 8))

2

다음은 라켓 관련 팁입니다 .

기본 인수

자주 사용되는 긴 함수 이름의 별명을 작성하는 데 특히 유용합니다.

골프를 사용하면 인수를 사용 reverse하는 함수를 작성할 수 있다고 가정하고 많이 사용해야한다고 가정합니다 . 당신은 다음과 같이 시작할 것입니다 :

(λ(x) ... reverse ... reverse ... reverse ...

대신보다 짧은 이름의 추가 인수를 사용하여 reverse기본값을 reverse다음 과 같이 설정할 수 있습니다 .

(λ(x[r reverse]) ... r ... r ... r ...

또한 동일한 인수로 여러 곳에서 사용하는 도우미 함수가있는 경우 유용합니다. 필요에 따라 인수를 함수에 다시 정렬해야하므로 가능한 한 많은 기본 인수를 사용하고 여러 호출 사이트에서 인수를 제거 할 수 있습니다.

match

이 글은 작은 글로 요약하기가 조금 어렵 기 때문에이 글에 대한 라켓 문서 를 읽어보십시오 . 간단히 말해서 match목록에서 특정 순서로 요소와 요소 시퀀스를 추출 할 수 있으며, 준 따옴표 구문을 사용하면 잘린 목록을 다시 연결할 수 있습니다.

(match (range 10)
 [`(,xs ... 3 ,ys ... 6 ,zs ...)
  `(,@(map f xs) 3 ,@(map f ys) 6 ,@(map f sz))]
 ...

또한 정규 표현식으로 작업하고 결과 그룹에 대한 추가 계산을 수행하는 쉬운 방법을 제공합니다.

명명 된 let

여기 에서 명명 된 구문을 참조 하십시오 .let proc-id ...

이를 통해 define정의한 후에 함수를 호출하거나 호출 하지 않고 즉시 호출되는 재귀 함수를 작성할 수 있습니다 .

다음과 같은 것 :

(define (fib i)
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))
(fib 10)

단축 할 수 있습니다 :

(let fib {[i 10]}
  (if (< i 2) i
      (+ (fib (- i 1)) (fib (- i 2)))))


이 마지막 하나는 바보입니다,하지만 난 아무데도 지금까지 약간의 트릭을 사용할 수 없었다 :
(apply map list matrix)의 전치 소요 matrix, matrix목록의 일부 직사각형 목록처럼입니다 '((1 2 3) (a b c)).
이것이 유용한 지 알려주세요.


1

마찬가지로 위니 지적 , #!일반적으로 대신 사용할 수있는 #lang4 바이트를 저장.

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