APL에서의 골프 팁


28

최근에 하나의 코드 골프 챌린지를 시작했으며 우승자가 GolfScript (놀랍고 놀랍습니다!) 인 것 같습니다. 흥미로운 것은 GolfScript를 이길 수있는 모든 기회를 가진 또 다른 강력한 경쟁자가 있다는 것입니다. 이름은 APL입니다. 여기 APL로 작성된 많은 답변이 있습니다. 이 언어는 코드 골프에 매우 효율적인 것 같습니다. 따라서 APL 프로그램에 대해 알고있는 코드 골프 팁을 요청하기로합니다. 코드 예제를 자유롭게 게시하십시오. 언어가 실제로 사용되는 것을 보는 것은 매우 흥미 롭습니다.

답변:


23

편집 : APL을 전혀 모르지만 그것을 받아들이고 싶은 사람들을 위해, Dyalog APL 마스터 링아주 좋은 자료입니다.

  1. 평가는 엄격하게 오른쪽에서 왼쪽입니다. 여기에는 변수 설정이 포함되므로 활용하십시오.

    2+a, 1+a←1 -> 3 4

    a로 설정 1, 1+a평가 2, a,2평가 1 22+1 2평가합니다 3 4.

  2. C 와 같이 함수와 결합 될 수 있습니다 a +← 3. C와 달리 이것은 일반적입니다 :로 foo F← bar설정 foo합니다 F bar. 직관적이지 않은 식으로, 이것이 bar아닌을 반환합니다 F bar.

    익명 함수에서도 작동합니다.

          a←0
          a+←3 ⋄ a
    3
          a+←3 ⋄ a
    6
          a { ⍵/'!' } ←4 ⋄ a
    !!!!
    
  3. A[3]←8예상대로 배열에을 (를) 할당 할 수 있습니다 . 그러나 동시에 여러 항목을 할당 할 수도 있습니다. A[3 5 6]←9 1 4또는 A[3 5 6]←9모든 항목을 동일한 항목으로 설정할 수도 있습니다. 물론 여기에도 함수를 추가 할 수 있습니다 . 이 기능은 마치 마치 마치 각 요소에 개별적으로 적용됩니다 .

  4. 너무 행복해 보이지 않더라도 친구입니다.

    1. Fdyadic 인 경우 , dyadic 는 인수를 a F b<-> 전환합니다 b F⍨ a. 이것은 중괄호를 사용하지 않아도되므로 골프 때 유용합니다.

      (F G H x) K y      <->     y K⍨ F G H x
      

      오른손은 항상 왼손보다 먼저 평가되므로 평가 순서가 변경됩니다.

    2. 경우 F이항이다, 모나드는 함수의 양쪽에 동일한 인수를 적용 :

            5⍴5
      5 5 5 5 5
            ⍴⍨5
      5 5 5 5 5
      

      인수는 한 번만 평가됩니다. 이것은 특히 외부 제품에 유용합니다. 즉, 배열의 각 값을 같은 배열의 다른 값과 비교 ∘.=⍨하려면 수행 하는 대신 사용할 수 있습니다 x∘.=x←(whatever).

    3. 경우 F모나드이다, 아무것도하지 않는다,하지만 인수에서 기능을 분리한다. 따라서 함수가 복잡한 경우 여전히 중괄호를 저장할 수 있습니다.

            {⍵+3}⍣5 6
            ∇{⍵+3}              
           ∇ ⍣ 5 6              
            ({⍵+3}⍣5)6
      21
            {⍵+3}⍣5⍨6
      21
      
  5. 관용구를 배우십시오! 그런 다음 관용구를 골프. 예를 들면 다음과 같습니다.

    ((((1↑⍴X),⍴Y)↑X)^.=Y)⌿X
    

    기계적으로 다음과 같이 변형 될 수 있습니다.

    X⌿⍨Y^.=⍨X↑⍨(1↑⍴X),⍴Y
    

    그리고 더 나아가 :

    X⌿⍨Y^.=⍨X↑⍨(⊃⍴X),⍴Y
    

    이 경우 (첫 번째)는 1↑(하나를 취하십시오)와 같습니다. 그리고 아마도 :

    X⌿⍨Y^.=⍨X↑⍨(≢X),⍴Y
    

    (탈리) ⊃⍴스칼라를 제외한 모든 스칼라에 대해 (모양의 첫 번째 요소 )와 같습니다 .


라즈베리 파이 버전 외에 무료 라이센스를받을 수있는 방법이 있습니까?
Fabinout

그것을 얻는 합법적 인 방법입니다.
Fabinout

2
@Fabinout : dyalog.com에서 무료 Windows 버전을 다운로드 할 수 있습니다. "다운로드 영역"을 클릭 한 다음 "등록되지 않은 다운로드"를 클릭하십시오. 그것은 당신을 등록하도록 잔소리하지만 그렇지 않으면 그것은 완전히 기능적이고 무료이며 합법적입니다. 학생 인 경우 양식을 작성하여 일반 버전을 무료로받을 수 있습니다. 그들이 해적판을 위해 당신의 인생을 망치는 나라에 살고 있지 않다면, 당신은 무엇을 해야할지 압니다.
marinus

또한 Dyalog보다 더 많은 기능을 가진 오픈 소스 구현 인 Nars2000 (및 일부 버그)도 있습니다. 일부 기능은 소수 함수 또는 다중 집합과 같은 골프에 편리합니다.
Tobia

1
GNU APL이 있습니다.
M. Alaggan

14

열차

A(f g h)B      ←→  (A f B)g A h B  ⍝ fork
 (f g h)B      ←→  (  f B)g   h B  ⍝ fork
A(  g h)B      ←→         g A h B  ⍝ atop
 (  g h)B      ←→         g   h B  ⍝ atop
 (A g h)       ←→  ({A} g h)       ⍝ "Agh" fork
 (f g h k)     ←→  (f (g h k))     ⍝ 4-train
 (f g h k l)   ←→  (f g (h k l))   ⍝ 5-train, etc
 (f g h k l m) ←→  (f(g h(k l m))) ⍝ groups of 3 from the right, last could be 2
  f∘g B        ←→    f g B         ⍝ "compose" operator, useful in trains
A f∘g B        ←→  A f g B

그것은 미래 독자들을 위해 Oberon에게 그것을 단축하는 방법을 말해서는 안된다는 것을 의미합니까?
Adám

아니오, 평소처럼 PPCG에서하는 것처럼하십시오. 표현이 최단에 도달하면 그 줄을 제거합니다. 그것은 쉬운 운동입니다-나는 당신이 개인적으로 그것으로부터 이익을 얻을 것이라고 생각하지 않습니다.
ngn

16으로 줄일 수는 있지만 팁을 사용하지 않고 있으므로 어쩌면 벗어날 수 있습니다.
Adám

@ Adám 잘, 당신은 기차를 사용하고 있습니다 :)내는 비슷하지만 더 오래 ⎕ML을 생각하지 않았기 때문에
ngn

" 오른쪽 에서 3 개의 그룹 "이 아닙니까?
Adám

7

취급에 대한 트릭 /기차에서

열차 를 사용할 때 f/합계 +/또는 복제 감소 와 같은 감소를 사용할 수 있습니다 //. 그러나 열차 왼쪽에 더 많은 부품이있는 경우 꼭대기를 만들려면 괄호가 필요합니다. 다음은 바이트를 절약하는 몇 가지 요령입니다.

1∊모나 딕 ∨/또는 ∨⌿불리언 배열 대신 사용

작업 : 길이가 같은 두 문자열 A와 B가 주어지면 A와 B의 해당 문자가 같은 경우 2를, 그렇지 않으면 0을 반환합니다. 예 A←'abc'B←'def'제공 0하고 A←'abc'하고 B←'dec'있습니다 2.

dfn 솔루션이있을 수도 A{2×∨/⍺=⍵}B있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. A(2×∨/=)B기차 형성 규칙이 이것을 파싱 2 (× ∨/ =)하지만 원하는 대로 작동하지 않습니다 2 × (∨/=).

그 관찰 ∨/또는 ∨⌿부울 벡터 (에 ∨/,또는 ∨⌿,더 높은 순위 배열) 즉, 어떤 한 존재가 있는지 여부를 묻는 1∊우리가 우리 기차를 작성할 수 있도록 2×1∊=.

참고 별도로 각 행 또는 열을 줄이기 위해 사용할 수 있도록, 오른쪽 인수를 ravels.

사용 1⊥하는 대신 모나드의 +/또는+⌿

작업 : 목록 L과 인덱스 N의 목록이 주어지면 N 번째 목록의 합계를 세 번 반환하십시오. 예 L←(3 1 4)(2 7)하고 N←1있습니다 24.

dfn 솔루션이있을 수도 N{3×+/⍺⊃⍵}L있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. N(3×+/⊃)L기차 형성 규칙이 이것을 파싱 3(× +/ ⊃)하지만 원하는 대로 작동하지 않습니다 3 × (+/⊃).

단항 (base-1)으로 숫자 목록을 평가하는 것은 ∑ { a , b , c , d } =  a + b + c + d  = ( a × 1³) + ( b × 1² 이므로리스트를 합산하는 것과 같습니다. ) + ( c × 1¹) + ( d × 1⁰). 따라서 +/a b c d와 동일하며 1⊥a b c d열차를 다음과 같이 작성할 수 있습니다 3×1⊥⊃.

순위가 높은 인수에서는와 1⊥같습니다 +⌿.

스칼라 및 / 또는 벡터 인수 f.g대신 사용f/g

작업 : 목록 L 및 개수 N이 주어 철저한 1 L의 요소 NEG로 나누어 최소 분할 나머지 숫자 범위 복귀 L←31 41 59N←7범에게 1 2 3.

dfn 솔루션이있을 수도 N{⍳⌊/⍺|⍵}L있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. N(⍳⌊/|)L기차 형성 규칙이 이것을 파싱 ⍳ (⌊/) |하지만 원하는 대로 작동하지 않습니다 ⍳ (⌊/|).

A f.g B인수가 스칼라 및 / 또는 벡터 일 때 스칼라 두 함수 의 내부 곱은 f/ A g B둘 다 (A[1] g B[1]) f (A[2] g B[2]) f (A[3] g B[3])등 이기 때문에 동일 하므로 기차를로 작성할 수 있습니다 ⍳⌊.|.

상위 어레이에서는 작동하지 않습니다.

부울 왼쪽 및 간단한 벡터 오른쪽 인수 ∊⊆대신 사용/

작업 : 목록 L과 숫자 N이 주어지면 N보다 큰 숫자 만 남도록 목록을 필터링하십시오. 예 L←3 1 4하고 N←1있습니다 3 4.

dfn 솔루션이있을 수도 N{(⍺<⍵)/⍵}L있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. N(</⊢)L바인딩 규칙이이를 구문 분석 할 것이기 때문에 작동하지 (</) ⊢않지만 연산자 reduce 대신 /함수 복제 가 되려고합니다 .

왼쪽 부울 인수가있는 Dyadic 은 왼쪽 인수에서 1의 실행에 따라 오른쪽 인수를 분할하고 0으로 표시된 요소를 삭제합니다. 이것은 우리가 원하는 것입니다. 원치 않는 파티셔닝을 절약하십시오. 그러나 monadic을 적용하여 분할을 제거 할 수 있습니다 . 따라서 {(⍺<⍵)/⍵}될 수 {∊(⍺<⍵)⊆⍵}있으므로 우리는 우리의 기차를 쓸 수 있습니다 ∊<⊆⊢.

상위 어레이에서는 작동하지 않습니다.

숫자 인수 0⊥대신 ⊢/또는 ⊢⌿숫자 인수와 함께 사용

작업은 : 다리의 오른쪽 요소 목록 L 및 숫자 N, 곱 N을 감안 L←3 1 4하고 N←2있습니다 8.

dfn 솔루션이있을 수도 N{⍺×⊢/⍵}L있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. N(⊣×⊢/⊢)L기차 형성 규칙이 이것을 파싱 ⊣ (× ⊢/ ⊢)하지만 원하는 대로 작동하지 않습니다 ⊣ × (⊢/⊢).

관찰 0⊥숫자 배열과 동일하다 ⊢⌿우리가 우리 기차를 작성할 수 있도록 ⊣×0⊥⊢.

이것은 상위 배열의 마지막 주요 셀을 선택합니다.


1
이 대화 답변 을이 대화에 추가 할 수 있습니까?
J. Sallé

1
@ J.Sallé 추가되었습니다.
Adám

7

곱셈과 덧셈을 결합하는 데 사용

(a×b)+C  ->  a⊥b,C
(C)+a×b  ->  a⊥b,C
(a×b)-C  ->  a⊥b,-C

가정 :

  • a그리고 b왼쪽 인자로 사용하는 경우 추가 괄호를 필요로하지 않는 용어입니다

  • C 왼쪽 인수로 사용될 때 괄호가 필요할 수있는 표현식입니다.

  • a b C 숫자 형 스칼라로 평가


5

복소수

간과되어 종종 격자, 미로, 도형 또는 기하학을 다루는 표현을 단축 할 수있는 훌륭한 기회를 제공합니다.

0j1⊥¨    0j1⊥   ⍝ pair(s) of reals -> complex
11 9∘○¨  11 9○  ⍝ complex -> pair(s) of reals
|z0-z1          ⍝ distance between two points
0j1×z   0j¯1×z  ⍝ rotate by ±90° around (0,0)
0j1*⍳4          ⍝ the four cardinal directions
+z       -+z    ⍝ reflect across x or y axis
+\0,z           ⍝ sequence of steps -> path
2-/z            ⍝ path -> sequence of steps
0j1⊥¨n-⍳2⍴1+2×n ⍝ lattice centred on (0,0)

4

인덱싱 모듈로 벡터 길이

⊃i⌽a종종 순진한 것보다 짧 ⊃a[(≢a)|i]거나 a⊃⍨i|⍨≢a( a벡터 i가 있고 정수 ⎕io이며 0 임)

이것에 대한 유용한 변형은 (EriktheOutgolfer가 지적한 덕분에) 다음과 같습니다. I↑Y⌽⍨I×X여기서 Y길이 I벡터 의 연결은 어디 이며 X우리가 선택하려는 인덱스는 다음 과 같습니다.3↑'JanFeb...Dec'⌽⍨3×month


3

상수 함수

=⍨그리고 ≠⍨ngn 덕분에.

때로는 목록의 각 요소에 대해 단일 값이 필요합니다. 을 사용 {value}¨하고 싶을 수도 있지만 사용 하는 것이 더 짧지 value⊣¨ 만 일반적인 값의 경우 더 짧아 질 수 있습니다 (을 사용하여 ⎕IO←0).

¯1와 함께 ⍬⍸list

0와 함께 ⍬⍳list

1와 함께 ⍬⍷list

이들은 목록에서만 작동합니다 (중첩 될 수도 있음). 상위 배열의 경우 다음을 사용하여 모든 0과 1을 얻을 수 있습니다.

1와 함께 =⍨

0와 함께 ≠⍨

을 설정하면 다음 ⎕ML←0과 같이 모든 숫자를 0으로 만들 수 있습니다 .

당신은 단지 하나의 번호가 필요하면 모나드 사용할 수 있습니다 사용하는 대신 1 또는 0을 얻기 위해 1⊣또는 0⊣.


" 목록의 각 요소에 대해 단일 값이 필요할 때도 있습니다. "-주목할만한 점 : 해당 값이 목록의 첫 번째 요소 인 경우⊣\
ngn

@ngn 나는 말할 것 함께 /하고 자신의 게시물 장점.
Adám

2

용도

괄호를 피하십시오

(통근)은 괄호를 피함으로써 바이트를 절약 할 수 있습니다. 왼쪽 인수를 괄호로 묶어야하고 오른쪽 인수는 그렇지 않은 함수가있을 때마다 바이트를 저장할 수 있습니다 (예 : (A<B)÷C→) C÷⍨A<B.

이중 배열

끝 사용에 배열의 복사본을 추가하려면 ,⍨A⍪⍨A.

이중 숫자

2∘×두 배로 사용 하는 대신 +⍨인수를 추가 하기 때문에 사용할 수 있습니다 . 1+2∘×1++⍨.

제곱수

2*⍨Y제곱 을 사용 하는 대신 ×⍨Y인수 자체를 곱하기 때문에 사용할 수 있습니다 . 2*⍨A+B×⍨A+B.

랜덤 순열

?⍨N길이의 임의 순열을 제공합니다 N.

자기 분류

다음과 같이 각 주요 셀의 첫 항목 색인을 찾습니다. ⍳⍨A

부울 벡터에서 후행 1을 센다

에 사용할 수 +/∧\⌽B있는 후행 1 수를 세는 대신을 N사용할 수 있습니다 ⊥⍨.

역 구성

A f∘g B입니다 A f g B.하지만 원하는 경우를 (g A) f B사용하십시오 f⍨∘g⍨.

반전 감소

f/ a1 a2 a3입니다 a1 f (a2 f a3). 원하는 경우을 (a1 f a2) f a3사용하십시오 f⍨/⌽.

역 스캔

f\ A B C입니다
A (A f B) (A f (B f C)).

f⍨/∘⌽¨,\ A B C입니다
A (A f B) ((A f B) f C).

f⍨\⌽ A B C입니다
((A f B) f C) (B f C) C.

⌽f/∘⌽¨,\⌽ A B C. 입니다
(A f (B f C)) (B f C) C.


2

문자열없이 문자를 열거 ⍳≢

작업 : 두 개의 문자열 S와 T가 주어지면 연결 지수를 나열합니다. 예 S←'abcd'하고 T←'xyz'있습니다 1 2 3 4 5 6 7.

dfn 솔루션이있을 수도 S{⍳≢⍺,⍵}T있지만 암묵적으로 처리하여 솔루션 을 줄이려고합니다. ⍳≢,열차 파싱 규칙이이를 분석 (⍳)≢(,)하지만 원하는 대로 작동하지 않습니다 (⍳≢),.

빈 왼쪽 인수가있는 Dyadic 는 현재 순서에 따라 간단한 문자 배열을 등급 화합니다 ⍳≢. 따라서 {⍳≢⍺,⍵} 될 수있는 {⍬⍋⍺,⍵}우리가 우리 기차를 작성할 수 있도록 ⍬⍋,.

숫자 형 배열이나 혼합형 배열에서는 작동하지 않습니다.


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