망막 , 12 바이트
바이트 수는 ISO 8859-1 인코딩을 가정합니다.
+%`\B
¶$`:
1
온라인으로 사용해보십시오!
대체 솔루션 :
+1`\B
:$`:
1
설명
이것은 아마도 오래된 골프 버전을 기반으로 설명하기가 더 쉬울 것이며 어떻게 단축했는지 보여줄 것입니다. 나는 바이너리를 십진수로 다음과 같이 변환했다.
^
,
+`,(.)
$`$1,
1
Retina에서 십진수를 구성하는 유일한 현명한 방법은 물건을 세는 것입니다 (Retina에는 금액을 나타내는 소수를 인쇄 할 수있는 몇 가지 기능이 있기 때문에). 따라서 실제로 가능한 유일한 방법은 이진을 단항으로 변환 한 다음 단항 자릿수를 계산하는 것입니다. 마지막 줄은 계산을 수행하므로 처음 네 개는 이진을 단항으로 변환합니다.
우리는 어떻게합니까? 일반적으로 비트 목록을 정수로 변환하기 위해 결과를 초기화 0
한 다음 가장 중요한 비트부터 가장 중요하지 않은 비트까지갑니다. 이미 가지고있는 값을 두 배로 늘리고 현재 비트를 추가합니다. 예를 들어 이진수가 1011
인 경우 실제로 계산합니다.
(((0 * 2 + 1) * 2 + 0) * 2 + 1) * 2 + 1 = 11
^ ^ ^ ^
명확성을 위해 개별 비트를 표시 한 위치
단항식 에서이 작업을 수행하는 트릭은 a) 두 배가되면 숫자를 반복한다는 의미입니다 .b) 1
끝에 s를 계산하기 때문에 프로세스에서 0
s와 1
s 를 구분할 필요조차 없습니다 . 이것은 곧 더 명확해질 것입니다.
프로그램이하는 일은 먼저 이미 처리 한 입력량을 나타내는 마커로 시작 부분에 쉼표를 추가한다는 것입니다.
^
,
마커의 왼쪽에는 누적되는 값 (0의 단항 표현으로 올바르게 초기화 됨)이 있으며 값의 오른쪽이 처리 할 다음 비트입니다. 이제 다음 대체를 루프에 적용합니다.
,(.)
$`$1,
,(.)
and을 보면 $1,
매번 마커가 오른쪽으로 1 비트 씩 이동합니다. 그러나 또한 $`
마커 앞에있는 모든 것, 즉 현재 값이 두 배가되는을 삽입합니다. input을 처리 할 때의 개별 단계는 다음과 같습니다. 여기 1011
에서 $`
각 줄 위에 삽입 한 결과를 표시했습니다 (첫 번째 단계에서는 비어 있음).
,1011
1,011
_
110,11
___
1101101,1
_______
110110111011011,
우리는 다른 모든 것들과 함께 0을 유지하고 두 배로 늘렸다는 것을 알 수 있습니다. 그러나 우리는 마지막에 그것들을 무시하기 때문에 1
s의 수는 옳은. 당신이 그들을 세면11
이 그들을 세면, 그들 중 우리가 필요한 것만 있습니다.
그래서 이것을 12 바이트로 골프하는 법에 대한 질문이 남습니다. 18 바이트 버전에서 가장 비싼 부분은 마커를 사용해야합니다. 목표는 그것을 제거하는 것입니다. 우리는 모든 비트의 접두사를 두 배로 늘리기를 원하므로 첫 번째 아이디어는 다음과 같습니다.
.
$`$&
문제는 이러한 대체가 동시에 발생하므로 첫 번째 비트는 각 비트마다 두 배가 되지 않지만 매번 한 번만 복사된다는 것입니다. 입력 1011
을 위해 우리는 (삽입 된 표시 $`
)을 얻습니다 .
_ __ ___
1101011011
배가 된 첫 번째 접두사가 두 번째로 다시 두 배가되도록 입력을 재귀 적으로 처리해야합니다. 한 가지 아이디어는 마커를 어디에나 삽입하고 반복적으로 접두어로 대체하는 것입니다.
\B
,
+%`,
¶$`
각 마커를 접두사로 처음 교체 한 후 입력 시작 위치를 기억해야하므로 줄 바꿈을 삽입하고 %
옵션을 사용 하여 다음 $`
줄이 가장 가까운 줄 바꿈을 선택하도록합니다.
이것은 작동하지만 여전히 너무 깁니다 ( 1
끝에 s를 세면 16 바이트 ). 우리는 어떻습니까? 마커를 삽입하려는 \B
위치는 (두 자리 사이의 위치) 로 식별됩니다 . 왜 우리는 단순히 그 위치에 접두사를 삽입하지 않습니까? 이것은 거의 효과가 있지만 이전 솔루션에서는 실제로 각 대체에서 하나의 마커를 제거했으며 프로세스를 종료하는 것이 중요하다는 차이점이 있습니다. 그러나 \B
캐릭터가 아니라 위치이므로 제거되지 않습니다. 그러나 우리 는\B
대신이 자리에 숫자가 아닌 문자를 삽입하여 일치에서. 이는 단어가 아닌 경계를 단어 경계로 바꾸는데, 이는 이전에 마커 문자를 제거하는 것과 같습니다. 이것이 12 바이트 솔루션의 기능입니다.
+%`\B
¶$`:
완전성을 위해 다음은 1011
각 단계마다 빈 줄 이있는 개별 처리 단계입니다.
1
1:0
10:1
101:1
1
1:0
1
1:0:1
1
1:0
10:1:1
1
1:0
1
1:0:1
1
1:0
1
1:0:1:1
다시 말하지만, 마지막 결과에는 정확히 11 1
초가 포함되어 있습니다 .
독자를위한 연습으로, 이것이 다른베이스에 얼마나 쉽게 일반화되는지 (베이스의 증분 당 몇 바이트 추가) 어떻게 알 수 있습니까?