수학 기호 해독


13

Carl Sagan 의 저서 ( Contact by Carl Sagan)를 읽었다면 이 도전은 익숙 할 것입니다.


숫자, 알 수없는 연산자, 다른 숫자 및 결과로 구성된 일련의 수학 방정식을 입력하면 어떤 연산자가 더하기, 빼기, 곱하기 또는 나누기를 나타내는지를 추론 할 수 있습니다.

각 입력 방정식은 항상 다음으로 구성됩니다

  • 음이 아닌 정수
  • 글자 하나 A, B, C, 또는D
  • 다른 음이 아닌 정수
  • 캐릭터 =
  • 음이 아닌 최종 정수

함께 연결됩니다. 예를 들어, 가능한 입력 값은을 더하여 1A2=3추론 할 수 있습니다 A. 각 정수는를 만족 0 ≤ x ≤ 1,000합니다.

그러나 항상 그렇게 간단하지는 않습니다. 다음 사이에 모호성이있을 수 있습니다.

  • 5A0=5: 더하기 / 빼기
  • 1A1=1: 곱셈 / 나눗셈
  • 0A5=0: 곱셈 / 나눗셈
  • 2A2=4: 덧셈 / 곱셈
  • 4A2=2: 빼기 / 나눗셈
  • 0A0=0: 더하기 / 빼기 / 곱하기

등등. 문제는이 기능을 사용하여 각 문자가 나타내는 연산자를 파악하기 위해 제거 프로세스와 결합 된 선택 범위를 좁히는 것입니다. (항상 하나 이상의 입력 방정식이있을 것이므로 입력에 사용 된 각 문자를 단일 연산자로 명확하게 일치시킬 수 있습니다.)

예를 들어 입력이 다음 방정식이라고 가정 해 봅시다.

  • 0A0=0: A를 더하기, 빼기 또는 곱하기로 좁 힙니다 (0으로 나눌 수 없음).
  • 10B0=10: B는 덧셈 또는 뺄셈이어야합니다.
  • 5C5=10: C는 분명히 덧셈이므로 B를 빼면 A가 곱해집니다.

따라서, 이러한 입력 식의 출력은 일치해야 A*, B-,와 C함께 +.

입력은 단일 공백 ​​/ 쉼표로 구분 된 문자열 또는 각각 하나의 방정식을 나타내는 문자열 배열로 제공 될 수 있습니다. 출력은 단일 문자열 ( "A*B-C+"), 배열 ( ["A*", "B-", "C+"]) 또는 사전 / dict-like 2D 배열 ( {"A": "*", ...}또는 [["A", "*"], ...]) 일 수 있습니다.

숫자를 나눌 수없는 다른 숫자로 나누지 않는다고 가정 할 수 있습니다 (따라서 나누기가 부동 소수점인지 잘림인지에 대해 걱정할 필요가 없습니다).

이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다.

테스트 사례 :

In                       Out
-------------------------------
0A0=0 10B0=10 5C5=10     A*B-C+
100D100=10000            D*
4A2=2 4B2=2 0A0=0        A-B/
15A0=15 4B2=2 2C2=0      A+B/C-
1A1=1 0A0=0              A*
0A0=0 2A2=4 5B0=5 2B2=4  A*B+
2A2=4 0C0=0 5B0=5 5A0=5  A+B-C*
0A1000=0 4A2=2           A/

1
정수 나누기를하고 있습니까?
Martin Ender

@ MartinBüttner 정수가 아닌 숫자로 나눌 수 없다고 가정 할 수 있습니다. (질문으로 편집 됨)
손잡이

사전으로 출력 할 수 있습니까?
lirtosiast

@ThomasKwa 물론 사전도 허용됩니다.
Doorknob

대부분의 예는 "상충 항상 유일하게, 명백하게에 할 수있는 연산자를 의미하는 편지 식별 들은"와 일치하지만, " 항상 명백하게에 사용되는 각 문자로 표현되는 연산자를 식별 할 수있을 것입니다 "를 입력하십시오 .
피터 테일러

답변:


9

MATL , 53 바이트

j61tthYX'+-*/'X{Y@!"t'ABCD'!XKX{@YXU?K@Y}hwxKGm1L3$).

용도 현재 버전 (10.1.0)

EDIT (6 월 (12), 2016), 언어 변화에 적응 교체 Y}g1L3$)에 의해 Y). 아래 링크는 이러한 수정 사항을 통합합니다

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

설명

이것은 하나의 순열이 모든 방정식을 만족시킬 때까지 루프에서 4 개의 연산자의 가능한 모든 순열을 테스트합니다.

방정식이 참인지 테스트하기 위해 정규식을 적용하여 연산자로 4 개의 문자를 바꾸고 (현재 순열에 따라 순서대로) 문자열을 숫자 (평가됨)로 변환합니다. 이것은 방정식만큼 많은 수의 배열을 제공하며, 여기서 참인 1방정식은되고 거짓 인 방정식은됩니다 0. 이 벡터에 값만 포함되어 있으면 1완료됩니다.

찾은 솔루션은 연산자를 네 글자에 할당하지만 모든 문자가 입력에 반드시 나타나는 것은 아닙니다. 따라서 사용되지 않은 문자 (및 일치하는 연산자)를 버리는 최종 테스트가 수행됩니다.

j            % input data string
61           % '=' (ASCII)
tth          % duplicate twice and concat: '==' (ASCII)
YX           % regexprep to change '=' into '==' in input string
'+-*/'       % push string
X{           % transform into cell array {'+','-','*','/'}
Y@!          % all permutations, each in a column
"            % "for" loop. Iterate columns (that is, permutations)
  t          %   duplicate data string containing '=='
  'ABCD'!XK  %   create column array ['A';'B';'C';'D'] and copy to clipboard K
  X{         %   transform into column cell array {'A';'B';'C';'D'} 
  @          %   push column cell array with current permutation of operator symbols
  YX         %   regexprep. Replaces 'A',...,'D' with current permutation of operators
  U          %   convert to numbers, i.e. evaluate string
  ?          %   if all numbers are 1 (truthy result): found it! But before breaking...
    K        %     push column array ['A';'B';'C';'D']
    @Y}      %     push column array with current permutation of operator symbols
    h        %     concatenate horizontally into 4x2 char array
    wx       %     delete original input so it won't be displayed
    K        %     push ['A';'B';'C';'D']
    G        %     push input string
    m        %     logical index that tells which of 'A',...,'D' were in input string
    1L3$)    %     apply that index to select rows of the 4x2 char array
    .        %     we can now break "for" loop
             %   implicitly end "if"
             % implicitly end "for"
             % implicitly display stack contents

6

파이썬, 278 자

코드 골프에 대한 첫 번째 대답은 ...

그것은 무차별 대입 알고리즘을 구현하는 함수 일 뿐이며 방정식의 문자열을 인수로 전달하는 것입니다.

from itertools import *
def f(s):
    l=list("ABCD")
    for p in permutations("+-*/"):
        t=s
        for v,w in zip(l+["="," "],list(p)+["=="," and "]):
            t=t.replace(v, w)
        try:
            o=""
            if eval(t):
                for c,r in zip(l,p):
                    if c in s:
                        o+=c+r
                return o
        except:
            pass

나는 그것이 작동하는지 모르겠어요,하지만 당신은 대체 할 수 ["A","B","C","D"]와 함께 list("ABCD")?
Adnan

@Adnan이 제안한 것은 실제로 작동합니다. =의 정의에서 공백을 제거 할 수도 있습니다 l.
Alex A.

@ Adnan과 Alex A. 감사합니다. 코드를 편집했습니다.
Bob

동일한 접근 방식에 대한 257 바이트 와 온라인 테스트 환경이 있습니다.
Alex A.

repl.it/BfuU 변경 했습니다 . 다른 출력 형식을 선택하여 많은 바이트를 더 많이 줄일 수 있습니다. 이 솔루션은 python 3 btw ( 4A2=2 4B3=1) 에서만 작동합니다 .
Nabb

4

자바 스크립트 (ES6) 213 208 바이트

f=(l,s="+-*/",p="",r)=>s?[...s].map(o=>r=f(l,s[g="replace"](o,""),p+o)||r)&&r:l.split` `.every(x=>(q=x.split`=`)[1]==eval(q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])))&&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

설명

입력과 출력은 문자열입니다.

f연산자의 모든 순열을 생성하는 재귀 함수로 두 배가 되는 함수 를 정의하고를 사용하여 입력 방정식으로 완전한 순열을 테스트 eval합니다.

f=(
  l,                          // l = input expression string
  s="+-*/",                   // s = remaining operators
  p="",                       // p = current permutation of operators
  r                           // r is here so it is defined locally
)=>
  s?                          // if there are remaining operators
    [...s].map(o=>            // add each operator o
      r=f(
        l,
        s[g="replace"](o,""), // remove it from the list of remaining operators
        p+o                   // add it to the permutation
      )
        ||r                   // r = the output of any permutation (if it has output)
    )
    &&r                       // return r
  :                           // else if there are no remaining operators
    l.split` `.every(x=>      // for each expression
      (q=x.split`=`)          // q = [ equation, result ]
      [1]==eval(              // if the results is equal to the eval result

        // Replace each letter with the current permutation
        q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])
      )
    )

    // If all results matched, add permutation symbols to present characters and return
    &&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

테스트

테스트는 브라우저 호환성을 위해 기본 인수를 사용하지 않습니다.

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