Mengevaluasi rantai ketidaksetaraan


17

Tulis kode untuk mengevaluasi apakah rantai ketidaksetaraan itu benar atau salah. Contoh input adalah string

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

Ini benar karena masing-masing komponennya benar:

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

Memasukkan:

String yang mewakili rantai satu atau lebih ketidaksetaraan. Operator perbandingan yang diizinkan adalah

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

Nomor diperbolehkan adalah nomor satu digit 0melalui 9. Tidak akan ada spasi, tanda kurung, atau simbol lainnya.

Keluaran:

Ketepatan ketidaksetaraan sebagai nilai Kebenaran atau Falsey yang konsisten . Konsisten berarti setiap output Kebenaran adalah sama dan setiap output Falsey adalah sama.

Larangan:

Maksud dari tantangan ini adalah bagi Anda untuk menulis kode yang memproses ketidaksetaraan, daripada meminta mereka untuk mengevaluasinya sebagai kode, bahkan untuk satu ketidaksetaraan dalam rantai. Dengan demikian, metode seperti Python evaldan execyang mengevaluasi atau mengeksekusi kode dilarang. Begitu juga fungsi yang mencari metode atau operator yang diberi nama sebagai string. Juga tidak diperbolehkan meluncurkan proses atau program untuk melakukan evaluasi untuk Anda.

Kasus uji:

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

3<=4!=4
False

5>5
False

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

Bisakah kita menerima input dengan tanda ketidakmerataan Unicode seperti ≤ dan ≥ bukan <= dan> =?
FUZxxl

@ FuZxxl Anda tidak bisa.
xnor

Jawaban:


7

Ruby, 71 + 1 = 72

Dengan bendera baris perintah -n, jalankan

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

Menghasilkan semua kemungkinan ekspresi reguler yang gagal, dan memeriksa apakah string input cocok dengan salah satu dari mereka. Keluaran truejika tidak ada yang melakukannyafalse . Mengambil input melalui STDIN, dipisahkan oleh baris baru.

Trik:

  • Kami mendapatkan semua pasangan digit yang memungkinkan dengan memutar dari 0 hingga 99 dan mengekstraksi angka 10s dan 1s.
  • Satu-satunya perbandingan aktual yang kami lakukan adalah a<=>b , yang mengembalikan -1,0, atau 1 kurang dari, sama dengan, atau lebih besar. Ini semua mengiris elemen yang berbeda dari array tiga-string, menemukan ekspresi reguler untuk perbandingan yang tidak cocok.

Strategi yang cerdas!
xnor

6

Perl, 82

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

Mencetak 1 saat true dan baris kosong ketika false, karena string kosong adalah nilai falsey utama Perl.

Loop sementara melewati string yang cocok dengan regex \d(.)(=?). Kemudian variabel $1dan $2sesuai dengan karakter operator, dan variabel khusus $&dan $'akan berperilaku sebagai dua operan dalam konteks numerik. Operan dibandingkan dengan <=>dan hasilnya cocok dengan karakter pertama operator. Kemudian persamaan dan ketidaksetaraan ditangani secara khusus.


4

CJam, 60 byte

Kode ini tampak agak jelek dan berpotensi tidak sepenuhnya dioptimalkan, tetapi itu yang terbaik yang saya dapatkan sejauh ini.

Cobalah online.

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

Penjelasan

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

Mudah: string pindai, c adalah digit saat ini, l adalah digit terakhir, o adalah operator.

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)

Uji di Firefox / konsol 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 benar
3 <= 4! = 4 salah
5> 5 salah
8 == 8 <9> 0! = 2> = 1 benar


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

Contoh penggunaan:

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

Versi tidak disatukan:

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)

evalmembutuhkan dua argumen: string ke parse (dimulai selalu dengan operator perbandingan) dan angka iyang merupakan argumen kiri untuk perbandingan (dan argumen yang tepat di babak sebelumnya). Operator dikembalikan oleh lookup2jika itu adalah operator dua karakter (periksa hanya karakter pertama, karena karakter kedua selalu =) dan lookup1jika itu hanya karakter tunggal. evalpanggilan itu sendiri secara rekursif dan menggabungkan semua nilai kembali dengan logis dan &&.


3

Gangguan Umum - 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)))

Contoh

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

Penjelasan

(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:splitterbagi dua; sebagai contoh:

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

    Perhatikan string kosong pertama, yang dibuang menggunakan cdr

  • Pemetaan read-from-stringke daftar ini memanggil readfungsi untuk setiap string, yang mengembalikan simbol dan angka.

  • loop for (a op b) on '(3 < 5 > 2) by #'cddriterates atas daftar dengan langkah 2 dan dengan demikian mengikat a, opdan bsebagai berikut, untuk setiap operan berturut-turut.

    a  op  b
    ----------
    3  <    5
    5  >    2
    2  nil  nil
    
  • alwaysmemeriksa apakah ungkapan berikutnya selalu benar: apakah operatornya nil(lihat di atas) atau hasil dari perbandingan berlaku (lihat di bawah).

  • yang casemenyeleksi Common-Lisp fungsi perbandingan, menurut simbol sebelumnya baca; karena beberapa operator identik dalam Lisp dan bahasa yang diberikan kita dapat dengan mudah kembali odalam kasus default.


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

Loop adalah lintasan langsung ke string karakter satu per satu. Bagian t&=...inilah tempat keajaiban terjadi. Pada dasarnya, saya hash operator bersama dengan nilai cmp(lhs,rhs)(-1, 0, atau 1 tergantung pada apakah lhskurang, sama, atau lebih besar dari rhs). Hasilnya adalah kunci ke dalam tabel pencarian yang memberikan 0 atau 1 tergantung pada apakah angka membandingkan dengan benar diberikan operator itu. Tabel pencarian apa, Anda bertanya? Itu angka 627 = 0001001110011dalam biner. Operator bitwise melakukan sisanya.

Ini bekerja pada empat kasus uji yang diberikan; beri tahu saya jika Anda menemukan kesalahan untuk kasus lain. Saya belum mengujinya dengan sangat ketat.


Anda harus menerima asebagai masukan.
xnor

@ xnor Whoops. Dikoreksi.
DLosc

1

Javascript 101 byte

pendekatan yang berbeda dari solusi js yang diposting di sini

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

Penjelasan:

Coba di sini.

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.