덧셈에 대한 곱셈


17

두 정수 사이의 곱셈은 일련의 덧셈으로 줄일 수 있습니다.

3 * 5 = 3 + 3 + 3 + 3 + 3 = 5 + 5 + 5

지수 ( a 를 거듭 제곱 b )는 일련의 곱셈으로 줄일 수도 있습니다.

5 ^ 3 = 5 * 5 * 5

따라서, 곱셈 식을 만든 다음 일련의 덧셈으로 지수를 일련의 덧셈으로 줄일 수 있습니다. 예를 들어 5 ^ 3(5 큐브)는 다음과 같이 다시 쓸 수 있습니다.

5 ^ 3 = 5 * 5 * 5
      = (5 + 5 + 5 + 5 + 5) * 5
      = (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5) + (5 + 5 + 5 + 5 + 5)
      = 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5

당신의 임무는 지수, 곱셈 및 덧셈으로 구성된 식을 더하면 주어진 가장 짧은 덧셈으로 줄입니다. "가장 짧은"표현식은 +기호 가 가장 적은 표현식으로 정의되며 원래 표현식에서 두 숫자 중 하나만 사용합니다. 예를 들어 가장 짧은 표현은 10 * 2입니다 10 + 10.

입력에 포함 된 숫자는 모두 양의 정수이며 식은 +(더하기), *(곱하기) 및 ^(지수)와 함께 정수와 괄호 ( ()) 와 함께 우선 순위를 나타냅니다.

출력은 양의 정수와 +기호로만 구성되어야 합니다. 축소의 개별 단계를 출력하지 말고 최종 출력 만 출력하십시오. 출력은 입력에 나타나지 않는 숫자로 구성 될 수 없습니다. 그러나 대신 3 개의 고유 한 기호를 사용할 수 +*^있지만 어떤 기호인지 알려주세요.

입력과 출력을 분리하는 공백은 프로그램에서 사용되거나 사용되지 않을 수 있습니다. 즉, 또는 3 * 5로 출력 될 수 있습니다 .5 + 5 + 55+5+5

대부분의 경우 추가는 실제로 수행되지 않습니다. 추가가 수행되는 유일한 경우는 다음과 같은 것이있을 때 5 ^ (1 + 2)입니다.이 경우 계속하려면 추가가 필요합니다 -> 5 ^ 3 -> 5 * 5 * 5 -> .... 테스트 사례 # 4를 참조하십시오.

코드는 모호한 표현에 도달하는 입력을 처리 할 필요가 없습니다. 예를 들면 다음과 같습니다 (2 + 2) * (4 + 1). 지금까지 설명한 규칙으로 인해 목표는 답을 계산하는 것이 아니라 목표를 더하기로 단순화하는 것입니다. 따라서 표현식이 해석되거나 정류되는 순서에 따라 결과가 다를 수 있습니다 (간단하게 추가하고 떠나야 할 추가 사항). 또 다른 잘못된 예 : ((3 + 2) ^ 2) ^ 3 -> ((3 + 2) * (3 + 2)) ^ 3 -> ???.

이것은 이므로 가장 짧은 코드가 승리합니다.

테스트 사례

Input => output

5 ^ 3 + 4 * 1 ^ 5 => 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 5 + 4
2 ^ 1 * 2 + 3 + 9 => 2 + 2 + 3 + 9
2 ^ 1 * (2 + 3) + 9 => 2 + 3 + 2 + 3 + 9
2 ^ (1 * (2 + 3)) + 9 => 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 9
10 + 3 * 2 + 33 ^ 2 => 10 + 3 + 3 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33 + 33
100 * 3 => 100 + 100 + 100
2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1 => 2 + 2 + 2 + 2 + 8
(1 + 2 + 5 * 8 + 2 ^ 4) * 2 => 1 + 2 + 8 + 8 + 8 + 8 + 8 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 2 + 8 + 8 + 8 + 8 + 8 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2

**대신에 사용할 수 ^있습니까?
Outgolfer Erik

@EriktheOutgolfer 그래, 그건 공평 해 보인다.
caird coinheringaahing 17


1
유효한 출력을 구성하는 것에 대해서는 여전히 혼란 스럽습니다. 질문에서 당신은 using only one of the two numbers in the original expression.말하지만 원래 표현은 두 개 이상의 숫자를 가질 수 있습니다. 에 8 + 8대한 올바른 출력이 아닌 이유 를 얻지 못했습니다 2 ^ 1 + 2 ^ 1 + 2 ^ 2 + 8 ^ 1. 이 질문은 여전히 ​​분명하지 않습니다.
Post Rock Garf Hunter

답변:


6

레티 나 302 바이트

나는 이것이 골프를 칠 수 있다고 확신하지만,이 시점에서 나는 그것이 작동하기 때문에 기쁘다. 지수와 곱셈 섹션은 매우 유사하지만 연산 순서가 중요하기 때문에 그것들을 결합하는 방법을 모르겠습니다.

y-지수
x-곱셈
p-덧셈

\d+
$*
{1`(\(\w+\)|1+)y(\(\w+\)|1+)
>$0<
(?<=>(\(\w+\)|1+)y1*)1
$1x
>(\(\w+\)|1+)y
(
x<
)
\((1+(x1+)*)\)(?!y)
$1
(?<!1)(1+)x(\(\w+\)|1+\1)(?!1)
$2x$1
1`(\(\w+\)|1+)x1+
>$0<
(?<=>(\(\w+\)|1+)x1*)1
$1p
>(\(\w+\)|1+)x
(
p<
)
(?<!x|y)\((1+(p1+)*)\)(?!x|y)
$1
y\((1+)p([1p]*\))
y($1$2
}`y\((1+)\)
y$1
1+
$.0

온라인으로 사용해보십시오 -모든 테스트 사례

테스트 케이스 변환기

설명

\d+                             Convert to unary
$*
{1`(\(\w+\)|1+)y(\(\w+\)|1+)    Begin loop: Delimit current exponentiation group
>$0<
(?<=>(\(\w+\)|1+)y1*)1          Replace exponentiation with multiplication
$1x
>(\(\w+\)|1+)y                  Replace garbage with parentheses
(
x<
)
\((1+(x1+)*)\)(?!y)             Remove unnecessary parentheses around multiplication
$1
(?<!1)(1+)x(\(\w+\)|1+\1)(?!1)  Maybe swap order of multiplicands
$2x$1
1`(\(\w+\)|1+)x1+               Delimit current multiplication group
>$0<
(?<=>(\(\w+\)|1+)x1*)1          Replace multiplication with addition
$1p
>(\(\w+\)|1+)x                  Replace garbage with parentheses
(
p<
)
(?<!x|y)\((1+(p1+)*)\)(?!x|y)   Remove unnecessary parentheses around addition
$1
y\((1+)p([1p]*\))               Handle the 4th test case by adding if necessary
y($1$2
}`y\((1+)\)                     End of loop
y$1
1+                              Convert unary back to decimal
$.0

가장 일반적으로 사용되는 그룹은 (\(\w+\)|1+)입니다. 내부 표현식을 괄호 또는 정수와 일치시킵니다. 나는 \w문자 클래스 대신 사용할 수 있도록 내가 한 기호를 사용하기로 결정했습니다 . 단어가 아닌 기호를 사용하고 일부 둘러보기를 단어 테두리 ( \b)로 바꾸는 것이 더 나은지 잘 모르겠습니다 .


5

매쓰, 250 218 183 170 바이트

f~(s=SetAttributes)~HoldAll;{a,t}~s~Flat;f@n_:=Infix[Hold@n//.{a_~Power~b_:>t@@Hold@a~Table~b,Times->t,Plus->a,Hold->Dot}/.t->(a@@Table[#,1##2]&@@Reverse@Sort@{##}&),"+"]

효과가있다! 드디어!

의 함수를 정의합니다 f.

입력은 평범한 수학 표현입니다. (즉, 1 + 2아닙니다 "1 + 2").

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

TIO 링크는 약간 다른 코드를 가지고 있습니다 Infix. 내가 사용 Riffle티카 REPL과 같은 모양을 얻을 대신.

언 골프

f~(s = SetAttributes)~HoldAll;  (* make f not evaluate its inputs *)

{a, t}~s~Flat;  (* make a and t flat, so that a[a[1,a[3]]] == a[1,3] *)

f@n_ :=  (* define f, input n *)

 Infix[

  Hold@n  (* hold the evaluation of n for replacement *)

    //. {  (* expand exponents *)

     (* change a^b to t[a,a,...,a] (with b a's) *)
     a_~Power~b_ :> t @@ Hold@a~Table~b,

     (* Replace Times and Plus with t and a, respectively *)
     Times -> t, 
     Plus -> a, 

     (* Replace the Hold function with the identity, since we don't need
         to hold anymore (Times and Plus are replaced) *)
     Hold -> Dot 

     } /.  (* Replace; expand all t (= `Times`) to a (= `Plus`) *)

        (* Take an expression wrapped in t. *)
        (* First, sort the arguments in reverse. This puts the term
            wrapped in `a` (if none, the largest number) in the front *)
        (* Next, repeat the term found above by <product of rest
            of the arguments> times *)
        (* Finally, wrap the entire thing in `a` *)
        (* This will throw errors when there are multiple elements wrapped
           in `a` (i.e. multiplying two parenthesized elements) *)
        t -> (a @@ Table[#, 1 ##2] & @@
               Reverse@Sort@{##} &),

  "+"]  (* place "+" between each term *)

6
좋아, Mathematica에 내장되어 있지 않은 도전을 만들게되어 기쁘다 : P
만들게되어 기쁘다

3

Mathematica, 405406 바이트

f~SetAttributes~HoldAll;p=(v=Inactive)@Plus;t=v@Times;w=v@Power;f@x_:=First@MinimalBy[Inactivate@{x}//.{w[a___,b_List,c___]:>(w[a,#,c]&/@b),t[a___,b_List,c___]:>(t[a,#,c]&/@b),p[a___,b_List,c___]:>(p[a,#,c]&/@b),p[a_]:>a,w[a_,b_]:>t@@Table[a,{Activate@b}],t[a___,t[b__],c___]:>t[a,b,c],p[a___,p[b__],c___]:>p[a,b,c],{a___,{b__},c___}:>{a,b,c},t[a__]:>Table[p@@Table[i,{Activate[t@a/i]}],{i,{a}}]},Length];f

언 골프 및 설명

SetAttributes[f, HoldAll]
p = Inactive[Plus]; t = Inactive[Times]; w = Inactive[Power];
f[x_] := First@MinimalBy[
   Inactivate[{x}] //. {
     w[a___, b_List, c___] :> (w[a, #, c] & /@ b),
     t[a___, b_List, c___] :> (t[a, #, c] & /@ b),
     p[a___, b_List, c___] :> (p[a, #, c] & /@ b),
     (* distribute lists of potential expansions over all operations *)
     p[a_] :> a,
     (* addition of a single term is just that term *)
     w[a_, b_] :> t @@ Table[a, {Activate@b}],
     (* a^b simplifies to a*a*...*a b times no matter what b is *)
     t[a___, t[b__], c___] :> t[a, b, c],
     p[a___, p[b__], c___] :> p[a, b, c],
     {a___, {b__}, c___} :> {a, b, c},
     (* operations are associative *)
     t[a__] :> Table[p @@ Table[i, {Activate[t@a/i]}], {i, {a}}]
     (* for a product, generate a list of potential expansions *)}
   , Length]
f

이 기능은 보통으로, 입력으로 표준 티카 표현을한다 : 나는 다음과 같은 효과를 얻을 수 문제의 큰 거래에 갔다 +, *그리고 ^작업 (괄호) 거기에, 출력 어떤 표준 티카 표현처럼 보이는 (하지만과를 "비활성화"더하기 부호)를 답으로합니다.

위의 기능은 입력의 모든 작업을 비활성화하여 시작합니다. 그런 다음 더 이상 아무것도 단순화 할 수 없을 때까지 확장 규칙을 반복해서 적용합니다. 2 * 3 * 4여러 가지 방법으로 확장 할 수있는와 같은 제품을 발견 할 때마다 가능한 확장 목록을 작성하고 계속 진행합니다. 마지막에는 가능한 최종 답변 목록이 표시되고 가장 짧은 답변이 선택됩니다.

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