나는 당신의 BIDMAS를보고 당신을 BADMIS를 키 웁니다


21

나는 당신의 BIDMAS를보고 당신을 BADMIS를 키 웁니다

도전

"5 + 4 * 9/3-8"사이에 연산자가있는 숫자 집합이 주어지면 기본 연산 순서의 모든 순열에 대해 식의 가능한 모든 결과를 반환합니다 : [/, *, +,-].

규칙

  • 금지 된 표준 허점
  • I / O
    • 입력은 삽입 연산으로 주문해야하지만 가장 쉬운 방법입니다 (문자열 또는 배열)
    • 단항 연산자를 지원하지 않아도됩니다 (예 : "-3 * 8 / +2")
    • 암시 적으로 형식을 구문 분석하는 언어의 정수는 부동 소수점으로 대체 될 수 있습니다 (예 : 45 ⟶ 45.0)
    • 출력은 표현식의 가능한 모든 결과 여야하며 지정된 형식이나 순서가 없어야합니다.
  • 모든 입력이 유효합니다 (예 : "7/3 + *"를 처리 할 필요가 없습니다). 이것은 또한 0으로 나눌 필요가 없다는 것을 의미합니다.
  • 연산자는 모두 왼쪽 연관이므로 "20/4/2"= "(20/4) / 2"
  • 이것은 코드 골프이므로 바이트 수가 가장 적습니다.

테스트 사례 (설명 포함)

  • "2 + 3 * 4"= [14, 20]
    • 2 + (3 * 4) ⟶ 2 + (12) ⟶ 14
    • (2 + 3) * 4 ⟶ (5) * 4 ⟶ 20
  • "18/3 * 2-1"= [11, 2, 6]
    • ((18/3) * 2)-1 ⟶ ((6) * 2)-1 ⟶ (12)-1 ⟶ 11
    • (18/3) * (2-1) ⟶ (6) * (1) ⟶ 6
    • (18 / (3 * 2))-1 ⟶ (18 / (6))-1 ⟶ (3)-1 ⟶ 2
    • 18 / (3 * (2-1)) ⟶ 18 / (3 * (1)) ⟶ 6
    • 18 / ((3 * 2)-1) ⟶ 18/5 ⟶ 3.6

테스트 사례 (설명없이)

  • "45/8 + 19/45 * 3"= [6.891666666666667, 18.141666666666666, 0.11111111111111113, 0.01234567901234568, 0.01234567901234568, 5.765740740740741]
  • "2 + 6 * 7 * 2 + 6/4"= [11296 23 87.5]

2
그러나 멋진 첫 번째 도전.
얽히고 설킨


제안 된 테스트 사례 2 - 3 + 4=>[-5, 3]
Jo King

권장 테스트 사례 : 2*3-6+2-9/6*8+5/2-9, 24 개의 뚜렷한 결과 제공.
Arnauld

답변:



3

C # (Visual C # 대화식 컴파일러) , 285 바이트

x=>{int c=0,j,t=1,i;for(;c++<25;t=c){var r="*+-/".ToList();for(i=j=1;j++<4;t=t/j+1)(r[j-1],r[t%j])=(r[t%j],r[j-1]);float k(float z,int p=4){char d;int l;float m;return i<x.Count&&(l=r.IndexOf(d=x[i][0]))<p?k((m=k(x[(i+=2)-1],l))*0+d<43?z*m:d<44?z+m:d<46?z-m:z/m,p):z;}Print(k(x[0]));}}

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

x=>{                                          //Lambda taking in a List<dynamic>
  int c=0,j,t=1,i;                            //A bunch of delcarations jammed together to save bytes
  for(;c++<25;t=c){                           //Loop 24 times (amount of permutations a set of length 4 can have)
    var r="/+*-".ToList();                    //Initialize r as list of operators
    for(i=j=1;j++<4;t=t/j+1)                    //Create the Tth permutation, saving result in r, also reset i to 1
      (r[j-1],r[t%j])=(r[t%j],r[j-1]);
    float k(float z,int p=4) {                //Define local function 'k', with z as current value accumalated and p as current precedence
      char d;int l;float m;                   //Some helper variables
      return i<x.Count                        //If this is not the last number
        &&(l=r.IndexOf(d=x[i][0]))<p?         //  And the current operator's precedence is higher than the current precedence
      k(                                      //  Recursive call with the accumalative value as
        (m=k(x[(i+=2)-1],l))                  //    Another recursive call with the next number following the current operator as seed value,
                                              //    And the next operator's precedence as the precedence value, and store that in variable 'm'
        *0+d<43?z*m:d<44?z+m:d<46?z-m:z/m,    //    And doing the appropriate operation to m and current value ('z')
        p)                                    //  Passing in the current precedence
    :z;                                       //Else just return the current number
    }
    Print(k(x[0]));                           //Print the result of calling k with the first number as starting value
  }
}

지적한대로 문제의 근본적인 부분이 아니기 때문에 중복을 생략 할 필요가 없도록 수정했습니다.
Freddie R

1
@Arnauld 4 바이트의 비용으로 고정되었습니다. 순열 알고리즘이 약간 잘못 되었기 때문입니다.
무지의 구현

3

자바 스크립트 (Node.js) , 132 바이트

a=>(w=[],F=(b,a)=>b?[...b].map(q=>F(b.replace(q,""),a.replace(eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`),eval))):w.push(a))("+-*/",a)&&w

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

이것은 중복 된 출력을 허용합니다.

자바 스크립트 (Node.js를) , 165 (161) 155 153 152 137 바이트

a=>Object.keys((F=(b,a)=>b?[...b].map(q=>F(b.replace(q,""),a.replace(eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`),eval))):F[a]=1)("+-*/",a)&&F)

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

연산자와 숫자 사이에 공백이있는 문자열을 사용합니다.

a=>                                             // Main function:
 Object.keys(                                   //  Return the keys of the -
  (
   F=(                                          //   Index container (helper function):
    b,                                          //    Operators
    a                                           //    The expression
   )=>
    b                                           //    If there are operators left:
    ?[...b].map(                                //     For each operator:
     q=>
      F(                                        //      Recur the helper function - 
       b.replace(q,""),                         //       With the operator deleted
       a.replace(                               //       And all -
        eval(`/[\\d.-]+( \\${q} [\\d.-]+)+/g`), //        Expressions using the operator
        eval                                    //        Replaced with the evaluated result
       )
      )
    )
    :F[a]=1                                     //     Otherwise - set the result flag.
  )(
   "+-*/",                                      //    Starting with the four operators
   a                                            //    And the expression
  )
  &&F
 )

@JoKing 앞에서 언급 한 수정을 구현하여 [3, -5]지금 출력해야합니다 .
Shieru Asakoto

2

펄 6 , 92 90 88 바이트

{map {[o](@_)($_)},<* / + ->>>.&{$^a;&{S:g{[\-?<[\d.]>+]+%"$a "}=$/.EVAL}}.permutations}

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

연산자 다음에 공백이있는 문자열을 가져와 일련의 숫자를 반환합니다. 이것은 대부분 n op n연산자의 모든 순열에 대한 평가 결과로 모든 인스턴스를 대체 하여 작동합니다.

설명:

{                                                                                   }  # Anonymous code block
                    <* / + ->>>.&{                                    } # Map the operators to:
                                  $^a;&{                             }  # Functions that:
                                        S:g{                }      # Substitute all matches of:
                                            \-?<[\d.]>+]+        # Numbers
                                                         %$a     # Joined by the operator
                                                              =$/.EVAL   # With the match EVAL'd
 map {           },                                                    .permutations   # Map each of the permutations of these operators
      [o](@_)        # Join the functions
             ($_)    # And apply it to the input

set중복 제거 조건이 제거되었으므로을 제거 할 수 있습니다 . 좋은 코드입니다.
Freddie R

2

파이썬 3 , 108 바이트

f=lambda e,s={*"+-*/"}:[str(eval(p.join(g)))for p in s for g in zip(*map(f,e.split(p),[s-{p}]*len(e)))]or[e]

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

이 함수는 단일 문자열을 입력으로 사용하여 가능한 결과 목록을 리턴합니다.

언 골프

def get_all_eval_results(expr, operators={*"+-*/"}):
    results = []
    for operator in operators:
        remaining_operators = operators - {operator}

        # Split expression with the current operator and recursively evaluate each subexpression with remaining operators
        sub_expr_results = (get_all_eval_results(sub_expr, remaining_operators) for sub_expr in expr.split(operator))

        for result_group in zip(*sub_expr_results):   # Iterate over each group of subexpression evaluation outcomes
            expr_to_eval = operator.join(result_group)  # Join subexpression outcomes with current operator
            results.append(str(eval(expr_to_eval)))   # Evaluate and append outcome to result list of expr
    return results or [expr]  # If results is empty (no operators), return [expr]

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


1

젤리 , 30 바이트

œṡ⁹¹jṪḢƭ€jŒVɗßʋFL’$?
Ḋm2QŒ!烀

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

한 쌍의 링크. 두 번째는 주요 링크이며, 연산자로 문자로 산재 된 부동 / 정수의 젤리 목록을 인수로 사용합니다. 이것은 명령 줄 인수가 포함 된 전체 프로그램으로 실행될 때 Jelly가 입력을받는 방식의 변형 된 버전입니다. 링크의 반환 값은 단일 멤버 목록의 목록 목록이며 각각은 식에 가능한 값입니다.

설명

도우미 링크

연산자 (문자)를 왼쪽 인수로, 연산자를 문자 (오른쪽 인수)로 번갈아 표시하는 부동 소수점 / 정수 목록을 가져옵니다. 관련 연산자로 구분 된 숫자를 평가 한 후 왼쪽에서 오른쪽으로 작업 한 후 입력 목록을 반환합니다.

œṡ⁹                  | Split once by the right argument (the operator currently being processed)
                   ? | If:
                  $  | - Following as a monad
                L    |   - Length
                 ’   |   - Decremented by 1
              ʋ      | Then, following as a dyad:
   ¹                 | - Identity function (used because of Jelly’s ordering of dyadic links at the start of a dyadic chain)
    j       ɗ        | - Join with the following as a dyad, using the original left and right arguments for this chain:
     ṪḢƭ€            |   - Tail of first item (popping from list) and head from second item (again popping from list); extracts the numbers that were either side of the operator, while removing them from the split list
         j           |   - Joined with the operator
          ŒV         |   - Evaluate as Python (rather than V because of Jelly’s handling of decimals with a leading zero)
            ß        | - Recursive call to this helper link (in case there are further of the same operator)
               F     | Else: Flatten

메인 링크

연산자로 대체되는 float / integers 목록을 문자로 취합니다.

Ḋ         | Remove first item (which will be a number)
 m2       | Every 2nd item, starting with the first (i.e. the operators)
   Q      | Uniquify
    Œ!    | Permutations
      烀 | For each permuted list of operators, reduce using the helper link and with the input list as the starting point

1

파이썬 2 , 182172 바이트

import re
def f(s,P=set('+-/*')):
 S=[eval(s)]
 for p in P:
	t=s
	while p+' 'in t:t=re.sub(r'[-\d.]+ \%s [-\d.]+'%p,lambda m:`eval(m.group())`,t,1)
	S+=f(t,P-{p})
 return S

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

"암시 적으로 형식을 구문 분석하는 언어의 정수를 부동 소수점으로 대체 할 수 있음"에 따라 부동 소수점 형식의 정수로 입력을받습니다.


1

Julia 1.2 , 88 (82) 바이트

f(t)=get(t,(),[f.([t[1:i-1];t[i+1](t[i],t[i+2]);t[i+3:end]] for i=1:2:length(t)-2)...;])
julia> f([2, +, 3, *, 4])
2-element Array{Int64,1}:
 20
 14

julia> f([18, /, 3, *, 2, -, 1])
6-element Array{Float64,1}:
 11.0
  6.0
  2.0
  3.6
  6.0
  6.0

숫자 및 삽입 함수 벡터 형태의 테이프를 가져 와서 단일 함수 호출을 각각 평가하고 단일 숫자 만 남을 때까지 각 결과 테이프를 재귀 적으로 전달합니다. 불행히도 get(t, (), ...)Julia 1.0에서는 제대로 작동하지 않으므로 최신 버전이 필요합니다.

많은 중첩 배열이 출력으로 허용되는 경우 6 바이트를 저장할 수 있습니다.

f(t)=get(t,(),f.([t[1:i-1];t[i+1](t[i],t[i+2]);t[i+3:end]] for i=1:2:length(t)-2))

산출:

julia> f([18, /, 3, *, 2, -, 1])
3-element Array{Array{Array{Float64,1},1},1}:
 [[11.0], [6.0]]
 [[2.0], [3.6]] 
 [[6.0], [6.0]] 

0

펄 5 ( -alp), 89 바이트

my$x;map{$x.=$`.(eval$&.$1).$2.$"while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=$x;/[-+*\/]/&&redo

TIO

또는 고유 한 값, 99 바이트

my%H;map{$H{$`.(eval$&.$1).$2}++while/\d+[-+*\/](?=(\d+)(.*))/g}@F;$_=join$",keys%H;/[-+*\/]/&&redo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.