Oceń łańcuch nierówności


17

Napisz kod, aby ocenić, czy łańcuch nierówności jest prawdziwy, czy fałszywy. Przykładowym wejściem jest ciąg

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

Dzieje się tak, ponieważ każdy z jego składników jest prawdziwy:

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

Wejście:

Łańcuch reprezentujący łańcuch jednej lub więcej nierówności. Dozwolone operatory porównania to

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

Dozwolone są numery numery jednocyfrowe 0przez 9. Nie będzie spacji, nawiasów ani innych symboli.

Wynik:

Poprawność nierówności jako spójnej wartości Prawdy lub Falseya . Spójny oznacza, że ​​każdy wynik Prawdy jest taki sam, a każdy wynik Falsey jest taki sam.

Ograniczenie:

Celem tego wyzwania jest napisanie kodu przetwarzającego nierówności, zamiast oceniania ich jako kodu, nawet w przypadku pojedynczej nierówności w łańcuchu. W związku z tym metody takie jak Python evali execoceniające lub wykonujące kod są zakazane. Podobnie są funkcje, które wyszukują metodę lub operator, podając jego nazwę jako ciąg znaków. Niedozwolone jest także uruchamianie procesów lub programów w celu dokonania oceny.

Przypadki testowe:

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

3<=4!=4
False

5>5
False

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

Czy możemy zaakceptować dane wejściowe ze znakami nierówności Unicode, takimi jak ≤ i ≥ zamiast <= i> =?
FUZxxl,

@FUZxxl Nie możesz.
xnor

Odpowiedzi:


7

Rubin, 71 + 1 = 72

Z flagą wiersza polecenia -nuruchom

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

Generuje wszystkie możliwe błędy wyrażeń regularnych i sprawdza, czy łańcuch wejściowy pasuje do któregokolwiek z nich. Wyprowadza, truejeśli nie, inaczej false. Pobiera dane wejściowe przez STDIN, oddzielone znakami nowej linii.

Wydziwianie:

  • Otrzymujemy wszystkie możliwe pary cyfr, zapętlając od 0 do 99 i wyodrębniając cyfry 10s i 1s.
  • Jedynym faktycznym porównaniem, które wykonujemy, jest a<=>bzwrócenie wartości -1,0 lub 1 dla wartości mniejszej, równej lub większej. Wszystkie one dzielą się na różne elementy tablicy trzy łańcuchowej, znajdując wyrażenie regularne dla porównań, które nie pasują.

Co za sprytna strategia!
xnor

6

Perl, 82

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

Wyświetla 1, gdy ma wartość true, a pustą linię, gdy ma wartość false, ponieważ pusty ciąg jest główną wartością falsela Perla.

Pętla while przechodzi przez ciąg pasujący do wyrażenia regularnego \d(.)(=?). Następnie zmienne $1i $2odpowiadają znakom operatora oraz zmienne specjalne $&i $'będą zachowywać się jak dwa operandy w kontekście numerycznym. Operandy są porównywane z <=>wynikiem, a wynik jest porównywany z pierwszym znakiem operatora. W takim przypadku równość i nierówność są traktowane specjalnie.


4

CJam, 60 bajtów

Ten kod wydaje się trochę brzydki i potencjalnie nie w pełni zoptymalizowany, ale jest najlepszy, jaki do tej pory miałem.

Wypróbuj online.

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

Wyjaśnienie

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

Prosto: skanuj ciąg, c to cyfra bieżąca, l to ostatnia cyfra, o to 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)

Przetestuj w konsoli 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 prawda
3 <= 4! = 4 fałsz
5> 5 fałsz
8 == 8 <9> 0! = 2> = 1 prawda


3

Haskell, 156 bajtów

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

Przykład użycia:

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

Wersja bez golfa:

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)

evalpobiera dwa argumenty: ciąg do analizy (rozpoczynający się zawsze od operatora porównania) i liczbę, iktóra jest lewym argumentem do porównania (i był prawym argumentem w poprzedniej rundzie). Operator jest zwracany przez, lookup2jeśli jest to operator dwuznakowy (sprawdź tylko 1. znak, ponieważ 2. jest zawsze =) i lookup1jeśli jest to tylko jeden znak. evalwywołuje się rekurencyjnie i łączy wszystkie zwracane wartości z logicznym i &&.


3

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

Przykład

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

Wyjaśnienie

(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:splitdzieli się na cyfry; na przykład:

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

    Zwróć uwagę na pierwszy pusty ciąg znaków, który jest odrzucany za pomocą cdr

  • Mapowanie read-from-stringdo tej listy wywołuje readfunkcję dla każdego łańcucha, która zwraca symbole i liczby.

  • loop for (a op b) on '(3 < 5 > 2) by #'cddrwykonuje iterację po liście o krok 2, a tym samym wiąże a, opi bnastępująco, dla każdego kolejnego przejścia.

    a  op  b
    ----------
    3  <    5
    5  >    2
    2  nil  nil
    
  • alwayssprawdza, czy następne wyrażenie jest zawsze prawdziwe: operator jest nil(patrz wyżej) lub wynik porównania jest wstrzymany (patrz poniżej).

  • że casewybiera funkcja porównanie Common Lisp, według symbolu wcześniej czytać; ponieważ niektóre operatory są identyczne w Lisp, a dany język możemy po prostu powrócić ow przypadku domyślnym.


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

Pętla jest prostym przejściem przez ciąg po jednym znaku na raz. t&=...Część, gdzie dzieje się magia. Zasadniczo mieszam operator wraz z wartością cmp(lhs,rhs)(-1, 0 lub 1 w zależności od tego, czy lhsjest mniejszy, równy lub większy niż rhs). Wynik jest kluczem do tabeli przeglądowej, która daje 0 lub 1 w zależności od tego, czy liczby są poprawnie porównywane z danym operatorem. Jaki stół przeglądowy pytasz? Jest to liczba 627 = 0001001110011binarnie. Operatorzy bitowi zajmują się resztą.

Działa to na czterech podanych przypadkach testowych; daj mi znać, jeśli znajdziesz błąd w innej sprawie. Nie testowałem tego bardzo rygorystycznie.


Musisz wziąć ajako dane wejściowe.
xnor

@xnor Whoops. Poprawione
DLosc

1

JavaScript 101 bajtów

inne podejście niż zamieszczone tutaj rozwiązanie 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 bajtów

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

Wyjaśnienie:

Wypróbuj tutaj.

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.