Kurzusok
/
Common Lisp
Common Lisp
/
Feladatok
/
Az összehasonlítás kulcsa
Az összehasonlítás kulcsa

Az összehasonlítás kulcsa

Tanulófeladat

Bevezetés

Egyenlőség

A Common Lispben sokféle egyenlőségpredikátum van. Ez eltér más programozási nyelvektől, amelyekben csak egy vagy kettő lehet (például == és ===). Ezek közül néhány predikátum típusspecifikus, míg mások generikusak. Itt az utóbbiakról lesz szó.

Négy generikus egyenlőségpredikátum létezik, és abban térnek el egymástól, hogy mennyire szigorúan veszik, mi számít „egyenlőnek”. A legszigorúbbtól a legmegengedőbbig: eq, eql, equal és equalp.

Íme egy gyors meghatározás-sorozat (néhány részlettől eltekintve):

  • eq: az egyenlőség jelentése: a két objektum azonos. pl.:
(eq 'a 'a)                 ; => T
(eq (list 1 2) (list 1 2)) ; => NIL
  • eql: az egyenlőség jelentése: két szám, ha ugyanaz a típusuk és az értékük; két karakter, ha ugyanazok; minden más esetben pedig, ha eq. pl.:
(eql 1 1)     ; => T
(eql #\a #\a) ; => T
(eql 1 1.0)   ; => NIL
(eql #\a #\A) ; => NIL
  • equal: az egyenlőség jelentése: két lista akkor equal, ha minden elemük is equal; két string akkor equal, ha minden elemük eql; két tömb akkor equal, ha eq; minden más pedig akkor equal, ha eql. pl.:
(equal (list 1 2) (list 1 2)) ; => T
(equal #(1 2) #(1 2))         ; => NIL
(equal "foo" "foo")           ; => T
  • equalp: az egyenlőség jelentése: a stringeket és a karaktereket kis- és nagybetű megkülönböztetése nélkül hasonlítja össze; a számokat bizonyos típuskonverzióval hasonlítja össze; a listák és a tömbök akkor equalp, ha minden elemük is equalp, a struktúrák akkor, ha ugyanolyan típusúak, és minden slotjuk equalp, a hash-táblák pedig akkor, ha a kulcsaik és az értékeik equalp pl.:
(equalp "foo" "FoO")                          ; => T
(equalp 3 3.0)                                ; => T
(equalp (make-a-structure :slot1 1 :slot2 2) 
        (make-a-structure :slot1 1 :slot2 2)) ; => T

Utasítások

Leslie, a Lisp-űrlakó épp a labirintusrobotját programozza (ahogy a fiatal Lisp-űrlakók azt szokták), és egy kis segítségre van szüksége. A labirintus szobák sorából áll. Minden szobában több ajtó közül lehet választani. Minden ajtóhoz kulcs kell. Ha rossz kulcsot használsz egy ajtónál, az valószínűleg felrobban (ne aggódj a robot miatt, nem sérül meg, de a pörkölésnyomok eltüntetése elég idegesítő Leslie-nek). Ha a robotnak nincs olyan kulcsa, amelyik bármelyik ajtót kinyitja, akkor az egész szoba felrobban! (Megint csak: ne aggódj, nem lesz kár, de idegesítő lesz takarítani.)

Amiben segítened kell Leslie-nek: add meg a robotnak a helyes kulcsot minden szobához. A robot sorban használja a kulcsot a szoba minden ajtaján, és az első kinyíló ajtón megy át.

Minden teszt egy labirintust képvisel, és minden állítás egy szoba. Olyan predikátumfüggvényeket kell írnod, amelyek T értéket adnak, ha az argumentumok egyenlők, és NIL értéket, ha nem.

1. Az objektumegyenlőség labirintusa

Ennek a labirintusnak csak egyetlen szobája van. Olyan függvényt kell adnod, amely meg tudja mondani, hogy két objektum ugyanaz az objektum-e.

Például:

a                         ; => "pizza"
b                         ; => "pizza"

(key-object-identity a a) ; => T
(key-object-identity a b) ; => NIL

mert bár a és b ugyanolyannak tűnik, nem ugyanaz az objektum.

2. A számok labirintusa

Ennek a labirintusnak két szobája van. Az elsőben van egy ajtó, amely kinyílik, ha a kulcsod meg tudja mondani, hogy két szám szigorúan egyenlő-e egymással. A második szobához olyan kulcs kell, amely némi rugalmasságot enged meg az egyenlő számok ellenőrzésében.

Például:

a                                    ; => 13
b                                    ; => 13.0
c                                    ; => 13

(key-numbers a b)                    ; => NIL
(key-numbers a c)                    ; => T
(key-numbers-of-different-types a b) ; => T

mert bár a és b numerikusan ugyanaz, különböző típusúak.

3. A karakterek labirintusa

Ennek a labirintusnak két szobája van. Az elsőben van egy ajtó, amely kinyílik, ha a kulcsod meg tudja mondani, hogy két karakter szigorúan egyenlő-e egymással. A második szobához olyan kulcs kell, amely lehetővé teszi a karakterek kis- és nagybetűtől független összehasonlítását.

Például:

a                                       ; => #\X
b                                       ; => #\x
c                                       ; => #\X

(key-characters a b)                    ; => NIL
(key-characters a c)                    ; => T
(key-characters-case-insensitively a b) ; => T

mert csak a nagyon megengedő egyenlőségpredikátumok hagyják figyelmen kívül a kis- és nagybetűket két karakter összehasonlításakor.

4. A stringek labirintusa

A karakterek labirintusához hasonlóan az első szobához olyan kulcs kell, amely ellenőrzi, hogy két string egyenlő-e; a második szobához olyan kulcs, amely lehetővé teszi a kis- és nagybetűtől független összehasonlítást.

Például:

a                                    ; => "pizza"
b                                    ; => "PIZZA"
c                                    ; => "pizza"

(key-strings a b)                    ; => NIL
(key-strings a c)                    ; => T
(key-strings-case-insensitively a b) ; => T

mert csak a nagyon megengedő egyenlőségpredikátumok hagyják figyelmen kívül a kis- és nagybetűket két string összehasonlításakor.

5. A consok labirintusa

Ez egy nagy labirintus, sok szobával. Minden szobához olyan kulcs kell, amely ellenőrzi, hogy a consok tartalmazzák-e azokat a dolgokat, amelyek egyenlők. Minden szoba a különböző tartalmú consok egyenlőségét ellenőrzi: szimbólumokét, számokét, karakterekét, és néhányukhoz rugalmasabb egyenlőségdefiníciókra lesz szükség ezekhez a tartalmakhoz.

Például:

syms-a                                     ; => (left . right)
syms-b                                     ; => (up . down)
syms-c                                     ; => (left . right)
chars-a                                    ; => (#\x . #\y)
chars-b                                    ; => (#\x . #\Y)
chars-c                                    ; => (#\x . #\y)
nums-a                                     ; => (13 . 23)
nums-b                                     ; => (13 . 23.0)
nums-c                                     ; => (13 . 23)


(key-conses-of-symbols syms-a syms-b)      ; => NIL
(key-conses-of-symbols syms-a syms-c)      ; => T

(key-conses-of-characters chars-a chars-b) ; => NIL
(key-conses-of-characters chars-a chars-c) ; => T
(key-conses-of-characters-case-insensitively 
  chars-a chars-b)                         ; => T

(key-conses-of-numbers nums-a nums-b)      ; => NIL
(key-conses-of-numbers nums-a nums-c)      ; => T
(key-conses-of-numbers-of-different-types 
  nums-a nums-b)                           ; => T

mert még egy olyan egyenlőségpredikátum is, amely belenéz egy consba, lehet, hogy nem elég megengedő ahhoz, hogy figyelmen kívül hagyja a kis- és nagybetűket vagy a numerikus típust összehasonlításkor.

6. A tömbök labirintusa

Ez a labirintus egyszerűbb, csak két szobája van. Az elsőhöz olyan kulcs kell, amely ellenőrzi, hogy a tömbök ugyanazok-e a tömbök. A másodikhoz olyan kulcs kell, amely a tömbök tartalmát ellenőrzi.

Például:

a                        ; => #[13 23]
b                        ; => #[13 23]
c                        ; => #[13 23.0]

(key-arrays a b)         ; => NIL
(key-arrays a c)         ; => NIL
(key-arrays-loosely a b) ; => T
(key-arrays-loosely a c) ; => T

mert csak a nagyon megengedő egyenlőségellenőrzők ellenőrzik, hogy a tömb tartalma egyenlő-e.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Common Lisp Exercism

Készen állsz elkezdeni a(z) Az összehasonlítás kulcsa feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Common Lisp nyelvet 27 fogalom92 feladat segítségével, valódi emberi mentorálással, mindez ingyen.