Brainflak 곱셈 Metagolf


17

이 질문은 Brain-Flak의 첫 번째 생일을 축하하기 위해 고안된 여러 Brain-flak 생일 도전 과제 중 첫 번째 질문입니다! Brain-Flak의 생일에 대한 자세한 정보는 여기 에서 찾을 수 있습니다.

지난 여름에 Brain-flak Integer Metagolf가있었습니다. 가 있었으며 그 결과로 Brain-Flak 커뮤니티에 매우 유용했습니다. Integer Metagolf를 매우 효율적으로 만드는 주된 것은 곱셈 하드 ​​코딩이라는 기술입니다.

Brain-Flak 런타임에서 곱셈은 매우 비쌉니다. 알려진 가장 짧은 곱셈 스 니펫은 다음과 같습니다.

({}<>)({<({}[()])><>({})<>}{}<><{}>)

Megatom에 의해 발견

그러나 컴파일 시간 곱셈을 만드는 매우 간단한 방법이 있습니다. 예를 들어 다음 코드는 5를 곱합니다.

 (({})({})({})({}){})

온라인으로 사용해보십시오!

연속식이 함께 추가되기 때문에 작동합니다. 각각 ({})은 스택에 아무것도하지 않고 ( {}팝을 (..)펴고 다시 밀어 넣습니다) 스택 상단에있는 것으로 평가합니다. 이 모든 표현은 스택의 맨 위에 있던 것의 합계를 5 배까지 합산합니다.

어떤 내용은 n다음 문자열 표현식은 스택의 상단을 증식하는 조각을 만들 것입니다 n:

"("+"({})"*(n-1)+"{})"

이것은 n스택의 최상위까지 평가되는 표현식을 만들어서 작동합니다 . 첫 번째 n-1는 실제로 아무것도 변경하지 않으며 마지막 것은 밀어 넣기 전에 스택의 상단을 제거합니다.

복합 숫자의 경우 여러 개의 작은 표현식을 연결하여 바이트를 절약 할 수 있습니다. 예를 들어 5를 두 번 곱하여 25를 곱할 수 있습니다.

(({})({})({})({}){})(({})({})({})({}){})

이것은 매우 간단하며 일부 숫자의 경우 꽤 잘 작동하지만 더 좋은 방법이 있습니다. 예를 들어 내가 생각해 낸 한 가지 방법은 숫자의 이진 표현을 사용합니다. ( 여기에 파이썬 구현이 있습니다. )이 새로운 방법은 앞에서 보여준 간단한 문자열 표현보다 훨씬 효과적이지만, 결국은 아니고, 곱셈을 하드 코딩하는 많은 흥미로운 방법과 아마도 아무도 발견하지 못한 톤이있다.

그래서 나는 우리가 얼마나 잘 얻을 수 있는지 볼 때가되었다고 생각합니다.

Brain-Flak 개요

여기에이 도전을 위해 Brain-Flak에 대해 알아야 할 모든 내용이 설명되어 있습니다.

Brain-Flak은 "nilads"와 "monads"를 가지고 있습니다. 닐라 드는 내부에 아무것도없는 괄호입니다. 각 nilad는 일을 수행하고 값을 반환합니다. 이 도전에 대해 우리가 걱정하는 두 nilads는 {}and <>입니다. {}활성 스택의 상단을 팝하고 그 값을 반환합니다. <>활성 스택과 활성 스택을 전환하여 활성 스택이 비활성화되고 비활성 스택이 활성화되면 0을 반환합니다.

모나드는 그 안에 물건이있는 괄호입니다. 그들은 하나의 인수, 그 안에있는 모든 것의 합계를 취하고 때로는 행동을 수행 한 다음 값을 반환합니다. 우리가 우려하는 이들의 세 가지이다 (...), <...>하고 [...]. 이 과제에서 가장 중요한 모나드 (...)는 내부의 가치를 가져 와서이를 활성 스택으로 푸시합니다. 그런 다음 인수를 반환합니다. <...>그리고 [...]그들이 어떤 작업을 수행 할 것이 아니라 그들이 전달되는 값을 수정하지 않는 즉, 모두 "비활성"모나드이다. <...>전달 된 인수에 관계없이 항상 0을 반환합니다. 한편 [...]항상 인수 시간을 반환합니다 -1.


설명이있는 샘플 프로그램

Brain-Flak에서 프로그래밍 한 적이 없다면 설명 된 작업을 사용하여 일부 예제 프로그램을 보는 것이 좋습니다.

({}{})

스택에 상위 2 개의 숫자가 추가됩니다. 각각 {}은 스택에서 값을 (...)꺼내고 합계를 다시 푸시합니다.

({}[{}])

마찬가지로 이것은 스택의 두 번째 항목을 첫 번째 항목에서 뺍니다. 각각 {}의 값이 나오기 전에 [..]두 번째 값 주위에 값 이 추가됩니다. 다시 한 번 (...)합계를 푸시합니다.

({}<{}>)

이렇게하면 스택에서 두 번째 값이 제거되고 최상위 값은 그대로 유지됩니다. 두 번째 값이 묵음을 제외하고 마지막 두 값과 동일하게 작동 <...>하므로 푸시는 첫 번째 값만 다시 푸시합니다.

(({}))

스택의 맨 위에 값의 두 번째 사본이 작성됩니다. 스택 상단에 {}값 을 가져 와서이를 수행하고, 첫 번째 는 스택을 값 (..)으로 평가합니다. 두 번째 (...)는 첫 번째에서 반환 한 값을 가져 와서 스택으로 푸시합니다. 두 번째 사본 만들기.

직무

정수가 주어지면 n현재 스택의 상단에을 곱하는 스택 클린 Brain-Flak 스 니펫을 만듭니다 n.

다음 Brain-Flak 작업을 사용할 수 있습니다

(...) -> Push Monad, Pushes the result of its contents
<...> -> Zero Monad, Returns zero
[...] -> Negative Monad, Returns the opposite of its contents result
{}    -> Pop nilad, Pops the TOS and returns its value
<>    -> Switch nilad, Switches the active and inactive stack

다른 작업은 도전 목적으로 금지되어 있습니다.

채점

당신의 점수는 모든 프로그램의 누적 길이 될 것입니다 n=2n=10000. 확인을 위해 프로그램 출력에 대한 링크를 포함하십시오.


1
관심이 없으면 1 및 루프 작업이 금지 된 이유는 무엇입니까?
Neil

@Neil 스택 높이 연산자도 금지됩니다.
Outgolfer Erik

1
@EriktheOutgolfer 나는 어쨌든 정수 metagolf에서 하나를 이미 금지했습니다.
Neil

7
컴퓨터 과학자들은 이상하다. 그들은 사용이 불가능하고 본질적으로 골프를 멈춘 프로그래밍 언어를 발명 한 다음이 언어의 간단한 문제를 해결하기 위해 골프 코드를 작성하도록 서로에게 도전합니다. 이보다 더 난해한 것은 없습니다. 좋은 선생님 +1
Draco18s는 더 이상 SE

1
@ Qwerp-Derp 나는 연결된 파이썬 프로그램 (현재 점수 681950)의 출력을 최적화하는 것을 보았고를 사용하여 4492의 사소한 절약을 발견 [...]했으므로 시작했습니다.
Neil

답변:


2

루비, 669856

$answers = Hash.new{|hash,n|
  valid = []
  2.upto(n**0.5){|i|
    valid.push("("+hash[n/i]+")"+"({})"*(i-2)+"{}") if n%i == 0
  }
  valid.push("({})"+hash[n-1])
  (hash[n] = valid.min_by{|s| s.length})
}
$answers[1] = "{}"

def full_answer n
  "("+$answers[n]+")"
end

이것은 빠른 기본 답변입니다. 처음 1000 분 프로그램을 찾았 습니다 . (모두 게시하려고 시도했지만 최대 pastebin 크기가 오버로드되었습니다.) 나중에 코드 설명을 추가 할 수 있습니다.

예 :

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