评估不平等链


17

编写代码以评估不等式链是对还是错。输入示例是字符串

3<=4!=9>3==3

这是正确的,因为其每个组成部分都是正确的:

(3<=4) and (4!=9) and (9>3) and (3==3)

输入:

代表一个或多个不等式链的字符串。允许的比较运算符为

==   equals
!=   does not equal
>    is greater than
>=   is greater than or equal to
<    is less than
<=   is less than or equal to

允许的数字是1位数字0通过9。不会有任何空格,括号或其他符号。

输出:

不等式作为一致的Truthy或Falsey值的正确性。一致意味着每个Truthy输出都是相同的,每个Falsey输出都是相同的。

限制:

挑战的目的是让您编写处理不平等的代码,而不是让它们将它们作为代码进行评估,即使对于链中的单个不平等也是如此。因此,像Python的方法evalexec计算结果或执行代码被禁止。查找以字符串形式给出的方法或运算符的函数也是如此。也不允许启动流程或程序来为您进行评估。

测试用例:

3<=4!=9>3==3
True

3<=4!=4
False

5>5
False

8==8<9>0!=2>=1
True

我们可以接受带有≤和≥等Unicode不等号而不是<=和> =的输入吗?
FUZxxl 2015年

@FUZxxl您不能。
xnor

Answers:


7

Ruby,71 +1 = 72

使用命令行标志-n,运行

p (0..99).none?{|i|~/#{a=i%10}(#{%w/!=|. <?=* >?=*/[a<=>b=i/10]})#{b}/}

生成所有可能的失败正则表达式,并检查输入字符串是否与它们中的任何一个匹配。true如果没有输出,则输出,否则输出false。通过STDIN接受输入,以换行符分隔。

技巧:

  • 通过从0到99循环并提取10s和1s数字,我们得到所有可能的数字对。
  • 我们所做的唯一实际比较是a<=>b,它返回-1,0或1表示小于,等于或大于。这些都切成三串数组的不同元素,找到不匹配的正则表达式。

多么聪明的策略!
xnor 2015年

6

Perl,82岁

$_=<>;($'<=>$&)-61+ord$1&&($2&&$&==$')^('$'lt$1)&&die"\n"while/\d(.)(=?)/g;print 1

因为为空字符串是Perl的主要falsey值,所以在true时打印1,在false时打印空白行。

while循环遍历与regex匹配的字符串\d(.)(=?)。然后,变量$1$2对应于运算符的字符,特殊变量$&$'在数值上下文中将充当两个操作数。将操作数与<=>运算符的第一个字符进行比较,并将结果与​​运算符的第一个字符进行匹配。然后,平等和不平等被专门处理。


4

CJam,60个字节

这段代码看起来有些丑陋,可能还没有完全优化,但这是迄今为止我所能得到的最好的代码。

在线尝试。

q_A,sSer_S%@@-(])1\@z{~:X\:^i['=")<"P"(>"P'<'^'>PPP]=~e&X}/;

说明

q               "Read the input";
_A,sSer         "Copy the input and replace each digit with a space";
_S%             "Split around spaces to obtain the operation list";
@@-             "Remove operations from the input to obtain the operand list";
(])1\@z         "Remove the first operand from the list to be the initial left
                 operand, initialize the result to 1 (true), and pair up the
                 operations and remaining operands";
{               "For each operation-operand pair:";
  ~:X             "Let the operand be the right operand of this operation";
  \:^i            "Hash the operation (bitwise XOR of all characters)";
  [               "Begin cases:";
    '=              " 0: Equals";
    ")<"            " 1: Less than or equal to";
    P               " 2: (Invalid)";
    "(>"            " 3: Greater than or equal to";
    P               " 4: (Invalid)";
    '<              " 5: Less than";
    '^              " 6: Bitwise XOR (stand-in for not equal to)";
    '>              " 7: Greater than";
    P               " 8: (Invalid)";
    P               " 9: (Invalid)";
    P               "10: (Invalid)";
  ]=~             "Execute the case selected by the operation hash modulo 11";
  e&              "Compute the logical AND of the result and the value produced
                   by this operation to be the new result";
  X               "Let the right operand be the new left operand";
}/              "End for each";
;               "Clean up and implicitly print result";

4

的JavaScript(ES6)110 116

直观:扫描字符串,c为当前数字,l为最后一位,o为运算符。

F=x=>(l='',[for(c of x)10-c?(v=!l||v&&(o<'<'?l!=c:(o[1]&&c==l)||(o<'='?l<c:o<'>'?c==l:l>c)),l=c,o=''):o+=c],v)

在Firefox / FireBug控制台中测试

;['3<=4!=9>3==3','3<=4!=4','5>5','8==8<9>0!=2>=1']
.forEach(s=>console.log(s,F(s)))

3 <= 4!= 9> 3 == 3是
3 <= 4!= 4否
5> 5否
8 == 8 <9> 0!= 2> = 1是


3

Haskell,156个字节

r a=read[a]::Int
l"!"=(/=)
l"="=(==)
l">"=(>=)
l"<"=(<=)
k">"=(>)
k"<"=(<)
[]#_=1<2
(a:'=':b:c)#i=l[a]i(r b)&&c#r b
(a:b:c)#i=k[a]i(r b)&&c#r b
f(h:t)=t#r h

用法示例:

f "3<=4!=9>3==3"        -> True
f "3<=4!=4"             -> False
f "5>5"                 -> False
f "8==8<9>0!=2>=1"      -> True

非高尔夫版本:

digitToInt d = read [d] :: Int

lookup2 "!" = (/=)
lookup2 "=" = (==)
lookup2 ">" = (>=)
lookup2 "<" = (<=)

lookup1 ">" = (>)
lookup1 "<" = (<)

eval []              _ = True
eval (op:'=':d:rest) i = lookup2 [op] i (digitToInt d) && eval rest (digitToInt d)
eval (op:d:rest)     i = lookup1 [op] i (digitToInt d) && eval rest (digitToInt d)

evalChain (hd:rest) = eval rest (digitToInt hd)

eval接受两个参数:要解析的字符串(始终从比较运算符开始)和一个数字i,该数字是用于比较的左参数(在上一轮中是右参数)。如果运算符是lookup2两个字符的运算符(仅检查1st char,因为2nd始终为=),则返回该运算符,lookup1如果它只是单个字符,则返回该运算符。eval递归地调用自身,并将所有返回值与逻辑和相结合&&


3

普通Lisp- 300 185 169 165

(lambda(s)(loop for(a o b)on(mapcar'read-from-string(cdr(ppcre:split"([0-9]+)"s :with-registers-p t)))by #'cddr always(if o(funcall(case o(=='=)(!='/=)(t o))a b)t)))

(mapcar (lambda(s) ...)
       '("2<=3<=6>2<10!=3"
         "3<=4!=9>3==3" 
         "3<=4!=4" 
         "5>5"
         "8==8<9>0!=2>=1"))
=> (T T NIL NIL T)

说明

(lambda (s)
  (loop for (a o b) on (mapcar
                        'read-from-string
                        (cdr
                         (cl-ppcre:split "([0-9]+)" s
                                         :with-registers-p t))) by #'cddr
        always (if o
                   (funcall (case o
                                  (== '=)
                                  (!= '/=)
                                  (t o))
                            a b)
                   t)))
  • ppcre:split按数字分割;例如:

    (ppcre:split "([0-9]+)" "2<=3<=6>2<10!=3" :with-registers-p t)
    => ("" "2" "<=" "3" "<=" "6" ">" "2" "<" "10" "!=" "3")
    

    请注意第一个空字符串,该字符串将使用丢弃 cdr

  • 映射read-from-string到此列表read将为每个字符串调用该函数,该函数返回符号和数字。

  • loop for (a op b) on '(3 < 5 > 2) by #'cddr遍历该列表通过的工序2个,因此结合aopb如下,对于每个连续的传递。

    a  op  b
    ----------
    3  <    5
    5  >    2
    2  nil  nil
    
  • always检查下一个表达式是否始终为真:运算符为nil(请参见上文)或比较结果成立(请参见下文)。

  • case选择一个共Lisp的比较函数,根据先前读取的符号; 由于某些运算符在Lisp和给定的语言中是相同的,因此我们可以o在默认情况下简单地返回。


1

Python 2中,95 102

t=1
n=o=3
for c in map(ord,raw_input()):
 o+=c
 if 47<c<58:t&=627>>(o-c+3*cmp(n,c))%13;n=c;o=0
print t

循环是一次直接在字符串中传递一个字符。这t&=...是魔术发生的地方。基本上,我会cmp(lhs,rhs)根据lhs(小于,等于或大于rhs)将运算符与(-1、0或1)值一起哈希。结果是查找表中的键,该键给出0或1,具体取决于给定该运算符的数字是否正确比较。您问什么查询表?数字627 = 0001001110011二进制。其余部分由按位运算符完成。

这适用于四个给定的测试用例;如果您发现其他情况下的错误,请告诉我。我还没有对它进行非常严格的测试。


您需要接受a输入。
xnor

@xnor糟糕。已更正。
DLosc

1

Javascript 101字节

与此处发布的js解决方案不同的方法

F=(s,i=0,l=o="")=>[...s].every(c=>c>=0?[l^c,l==c,,l<c,l>c,l<=c,,l>=c]["!==<><=>=".search(o,l=c,o="")]:o+=c,l=o="")

console.log(F("3<=4!=9>3==3")==true)
console.log(F("3<=4!=4")==false)
console.log(F("5>5")==false)
console.log(F("8==8<9>0!=2>=1")==true)


0

Java 8,283字节

s->{String[]a=s.split("\\d"),b=s.split("\\D+");int i=0,r=1,x,y;for(;i<a.length-1;)if((x=new Byte(b[i]))!=(y=new Byte(b[++i]))&(a[i].equals("=="))|(a[i].equals("!=")&x==y)|(a[i].equals(">")&x<=y)|(a[i].equals(">=")&x<y)|(a[i].equals("<")&x>=y)|(a[i].equals("<=")&x>y))r--;return r>0;}

说明:

在这里尝试。

s->{                            // Method with String parameter and boolean return-type
  String[]a=s.split("\\d"),     //  All the inequalities
          b=s.split("\\D+");    //  All the digits
  int i=0,                      //  Index-integer (starting at 0)
      r=1,                      //  Flag integer for the result, starting at 1
      x,y;                      //  Temp integer `x` and `y`
  for(;i<a.length-1;)           //  Loop from 0 to the length - 1
  if((x=new Byte(b[i]))!=(y=new Byte(b[++i]))&(a[i].equals("=="))
                                //   If "==" and `x` and `y` as int are not equal:
     |(a[i].equals("!=")&x==y)  //   Or "!=" and `x` and `y` are equal
     |(a[i].equals(">")&x<=y)   //   Or ">" and `x` is smaller or equal to `y`
     |(a[i].equals(">=")&x<y)   //   Or ">=" and `x` is smaller than `y`
     |(a[i].equals("<")&x>=y)   //   Or "<" and `x` is larger or equal to `y`
     |(a[i].equals("<=")&x>y))  //   Or "<=" and `x` is larger than `y`
    r--;                        //    Decrease `r` by 1
                                //  End of loop (implicit / single-line body)
  return r>0;                   //  Return if `r` is still 1
}                               // End of method
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.