Bir eşitsizlik zincirini değerlendirin


17

Bir eşitsizlik zincirinin doğru mu yanlış mı olduğunu değerlendirmek için kod yazın. Örnek bir girdi dizedir

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

Bu doğrudur çünkü bileşenlerinin her biri doğrudur:

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

Giriş:

Bir veya daha fazla eşitsizlik zincirini temsil eden bir dize. İzin verilen karşılaştırma operatörleri

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

Kullanılan sayılar tek basamaklı sayılardır 0yoluyla 9. Boşluk, parantez veya başka simgeler olmayacak.

Çıktı:

Eşitsizliğin tutarlı bir Gerçek veya Falsey değeri olarak doğruluğu . Tutarlı, her Doğruluk çıktısının aynı ve her Falsey çıktısının aynı olduğu anlamına gelir.

Kısıtlama:

Bu zorluğun amacı, zincirdeki tek bir eşitsizlik için bile onları kod olarak değerlendirmek yerine, eşitsizlikleri işleyen kod yazmanızdır. Bu nedenle, Python'lar gibi evalve execkodu değerlendiren veya yürüten yöntemler yasaklanmıştır. Bir yöntem veya operatöre bir dize adı verilen işlevleri arayan işlevler de öyle. Değerlendirmeyi sizin için yapmak için süreçler veya programlar başlatmanıza da izin verilmez.

Test senaryoları:

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

3<=4!=4
False

5>5
False

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

<= Ve> = yerine ico ve ≥ gibi Unicode eşitsizlik işaretleriyle girişi kabul edebilir miyiz?
FUZxxl

@FUZxxl Yapamazsın.
xnor

Yanıtlar:


7

Yakut, 71 + 1 = 72

Komut satırı işaretiyle -nçalıştırın

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

Tüm olası başarısız düzenli ifadeleri oluşturur ve giriş dizesinin bunlardan herhangi biriyle eşleşip eşleşmediğini kontrol eder. trueHiçbiri yoksa çıkış yapar false. Yeni satırlarla ayrılmış STDIN üzerinden girdi alır.

Hileler:

  • Olası tüm basamak çiftlerini 0'dan 99'a döngü yaparak ve 10s ve 1s basamaklarını çıkararak elde ederiz.
  • Yaptığımız tek gerçek karşılaştırma a<=>b, daha küçük, eşit veya daha büyük için -1,0 veya 1 döndürür. Bunların hepsi, eşleşmeyen karşılaştırmalar için normal ifadeyi bularak, üç dize dizisinin farklı öğelerine dilim yapar.

Ne kadar zekice bir strateji!
xnor

6

Perl, 82

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

True dize ana falsey değeri olduğundan, true olduğunda 1 ve false olduğunda boş bir satır yazdırır.

While döngüsü normal ifadeyle eşleşen dizenin üzerinden geçer \d(.)(=?). Daha sonra değişkenler $1ve $2operatörün karakterlerine ve özel değişkenlere karşılık gelir $&ve $'sayısal bir bağlamda iki işlenen gibi davranacaktır. İşlenenler ile karşılaştırılır <=>ve sonuç operatörün ilk karakterine göre eşleştirilir. Sonra eşitlik ve eşitsizlik özel olarak ele alınır.


4

CJam, 60 bayt

Bu kod biraz çirkin ve potansiyel olarak tam olarak optimize edilmemiş gibi görünüyor, ancak şimdiye kadar aldığım en iyisi.

Çevrimiçi deneyin.

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

açıklama

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

Basit: tarama dizesi, c geçerli basamak, l son basamak, o operatör.

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 konsolunda test et

;['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 doğru
3 <= 4! = 4 yanlış
5> 5 yanlış
8 == 8 <9> 0! = 2> = 1 doğru


3

Haskell, 156 bayt

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

Kullanım örneği:

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

Ungolfed sürümü:

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)

evaliki argüman alır: ayrıştırılacak dize (her zaman bir karşılaştırma işleci ile başlar) ve karşılaştırma iiçin sol argüman olan bir sayı (ve önceki turda doğru argüman). İşleç, lookup2iki karakterli bir işleçse (yalnızca 2. karaktere bakın, çünkü her zaman 2. karakterdir =) ve lookup1yalnızca tek bir karakterle döndürülür . evalkendini özyinelemeli olarak çağırır ve tüm dönüş değerlerini mantıksal ve ile birleştirir &&.


3

Yaygın 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)))

Misal

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

açıklama

(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:splitbasamaklara böler; Örneğin:

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

    Kullanılarak atılan ilk boş dizeye dikkat edin cdr

  • read-from-stringBu listeye eşleme , readher dizenin sembol ve sayı döndüren işlevini çağırır .

  • loop for (a op b) on '(3 < 5 > 2) by #'cddrbir adım liste üzerinde dolaşır 2 ve bu şekilde bağlar a, opve başağıdaki gibi, birbirini izleyen her geçiş için.

    a  op  b
    ----------
    3  <    5
    5  >    2
    2  nil  nil
    
  • alwayssonraki ifadenin her zaman doğru olup olmadığını kontrol eder: ya operatör nil(yukarıya bakın) ya da karşılaştırma bekletmesinin sonucu (aşağıya bakın).

  • caseseçer Ortak-Lisp karşılaştırma fonksiyonu, daha önce okuma sembole göre; bazı operatörler Lisp ve verilen dilde aynı oolduğundan, varsayılan durumda geri dönebiliriz .


1

Piton 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

Döngü, bir seferde bir karakter dizeden basit bir geçiştir. t&=...Sihirin parçasıdır. Temel olarak, operatörün değerini cmp(lhs,rhs)(-1, 0 veya 1 lhsdeğerine göre daha az, eşit veya daha büyük olmasına bağlı olarak rhs) eklerim . Sonuç, arama operatörünün verilen sayıları doğru karşılaştırıp karşılaştırmamasına bağlı olarak 0 veya 1 veren bir arama tablosunun anahtarıdır. Ne arama tablosu? 627 sayısı =0001001110011İkili . Bitsel operatörler gerisini halleder.

Bu, verilen dört test vakasında çalışır; başka bir vaka için hata bulursanız bana bildirin. Çok titiz bir şekilde test etmedim.


aGirdi olarak almanız gerekir .
xnor

@xnor Whoops. Düzeltildi.
DLosc

1

Javascript 101 bayt

burada yayınlanan js çözümünden farklı bir yaklaşım

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 bayt

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

Açıklama:

Burada deneyin.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.