기초 증명 출력


21

배경

가능한 미래에, 세계는 그들의 숫자 체계를 10 진수 (10 진수 또는 10 진수 b10)에서 다른 2 b2진수 ( 8 진수 b8, 8 진수 , 16 진수 b16또는 1 진수 b1)로 변환 할 것입니다. 따라서,이 세상을 바꿀 수있는이 이벤트에 대비하여 모든 프로그램의 기본 증거를 결정합니다. 이는 연산자와 함께 단수 01s 만 사용 하여 기존 숫자 상수를 대체 하여 수행 할 수 있습니다 .

그러나 한 가지 문제가 있습니다. 수 많은 프로그램을 변경해야하며 각 숫자를 표현식으로 수동으로 변환하는 데 몇 주가 걸립니다! 따라서 프로그램 (또는 함수)을 작성하여 각 숫자를 대체 할 식을 결정합니다.

입력

입력은 양의 정수입니다. 코드 1000까지의 정수를 처리 할 수 있어야합니다 .

(코드가 10 진수 및 / 또는 음수 입력을 지원하는 경우 아래 스코어링을 참조하십시오 .)

산출

코드는 적어도 하나의 언어로 입력으로 평가되는 표현식을 출력해야합니다. 이것은 모든 언어 일 수 있습니다. 프로그램이나 함수가 작성된 것과 같을 필요는 없습니다. 또한이 표현식은 전체 프로그램이나 함수일 필요는 없습니다.

명확성을 위해 출력에는 다음 작업 중 하나가 포함될 수 있습니다.

  • 증감
  • 추가 / 합
  • 빼기 / 부정
  • 곱하기 / double (숫자가 직접 포함되지 않는 경우에만 2!)
  • 나누기 / 모듈로
  • 지수 / 대수
  • square / sqrt (다시 말하지만, 숫자와 직접 관련이없는 경우에만 2!)
  • 비트 단위 연산 (bOR, bAND, bNOT, bXOR, 비트 시프트)
  • 변수 설정 / 가져 오기
  • 스택 조작

출력에서 또는 이와 유사한 기능을 사용 하지 못할 수 있습니다 eval(). 위에서 언급 한 것 이외의 동작을 수행하는 기능을 출력에 사용할 수 없습니다.

아, 그리고 한가지 더 : 출력은 가능한 많은베이스에서 유효하기를 원하기 때문에, 포함 할 수있는 유일한 상수는 0and 1입니다. 10언어에서 a 1및 a 로 해석하지 않으면 (ten) 과 같은 숫자 는 허용되지 않습니다 0. 같은 CJam의 같은 문자를 사용하고, 하나 허용되지 않는 숫자를 포함하는 문자열을 사용하여 A- K(대표 10- 20).

테스트 사례

(모든 출력은 JavaScript로되어 있지만 다른 언어로 작동 할 수 있습니다.)

입력 1 :

2

가능한 출력 1 :

1+1

입력 2 :

13

가능한 출력 2 :

(a=1+1+1)*a+a+1

입력 3 :

60

가능한 출력 3 :

(b=(a=1+1+1+1)*a)*a-a

입력 4 :

777

가능한 출력 4 :

(c=(b=((a=1+1+1+1)*a-a+1)*a)*a+b)+c+c-a+1

입력 5 :

1000

가능한 출력 5 :

Math.pow((a=1+1+1)*a+1,a)

채점

이 과제의 목표는 코드의 출력을 최대한 줄이는 것입니다. 점수는 다음과 같이 계산됩니다.

  • 기본 점수 : 정수 1-1000에 대한 모든 출력의 평균 바이트 수입니다.

  • 소수점 점수 : 코드가 소수점 이하 3 자리 이상을 지원하는 경우 시작 시간 0.001과 종료 시간 의 모든 시퀀스 출력의 평균 바이트 수입니다 ( 매번 1000증가 함) 1.001. 0.001, 1.002, 2.003...998.999, 1000.000그런 다음이 점수에서 50 % 할인을 받으십시오.

  • 음수 점수 : 코드가 음수와 0을 지원하는 경우 -1000~ 에서 모든 정수의 출력의 평균 바이트 수입니다 0. 그런 다음이 점수에서 10 % 할인을 받으십시오.

(이를 계산하는 가장 쉬운 방법은 프로그램 / 함수가있는 루프 일 것입니다.)

최종 점수는 위의 공식 중 적용되는 평균입니다.

출력이 결정적이지 않은 경우 (예 : 다소 임의적입니다. 동일한 입력으로 여러 번 실행하면 여러 개의 고유 한 출력이 생성됨) 각 입력에 대한 점수는 내 CPU에서 10 번 이상 실행 된 최대 출력에 의해 결정됩니다.

또한 미래의 컴퓨터 데이터가 얼마나 소중한 지 알지 못하므로 생성기 코드의 바이트 수는 512 바이트보다 작아야합니다.

2 주 (9 월 30 일)에 가장 낮은 점수가 승자로 선언됩니다. 우승자 축하합니다, @ThomasKwa !


리더 보드

답변이 올바르게 표시되도록하려면 다음 헤더로 시작하십시오.

# Language name/Other language name, X points

X답의 점수는 어디에 있습니까 ? 예:

# CJam/Pyth, 25.38 points

질문이나 제안 사항이 있으면 알려주십시오. 행운을 빕니다!


나는 보유 변수를 사용할 수 0또는 1기본적를?
Dennis

@Dennis 나는 그것에 아무런 문제가 보이지 않으므로 계속하십시오!
ETHproductions

기본 2와 기본 기본 간의 기본 변환을 수행 할 수 없다고 가정합니다.
Blue

@muddyfish 아니요, 출력에 기본 변환이 허용되지 않습니다.
ETHproductions

우리도 같은 것을 사용할 수 없다고 생각 Integer.parseInt("1000", 1+1+1+1+1+1+1+1+1+1)합니까? 나는 확실히 parseInt허용 된 연산만을 사용
한다고

답변:


10

Python / Zilog Z80 기계 코드, 11.653 11.488

import math,numpy as np
def R(n):
    if n==0:return []
    if n<0:return -R(-n)
    e=int(math.log(n,2))
    if n >= 5/3 * 2**e:
        return np.append(2**(e+1),-R(2**(e+1)-n))
    return np.append(2**e,R(n-2**e))

def strR(n):
    b = R(n)
    s = ""
    if n==0:return s
    e=max(abs(b))
    while e:
        if e in b:s+="#"
        elif -e in b:s+="+"
        s+=")"
        e//=2
    return s[:-1]

보너스 : 음수.

hl레지스터 쌍이 초기에 0을 보유하고 결과를로 리턴 한다고 가정합니다 hl.

이 세 가지 지침 만 사용됩니다.

ASCII   Hex    Instruction
--------------------------
#       23     inc hl
)       29     add hl,hl
+       2B     dec hl

최소 가중치 균형 이진 표현 BBR2 의 작은 수정을 사용합니다 . BBR2는 무게 (제로 자리 수)를 최소화하지만 우리가 무게를 더한 비트 이동의 수를 최소화하려는 때문에, 우리는에서 알고리즘의 일정을 변경 3/2하는 5/3.

점수를 계산하고 확인하려면 다음 코드를 사용하십시오.

def verify(n):
v = 0
for c in strR(n):
    if c=="#":v += 1
    elif c=="+":v -= 1
    else: v *= 2
return v==n

print(0.5*(sum([len(strR(n)) for n in range(1,1001)])/1000 + \
           sum([len(strR(n)) for n in range(-1000,1)])/1001 * 0.9))

print(all([verify(n) for n in range(-1000,1001)]))

출력 예 :

strR(486)
         '#)))))+)+))+)'

또는 조립 중 :

inc hl \ add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl \ add hl,hl \ dec hl \ add hl,hl \ dec hl \ add hl,hl \ add hl,hl \ dec hl \ add hl,hl

더 많은 예제 프로그램 :

-256  +))))))))
-255  +))))))))#
-254  +)))))))#)
-253  +)))))))#)#
-252  +))))))#))
-251  +))))))#))#
-250  +))))))#)#)
-249  +)))))#)))+
-248  +)))))#)))
-247  +)))))#)))#
-246  +)))))#))#)
-245  +)))))#))#)#
-244  +)))))#)#))
-243  +)))))#)#))#
-242  +))))#)))+)
-241  +))))#))))+

  -5  +))+
  -4  +))
  -3  +)+
  -2  +)
  -1  +
   0  
   1  #
   2  #)
   3  #)#
   4  #))
   5  #))#

가능한 최적화 : 의 상위 바이트를 직접 변경 하는 inc hdec h명령어 hl는 불법이지만 sla h문서화되지 않은 sl1 h( 및 각 h시프트에서 왼쪽 비트가 1 씩 시프트 됨) OP 규칙 이 허용됩니다. 그리고 각 바이트이 있지만, 그들은 때로는 출력을 줄일 수 있습니다.01sla hsl1 h


아주 좋은, 지금까지 가장 낮은! 이것이 순수한 기계 코드가 유용한 하나의 사례라고 생각합니다. ;)
ETH 프로덕션

2
+1 아마도 무적입니다. 또한 머신 코드를 사용하는 천재 (대부분 8 비트 명령어 세트와 일부 16 비트 레지스터가있는 CPU)
Level River St

+번역 하는 방법이 이상합니다 dec. 부정적인 예를 계속 잘못 읽습니다.
ETHproductions

9

CJam / CJam, 143.263 42.713 28.899 23.901 21.903 20.468

ri
[
    ['X\2b1>e`{~{"1)*)"*}{_({(')*1\"m<"}{"1)*"*}?}?}/]s
    "X1)*"/"1)"*
    "1)1)*"/"1)))"*
    "X1)m<"/"1)))"*
    _"1)"/("1):Y"+\'Y*+
]
{,}$0=

보너스는 적용되지 않습니다.

온라인으로 사용해보십시오 : 샘플 실행 | 점수 계산기 | 확인

예제 실행

   1 X
   2 1)
   3 1))
   4 1)))
   5 1))))
   6 1))1)*
   7 1))1)*)
   8 X1))m<
   9 1)))1)*)
  10 1))))1)*
  11 1))))1)*)
  12 1))1)m<
  13 1))1)*1)*)
  14 1))1)*)1)*
  15 1))1)*)1)*)
  16 X1)))m<
  17 X1))m<1)*)
  18 1)))1)*)1)*
  19 1)))1)*)1)*)
  20 1))))1)m<
 981 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*Y*)
 982 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*)Y*
 983 1):Y)Y*)Y*)Y*Y*)Y*Y*)Y*)Y*)
 984 1):Y)Y*)Y*)Y*Y*)Y*)Y)m<
 985 1):Y)Y*)Y*)Y*Y*)Y*)Ym<Y*)
 986 1):Y)Y*)Y*)Y*Y*)Y*)Y*Y*)Y*
 987 1):Y)Y*)Y*)Y*Y*)Y*)Y*Y*)Y*)
 988 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Ym<
 989 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*Y*)
 990 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*)Y*
 991 1):Y)Y*)Y*)Y*Y*)Y*)Y*)Y*)Y*)
 992 1):Y)Y*)Y*)Y*)Y)))m<
 993 1):Y)Y*)Y*)Y*)Y))m<Y*)
 994 1):Y)Y*)Y*)Y*)Y)m<Y*)Y*
 995 1):Y)Y*)Y*)Y*)Y)m<Y*)Y*)
 996 1):Y)Y*)Y*)Y*)Ym<Y*)Ym<
 997 1):Y)Y*)Y*)Y*)Ym<Y*)Y*Y*)
 998 1):Y)Y*)Y*)Y*)Ym<Y*)Y*)Y*
 999 1):Y)Y*)Y*)Y*)Ym<Y*)Y*)Y*)
1000 1):Y)Y*)Y*)Y*)Y*Y*)Y)m<

나의 말, 그것은 빨랐다! 그러나 Firefox에서는 링크가 작동하지 않습니다.
ETHproductions

이것은 코드 골프가 아니기 때문에 각각 %을 더 긴 표현으로 바꿨습니다. 이제 링크가 작동해야합니다.
Dennis

입력 34는 1을 제공합니다. 어떤 입력이 더 잘 작동합니까
Kishan Kumar

2
@KishanKumar이 검증은 1000 개의 가능한 입력을 모두 테스트합니다. 출력 1 은 비교에 성공했음을 나타냅니다.
Dennis

예제 출력을 추가 할 수 있습니까?
Paŭlo Ebermann

3

ß / BrainFuck, 34.201 포인트

ß 소스 (194B) :

E='++[------>+<]>++'°\c[1]<0°{E&='.'µA=ß"-ß°°c[1]),'')µE&='+++'°/B=1°(A[0]°\A[B]='.'°{µE&='--.++'°]E&=ß~A'+',A[B])&'.'&ß~A'-',A[B])°}°)°'ß"&E,'+-')+ß"&E,'-+')>0µE=ß"'ß"'E,'-+',''),'+-','')°!€E)

누군가 관심이 있다면 설명을 추가하겠습니다. BF 출력은 이미 최적화되어 있지만 나머지 318B 코드를 사용하여 구현할 수 있다고 생각합니다.

  • 루프 중첩 최적화
  • 더 많은 8 비트 오버 플로우 단축키,
  • 운전자 충돌 제거 .

시료:

창에서 실행 :

$ sharps encode.ss 42
++[------>+<]>+++++++++.--.--

$ sharps encode.ss -42
++[------>+<]>++.+++++++.--.--

$ sharps encode.ss 1.427
++[------>+<]>++++++.---.++++++.--.+++++.-------

$ sharps encode.ss -946.427
++[------>+<]>++.++++++++++++.-----.++.--------.++++++.--.+++++.-------

리눅스에서 실행 :

$ WINEDEBUG=-all wine sharps source.ss -4.72
++[------>+<]>++.+++++++.------.+++++++++.-----.--

온라인 BF 인터프리터 에서 확인하십시오 .

점수 :

  1. 기본 평균 = 37.495.
  2. 십진 평균 = 60.959 * 0.5 = ~30.48.
  3. 제외 평균 = 38.4765234765235 * 0.9 = ~34.629
  4. 상기의 평균, 최종 점수 = (37.495 + 30.48 + 34.629)/3 = 34.201.

1
나는 항상 사람들이 만든 새로운 언어를보고 싶어한다. :) 점수 분석에 감사드립니다! 소수 부분에 보너스를 더 많이주고 싶습니다. 공제액을 40 %에서 50 %로 변경했습니다.
ETHproductions

@ETHproductions 예, 온라인 통역사를 설정해 보겠습니다. 약 435 개의 매우 추상적 인 연산자가 있으며 추가 9,9k를 정의 할 수 있습니다. 계산을 올바르게 수정했습니다.
mınxomaτ

3

루비 / 루비, 29.77885

31.873 * 0.9 (음수) 30.872 (양수).

기본 전략은 대칭 기저 3 표현 ( "균형 삼항")입니다. 즉, 숫자가 -1,0,1 대신0,1,2

#function
f=->n{m=n  
  a='0' 
  7.times{|i|
    r=m%3;r-=r/2*3
    m=(m-r)/3
    #produce expression: replace 0 with (0*x+-1)
    #only add 0*x if there are higher base 3 digits to follow.
    #only add (..+-1) if the current base 3 digit is nonzero. 
    a.sub!('0',['','(','('][r]+(m.abs>0?'0*x':'')+['','+1)','-1)'][r])
  }
  #tidy up expression
  a.sub!('(-1)*','-')          #remove internal (-1)*
  a.sub!('(+1)*','')           #remove internal (+1)*
  a[-1]==')' && a=a[1..-2]     #remove unnecessary global brackets
  a.sub!('x','(x=1+1+1)')      #find the first x and define it as 1+1+1=3
  #special cases for small numbers 
  n.abs<8 && a=n==0?'0':['','1'+'+1'*(n-1).abs,'-1'*n.abs][n<=>0] 
  a 
}

#call like this
(1..1000).each{|p|
b=f.call(p)
puts b

정리하기 전에 0에서 40까지의 출력이 있습니다.

(+1)
((+1)*x-1)
(+1)*x
((+1)*x+1)
(((+1)*x-1)*x-1)
((+1)*x-1)*x
(((+1)*x-1)*x+1)
((+1)*x*x-1)
(+1)*x*x
((+1)*x*x+1)
(((+1)*x+1)*x-1)
((+1)*x+1)*x
(((+1)*x+1)*x+1)
((((+1)*x-1)*x-1)*x-1)
(((+1)*x-1)*x-1)*x
((((+1)*x-1)*x-1)*x+1)
(((+1)*x-1)*x*x-1)
((+1)*x-1)*x*x
(((+1)*x-1)*x*x+1)
((((+1)*x-1)*x+1)*x-1)
(((+1)*x-1)*x+1)*x
((((+1)*x-1)*x+1)*x+1)
(((+1)*x*x-1)*x-1)
((+1)*x*x-1)*x
(((+1)*x*x-1)*x+1)
((+1)*x*x*x-1)
(+1)*x*x*x
((+1)*x*x*x+1)
(((+1)*x*x+1)*x-1)
((+1)*x*x+1)*x
(((+1)*x*x+1)*x+1)
((((+1)*x+1)*x-1)*x-1)
(((+1)*x+1)*x-1)*x
((((+1)*x+1)*x-1)*x+1)
(((+1)*x+1)*x*x-1)
((+1)*x+1)*x*x
(((+1)*x+1)*x*x+1)
((((+1)*x+1)*x+1)*x-1)
(((+1)*x+1)*x+1)*x
((((+1)*x+1)*x+1)*x+1)

그리고 정리 후

0
1
1+1
1+1+1
1+1+1+1
1+1+1+1+1
1+1+1+1+1+1
1+1+1+1+1+1+1
(x=1+1+1)*x-1
(x=1+1+1)*x
(x=1+1+1)*x+1
((x=1+1+1)+1)*x-1
((x=1+1+1)+1)*x
((x=1+1+1)+1)*x+1
(((x=1+1+1)-1)*x-1)*x-1
(((x=1+1+1)-1)*x-1)*x
(((x=1+1+1)-1)*x-1)*x+1
((x=1+1+1)-1)*x*x-1
((x=1+1+1)-1)*x*x
((x=1+1+1)-1)*x*x+1
(((x=1+1+1)-1)*x+1)*x-1
(((x=1+1+1)-1)*x+1)*x
(((x=1+1+1)-1)*x+1)*x+1
((x=1+1+1)*x-1)*x-1
((x=1+1+1)*x-1)*x
((x=1+1+1)*x-1)*x+1
(x=1+1+1)*x*x-1
(x=1+1+1)*x*x
(x=1+1+1)*x*x+1
((x=1+1+1)*x+1)*x-1
((x=1+1+1)*x+1)*x
((x=1+1+1)*x+1)*x+1
(((x=1+1+1)+1)*x-1)*x-1
(((x=1+1+1)+1)*x-1)*x
(((x=1+1+1)+1)*x-1)*x+1
((x=1+1+1)+1)*x*x-1
((x=1+1+1)+1)*x*x
((x=1+1+1)+1)*x*x+1
(((x=1+1+1)+1)*x+1)*x-1
(((x=1+1+1)+1)*x+1)*x
(((x=1+1+1)+1)*x+1)*x+1

나는 그것이 "균형 삼항"이라고 믿습니다.
lirtosiast

@ThomasKwa 님이 수정 함
Level River St

3

실론 / 실론, 49.86 40.95 점

세 번째 버전은 생성기와 509 바이트 코드에 Ceylon 1.2를 사용합니다.

import ceylon.language{S=String,I=Integer,e=expand}S q(I n)=>n==0then"0"else(n<0then"-"+p(-n,"-")else p(n,"+"));variable Map<[I,S],S>c=map{};S p(I n,S s){S v=c[[n,s]]else(n<8then s.join([1].repeat(n)))else(let(a="+-".replace(s,""))e(e{for(x in 2..8)let(l=(n^(1.0/x)).integer){for(r in l:2)if(r>1)let(w=r^x){if(w-n<n)"("+p(r,"+")+")^("+p(x,"+")+")"+(w<n then s+p(n-w,s)else(n<w then a+p(w-n,a)else""))}}}).reduce<S>((x,y)=>x.size<y.size then x else y))else"";c=[n,s]in c then c else map{[n,s]->v,*c};return v;}

Celyon 1.2는 10 월 29 일에 발표 되었기 때문에 35.22 포인트로 떨어졌지만 타이틀 라인에 넣지 않을 것입니다.이 알고리즘을 Ceylon 1.1에서이 크기로 구현할 수있을 것 같지는 않습니다.) 자세한 내용은 여기에서 두 번째 버전을 설명하겠습니다. 첫 번째 버전은 기록에서 볼 수 있습니다. 양수 만 지원했지만 256 바이트에 맞았습니다.

두 번째 버전

이제 음수 (및 0)를 지원하는 두 번째 버전은 일반적으로을 사용하여 조금 더 짧은 출력을 만듭니다 -. (이 버전은 실제로 허용 된 길이를 사용합니다. 첫 번째 버전은 512 바이트 대신 256 바이트 미만으로 유지하려고했습니다.)

String proof(Integer n) {
    if (n == 0) { return "0"; }
    if (n < 0) { return "-" + p(-n, "-"); }
    return p(n, "+");
}
String p(Integer n, String sign) {
    if (n < 9) {
        return sign.join([1].repeat(n));
    }
    value anti = (sign == "+") then "-" else "+";
    value root = ((n^0.5) + 0.5).integer;
    return "(" + p(root, "+") + ")^(1+1)" +
       ( (root^2 < n) then sign + p(n - root^2, sign) else
         ((n < root^2) then anti + p(root^2 - n, anti) else ""));
}

코드 길이는 487이므로 나중에 더 최적화 할 수있는 공간이 남아 있습니다. (공백과 긴 변수 이름의 형태로 많은 예약이 있습니다.)

점수 :

Total positive: 42652
Average positive:42.652
Total negative: 43653
Average negative: 43.60939060939061
With bonus:39.24845154845155
Overall score: 40.95022577422577

일부 샘플 출력 :

   27:  21: (1+1+1+1+1)^(1+1)+1+1
   28:  23: (1+1+1+1+1)^(1+1)+1+1+1
   29:  25: (1+1+1+1+1)^(1+1)+1+1+1+1
   30:  27: (1+1+1+1+1)^(1+1)+1+1+1+1+1
   31:  29: (1+1+1+1+1+1)^(1+1)-1-1-1-1-1
   32:  27: (1+1+1+1+1+1)^(1+1)-1-1-1-1
   33:  25: (1+1+1+1+1+1)^(1+1)-1-1-1
   34:  23: (1+1+1+1+1+1)^(1+1)-1-1

  -27:  22: -(1+1+1+1+1)^(1+1)-1-1
  -28:  24: -(1+1+1+1+1)^(1+1)-1-1-1
  -29:  26: -(1+1+1+1+1)^(1+1)-1-1-1-1
  -30:  28: -(1+1+1+1+1)^(1+1)-1-1-1-1-1
  -31:  30: -(1+1+1+1+1+1)^(1+1)+1+1+1+1+1
  -32:  28: -(1+1+1+1+1+1)^(1+1)+1+1+1+1
  -33:  26: -(1+1+1+1+1+1)^(1+1)+1+1+1
  -34:  24: -(1+1+1+1+1+1)^(1+1)+1+1


  993:  65: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1+1)^(1+1)+1+1+1+1+1
  994:  63: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1-1-1-1
  995:  61: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1-1-1
  996:  59: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1-1
  997:  57: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1-1
  998:  55: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)-1
  999:  53: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)
 1000:  55: ((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)-(1+1+1+1+1)^(1+1)+1

 -993:  66: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1+1)^(1+1)-1-1-1-1-1
 -994:  64: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1+1+1+1
 -995:  62: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1+1+1
 -996:  60: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1+1
 -997:  58: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1+1
 -998:  56: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)+1
 -999:  54: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)
-1000:  56: -((1+1+1+1+1+1)^(1+1)-1-1-1-1)^(1+1)+(1+1+1+1+1)^(1+1)-1

    1:   1: 1
    2:   3: 1+1
    3:   5: 1+1+1
    4:   7: 1+1+1+1
    5:   9: 1+1+1+1+1
    6:  11: 1+1+1+1+1+1
    7:  13: 1+1+1+1+1+1+1
    8:  15: 1+1+1+1+1+1+1+1
    9:  13: (1+1+1)^(1+1)
   10:  15: (1+1+1)^(1+1)+1

    0:   1: 0
   -1:   2: -1
   -2:   4: -1-1
   -3:   6: -1-1-1
   -4:   8: -1-1-1-1
   -5:  10: -1-1-1-1-1
   -6:  12: -1-1-1-1-1-1
   -7:  14: -1-1-1-1-1-1-1
   -8:  16: -1-1-1-1-1-1-1-1
   -9:  14: -(1+1+1)^(1+1)
  -10:  16: -(1+1+1)^(1+1)-1

보시다시피, 음수 -는 해당 양수보다 항상 1 바이트 (선행 ) 더 깁니다.

기본 아이디어는 이전 프로그램과 동일합니다. 대상 번호 근처의 사각형을 찾아 근본과 나머지를 재귀 적으로 나타냅니다. 그러나 이제 우리는 우리의 제곱도 목표 수보다 약간 크게 허용하여 나머지는 음수로 만듭니다. ( +0.5알고리즘을 조정하기 위해 다른 상수로 변경할 수는 있지만 이미 0.4와 0.6 모두에서 최적의 결과를 얻은 것으로 보입니다.

음의 값의 부정을 (그렇지 않으면 양의 것과 동일한 구조를 가지려면, 우리는 연산자를 통과 sign우리의 재귀 함수에 p- 그 중 하나가 있습니다 "+"또는"-" . 우리는뿐만 아니라 (사소한 경우에 목공에 대한 즉, N <9)이 사용할 수 있습니다 양수이면 나머지에 대해서는 음수이면 나머지에 반대 부호를 사용하십시오.

proof함수는 초기 부호 (0의 경우 특수한 경우)를 처리하고이 p함수는 재귀와 함께 실제 작업을 수행합니다.

실론 1.2의 세 번째 버전

import ceylon.language { S=String, I=Integer,e=expand }

// output a base-proof Ceylon expression for an integer
// (i.e. using only 0 and 1 as digits).
//
// Question: http://codegolf.stackexchange.com/q/58084/2338
// My Answer:  http://codegolf.stackexchange.com/a/58122/2338
//
// The goal is to produce an expression as short as possible, with
// the code staying under 512 bytes in length.
//
// This approach is to represent a positive integer as a square
// of a positive integer plus some remainder (where the remainder
// can be negative), and for negative integers replace the + on the
// outer level by -.

S q(I n) =>
        n == 0 then "0"
        else (n < 0 then "-" + p(-n, "-")
            else p(n, "+"));

// cache for values of p
variable Map<[I, S],S> c = map { };

// Transforms a positive number into a base-proof term, using
// the given sign for the summation on the outer level.
S p(I n, S s) {
    S v =
    // look into the cache
            c[[n, s]] else (
        // hard-code small numbers
        n < 8 then s.join([1].repeat(n)))
            else
    // do the complicated stuff
    (let (a = "+-".replace(s,""))
            e(e {
                    for (x in 2..8) // try these exponents
                        let (l = (n ^ (1.0 / x)).integer) // \[ sqrt[exp]{n} \] in LaTeX
                            { for (r in l:2) // lowerRoot, lowerRoot + 1
                                    if (r > 1)
                                        let (w = r ^ x)
                                            { if (w-n < n) // avoid recursion to larger or same number
                                                    // format the string as  r^x + (n-w)
                                                    "(" + p(r, "+") + ")^(" + p(x, "+") + ")" +
                                                            (w < n then s + p(n - w, s)
                                                                else (n < w then a + p(w - n, a)
                                                                    else ""))
                                            } } })
            // and now find the shortest formatted string
                .reduce<S>((x, y) => x.size < y.size then x else y))
    // this should never happen, but we can't tell the compiler
    // that at least some of the iterables are non-empty due to the if clause.
            else "";

    // this builds a new cache in each step – quite wasteful,
    // as this also happens when the value was found in the cache,
    // but we don't have more characters remaining.
    //// c = map { [n, s] -> v, *c };
    ///better way:
     c = [n,s] in c then c else map{[n,s]->v, *c}; 
    return v;
}

골프 버전 (예 : 주석 및 공백 제거)은 정확히 509 바이트의 코드로 맨 위에 게시됩니다.

이것은 두 번째 버전과 동일한 기본 원칙을 사용하지만 정사각형 대신 높은 수의 거듭 제곱 (2에서 8까지 지수를 시도)을 사용하고 가장 짧은 결과를 사용합니다. 그렇지 않으면 많은 재귀 호출로 큰 숫자의 경우 허용되지 않을 수 있으므로 결과를 캐시합니다.

채점 :

Total positive: 36622
Average positive: 36.622
Total negative: 37623
Average negative: 37.58541458541458
With bonus:33.826873126873124
Overall score: 35.22443656343656

가운데에 들여 쓰기 된 큰 구조는 중첩 된 세 개의 이해력으로, 내부의 내부는 let 표현식입니다. 그런 다음 확장 함수를 두 번 사용하여 중첩 해제하고 함수 reduce는 해당 문자열 중 가장 짧은 문자열을 찾습니다.

단일 이해 로이 작업을 수행 할 수 있도록 기능 요청 을 제출했습니다 .

이해 내에서 우리는 근 r, 지수 x및 나머지 ( n-w또는 w-n) 에서 문자열을 작성합니다 .

let발현 및 map기능 실론 1.2 새로운. map로 대체 될 수 있습니다 HashMap(가져 오기에 더 많은 문자가 필요했지만, 각각의 새로운 항목에 대해 새로운 맵을 작성하지 않기 때문에 더 빠를 것입니다). let같은 표현은 let (w = r ^ x)사용에 의해 대체 될 수 있었다 if같은 절을 if(exists w = true then r ^ x)(그리고 나는이 개 필요하지 않았을 expand511 수 바이트 내부에 피팅하지, 중 통화),하지만 여전히 조금 더 될 것입니다.

여기에 위에서 선택한 것과 일치하는 샘플 출력이 있습니다. 실제로 작은 숫자를 제외한 모든 출력이 더 짧습니다.

   27:  15: (1+1+1)^(1+1+1)
   28:  17: (1+1+1)^(1+1+1)+1
   29:  19: (1+1+1)^(1+1+1)+1+1
   30:  21: (1+1)^(1+1+1+1+1)-1-1
   31:  19: (1+1)^(1+1+1+1+1)-1
   32:  17: (1+1)^(1+1+1+1+1)
   33:  19: (1+1)^(1+1+1+1+1)+1
   34:  21: (1+1)^(1+1+1+1+1)+1+1

  -27:  16: -(1+1+1)^(1+1+1)
  -28:  18: -(1+1+1)^(1+1+1)-1
  -29:  20: -(1+1+1)^(1+1+1)-1-1
  -30:  22: -(1+1)^(1+1+1+1+1)+1+1
  -31:  20: -(1+1)^(1+1+1+1+1)+1
  -32:  18: -(1+1)^(1+1+1+1+1)
  -33:  20: -(1+1)^(1+1+1+1+1)-1
  -34:  22: -(1+1)^(1+1+1+1+1)-1-1

  993:  39: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1-1-1
  994:  37: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1-1
  995:  35: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1-1
  996:  33: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1-1
  997:  31: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1-1
  998:  29: ((1+1+1)^(1+1)+1)^(1+1+1)-1-1
  999:  27: ((1+1+1)^(1+1)+1)^(1+1+1)-1
 1000:  25: ((1+1+1)^(1+1)+1)^(1+1+1)

 -993:  40: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1+1+1
 -994:  38: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1+1
 -995:  36: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1+1
 -996:  34: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1+1
 -997:  32: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1+1
 -998:  30: -((1+1+1)^(1+1)+1)^(1+1+1)+1+1
 -999:  28: -((1+1+1)^(1+1)+1)^(1+1+1)+1
-1000:  26: -((1+1+1)^(1+1)+1)^(1+1+1)

    1:   1: 1
    2:   3: 1+1
    3:   5: 1+1+1
    4:   7: 1+1+1+1
    5:   9: 1+1+1+1+1
    6:  11: 1+1+1+1+1+1
    7:  13: 1+1+1+1+1+1+1
    8:  13: (1+1)^(1+1+1)
    9:  13: (1+1+1)^(1+1)
   10:  15: (1+1+1)^(1+1)+1

    0:   1: 0
   -1:   2: -1
   -2:   4: -1-1
   -3:   6: -1-1-1
   -4:   8: -1-1-1-1
   -5:  10: -1-1-1-1-1
   -6:  12: -1-1-1-1-1-1
   -7:  14: -1-1-1-1-1-1-1
   -8:  14: -(1+1)^(1+1+1)
   -9:  14: -(1+1+1)^(1+1)
  -10:  16: -(1+1+1)^(1+1)-1

예를 들어 이제 1000 = (6 ^ 2-4) ^ 2-5 ^ 2 + 1 대신 1000 = (3 ^ 2 + 1) ^ 3이됩니다.


나는 256 바이트로 프로그램 제한을 잘못 기억했다 .512에서 훨씬 더 많은 것을 할 수있다. 나중에 시도하겠습니다.
Paŭlo Ebermann

아냐 less than 512. 당신은 최대를 사용할 수 있습니다. of 511 bytes;)
mınxomaτ

이 언어에 대해 어떻게 들어 보지 못했습니까?!? : O 그러나 진지하게, 훌륭한 설명! 나는 다른 사람들이 그들의 답변에 사용하는 기술을 이해하는 것을 좋아합니다. +1
ETH 프로덕션

@ETHproductions 나는 또한 약 2 주 전에 여기 사이트에서 그것을 읽었고 그것을 좋아하기 시작했습니다. 그래서 더 잘 알기 위해 여기 실론을 사용하여 질문에 대답하려고합니다.
Paŭlo Ebermann

2

루비 / DC, 20.296 18.414 16.968

다이나믹 프로그래밍! dc 명령어가 주어지면 새 표현식과 해당 표현식의 숫자 값을 반환하는 함수 목록을 정의합니다. 그런 다음 1미리 정의 된 것부터 원하는 값까지의 모든 도달 가능한 값 목록을 작성합니다.

편집하다:

n-1에 대한 기능을 추가하고 여러 패스를 통해 알고리즘을 실행했습니다. 안정화하려면 7 패스가 필요한 것 같습니다. 일부 변수 이름을 줄여서 512 바이트 이내로 유지해야했습니다.

편집 2 :

내가있는 동안 n (n-1) , n (n + 1)n ^ 3에 대한 기능을 추가 했습니다. 정확히 512 바이트로 랜딩하여 코드를 더 줄였습니다.

N = gets.to_i

fns = [
  ->(n,s){[n-1,   s+'1-']},
  ->(n,s){[n+1,   s+'1+']},
  ->(n,s){[n*2,   s+'d+']},
  ->(n,s){[n*3,   s+'dd++']},
  ->(n,s){[n*~-n, s+'d1-*']},
  ->(n,s){[n*n,   s+'d*']},
  ->(n,s){[n*-~n, s+'d1+*']},
  ->(n,s){[n*n*n, s+'dd**']},
]

lst = []*(N+1)
lst[0..2] = %w[0 1 1d+]

loop do
  prev = lst.dup

  (1..N).each do |n|
    fns.each do |f|
      m,s = f[n, lst[n]]
      lst[m] = s if m <= N && (lst[m].nil? || lst[m].size > s.size)
    end
  end

  break if lst == prev
end

puts lst[N]

생성 된 숫자 :

출력은 전적으로 5 개의 다른 문자로 구성됩니다 1. 스택에서 값 1을 푸시합니다. d스택의 상단을 복제합니다. +,, -* 두 개의 최상위 값을 표시하고 합계, 차이 및 곱을 각각 푸시합니다. 생성 된 각 표현식은 실행 후 스택에 하나의 값만 추가합니다.

   1: 1
   2: 1d+
   3: 1dd++
   4: 1d+d+
   5: 1d+d+1+
   6: 1d+dd++
   7: 1d+dd++1+
   8: 1d+dd**
   9: 1dd++d*
  10: 1d+d+1+d+
  11: 1d+d+1+d+1+
  12: 1dd++d1+*
  13: 1dd++d1+*1+
  14: 1d+dd++1+d+
  15: 1d+d+d*1-
  16: 1d+d+d*
  17: 1d+d+d*1+
  18: 1dd++d*d+
  19: 1dd++d*d+1+
  20: 1d+d+d1+*
  21: 1d+d+d1+*1+
  22: 1d+d+1+d+1+d+
  23: 1d+dd**dd++1-
  24: 1d+dd**dd++
  25: 1d+d+1+d*

...

 989: 1d+d+d*d+d1-*1-1-1-
 990: 1d+d+d*d+d1-*1-1-
 991: 1d+d+d*d+d1-*1-
 992: 1d+d+d*d+d1-*
 993: 1d+d+d*d+d1-*1+
 994: 1d+d+d*d+d1-*1+1+
 995: 1d+d+d*d+d1-*1+1+1+
 996: 1d+d+1+dd**d+1-d+d+
 997: 1d+d+1+d+dd**1-1-1-
 998: 1d+d+1+d+dd**1-1-
 999: 1d+d+1+d+dd**1-
1000: 1d+d+1+d+dd**

1
지금까지 z80 머신 코드를 제외한 모든 것을 능가했습니다 (심지어 Dennis 'CJam!). -바이트 수를 유지하면서 연산자 를 추가 할 수 있다고 생각하십니까 ?
ETHproductions

@ETHproductions 어때요? ;) 지금도 음수를 추가하는 것은 어렵지 않습니다.
daniero

0

파이썬 2.6, 78.069 - 66.265 점

가치있는 것에 대한 대답을 제출하십시오 (이 경우에는 많지 않지만 ...이 도전에 대해 단순히 출력을 비트 시프트 된 값의 합계로 생각하는 것만으로는 충분하지 않습니다. 출력에 0 또는 1이 아닌 것이 나타날 수 있습니다. 나중에 다른 방법으로 출력을 생성 할 수 있습니다.

코드 자체가 너무 길지 않습니다 (176 자).

def f(a):return'+'.join(('(1<<%s)'%['0','+'.join('1'*x)][x>0]).replace('(1<<0)','1')for x in[i for i,e in enumerate(bin(a)[::-1][:-2])if int(e)])
print"".join(f(int(input())))

정확하지만 자세한 출력을 생성합니다.

17
1+(1<<1+1+1+1)

800
(1<<1+1+1+1+1)+(1<<1+1+1+1+1+1+1+1)+(1<<1+1+1+1+1+1+1+1+1)

점수를 계산하는 스 니펫 :

def f(a):return'+'.join(('(1<<%s)'%['0','+'.join('1'*x)][x>0]).replace('(1<<0)','1')for x in[i for i,e in enumerate(bin(a)[::-1][:-2])if int(e)])
print sum(len("".join(f(i)))for i in range(1000))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.