解读数学符号


13

如果您已经读过卡尔·萨根(Carl Sagan)的《接触》一书,这个挑战对您来说似乎很熟悉。


给定一组数学方程式的输入,该数学方程式由一个数字,一个未知算子,另一个数字和结果组成,推论出哪些算子表示加,减,乘或除。

每个输入方程将始终包含

  • 非负整数
  • 一个字母ABC,或者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+"])或类似字典/字典的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 '16

@ThomasKwa当然,字典也是可接受的输出。
Doorknob

大多数示例与“ 始终可以明确,唯一地标识哪个字母代表哪个运算符 ”不一致,尽管它们与“ 始终可以明确地标识哪个运算符由使用的每个字母代表 ”不一致。输入 “。
彼得·泰勒

Answers:


9

MATL,53字节

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

使用当前版本(10.1.0)

编辑(2016年6月12日):适应变化的语言,取代Y}通过g1L3$)通过Y)。下面的链接包含了这些修改

在线尝试!

说明

这将循环测试四个算子的所有可能置换,直到一个置换使所有方程式成立。

为了测试方程式是否正确,使用正则表达式由运算符替换四个字母(按当前排列指示的顺序),并将字符串转换为数字(求值)。这样就得到了一个具有与方程式一样多的数字的数组,其中,正确的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

Python,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的建议确实有效。您也可以=在的定义中删除空格l
Alex A.

@Adnan和Alex A.谢谢,我编辑了代码。
鲍勃

这是相同方法的257个字节,另外还有一个在线测试环境。
Alex A.

进行了一些更改-repl.it/BfuU。您可以通过选择其他输出格式来减少很多字节。此解决方案仅适用于python 3 btw(4A2=2 4B3=1)。
Nabb

4

的JavaScript(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]:"")

测试

测试不使用默认参数来实现浏览器兼容性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.