Jump to content
actunderdc

Programare functionala [Scheme]

Recommended Posts

Posted

Buna ziua tuturor,

Am un proiect de facut in Scheme dar sunt incepator in acest limbaj, iar la unele chestii nu gasesc raspunsul pe google (cel putin nu suficient de repede). As dori sa mai pun cateva intrebari pe parcurs, daca este cineva care se pricepe bine si poate sa imi dea un raspuns mi-ar fi de mare folos.

Pentru inceput, m-am blocat aici:

Am o lista de liste de caractere:

(define ls '( '(#\c #\d #\d) '(#\a #\c #\s) '(#\d #\s #\k) '(#\c #\b #\a)))

Si am nevoie sa sortez aceasta lista lexicografic (dupa primul caracter din fiecare lista, daca sunt egale dupa al doilea, s.a.m.d).

Outputul ar trebui sa arate (sub forma unei noi liste) :

'('(#\a #\c #\s) '(#\c #\b #\a) '(#\c #\d #\d) '(#\d #\s #\k))

Functia sort nu functioneaza (pentru ca are nevoie ca elementele listei sa fie numere, in cazul meu sunt liste)

Multumesc anticipat!

Posted

Nu stiu programare funtionala pentru ca nu am facut inca la faculta dar cred ca iti pot da o idee. Daca zici ca sort functioneaza doar cu numere ai putea sa transformi caracterele in coduri ascii si apoi sa le sortezi. Dupa sortare faci conversia din codurile ascii inapoi in caractere. Doar o idee, hope it helps.

  • Downvote 1
Posted

Prea multe quoturi. Functia de care a zis M2G. Acum foloseste sort.


(define ls '( (#\c #\d #\d) (#\a #\c #\s) (#\d #\s #\k) (#\c #\b #\a)))

(define convert
(?(x)
(if (null? x)
'()
(append (list (cons (char->integer (first (car x))) (cons (char->integer (second (car x))) (cons (char->integer (third (car x))) '())))) (convert (cdr x))))))


Sau direct asa


(define ls '( (#\c #\d #\d) (#\a #\c #\s) (#\d #\s #\k) (#\c #\b #\a)))
(define maimic
(?(x y)
(if (null? x)
#f
(if (eq? (car x) (car y))
(maimic (cdr x) (cdr y))
(if (char<? (car x) (car y))
#t
#f)))))
(sort ls maimic)

Output:

((#\a #\c #\s) (#\c #\b #\a) (#\c #\d #\d) (#\d #\s #\k))

E la fel ca in java, trebuie sa ii dai argument un comparator.

  • Downvote 1
Posted

In continuare:

(define ls '( (#\c #\d #\d) (#\a #\c #\s) (#\d #\s #\k) (#\c #\b #\a)))

Si imi doresc din aceasta lista de liste sa creez o noua lista care contine doar ultimul element din fiecare lista, adica noua lista sa fie:

'( #\d #\s #\k #\a).

Codul implementat de mine:

(define extract

(lambda (x y)

(define aux1 (car x)) ; extrag prima lista

(define aux2 (reverse aux1)) ; inversez prima lista

(define aux3 (cons (car aux2) y)) ; pun primul elem din lista inversata in y

(if (null? x)

#f

(extract (cdr x) y)) ; reapelez functia pt a trece la urmatoarea lista din lista

#t))

La apelul:

(extract ls '())

primesc eroare: car: expects argument of type <pair>; given ()

Unde gresesc? Observ ca daca comentez if-ul, totul merge ok, deci undeva in recursivitate se buseste ceva :(

Posted

Încearc? s? gânde?ti totul recursiv. Asta e ideea acestei paradigme.



(define ls '( (#\c #\d #\d) (#\a #\c #\s) (#\d #\s #\k) (#\c #\b #\a)))
(define ultimele
(?(x)
(if (null? x) '()
(cons (cddar x) (ultimele (cdr x))))))
(ultimele ls)

> ((#\d) (#\s) (#\k) (#\a))

LE: Acum am vazut ca de fapt iti returneaza o lista de liste. No prob. Mai aplici inca un car cddar-ului. :)

Posted

(define ls '( (#\c #\d #\d) (#\a #\c #\s) (#\d #\s #\k) (#\c #\b #\a)))
(define ultimele
(?(x)
(if (null? x) '()
(cons (car (reverse (car x))) (ultimele (cdr x))))))
(ultimele ls)

Posted

Ma intereseaza daca exista in Scheme o functie care sa imi intoarca indexul unui caracter dintr-un string. (se presupune ca nu se repeta caracterele in string).

De exemplu:

(define s "AbcaeNmR")

Iar functia pos (asa sa o botezam):

(pos s #\B)

sa intoarca 1 sau 2 (depinde daca numerotarea incepe de la 0 sau 1)

Pe net ( MIT Scheme Reference - Strings ) am gasit functia string-find-next-char , dar la un apel :

(string-find-next-char "Adam" #\A)

Primesc eroarea:

reference to undefined identifier: string-find-next-char

Posted


(define aparitii
(?(string caracter)
(if (= 0 (string-length string)) -1337
(if (eq? (car (string->list string)) caracter) 0
(+ 1 (aparitii (list->string (cdr (string->list string))) caracter))))))


> (aparitii "Geosu" #\e)
1
> (aparitii "Geosu" #\g)
-1332
> (aparitii "Geosu" #\G)
0
>

Da numar negativ in caz de nu gaseste. Dac? ai înv??at call/cc î?i pot face s? returneze -1 mereu când nu g?se?te, am zis s? nu complic.

Posted

Acum imi bat capul rau cu o functie care imi da raspuns eronat.

Se da o lista/vector (sa luam '(5 3 2 1)) si un numar (de exemplu 7). Codul C pt ceea ce vreau sa fac este:

result="1"
for i in l:
if n >= l[i]:
n = n - l[i]
result = "1" + result
else
result = "0" + result
return result

In urma evaluarii se obtine : 01011

Acum incerc sa fac acest lucru in Scheme:

(define result "1")
(define fibo_encode
(lambda (x l)
(if (null? l)
result
(if (>= x (car l))
(begin (set! x (- x (car l))) (string-append "1" result) (fibo_encode x (cdr l)))
(begin (string-append "0" result) (fibo_encode x (cdr l)))))))

Si apelez:

(fibo_encode 7 '(5 3 2 1))

Dar la output obtin doar "1". Din cate am observat (null? l) il evalueaza eronat. Ce imi scapa?

Posted


(define fibo_encode_temp
(lambda (x l)
(if (null? l)
""
(if (or (null? l) (>= x (car l)))
(string-append (fibo_encode_temp (- x (car l)) (cdr l)) "1" )
(string-append (fibo_encode_temp x (cdr l)) "0" )))))

(define fibo_encode
(lambda (x l)
(string-append (fibo_encode_temp x l) "1")))

(fibo_encode 7 '(5 3 2 1))

F?r? seturi. :) Chiar sunt curios cum a? putea face recursivitatea aia intr-o singur? func?ie.

Posted

A functionat, multumesc.

Acum am asa. Se da o lista de 0 si 1:


(define l '(0 0 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1))

Si doresc spargerea ei intr-o lista de liste la intalnirea a doua aparitii de "1" consecutiv:

'( (0 0 1 1) (1 0 1 1) (1 0 1 1) (1 0 0 1 1) (1 1) (0 1 0 1 1) (0 1 0 1 1) ( 0 0 0 1 1) (1 1) (0 1 1) (0 0 1 1) (1 0 1 1) )

Iar apoi (eventual si mai putin imporant) ultimul 1 trebuie scos dn fiecare lista) :

'( (0 0 1) (1 0 1) (1 0 1) (1 0 0 1) (1) (0 1 0 1) (0 1 0 1) ( 0 0 0 1) (1) (0 1) (0 0 1) (1 0 1) )

Codul incercat de mine imi scoate doar prima lista, apoi se opreste. Nu stiu cum sa folosesc recursivitatea sa mearga pana la final

(define l '(0 0 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1))

(define q '())

(define break
(lambda (l p)
(if (eq? 1 (* (car l) (cadr l)))
(cons (reverse (cons 1 p)) q)
(begin (cons(car l)p ) (break(cdr l)(cons (car l) p) )
)
)
))

(break l '())

Output:

((0 0 1))

Posted

Rezolvarea


(define l '(0 0 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 0 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1))
(define sparge
(?(list)
(if (or (null? list) (= 1 (length list))) '()
(if (= 0 (* (car list) (cadr list)))
(cons (car list) (sparge (cdr list)))
(append '(1 2) (sparge (cddr list))
)))))

(define dothat
(?(bitisori)
(if (null? bitisori) '()
(append (list (bytes->list (car bitisori))) (dothat (cdr bitisori))))))

(dothat (regexp-split #rx"\2+" (list->bytes (sparge l))))

Output.


((0 0 1) (1 0 1) (1 0 1) (1 0 0 1) (1) (0 1 0 1) (0 1 0 1) (0 0 0 1) (1) (0 1) (0 0 1) (1 0 1) ())

Dac? mai ai întreb?ri, te ajut doar dac? îmi explici problemele la ED. Have a nice day. :)

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...