Đánh giá một chuỗi bất bình đẳng


17

Viết mã để đánh giá xem một chuỗi bất đẳng thức là đúng hay sai. Một ví dụ đầu vào là chuỗi

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

Điều này đúng bởi vì mỗi thành phần của nó là đúng:

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

Đầu vào:

Một chuỗi đại diện cho một chuỗi của một hoặc nhiều bất đẳng thức. Các toán tử so sánh được phép là

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

Các số được phép là các số có một chữ số 0thông qua 9. Sẽ không có bất kỳ khoảng trắng, dấu ngoặc đơn hoặc biểu tượng nào khác.

Đầu ra:

Tính chính xác của bất đẳng thức như một giá trị Truthy hoặc Falsey nhất quán . Nhất quán có nghĩa là mọi đầu ra Truthy đều giống nhau và mọi đầu ra Falsey đều giống nhau.

Sự hạn chế:

Mục đích của thử thách này là để bạn viết mã xử lý các bất đẳng thức, thay vì đánh giá chúng là mã, thậm chí cho một bất đẳng thức duy nhất trong chuỗi. Như vậy, các phương thức như Python evalexecđánh giá hoặc thực thi mã đều bị cấm. Vì vậy, các hàm tìm kiếm một phương thức hoặc toán tử được đặt tên của nó dưới dạng một chuỗi. Nó cũng không được phép khởi chạy các quy trình hoặc chương trình để thực hiện đánh giá cho bạn.

Các trường hợp thử nghiệm:

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

3<=4!=4
False

5>5
False

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

Chúng tôi có thể chấp nhận đầu vào với các dấu hiệu bất bình đẳng Unicode như và ≥ thay vì <= và> = không?
FUZxxl

@FUZxxl Bạn không thể.
xnor

Câu trả lời:


7

Ruby, 71 + 1 = 72

Với cờ dòng lệnh -n, chạy

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

Tạo tất cả các biểu thức thông thường có thể thất bại và kiểm tra xem chuỗi đầu vào có khớp với bất kỳ biểu thức nào không. Đầu ra truenếu không làm, khác false. Đưa đầu vào qua STDIN, được phân tách bằng các dòng mới.

Thủ thuật:

  • Chúng tôi nhận được tất cả các cặp chữ số có thể bằng cách lặp từ 0 đến 99 và trích xuất các chữ số 10 và 1.
  • Sự so sánh thực tế duy nhất chúng tôi làm là a<=>b, trả về -1,0 hoặc 1 với giá trị nhỏ hơn, bằng hoặc lớn hơn. Tất cả đều cắt các phần tử khác nhau của một mảng ba chuỗi, tìm biểu thức chính quy để so sánh không khớp.

Thật là một chiến lược thông minh!
xnor

6

Perl, 82

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

In 1 khi đúng và một dòng trống khi sai, vì chuỗi trống là giá trị falsey chính của Perl.

Vòng lặp while đi qua chuỗi khớp với biểu thức chính quy \d(.)(=?). Sau đó, các biến $1$2tương ứng với các ký tự của toán tử, và các biến đặc biệt $&$'sẽ hoạt động như hai toán hạng trong ngữ cảnh số. Các toán hạng được so sánh với <=>và kết quả khớp với ký tự đầu tiên của toán tử. Sau đó, bình đẳng và bất bình đẳng được xử lý đặc biệt.


4

CJam, 60 byte

Mã này có vẻ hơi xấu và có khả năng không được tối ưu hóa hoàn toàn, nhưng đó là mã tốt nhất mà tôi có được cho đến nay.

Hãy thử trực tuyến.

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

Giải trình

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

Nói thẳng: chuỗi quét, c là chữ số hiện tại, l là chữ số cuối cùng, o là toán tử.

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)

Kiểm tra trong bảng điều khiển 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 đúng
3 <= 4! = 4 sai
5> 5 sai
8 == 8 <9> 0! = 2> = 1 đúng


3

Haskell, 156 byte

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

Ví dụ sử dụng:

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

Phiên bản bị đánh cắp:

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)

evallấy hai đối số: chuỗi để phân tích cú pháp (bắt đầu luôn bằng toán tử so sánh) và một số ilà đối số bên trái để so sánh (và là đối số bên phải trong vòng trước). Toán tử được trả về bởi lookup2nếu đó là toán tử hai ký tự (chỉ kiểm tra char thứ nhất, vì thứ 2 luôn luôn =) và lookup1nếu đó chỉ là một ký tự. evalgọi chính nó đệ quy và kết hợp tất cả các giá trị trả về với logic và &&.


3

Lisp thường gặp - 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)))

Thí dụ

(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)

Giải trình

(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:splitchia nhỏ trên các chữ số; ví dụ:

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

    Lưu ý chuỗi trống đầu tiên, được loại bỏ bằng cách sử dụng cdr

  • Ánh xạ read-from-stringvào danh sách này gọi readhàm cho mỗi chuỗi, trả về các ký hiệu và số.

  • loop for (a op b) on '(3 < 5 > 2) by #'cddrLặp lại danh sách theo bước 2 và do đó liên kết a, opbnhư sau, cho mỗi lần vượt qua liên tiếp.

    a  op  b
    ----------
    3  <    5
    5  >    2
    2  nil  nil
    
  • alwayskiểm tra xem biểu thức tiếp theo có luôn đúng hay không: toán tử là nil(xem bên trên) hoặc kết quả của các phép so sánh (xem bên dưới).

  • các casechọn một chức năng so sánh Common Lisp-, theo biểu tượng đọc trước đó; vì một số toán tử giống hệt nhau trong Lisp và ngôn ngữ đã cho, chúng ta có thể chỉ cần trả về otrong trường hợp mặc định.


1

Con trăn 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

Vòng lặp là một đường thẳng đi qua chuỗi một ký tự tại một thời điểm. Phần t&=...là nơi phép màu xảy ra. Về cơ bản, tôi băm toán tử cùng với giá trị cmp(lhs,rhs)(-1, 0 hoặc 1 tùy thuộc vào nếu lhsnhỏ hơn, bằng hoặc lớn hơn rhs). Kết quả là một khóa vào bảng tra cứu cho 0 hoặc 1 tùy thuộc vào việc các số có so sánh đúng với toán tử đó hay không. Bảng tra cứu gì, bạn yêu cầu? Đó là số 627 = 0001001110011trong hệ nhị phân. Toán tử bitwise làm phần còn lại.

Điều này hoạt động trên bốn trường hợp thử nghiệm nhất định; cho tôi biết nếu bạn tìm thấy một lỗi cho trường hợp khác. Tôi đã không kiểm tra nó rất nghiêm ngặt.


Bạn cần phải đưa vào anhư là đầu vào.
xnor

@xnor Rất tiếc. Đã sửa.
DLosc

1

Javascript 101 byte

một cách tiếp cận khác với giải pháp js được đăng ở đây

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 byte

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;}

Giải trình:

Hãy thử nó ở đây.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.