Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Scheme Xor

Name: Anonymous 2012-09-14 15:09

So in my intro to computer science class with SICP scheme, we have to write an xor function. Is there a simpler way to do this than what I have (I only used and, or, and equal)

(define (xor2 a b)
        (if (or a b)
            (if (and a b)
                        #f
                        #t)
            #f))

(define (xor3 a b c)
        (if (and a b c)
                #t
                (if (or a b c)
                        (if (and a b)
                                (xor2 a b)
                                (if (and a c)
                                        (xor2 a c)
                                        (if (and b c)
                                                (xor2 b c)
                                                #t)))
                        #f)))
(define (xor4 a b c d)
        (if (or a b c d)
            (if (and a b c d)
                #f
                (if (or a b c)
                    (if (equal? a #f)
                        (xor3 b c d)
                        (if (equal? b #f)
                            (xor3 a c d)
                            (if (equal? c #f)
                                (xor3 a b d)
                                (xor3 a b c))))))
            #f))

This works, but is there a way to simplify it, and maybe generalize it to n elements?

Name: Anonymous 2012-09-14 15:25

an xor

Name: Anonymous 2012-09-14 15:49

>>2
An exclusive or?

Name: Anonymous 2012-09-14 15:53

>>3
Yes. Also, before I posted this I hadn't really looked into the function beyond its definition. I can see that I could probably make it simpler by just repetitively using the two input thing instead of redefining the next in terms of the previous one (which I suppose ends up being a repetition of the 2 input anyways).

Name: Anonymous 2012-09-14 15:57

(define-syntax xor
  (syntax-rules ()
    ((_)
     #f)
    ((_ #f e ...)
     (xor e ...))
    ((_ #t e ...)
     (not (xor e ...)))))

Name: Anonymous 2012-09-14 16:03

Fixed version:
(define-syntax xor
  (syntax-rules ()
    ((_)
     #f)
    ((_ #f e ...)
     (xor e ...))
    ((_ _ e ...)
     (not (or e ...)))))

Name: Anonymous 2012-09-14 16:31

CLISP:


(defmacro xor (n p)
   `(if (and ,n ,p)
      nil
      (or ,n ,p)))

Name: Anonymous 2012-09-14 16:36

>>7
DIRTY! DIRTY MACRO! YOU WILL DIE OF CHOLERA!

Name: Anonymous 2012-09-14 16:58

(define (xor a b)
  (not (equal? (or a b) (and a b))))

Name: Anonymous 2012-09-14 17:39

If it really has to be a function, you can use a fold to generalize the 2-argument function to n arguments, like this:

(define (xor2 p q)
  (and (or p q)
       (not (and p q))))

(define (foldr f z xs)
  (if (null? xs)
      z
      (f (car xs)
         (foldr f z (cdr xs)))))

(define (xor . xs)
  (foldr xor2 #f xs))


The catch it this doesn't support short-circuiting, while a macro (as in >>6) does. If you haven't learned about folds yet, maybe this is more clear:

(define (xor . xs)
  (if (null? xs)
      #f
      (xor2 (car xs)
            (apply xor (cdr xs)))))


Or if you're feeling funky, just count the number of #ts in the list:

(define (xor . xs)
  (odd? (apply + (map (lambda (x) (if x 1 0)) xs))))

Name: Anonymous 2012-09-14 20:27

(define (xor a b)
  (or (and a (not b))
      (and (not a) b)))

Name: Anonymous 2012-09-14 22:45

(define (xor . xs)
  (odd? (count (compose not not) xs)))

Name: Anonymous 2012-09-15 4:00

Boing.

(define (xor a b)
  (and (or a b) (not (and a b))))

Name: Anonymous 2012-09-15 8:12

>>8
You know what the best thing is about lisp macros?

the smell

Name: Anonymous 2012-09-15 9:39

(define (xor a b)
    (not
        (or (and a b) (and (not a) (not b))))

Check for failure then invert it. There are only 2 possible failure conditions, so this is much easier and can be generalised.

Name: Anonymous 2012-09-15 12:06

We are all noobs.

(define (xor a b)
  (eqv? a (not b)))

Name: Anonymous 2012-09-15 14:11

>>16
fails if b is #f and a is not a boolean.

Name: Anonymous 2012-09-15 16:43

> (or 1 #f)
1

Name: Anonymous 2012-09-15 16:50


#!r6rs
(import (rnrs (6)))

(define (xor a b)
  (if (and (boolean? a)
           (boolean? b))
    (not (eq? a b))
    (raise '(a or b is not a boolean value))))

Name: Anonymous 2012-09-15 17:22

>>19 here, scratch that, this version is more feature-complete, better looking and accepts a shitton of parameters:

#lang racket

(define xor
  (lambda bools
   
    (define (xor-helper res lst)
      (if (null? lst)
          res
          (xor-helper (not (eq? res (car lst)))
                      (cdr lst))))
   
    (if (foldl (lambda (a res)
                 (and res (boolean? a)))
               #t
               bools)
        (xor-helper (car bools)
                    (cdr bools))
        (raise `(xor -- Non-boolean elements in parameters: ,bools)))))



R6RS needs some fucking fuck shit SRFI to use fucking fold. So I used Racket instead.

Name: Anonymous 2012-09-15 18:35

>>20
I guess I'm tired... how did I NOT notice that I can replace the helper with just a fold?

#lang racket

(define xor
  (lambda bools
    (display bools)
    (if (foldl (lambda (a res)
                 (and res (boolean? a)))
               #t
               bools)
        (foldl (lambda (b res)
                 (not (eq? res b)))
               (car bools)
               (cdr bools))
        (raise `(xor -- Non-boolean elements in parameters: ,bools)))))

Name: Anonymous 2012-09-15 18:36

>>21
Also disregard the (display bools) part, I put that in for quick debugging.

Name: Anonymous 2012-09-15 20:52

;__;

disregard my anus

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List