교대에서 수학적 표현 풀기


9

식의 교대로 나오는 요소를 사용하여 수학 식을 푸는 프로그램을 만듭니다. 그 방법은 왼쪽에서 오른쪽으로 읽는 대신 첫 번째 문자, 마지막, 두 번째, 두 번째에서 마지막 등을 읽는 것입니다. 그러면 평가하고 출력해야하는 새로운 표현이 제공됩니다.

a*b/c+d-e
135798642  <-- Order you read the expression in
ae*-bd/+c  <-- Order of operation. 

예:

1*3/2+4-5
15*-34/+2 = -255

표현식이«작동하지 않으면 1, 필요한 위치에 표현식을 삽입해야 작동합니다.

몇 가지 예는 아마도 더 잘 설명 할 것입니다.

Input: 1+1+1+1+1
Result: 23     // Because 1+1+1+1+1 -> 11++11++1 -> 23

Input: 1+2-3+12-5
Result: -19    // Because 1+2-3+12-5 -> 15+-22-13+ -> 15+-22-13+1 -> -19
               //                                 |
               //                                 Not valid expression

Input: 2*2*2*2*2
Result: 968    // Because 2*2*2*2*2 -> 22**22**2 -> 22*1*22*1*2 -> 968
               //                        ||  ||
               //                        Not valid, 1 must be inserted

Input: 17/2
Output: 127    // Because 17/2 = 127/ -> 127/1 -> 127

지원해야하는 연산자는 + - * /입니다. 괄호는 없습니다. 일반적인 수학 규칙과 "구문"이 사용되므로 예를 들어 **지수화를 의미하지는 않습니다. C ++가 아닌 MATLAB 스타일 a++++1과 같습니다 a+1.

의심스러운 경우 일부 유효한 작업은 다음과 같습니다.

-a
+a
a++b
a+-b
a*-b
a*+b
a*++b
a/b
a/-b
a/+b
-a/--b

다음은 모두 유효하지 않습니다. 무엇으로 대체해야하는지 보여줍니다.

a+      | a+1
a-      | a-1
a++++   | a++++1   (This is equivalent to a+1)
a*+++   | a*+++1   (This is equivalent to a*1)
a**b    | a*1*b
a*/b    | a*1/b
a/*b    | a/1*b
a*      | a*1
*a      | 1*a
***a    | 1*1*1*a

규칙 :

  • 코드는 함수 또는 전체 프로그램 일 수 있습니다
  • 입력은 STDIN 또는 함수 인수 일 수 있습니다.
  • 입력은 따옴표없이''"" 유효한 수학 표현식이어야합니다 . 또는 .
  • 결과는 정수, 소수 또는 단순화 된 분수로 새 표현식에 대한 답변이어야합니다.
  • 소수점 다음 세 자리 이상이 지원되어야합니다. 그래서 1/3 = 0.333,하지 0.33. 0.333333333허용됩니다.
  • ans = ... 허용됩니다.
  • 선행 및 후행 줄 바꿈 및 공백이 허용됩니다.
  • 입력은 정수만됩니다
  • 0으로 나누면 오류, NaN, Inf 등이 발생할 수 있습니다. 숫자 출력은 허용되지 않습니다.

항상 그렇듯이 바이트 단위의 가장 짧은 코드가 이깁니다. 당첨자는 챌린지가 게시 된 날로부터 1 주일 후에 선정됩니다. 나중에 게시 된 답변이 현재 리더보다 짧은 경우 여전히 이길 수 있습니다.


입력 문자열 또는 연산자 / 정수 입력 수에 최대 길이가 있습니까? 또한 수학을 최대까지 지원해야하며 2^64, 계속하면 오류가 발생하거나 줄 바꿈해야합니까?
cat

"출력은 정답 [ ... ] 단순화 된 분수 여야합니다 ..." 0/0식이 정수 나누기 또는 모듈로 0으로 사라지는 경우 반환 할 수 있습니까?
cat

2
대답이 0 x/0으로 나누면 유효한 출력입니다. 잘못된 답변을 출력하지 않는 한 괜찮습니다. 오류와 "숫자가 아님"은 정의상 정확하고, 무한대는 "충분히 정확합니다"
Stewie Griffin

확실하게 eval을 사용할 수 있습니까?
orlp

예, 평가는 괜찮습니다.
Stewie Griffin

답변:


3

펄, 108100 바이트

$_="";while(@F){$_.=shift@F;$_.=pop@F}s@(\*|/)\1+@\1@g;s@^[*/]@1$&@;s@\D$@$&1@;s@\D@$&@g;$_=eval

코드는 96 바이트에 명령 행 인수에 4를 더한 값입니다. -pF//여기서

  • -p삽입 while (<>) { .. } continue { print }
  • -F//입력을 분할하여에 넣습니다 @F.

입력에 후행 줄 바꿈이 없어야하므로 /bin/echo -n 'formula' | perl ...

덜 골프 :

$_='';              # reset $_
while(@F) {         # reorder input
   $_.=shift @F;    # take first element off of @_
   $_.=pop @F       # idem for last; if @F is empty, undef is appended
}

s@(\*|/)\1+@\1@g;   # replace 2 or more '*' or '/' with just one: *1 and /1 = nop
s@^[*/]@1$&@;       # if expression starts with * or / prepend a 1
s@\D$@$&1@;         # if expression doesn't end with a number, append 1
s@\D@$& @g;         # eval doesn't like '++1': add spaces after operators
$_ = eval           # set $_ to 3v1l, so the `-p` will print the new value

테스팅

위의 파일에 위의 파일 114.pl을 넣고 아래 테스트 스크립트는 그 옆의 파일에 넣으십시오 .

%test = (
    '1+1+1+1+1' =>   23,
    '1*3/2+4-5' => -255,
    '1+2-3+12-5'=>  -19,
    '2*2*2*2*2' =>  968,
    '17/2'      =>  127,
    '--/-1-2-'  =>   -2,
    '**2*'      =>    2,
    '++1++'     =>    1,
    '/2/'       =>  0.5,
    '10/'       =>   '',
);

printf "%-20s -> %5s: %5s\n", $_, $test{$_}, `/bin/echo -n '$_' | perl -pF// 114.pl`
for keys %test;

실행하면 다음이 출력됩니다.

++1++                ->     1:     1
**2*                 ->     2:     2
17/2                 ->   127:   127
10/                  ->      :
1+1+1+1+1            ->    23:    23
1*3/2+4-5            ->  -255:  -255
2*2*2*2*2            ->   968:   968
1+2-3+12-5           ->   -19:   -19
--/-1-2-             ->    -2:    -2
/2/                  ->   0.5:   0.5

참고 1/0: 제로 오류로 분할 인해 eval출력 undef빈 문자열로 표현된다.


몇 가지 테스트 사례! 나는 그들을 사용할 것입니다
edc65

3

자바 스크립트 ES6, 105 (106)

저장된 1 바이트 thx @Kenney 편집

t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

// Less golfed
t=>{
  for(t = [...t], p = o = '';
      c = t.reverse().pop();
      p = c)
    o += p<'0' 
     ? (c=='/' | c=='*' || ' ')+c  // '1' or ' '
     : c;
  return eval(p<'0' ? o+1 : o)
}

테스트 스 니펫

f=t=>eval("for(t=[...t],p=o='';c=t.reverse().pop();p=c)o+=p<'0'?(c=='/'|c<'+'||' ')+c:c;eval(p<'0'?o+1:o)")

console.log=x=>O.innerHTML+=x+'\n'

function test() { console.log(I.value + ' -> '+f(I.value)) }

;['1+1+1+1+1', '1*3/2+4-5', '1+2-3+12-5', '2*2*2*2*2',
  '17/2', '--/-1-2-', '**2*', '++1++', '/2/', '10/' ]
.forEach(t=>console.log(t+' -> '+f(t)))
Your test <input id=I><button onclick="test()">-></button>
<pre id=O></pre>


바이트를 절약했습니다 : p < '0' ? ( c=='/' | c<'+' || ' ' )+c : c ;.
Kenney
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.