답변:
참고 : Julia는 구조 측면에서 아직 안정화되지 않았으므로 아래에 오래된 팁이 포함될 수 있습니다.
몇 문자를 저장하는 몇 가지 트릭
\ =div하고 a\b대신 을 입력 할 수 있습니다 div(a,b). 공백에 유의하십시오- "\ ="연산자로 구문 분석되지 않도록해야합니다. 또한 REPL 프롬프트 레벨에서 오버로드 된 경우 (\)=Base.(\)또는 \ =Base. \을 사용 하여 재설정하십시오. 참고 : Alex A에서 언급 한 것처럼 일부 함수에는 ÷for 와 같이 미리 정의 된 기존 UTF-8 연산자가 있습니다 div.a>0?"Hi":""하는 "Hi"^(a>0)데 사용 하거나 부울 a의 경우 "Hi"^a3 바이트를 저장 하는 데 사용 합니다.a=split("Hi there"," "), 당신은 방지 할 수 있습니다 a[1]및 a[2]사용하여 a,b=split("Hi there"," ")로 참조 될 수있는 a및 b할당에서 두 추가 문자의 비용으로, 각 사용을위한 3 바이트를 절약. 벡터 연산으로 작업 할 수있는 경우에는이 작업을 수행하지 마십시오.[]-for arrays를 사용하여 Array의 첫 번째 요소에 액세스 하면 표현식 A[]은와 동일합니다 A[1]. 첫 번째 문자를 얻으려면 문자열이나 Tuples에서는 작동하지 않습니다.==[]배열 및 ==()튜플에 사용하십시오. 마찬가지로, 음의 경우 !=[]및을 사용하십시오 !=(). 문자열의 경우 ""가 다른 문자열보다 사전 식으로되어 ==""있으므로 비어있는 경우 에는 사용 하고 비어 있지 않은 경우에는 사용하십시오 >"".x<=1&&"Hi"로 쓸 수 있습니다 x>1||"Hi".in('^',s)하기보다는 contains(s,"^"). 다른 문자를 사용할 수 있으면을 사용하여 조금 더 절약 할 수 '^'∈s있지만 ∈UTF-8에서는 3 바이트입니다.minimum(x)또는 maximum(x), 사용 min(x...)또는 max(x...)당신이 알고있는 경우에, 당신의 코드를 해제 한 문자를 면도, x두 개 이상의 요소가됩니다. 또는 모든 요소가 x음이 아닌 것으로 알고 있다면 minabs(x)또는maxabs(x)r"(?m)match^ this", type r"match^ this"m, 3자를 저장 하지 마십시오 .reverse(x)한 바이트 이상이고 flipud(x)후자가 더 때문에, 동일한 작업을 수행합니다.{[1,2]}, 아님 {1,2}). Julia 0.4의 경우 필요합니다 Any[[1,2]].end 배열 색인 내에서 사용할 경우 배열 / 문자열의 길이로 자동 변환됩니다. 대신 3자를 저장 k=length(A)하는 A[k=end]데 사용하십시오 . k를 즉시 사용하려면이 방법이 도움이되지 않을 수 있습니다. 이것은 다차원의 경우에도 작동합니다- A[k=end,l=end]각 차원의 크기를 얻 A습니다. 그러나이 (k,l)=size(A)경우에는 1 바이트 씩 짧아 지므로 동시에 마지막 요소에 즉시 액세스하려는 경우에만 사용하십시오.A[k=1:end].이 경우 k반복자 일치를 유지합니다 1:length(A). A동시에 배열 을 사용하려는 경우에 유용 할 수 있습니다 .collect(A)사용 [A...]하십시오. 동일한 작업을 수행하고 4 바이트를 절약 할 수 있습니다."$(s[i])"또는 dec(s[i])표현 또는 멀티 문자 변수, 및 "$i"단일 문자 변수.?:대신 &&또는 ||조건부 할당에 사용 합니다. 즉, 특정 조건에서만 할당을 수행하려는 cond?A=B:1경우 cond&&(A=B), 또는 cond?1:A=B대신 쓰기로 1 바이트를 절약 할 수 있습니다 cond||(A=B). (가) 있습니다 1, 여기에 더미 값이다.union또는 ∪대신은unique - union(s)같은 일을 할 것 unique(s), 그리고 그 과정에서 바이트를 저장합니다. 비 ASCII 문자를 사용할 수 ∪(s)있는 경우 동일한 작업을 수행하며 ∪의 5 바이트 대신 3 바이트 만 소요됩니다 union.split("Hi there")pattern 인수의 기본값이 공백 이므로 간단히 공백을 사용하여 분할 할 수 있습니다 .
재정의 연산자는 괄호와 쉼표로 많은 바이트를 저장할 수 있습니다.
단항 예제의 경우 다음과 같은 피보나치 시퀀스의 반복 구현을 비교하십시오.
F(n)=n>1?F(n-1)+F(n-2):n # 24 bytes
!n=n>1?!~-n+!(n-2):n # 20 bytes
!n=n>1?!~-n+!~-~-n:n # 20 bytes
재정의 된 연산자는 초기 우선 순위를 유지합니다.
이미 정수에 대해 정의되어 있고 부울에 대해서만 정의되어 있기 때문에 !를 대신하여 간단히 바꿀 수는 없습니다 .~~!
재귀 없이도 연산자를 재정의하는 것이 이진 함수를 정의하는 것보다 짧습니다. 단순 분할 성 테스트에 대한 다음 정의를 비교하십시오.
f(x,y)=x==0?y==0:y%x==0 # 23 bytes
(x,y)->x==0?y==0:y%x==0 # 23 bytes
x->y->x==0?y==0:y%x==0 # 22 bytes
x\y=x==0?y==0:y%x==0 # 20 bytes
다음은 이진 연산자를 재정 의하여 Ackermann 함수를 계산하는 방법을 보여줍니다.
A(m,n)=m>0?A(m-1,n<1||A(m,n-1)):n+1 # 35 bytes
^ =(m,n)->m>0?(m-1)^(n<1||m^~-n):n+1 # 36 bytes
| =(m,n)->m>0?m-1|(n<1||m|~-n):n+1 # 34 bytes
m\n=m>0?~-m\(n<1||m\~-n):n+1 # 28 bytes
주 ^의 우선 순위가 너무 높기 때문에, 더 오래 일반 식별자를 사용하는 것보다.
전에 언급했듯이
m|n=m>0?m-1|(n<1||m|~-n):n+1 # 28 bytes
|이 경우 이미 정의되어 있기 때문에 정수 인수에는 작동하지 않습니다 . 정수의 정의 는 다음과 같이 변경할 수 있습니다
m::Int|n::Int=m>0?m-1|(n<1||m|~-n):n+1 # 38 bytes
그러나 그것은 엄청나게 길다. 그러나, 하지 우리가 왼쪽 인자과 오른쪽 인수로 정수로 부동 소수점을 전달하는 경우 작업을.
factor (n)에 의해 너무 쉽게 유혹받지 마십시오 . 유혹 기본 라이브러리 함수 factor(n)에는 치명적인 결함이 있습니다. 정수의 인수 분해를 순서가없는 Dict유형으로 반환합니다 . 따라서, 비용이 필요 collect(keys())하고 collect(values())잠재적 또한 cata는 sort당신이 그것을 밖으로 원하는 데이터를 얻을 수 있습니다. 많은 경우에 시험 부문별로 고려하는 것이 더 저렴할 수 있습니다. 슬프지만 사실이야.
맵 사용 map 은 루핑의 훌륭한 대안입니다. 의 차이에주의 map하고 map!후자의 현재 위치에서 기능 수있을 때를 이용한다.
mapreduce를 사용하면 mapreduce map의 기능이 더욱 확장되고 바이트를 크게 절약 할 수 있습니다.
익명의 기능은 훌륭합니다! .. 특히 위에서 언급 한 map기능에 전달 될 때 .
누적 배열 함수 cumprod , cumsumflavourful cummin및 기타 유사한 이름이 지정된 함수는 n 차원 배열의 지정된 차원을 따라 누적 연산을 수행 할 수 있습니다. (또는 배열이 1-d이면 * un * 지정됨)
Any에 대한 짧은 표기법 예를 들어 다차원 배열 (또는 Dict)의 특정 차원을 모두 선택하려는 A[Any,2]경우 다음을 사용하여 바이트를 절약 할 수 있습니다.A[:,2]
기능에 대한 한 줄 표기법을 사용 하는 대신 function f(x) begin ... end당신이 종종 단순화 할 수 있습니다f(x)=(...)
삼항 연산자 사용 단일 표현식 If-Then-Else 구조의 경우 공간 절약이 될 수 있습니다. 주의 사항 : 다른 언어로는 가능하지만 Julia에서 콜론 다음 부분은 생략 할 수 없습니다. 또한 Julia의 연산자는 식 수준이므로 전체 코드 블록을 조건부로 실행하는 데 사용할 수 없습니다.
if x<10 then true else false endvs
x<10?true:false
이것은 다른 언어에서도 가능하지만 일반적으로 간단한 방법보다 깁니다. 그러나, 단항 및 이항 연산자를 재정의 할 수있는 Julia의 능력은 상당히 골치 거리가됩니다.
예를 들어 1에서 10까지의 자연수에 대한 더하기, 빼기, 곱하기 및 나누기 테이블을 생성하려면
[x|y for x=1:10,y=1:10,| =(+,-,*,÷)]
재정의되는 이진 연산자 |로 +, -, *및 ÷, 그때 연산 x|y각각 동작하고 x그리고 y원하는 범위이다.
이것은 단항 연산자에도 적용됩니다. 예를 들어, 복소수 1 + 2i , 3-4i , -5 + 6i 및 -7-8i , 음수, 복소수 복소수 및 곱셈의 역수를 계산하려면
[~x for~=(+,-,conj,inv),x=(1+2im,3-4im,-5+6im,-7-8im)]
이는 재정의 단항 연산자 ~로 +, -, conj및 inv다음 계산 ~x원하는 모든 복소수.
여성 및 남성 서열 (이진)
대소 문자 치환 (단항)
키워드는 공백이나 세미콜론 없이도 상수를 즉시 따를 수 있습니다. 예를 들면 다음과 같습니다.
n->(for i=1:n n-=1end;n)
1와 사이에 공백이 없습니다 end. 이것은 또한 end가까운 paren 후에 발생하는 경우에도 마찬가지입니다 )end.
연산자를 오버로드하거나 오버로드 ÷하지 않고 정수 나누기를 수행하십시오 div(). 주 ÷2 가치는 UTF-8 바이트.
가능할 때마다 대신 vec()또는 A[:](일부 배열의 경우 A) 를 사용하십시오 reshape().
챌린지 규칙에 허용 된 경우 전체 프로그램이 아닌 함수를 작성하십시오. stdin에서 읽음으로써 변수를 정의하는 대신 입력을 받아들이는 함수를 정의하는 것이 더 짧습니다. 예를 들면 다음과 같습니다.
n->(n^2-1)
n=read(STDIN,Int);n^2-1변수는 함수의 인수 내에서 증분 될 수 있습니다. 예를 들어, 다음은 내 대답 받는 사람 찾기 다음 1 스파 스 이진 번호 도전 :
n->(while contains(bin(n+=1),"11")end;n)
이것은 n루프 내부에서 증가하는 것보다 짧습니다 .