Nemrég kriz kérte, hogy csináljak egy olyan cikket is, ahol C++, Prolog, SML összehasonlítások vannak :) Nos most hirtelen egy jut eszembe, nálunk volt zh példa. Van egy bemenő listánk és ebből kell kiszűrni az első pithagoraszi számhármast.
% Prolog % A léptetés miatt kétszer adom át a listát, egyéb segéd- % függvényekkel lehet máshogy is de beépített függvények % nincsenek, csak tanítanak néhány alapot, de ezekre most % nem térnék ki, és nem is alkalmazok. pith(L,P):- getpith(L,L,P). % Gyorsan leírom a listákat hogy tiszta legyen, alapvetően % kétféleképpen lehet listákat leírni, az első: [A,B], ez % egy két elemű lista, ami tulajdonképpen 3 elemű. Na ezt % adjátok össze :) szóval, az első, tehát az A az mindig az % első elem, a B pedig egy másik kételemű lista, aminek első % eleme a B, a második eleme pedig a [], tehát az üres lista. % A második típus a listáknál a [A|B] kinézetű, ez annyit % tesz, hogy A a lista első eleme, B pedig az utána lévő % összes többi. pl. ha ezt adjuk rá: [1,2,3,4,5] vagyis egy % 5 elemű listát akkor az A = 1, és a B = [2,3,4,5] vagyis % 4 elemű lista. Ezen kívül még egy elem látható, a '_', % ez minden karakter lehet, tehát ez egy olyan, amit % figyelmen kívül hagyunk. Ennyit a listák bevezetéséről :) % A két listát máshogy dolgozom fel, az A,B,C a lista első % három eleme mindig. A második lista az első elemen kívül % mindent tartalmaz, tehát a léptetést szolgálja a mi % esetünkben, de mint említettem erre már vannak kifinomultabb % technikák is, de beépített függvény nincs. Ezen felül a P % a visszatérési érték. A ZH-ban egy struktúraként kellett % visszaadni a megtalált számhármast, ezért most egy kicsit % a struktúrákról is: A struktúrák abban különböznek a % függvényektől, hogy nincs testük, tehát pl. p(A,B,C). % Függvénynév, argumentumok, és egy '.' :) % Még egy új elem, amit eddigi prolog tudásotok még nem % tartalmaz, hogy prologban az if-then-else így néz ki: % ( feltétel -> igaz ág ; hamis ág ) getpith([A,B,C|_],[_|D],P):- % függvény kezdete ( % feltétel kezdete A > 0 , % A,B,C > 0 B > 0 , C > 0 , A < B , % A < B < C B < C , X is A*A+B*B, % A*A+B*B=C*C - vizsgálat Y is C*C, % előtt a kiértékelődés X = Y % miatt két változót használok -> % igaz ág P = p(A,B,C) % a 3 szám p struktúrában ; % hamis ág getpith(D,D,P) % a következő 3 elem vizsgálata ) % if-then-else vége . % függvény vége % Tömörebben: getpith([A,B,C|_],[_|D],P):- (A>0,B>0,C>0,A<B,B<C,X is A*A+B*B,Y is C*C,X=Y->P=p(A,B,C);getpith(D,D,P)). % Használat: % pith([1,3,5,3,7,24,25,8,7],P). % Várt eredmény: % P = p(7,24,25)
SML-ben most hirtelen nem is tudom van-e comment, nem rémlik, hogy láttam volna, úgyhogy inkább ide írom, a hozzászólásokat :) Tehát SMLben máshogy működnek a listák, egy kicsit ezekről: a listák formailag ugyanolyanok, de a függvényekben másként lehet szétszedni őket, amint látható. Most n1 az első elem, n2 a második, n3 a harmadik, ns pedig az összes többi. Az operátor ami ezek között van op:: egy listába fűzi össze a tagokat, így a léptetés is jóval egyszerűbb, ahogy az else ágnál is látszik; szándékosan nem szedtem szét több sorba, mivel lényegében ugyanaz, mint a prolognál. A további különbségek, hogy itt normális if-then-else szerkezet van, csak ugye még a then-t is ki kell írni :) illetve az andalso a sima 'és' kapcsolatot hivatott jelképezni, and-jellel nem megy a dolog, próbáltam kettővel és hárommal is :D igazából hárommal jó lenne, csak akkor más formában kéne, de erről most nem beszélnék, így egyszerűbb. A prologgal ellentétben itt egy listát adunk vissza, mivel nincs olyan struktúra, mint prologban, és ide nem is kell külön X, és Y a másodfokú egyenlethez, mivel az '='-nél kiértékelődik a két oldal :) Még két újdonság lehet, a függvény végén a '| pith _ = []', ami azt jelenti, hogyha a legelső argumentumra nem illeszkedik a bemenet, akkor egy üres lista lesz az eredmény. Tehát ha n1::n2::n3::ns -re nem négyelemű lista jön, ami lehet 3 érték és egy üres elem, akkor átugrik a másik lehetőségre pith _ -ra, ahol a _ a prologhoz hasonlóan a bármit jelenti. Erről azt hiszem eleget is beszéltem. Aztán pedig a függvényhívást így is el lehet végezni, kicsit rövidebben, mint az SML bevezetőben írtam, tehát nem kell 'val x =' az elejére, ilyenkor azt kapjuk, hogy az 'it'-nek az eredménye amit kaptunk, magyarán, "valami pont annyi amennyi a függvény értéke" :D Az utolsó sor végén pedig láthatjuk hogy ez egy int lista.
fun pith(n1::n2::n3::ns) = ( if n1 > 0 andalso n2 > 0 andalso n3 > 0 andalso n1 < n2 andalso n2 < n3 andalso n1*n1+n2*n2=n3*n3 then [n1,n2,n3] else pith(n2::n3::ns)) | pith _ = []; > val pith = fn : int list -> int list pith([1,3,5,3,7,24,25,8,7]); > val it = [7, 24, 25] : int list
/* C++ megvalósítás */
/* Ennek a működését remélem nem kell ecsetelnem :) próbáltam
Prologhoz hasonlóan struktúrában visszaadni a pith()
visszatérési értékét, azt hiszem eléggé jól látható,
hogy mi is a prolog és sml pozitívuma cpp-vel ellentétben :)
azt hiszem a listakezelésük egy csöppet veri a cpp-ét,
legalábbis rövidségben, és hatékonyságban :) */
#include <iostream>
using namespace std;
struct p { int a,b,c; };
p pith(int a, int b, int c) {
p tmp;
tmp.a=0;
tmp.b=0;
tmp.c=0;
if(a>0&&b>0&&c>0&&a<b&&b<c&&(a*a+b*b==c*c)) {
tmp.a=a;
tmp.b=b;
tmp.c=c;
}
return tmp;
}
int main() {
int listaelemek[8];
listaelemek[0]=1;
listaelemek[1]=3;
listaelemek[2]=5;
listaelemek[3]=3;
listaelemek[4]=7;
listaelemek[5]=24;
listaelemek[6]=25;
listaelemek[7]=8;
p tmp;
for(int i=0;listaelemek[i+2]!=0;i++) {
tmp=pith(listaelemek[i],listaelemek[i+1],listaelemek[i+2]);
if(tmp.a!=0) {
cout << "p(" << tmp.a << ",";
cout << tmp.b << "," << tmp.c << ")";
break;
}
}
return 0;
}
Ezt az írást követte el 20:11-kor. Kommentelj! 

Sirályos, bár még mindig lövésem sincs ezekkel a nyelvekkel kapcsolatban, de legalább már látom, hogy tényleg rövidebb... :)