수학을 할 시간이다


14

소개

이것은 내가 가장 좋아하는 수학 퍼즐 중 하나입니다.

숫자 (예 : 3)와 해당 숫자 (5)를 사용할 횟수가 주어지면 +, +, +, +, +, +, +, +, +, +, −, ×, ÷, ^ 및 √ (루트) (대괄호는 작업을 그룹화 할 수 있습니다).

예를 들면 다음과 같습니다.

(3^3 + 3)/(3 + 3) = (33 - 3)/(3 + 3) = 3 + 3/3 + 3/3 = 5

위의 모든 5 개의 3과 수학 연산 및 결과는 5를 사용합니다. √ 앞에 3을 사용하여 입방체 근을 나타낼 수도 있습니다. √ 앞에 4를 사용하여 네 번째 근을 나타냅니다.

또한 2 개의 3을 사용하여 33을 형성하거나 3을 사용하여 333 등을 형성 할 수 있습니다.

도전

  • 함수 인수, STDIN 또는 명령 행 인수로 두 개의 숫자 (1-5 범위)가 제공 됩니다.
  • 첫 번째 숫자는 사용할 자릿수를 나타내며 두 ​​번째 숫자는 숫자가 식에 사용될 횟수를 나타냅니다.
  • 프로그램은 크기 10의 배열 (또는 공백으로 구분 된 10 개의 숫자)을 출력해야합니다. 여기서 각 요소는 (index + 1)숫자 로 이어지는 수학적 표현 (허용 연산자 만 사용)이 가능한지 아닌지 / 진실한 값을 사용 하는지를 나타냅니다.

예를 들어 입력이

1 3

그런 다음 출력은

[1, 1, 1, 0, 0, 0, 0, 0, 0, 1]

1, 2, 3, 10 만 세 개의 1을 사용하여 표현할 수 있기 때문입니다.

점수

  • 이것은 이므로 바이트 단위의 최소 코드 길이가 이깁니다.

보너스

모두 인쇄 [−50]

출력 배열 요소가 (index + 1)실제 또는 허위 값 대신 값 을 얻기 위해 가능한 전체 조합 수와 같으면 점수에서 50을 뺍니다 .

예를 들어 5 개의 5를 조합 할 수있는 조합이 5 개만있는 경우 출력 배열의 4 번째 항목은 3이어야합니다.

익스트림 수학 [−100]

출력 배열 요소에 실제 결과 중 하나 이상이 포함되어 있으면 점수에서 100을 뺍니다 (index + 1).

예를 들어, 다섯의 3을 사용하는 경우, 출력 배열의 4 번째 항목 일 수있다 (3^3 + 3)/(3 + 3), (33 - 3)/(3 + 3)또는3 + 3/3 + 3/3

과잉 살상 [-200]

출력 배열 요소에 가능한 모든 조합이 포함되어 있으면 점수에서 200을 뺍니다 (로 구분 |). 이 보너스는 익스트림 수학 보너스에 추가되어 총 -300을 얻습니다.

예를 들어 5 개의 3을 사용하는 경우 출력 배열의 4 번째 요소는(3^3 + 3)/(3 + 3)|(33 - 3)/(3 + 3)|3 + 3/3 + 3/3

참고 : 동일한 결과를 얻기위한 두 표현은 논리적으로 달라야합니다.

예를 들어 5를 3으로 5를 얻는 3 + 3/3 + 3/3것은 동일 3/3 + 3 + 3/3하거나 3/3 + 3/3 + 3각각에 대해 동일한 접근 방식이 적용되기 때문입니다. (3^3 + 3)/(3 + 3)(33 - 3)/(3 + 3)분자의 30 가지 방법을 통해 달성되는 한, 다르다.

업데이트 : 모든 답변을 거친 후 단항 -및 √의 경우로 인해 모든 답변에 결함이 있음을 발견했습니다 . 따라서, 완전한 답이 관련되는 한, 그러한 최첨단 사례를 놓치는 것은 괜찮은 것으로 간주됩니다.

이것은 어려운 질문이지만 다소 흥미로운 질문입니다.

행복한 골프!


1
죄송합니다. 바보 일 수도 있지만 3 1초 만으로 10 점을 받으려면 어떻게해야 합니까?
FryAmTheEggman

3
@FryAmTheEggman 11-1
옵티 마이저

1
아, 그래서 바보였다 : p
FryAmTheEggman

4
매우 모호한 규칙입니다. 나는 1의 제곱근, 1의 제곱근 등이 모두 다른 접근법이라고 결정할 수 있으며 무한한 대답이 있습니다. a + b가 b + a와 다른가요? (-a) * (-b)가 b * a와 다른가요?
feersum

2
나는 이것을 알고 있지만 정규 숫자 형식으로 4 ^ (4 ^ (4 ^ (4 ^ 4)))를 표현할 수는 없습니다. 정수로 4 ^ (4 ^ (4 ^ 4))를 저장하면 이미 더 많은 비트가 필요합니다 우주에 원자가있는 것보다). 따라서 그러한 숫자를 처리 할 수있는 컴퓨터 대수 시스템을 사용하지 않는 한 (만약 존재한다면) 이것을 특별한 경우로 취급해야합니다. 그러나 이것은 거의 확실히 내가 과잉으로 이기는 것보다 더 많은 캐릭터를 요구합니다 . 따라서 여러 개의 제곱근을 다소 배제하지 않는 한 이러한상은 의미가 없습니다.
Wrzlprmft

답변:


1

파이썬 3 (불완전), 449-300 = 149

KSab의 솔루션 과 동일한 단점 이 있습니다 . 완전히 괄호로 묶인 단항 연산자는 (1+1)+1및과 같은 식을 포함하지 않습니다 1+(1+1). 결과를에 전달하여 정확한 중복을 제거했습니다 set(). 몇 바이트를 절약하기 위해 출력이 약간 더 나빠질 수 있지만 이런 식으로 좋아합니다. 그들은 또한이 문제에서 당신을 많이 사지 않는 것처럼 보이기 때문에 n 번째 뿌리를하지 않았습니다.

R=range
E=lambda z:eval(z.replace("^","**"))
def m(d,n):_=R(1,11);s={i:[]for i in _};r=R(1,n);n<2 and s[d].append(str(d));d=str(d);t=[[(d*i,i)for i in r]]+[[]]*n;h=[];[(h.append("("+A+o+B+")"),t[l].append((h[0],a+b))if a+b<n else E(*h)in _ and s[E(*h)].append(h[0]),h.pop())for l in r for j in R(l)for A,a in t[j]for k in R(l)for B,b in t[k]if a+b<=n for o in"+-*/^"if(o=="^"and-~-(0<E(B)<9)or 0==E(B)and"/"==o)-1];[print(i,set(s[i])or'')for i in _]

두 번째 인수가 5 인 경우 실행하는 데 몇 분이 소요됩니다 m(digit, number).

>>> m(1,3)
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))', '(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+1)-1)', '((1*1)/1)', '((1^1)^1)', '(1*(1/1))', '((1/1)^1)'}
2 {'(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+1)*1)'}
3 {'((1+1)+1)', '(1+(1+1))'}
4 
5 
6 
7 
8 
9 
10 {'(11-1)'}
>>> m(3,3)
1 {'((3/3)^3)'}
2 {'(3-(3/3))', '((3+3)/3)'}
3 {'(3-(3-3))', '((3-3)+3)', '((3/3)*3)', '(3*(3/3))', '(3/(3/3))', '((3+3)-3)', '(3^(3/3))', '(3+(3-3))', '((3*3)/3)'}
4 {'((3/3)+3)', '(3+(3/3))'}
5 
6 {'((3*3)-3)'}
7 
8 
9 {'(3+(3+3))', '((3+3)+3)', '((3^3)/3)'}
10 

4

파이썬 (불완전) 493 474-300 = 174

이 솔루션에는 상당히 많은 문제가 있습니다. 먼저 너무 큰 지수 (지수가 100보다 큰 지수)를 무시합니다. 실제로 이것이 5 이하의 입력에 대한 가능성을 제거한다고 생각하지 않지만 100 % 확실하지는 않습니다.

또 다른 것은 복잡해지기 때문에 단항 제곱근을 고려하지 않는다는 것입니다 (0 또는 1과 같은 용어를 가진 솔루션은 무한한 수의 솔루션을 생성합니다). 또한 동일한 이유로 단항 부정 ( '-'기호)을 고려하지 않으며, 질문이 실제로 요청되었는지 확실하지 않다는 사실도 고려하지 않습니다.

또한 두 표현식이 동일한 경우 어떤 기준을 결정해야하는지 고려했지만 직관적 인 것으로 판단되는 방식으로 엄격하게 정의 할 수 없었습니다. 이것은 꽤 많은 결과를 출력하고 괄호를 상당히 순진하게 사용한다는 것을 의미합니다.

참고로, 이것은 내가 완전히 골프를 치기 전에 내가 작성한 가장 긴 단일 코드 줄을 포함한다고 생각합니다.

R=range
F=lambda s:lambda a,b:eval(s)
L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)|(b>99)else a**b")),('v',F("b**(1./a)if a and(a>=0 or b)and(b>=0 or int(1./a)==1./a)&(1./a<99)else''"))]if o(u,v)!='']
A=L(*input())
for i in R(11):
 for v,s in A:
    if v==i:print i,s[1:-1]

예 : ( 'v'는 '√'를 나타냄)

2,3

0 2*(2-2)
0 2v(2-2)
0 (2-2)*2
0 (2-2)/2
0 (2-2)^2
1 2^(2-2)
1 2-(2/2)
1 2v(2/2)
1 (2/2)^2
2 2v(2+2)
2 2+(2-2)
2 2-(2-2)
2 2v(2*2)
2 2*(2/2)
2 2/(2/2)
2 2^(2/2)
2 2v(2^2)
2 (2+2)-2
2 (2+2)/2
2 (2-2)+2
2 (2*2)-2
2 (2*2)/2
2 (2/2)*2
2 (2/2)v2
2 (2^2)-2
2 (2^2)/2
3 2+(2/2)
3 (2/2)+2
6 2+(2+2)
6 2+(2*2)
6 2+(2^2)
6 (2+2)+2
6 (2*2)+2
6 (2^2)+2
8 2*(2+2)
8 2*(2*2)
8 2*(2^2)
8 (2+2)*2
8 (2*2)*2
8 (2^2)*2

난 당신이 단축하기 위해 할 수있는 몇 가지를 발견 L:L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)or b>100 else a**b")),('v',F("''if a==0 or(b<0 and int(1./a)!=(1./a))or(b or a<0)or(1./a)>100 else b**(1./a)"))]if o(u,v)!='']
FryAmTheEggman

미안, 어쨌든 :( 그 코멘트 모습 정말 나쁜, 설명 할 수 있어요 :에 비교할 때 0, 나는, 그 결과를 교환 문을 부정하려고 나는 또한 사용에 몇 군데를 발견했다. |그리고 &대신 or하고 and이러한 트릭 모두를. F에 대한 마지막 호출을 단축하는 데 사용될 수 있지만, 그 중 하나는 Demorgan을 필요로하고 부리 시간이 부족합니다. p
FryAmTheEggman

@FryAmTheEggman 오, 그거 좋은 생각입니다. 게시 한 내용으로 답변을 업데이트했으며 시간이 있으면 마지막 답변을 살펴 보겠습니다. 입력의 유효성을 검사하기위한 조건들은 내가 예상했던 것보다 조금 더
무거워졌습니다

중첩 된 람다의 광채로 +10하고 eval두 번째 줄을 알아내는 데 꽤 오랜 시간이 걸렸습니다! 그래도 "가장 긴 싱글 라인"에서 이길 수 있다고 생각합니다. ;) 나는 큰 지수를 무시하는 것에 동의합니다. 사실, 9보다 큰 지수는 유용하지 않을 것이라고 생각합니다 (베이스가 1 일 때 no-op 제외).
DLosc

@DLosc 글쎄, 당신이 가질 수있는 한 가지 시나리오는 다음과 같습니다 3 = 33 √ (3 ^ 33). 실제로 이것을 쓰면서 내 대답이 놓친 두 가지 (아마도 두 가지?) 조합 4 = (4^4) √ (4 ^ (4^4))5s 와 동등한 표현 이라는 것을 알았습니다 . 분명히 뿌리는 문제에 많은 것을 추가하지 않는 것 같습니다. 대부분의 루트는 0 또는 1에서 no-ops로 사용되거나 root가 1 일 때 no-ops로 사용되거나 전원을 취소하기 때문에 문제가되지 않습니다.
KSab

3

파이썬 3 – 349 346

r=range
l=lambda s:eval("lambda a"+s)
def T(u,f,X,Y):
    try:return u(f(X,Y))
    except:0
c=l(',x:{x}.union(*[{u(int("1"*a)*x)}|{T(u,f,X,Y)for j in r(1,a)for X in c(j,x)for Y in c(a-j,x)for f in[l(",b:a%sb"%o)for o in{"**"}|set("+-*/")]+[l(",b:a**b**-1")]}for u in[l(":-a")]+[l(":a**.5**%i"%k)for k in r(9)]])')
R=l(",i:[{n+1}<c(i,a)for n in r(10)]")

다소 ungolfed 버전은 다음과 같습니다.

def R(x,i):
    # Unary Operations
    U = [lambda a:-a] + [eval("lambda a:a**(1/2.**%i)" % j) for j in range(9)]
    # Binary Operations
    F = [eval("lambda a,b:a%sb"%o) for o in ["+","-","*","/","**"]] + [lambda a,b:a**(1./b)]

    def combos(i):
        L = {x}
        for u in U:
            # 3, 33, 333, etc.
            L |= {u(int(str(x)*i))}

            for j in range(1,i):
                for X in combos(j):
                    for Y in combos(i-j):
                        for f in F:
                            # To avoid trouble with division by zero, overflows and similar:
                            try:
                                L |= {u(f(X,Y))}
                            except:
                                pass
        return L

    return [n in combos(i) for n in range(1,11)]

테스트를 (9)위해 더 작은 것으로 변경 하는 것이 좋습니다. 이는 여러 제곱근이 고려되어 성능에 큰 영향을 미치기 때문입니다.

마지막으로, 이것은 어떤 경우에 단항 마이너스가 실제로 필요한지 궁금합니다.


1
나는 당신이 단항 '-'에 대해 아마도 아무것도 추가하지 않을 것이라고 생각합니다 (적어도 보너스없이 기본 질문에). 내가 생각할 수있는 사소한 시나리오는 다음과 같을 것입니다 1 = 3^3 * 3^(-3). 그러나 이것을 고려하더라도 다른 것이 없을 때 가능한 해결책이 될 수는 없습니다.
KSab

1
여러 제곱근을 계산하는 a**.5**%i대신 대신 3 바이트를 절약 할 수 있습니다 a**(1/2**%i).
DLosc

@DLosc : 감사합니다.
Wrzlprmft

4 개의 공백 들여 쓰기를 1 공백으로 줄여 6 바이트를 절약 할 수 있습니다.
Beta Decay

@ BetaDecay : 나는 4 개의 공백 들여 쓰기 (shudder)를 사용하지 않으며 탭을 사용합니다. 내 게시물의 출처를 살펴보십시오. 스택 교환은 단지 4 개의 공간으로 렌더링합니다.
Wrzlprmft

2

Mathematica-246 자 (보너스 없음)

f[x_,y_]:=x-y
g[x_,y_]:=x/y
h[x_,y_]:=x^(1/y)
j[x_,y_]:=FromDigits@Join[IntegerDigits@x,{y}]
z[{r_,n_,L_}]:=z[{L[[1]][r,n],n,Rest@L}]
z[{r_,n_,{}}]:=r
a[n_,t_]:=Union@Select[z[{n,n,#}]&/@Tuples[{Plus,f,Times,g,Power,h,j},t-1],IntegerQ@#&&0<#<11&]

설명

이 함수는 j숫자 두 자리를 숫자로 연결합니다.

함수 z는 결과 r, 수 n및 함수 목록을 가져 오며 L, 각 함수 는 두 개의 인수에서 작동합니다. 그런 다음 [r,n]목록이 비워 질 때까지 재귀를 사용하여 함수 목록을 인수에 순차적으로 적용 하여 결과를 반환합니다.

함수 an여러 매를 복사 t합니다. 함수 목록에서 길이 (t-1)의 모든 튜플을 작성하고 {Plus, f, Times, g, Power, h, j}함수 z를 통해 각 튜플을 전송 한 다음 작성된 1에서 10까지의 모든 숫자 목록을 리턴합니다.

실행 a[2,3]리턴 예제 {1, 2, 3, 6, 8}.

한계

함수 목록은 순차적으로 적용되기 때문에 매번 하나의 사본을 소비하므로 일부 조합을 놓칠 수 있습니다. 예를 들어, 4 개의 2 개로 작동하는 경우 기능 목록을 순서대로 평가할 수 없기 때문에 22/22 = 1이 누락됩니다. 물론 2 / 2 * 2 / 2 = 1이이 경우를 다룹니다.

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