Reputation: 53
What I'm currently trying to do is have two sets of integers in a text file be used as parameters for executing a function that calculates the symmetric difference of two sets. The format of the text file is that on first line, there is a set of numbers each separated by a space and on the second line, there is another set of different numbers that's separated by spaces. For example:
1 2 3 4
5 6 1 2
I have successfully implemented a function that is able to read the file and a function that is able to calculate the symmetric difference of two sets, that takes as input of two lists that's interpreted as sets:
function that reads the file:
(define in
(lambda ()
(let ((pin(open-input-file (symbol->string (read)))))
(let g ((x(testchar pin)))
(if (eof-object? x)
(begin
(close-input-port pin)
'())
(write x))
))))
and
function that calculates the symmetric difference:
(define Sym-Dif
(lambda (L1 L2)
(cond ((null? L1) L2)
((union (intersection L1 L2) (intersection L2 L1))))))
In order to use the values from the file, I tried to implement a helper function that examines each characters from the text file such that when it hits the newline character, it recursively builds the first list and when it hits the end of file character, it recursively builds the second list:
helper function:
(define testchar
(lambda(x)
(let f()
(let ((c(read-char x)))
(cond
((eof-object? c) '())
((equal? c #\newline) (begin (list c) (testchar x)))
((char? c) (begin (append c)(write c)(testchar x))))))))
but when running the helper function with function that reads the file, I'm getting #\1#\space#\2#\space#\3#\space#\4#\5#\space#\6#\space#\1#space#\2()
How can I make the helper function to return lists instead of characters?
Any help would be greatly appreciated. P.s I am using Dr. Racket for this.
Upvotes: 1
Views: 407
Reputation: 9865
"test.txt" contains two lines:
1 2 3 4
5 6 1 2
As sets
How about using the built-in module racket/set
?
(require racket/set)
(define (lines->sets filepath)
(let* ((lines (file->lines filepath))
(lists (map (lambda (s) (string-split s " ")) lines)))
(values (list->set (list-ref lists 0)) (list->set (list-ref lists 1)))))
(define-values (set1 set2) (lines->sets "test.txt"))
(set-symmetric-difference set1 set2)
The problem of your code is, it calculates the intersection (union of two intersections) instead of the real symmetric difference (union of differences).
output:
(set "6" "3" "5" "4")
But if you want to have it as lists and not sets:
As lists
(define (lines->lists filepath)
(let* ((lines (file->lines filepath))
(lists (map (lambda (s) (string-split s " ")) lines)))
(values (list-ref lists 0) (list-ref lists 1))))
(define-values (list1 list2) (lines->lists "test.txt"))
;; translated from CL code in http://www.lee-mac.com/listsymdifference.html
(define (list-symmetric-difference l1 l2)
(append
(filter-not (lambda (x) (member x l2)) l1)
(filter-not (lambda (x) (member x l1)) l2)))
(list-symmetric-difference list1 list2)
output:
'("3" "4" "5" "6")
Upvotes: 1