골프를위한 팁


17

K는 Arthur Whitney가 설계 한 APL 제품군의 프로그래밍 언어입니다. 공식 통역사는 비공개 소스이며 상용이지만 Kx Systems 웹 사이트 에서 32 비트 주소 지정 공간 (코드 골프에 문제가되지 않아야 함)의 시험판 버전을 찾을 수 있습니다 . kdb + 데이터베이스의 일부로 번들 된이 버전을 구어 적으로 "K4"라고합니다. K3을 기반으로하는 Kona 및 K5를 기반으로하며 브라우저 기반 REPL을 가진 oK 라는 내 자신의 인터프리터를 포함하여 사용 가능한 오픈 소스 K 구현도 있습니다 .

Kx Systems에는 K4 / kdb + / Q 정보 가 포함 된 Wiki 가 있으며 Kona GitHub 페이지에는 훌륭한 참조 자료 모음 이 있습니다. 유용한 참고 자료가 될 수있는 oK / k5 설명서 를 작성하기 시작했습니다 .

J 와 APL 처럼 K는 매우 간결하고 강력한 언어이며 종종 코드 골프에서 잘 보여 질 수 있습니다. 발견 한 팁, 요령 및 관용구를 공유하십시오. K를 시도하지 않은 경우 스핀을 고려하십시오! 답변 당 하나의 팁을 게시하십시오.

답변:


5

Dyad 호출

당신이 dyadic (2 인수) 함수를 가지고 있다고 가정하자 f:

f: {x+2*y}

일반적으로 다음과 같이 호출합니다.

f[3;47]

대신 첫 번째 인수를 카레 한 다음 결과 부분 함수를 병렬로 두 번째 인수에 적용하여 문자를 저장할 수 있습니다.

f[3]47

배열 인덱싱에도 동일하게 작동합니다.

  z: (12 17 98;90 91 92)
(12 17 98
 90 91 92)

  z[1;2]
92

  z[1]2
92

5

개행 인쇄

당신의 출력이 경우 합니다 줄 바꿈을 가지고, 당신은이 일을 유혹 할 수있다 :

`0:whatever,"\n"

하지 마십시오 . K2 (및 다른 버전)에는 줄 목록을 인쇄 할 수있는 깔끔한 기능이 있습니다.

  `0:("abc";"def")
abc
def

따라서 출력에 개행을 추가 해야하는 경우 다음을 수행하십시오.

`0:,whatever

3

범위

일반적으로 순차 숫자로 구성된 벡터를 만들려면 다음을 사용하십시오 !.

  !5
0 1 2 3 4

0 이외의 숫자로 시작하는 범위를 만들려면 결과 벡터에 오프셋을 추가합니다.

  10+!5
10 11 12 13 14

특정 상황에서 더 잘 작동 할 수있는 몇 가지 비정상적인 접근 방식이 있습니다. 예를 들어베이스와 오프셋이 이미 목록의 멤버 인 경우 "where"를 두 번 사용할 수 있습니다.

  &10 5
0 0 0 0 0 0 0 0 0 0 1 1 1 1 1
  &&10 5
10 11 12 13 14

느리게 성장하는 시퀀스의 경우 "where"와 "take"를 결합하는 것이 좋습니다.

  5#2
2 2 2 2 2
  &5#2
0 0 1 1 2 2 3 3 4 4

여러 배수의 범위를 만들려면 결과의 수를 곱 !하거나 \단계 크기의 사본 목록을 스캔 ( ) 할 수 있습니다.

  2*!5
0 2 4 6 8
  +\5#2
2 4 6 8 10

괄호를 피하려고하면 시퀀스의 길이가 가변적이고 단계 크기가 고정되어 있으면 전자가 더 좋고 단계 크기가 가변적 인 경우 후자가 더 좋습니다. 올바른 변형을 선택하면 1 ~ 2자를 저장할 수 있습니다. 일대일 차이도 유리하게 작용할 수 있습니다.


2

줄에서 캐스트는 비싸다. eval을 사용하십시오. 이:

0.0$a

그냥이 될 수 있습니다 :

. a

K5에서는 바이트가 짧습니다.

.a

2

각각의 권리

때때로 각 모나드를 통해 적용되는 괄호로 묶은 표현을 작성 (또는 단순화하여 작성) 할 수 있습니다.

  (2#)'3 4 5
(3 3
 4 4
 5 5)

이 패턴을 각 오른쪽의 응용 프로그램으로 변환하는 것이 한 문자 짧습니다.

  2#/:3 4 5
(3 3
 4 4
 5 5)

1

순환 순열

!K3 / K4의 Dyadic 는 "회전"입니다 :

  2!"abcd"
"cdab"
  -1!"abcd"
"dabc"

"스캔"( \)에 모나 딕 동사가 제공되면 고정 소수점 연산자로 작동합니다. K에서 고정 소수점 연산자는 초기 값이 다시 표시되거나 값 변경이 중지 될 때까지 동사를 반복해서 값에 적용합니다. 회전을 고정 소수점 스캔과 결합하면 목록의 순환 순열 집합을 계산하는 매우 편리한 방법을 제공합니다.

  ![1]\1 2 4 8
(1 2 4 8
 2 4 8 1
 4 8 1 2
 8 1 2 4)

!괄호 또는 괄호를 통해 카레 를 만들어 동사 기차를 만들 수 있습니다 (1!).

![1]\
(1!)\

( 1!\완전히 다른 동작을합니다!) 이들 각각의 길이는 동일하지만 회전 보폭이 1 이외의 것이면 전자가 더 바람직 할 수 있습니다. 이 경우 대괄호는 "무료로"괄호로 묶은 하위 표현식을 구분합니다.

예를 들어, 다음은 문자열 x에 하위 문자열 y가 포함되어 있는지 여부를 주기적으로 테스트하는 간단한 프로그램입니다.

{|/(y~(#y)#)'![1]\x}

K5 사용자는 조심하십시오! K5는 dyadic의 의미를 바 꾸었으므로이 !기술은 쉽지 않습니다. 코나에서 예상대로 작동합니다.


1

조건을 피하십시오

K는 :[Lisp 스타일과 동등한 조건부 구문 ( )을 갖습니다 cond.

:[cond1;result1; cond2;result2; cond3;result3; default]

원하는만큼 조건을 가질 수 있으며, 일치하는 것이 없으면 기본값이 반환됩니다.

때때로 (재귀 적 프로그램이나 다른 일련의 부작용에 의존하는 프로그램에서와 같이), 이들 중 하나를 사용하지 않아도됩니다. 그러나 약간의 추가 작업을 수행 할 수있는 상황에서는 종종 "cond"를 목록 인덱싱으로 바꿀 수 있습니다.

악명 높은 피즈 버즈 프로그램을 고려하십시오 . 일반적인 명령형 프로그래밍 스타일로 작성하면 다음과 같이 할 수 있습니다.

{:[~x!15;"FizzBuzz";~x!3;"Fizz";~x!5;"Buzz";x]}'1+!100

분할 성 테스트에는 약간의 반복이 있습니다. 다른 접근법은 4 가지 경우 (수, 3으로 나눌 수 있음, 5로 나눌 수 있음, 3 및 5로 나눌 수 있음)를 인식하고 다음 사례 중 하나를 목록에서 선택하는 인덱스를 직접 계산하려고 시도합니다.

{(x;"Fizz";"Buzz";"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

두 글자가 짧고 언어를 더 잘 사용합니다. 목록 리터럴이 오른쪽에서 왼쪽으로 평가된다는 것을 알면 재사용되는 하위 표현식을 결합 할 수있는 추가 골프 기회도 얻게됩니다. 선택하지 않으면 문자열 케이스가 전혀 평가되지 않으므로 cond 기반 버전에서는이 작업을 쉽게 수행 할 수 없었습니다.

{(x;4#t;4_ t;t:"FizzBuzz")@+/1 2*~x!/:3 5}'1+!100

이제 전체적으로 5자를 저장했습니다. 덧붙여서,이 특정 예제는 k5에서 훨씬 더 잘 작동합니다. 왜냐하면 우리는 /계수와 합산 벡터를 곱하는 단계를 처리하기 위해 "팩"과부하가 있기 때문입니다 .

{(x;4_t;4#t;t:"FizzBuzz")@2 2/~3 5!\:x}'1+!100

또한 ?항목을 찾을 수없는 경우 키 목록 끝을지나 색인을 생성하는 "find"( ) 의 동작은 이러한 종류의 색인에서 "기본"사례 처리를 지원하도록 특별히 설계되었습니다. 모음을 대문자로 변환하려면이 조각을 고려하십시오.

{("AEIOU",x)"aeiou"?x}'

다음 중 하나와 비교하십시오.

{t:"aeiou"?x;:[t<5;"AEIOU"t;x]}'
{:[~4<t:"aeiou"?x;"AEIOU"t;x]}'

(나도 어느 쪽을 읽을 것인지 안다!)

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