#lang racket ;; File: rdm.rkt ;; Date: Oct 25, 2010 ;; Author: Collin J. Doering =0] -> int[>=0] ;; Purpose: returns the factorial of the given positive (or zero) integer ;; Examples/Tests: (define (factorial n) (define (factorial-helper n acc) (cond [(<= n 1) acc] [else (factorial-helper (- n 1) (* acc n))])) (if (integer? n) (factorial-helper n 1) (error "Expects argument to be an integer!"))) ;; factorial function written using pattern matching (define (factorial1 n) (define/match (fac i acc) [(0 _) acc] [(n _) (fac (- n 1) (* n acc))]) (fac n 1)) (define factorial! (letrec ([fact-helper (lambda (n acc) (if (<= n 1) acc (fact-helper (- n 1) (* acc n))))] [fact! (lambda (n) (fact-helper n 1))]) fact!)) (define (factorial-close [n 0]) (letrec ([acc 1] [x 1] [fac-c (lambda () (cond [(> x n) (set! n (+ n 1)) acc] [else (set! acc (* x acc)) (set! x (+ x 1)) (fac-c)]))]) fac-c)) (define (sum-digits n [base 10]) (letrec ([sum-digits-helper (lambda (n acc) (cond [(zero? (floor (/ n base))) (+ acc (remainder n base))] [else (sum-digits-helper (floor (/ n base)) (+ acc (remainder n base)))]))]) (sum-digits-helper n 0))) ;; fibinocci sequences ;; Very slow...big-O anaylsis of O(2^n) (not 100% sure tho) (define (fib n) (cond [(<= n 0) 0] [(= n 1) 1] [else (+ (fib (- n 1)) (fib (- n 2)))])) ;; fibinocci sequence...but implemented smart ;) haven't looked at the big-O analysis yet (define (fast-fib n) (letrec ([fib-lst empty] [gen-fib (lambda (n x) (cond [(> x n) (first fib-lst)] [(= x 0) (set! fib-lst (cons 0 empty)) (gen-fib n (+ x 1))] [(= x 1) (set! fib-lst (cons 1 fib-lst)) (gen-fib n (+ x 1))] [else (let ([fibx (+ (first fib-lst) (second fib-lst))]) (set! fib-lst (cons fibx fib-lst)) (gen-fib n (+ x 1)))]))]) (gen-fib n 0))) ;; another fibinocci sequence function but with significantly improved memory performance :D (TODO: big-O analysis) (define (fast-mem-fib n) (letrec ([fib-dot-lst empty] [gen-fib (lambda (n x) (cond [(> x n) (car fib-dot-lst)] [(= x 0) (set! fib-dot-lst (cons 0 empty)) (gen-fib n (+ x 1))] [(= x 1) (set! fib-dot-lst (cons 1 0)) (gen-fib n (+ x 1))] [else (let* ([fst (car fib-dot-lst)] [scd (cdr fib-dot-lst)] [fibx (+ fst scd)]) (set! fib-dot-lst (cons fibx fst)) (gen-fib n (+ x 1)))]))]) (gen-fib n 0))) ;; fibinocci closure..pretty much the same as fast-mem-fib but returns a gen-fib like function that takes ;; no paramters but instead encapsulates the values for n and x thus creating a fibinocci closure starting at n (define (fibc [n 0]) (letrec ([fib-dot-lst empty] [x 0] [gen-fib-c (lambda () (cond [(> x n) (set! n (+ n 1)) (car fib-dot-lst)] [(= x 0) (set! fib-dot-lst (cons 0 empty)) (set! x (+ x 1)) (gen-fib-c)] [(= x 1) (set! fib-dot-lst (cons 1 0)) (set! x (+ x 1)) (gen-fib-c)] [else (let* ([fst (car fib-dot-lst)] [scd (cdr fib-dot-lst)] [fibx (+ fst scd)]) (set! fib-dot-lst (cons fibx fst)) (set! x (+ x 1)) (gen-fib-c))]))]) gen-fib-c)) ;; pow num num -> num ;; Purpose: given two real numbers x and n returns x^n ;; Examples/Tests: (define (pow x n) (define (pow-helper x n acc) (cond [(= n 0) acc] [(> n 0) (pow-helper x (- n 1) (* acc x))] [(< n 0) (pow-helper x (+ n 1) (* acc (/ 1 x)))])) (pow-helper x n 1)) ;; Expandtion of the below macro: ;; (define (natural-number? n) ;; (if (and (interger? n) (>= n 0) #t #f))) (define natural-number? (lambda (n) (if (and (integer? n) (>= n 0)) #t #f))) (define average-num (lambda lst (/ (apply + lst) (length lst)))) (define (average-list lst) (define (sum-list lst acc) (cond [(empty? lst) acc] [else (sum-list (rest lst) (+ acc (first lst)))])) (/ (sum-list lst 0) (length lst))) ;; increasing common interval (define (icd-interval i j d) (define (icd-interval-helper i j d acc) (cond [(> i j) acc] [else (icd-interval-helper (+ i d) j d (cons i acc))])) (if (> i j) (error "i > j for a increasing common interval list to be generated!") (reverse (icd-interval-helper i j d empty)))) ;; interval num num -> listof(num) ;; Purpose: Given two (define (interval i j) (define (interval-helper i j acc) (cond [(> i j) acc] [else (interval-helper (+ i 1) j (cons i acc))])) (reverse (interval-helper i j empty))) (define (repeat f n) (define (rep i acc) (cond [(<= i 0) acc] [else (rep (- i 1) (cons (f) acc))])) (rep n '())) ;; common poduct interval (define (cp-interval i j m) (map (lambda (x) (if (= x 0) x (* m x))) (interval i j))) ;; letrec is cool :P ;; (letrec [(fact! (lambda (n) (if (<= n 1) 1 (* n (fact! (- n 1))))))] ;; (fact! 5)) ;; take a looksi at racket/tcp and racket/ssl (define (client) (let-values ([(s-in s-out) (tcp-connect "localhost" 1342)]) (let ([read-and-display (lambda (in-port) (let ([responce (read in-port)]) (display responce) (newline)))]) (read-and-display s-in) (write (read-line (current-input-port) 'return-linefeed) s-out) (close-output-port s-out) (read-and-display s-in) (close-input-port s-in)))) ;; server (define listener (tcp-listen 1342)) (let echo-server () (define-values (in out) (tcp-accept listener)) (thread (lambda () (copy-port in out) (close-output-port out))) (echo-server)) ;; server (Version 2) (define listener (tcp-listen 1342)) (define (server) (let-values ([(in out) (tcp-accept listener)]) (thread (lambda () (copy-port in out) (close-output-port out)))) (server)) (define (read-it-all f-in [acc ""]) (let ([line (read-line f-in)]) (if (eof-object? line) (begin acc (close-input-port f-in)) (read-it-all f-in (string-append acc line "\n"))))) ;; takes a lowercase char and returns it shifted by 13 characters (define (rot-char char) (cond [(or (char-symbolic? char) (char-numeric? char) (char-whitespace? char)) char] [(< (char->integer char) 109) (integer->char (modulo (+ (char->integer char) 13) 122))] [else (integer->char (+ 96 (modulo (+ (char->integer char) 13) 122)))])) (define (rot13 str) (letrec ([rot13-helper (lambda (lst acc) (cond [(empty? lst) acc] [(char-upper-case? (first lst)) (rot13-helper (rest lst) (cons (char-upcase (rot-char (char-downcase (first lst)))) acc))] [else (rot13-helper (rest lst) (cons (rot-char (first lst)) acc))]))]) (list->string (reverse (rot13-helper (string->list str) empty))))) ;; a much better written rot13 which takes advantage of testing intervals (define (best-rot13 str) (letrec ;; add-to-char char int -> char ;; Purpose: takes the unicode value of the given char and adds n evauluating to the char the additions represents ([add-to-char (lambda (char n) (integer->char (+ n (char->integer char))))] ;; best-rot listof(char) (or listof(char) acc) -> listof(char) ;; Purpose: Given a list of characters returns the rot13 representation [best-rot (lambda (lst acc) (cond [(empty? lst) acc] [(<= 65 (char->integer (first lst)) 77) (best-rot (rest lst) (cons (add-to-char (first lst) 13) acc))] [(<= 78 (char->integer (first lst)) 90) (best-rot (rest lst) (cons (add-to-char (first lst) -13) acc))] [(<= 97 (char->integer (first lst)) 109) (best-rot (rest lst) (cons (add-to-char (first lst) 13) acc))] [(<= 110 (char->integer (first lst)) 122) (best-rot (rest lst) (cons (add-to-char (first lst) -13) acc))] [else (best-rot (rest lst) (cons (first lst) acc))]))]) (list->string (reverse (best-rot (string->list str) empty))))) ;; map defined in terms of foldr (define (foldr-map fn lst) (foldr (lambda (x y) (cons (fn x) y)) empty lst)) (define (foldr-copy lst) (foldr cons empty lst)) (define (compose fn1 fn2) (lambda (x) (fn1 (fn2 x)))) (define (foldr-append lst1 lst2) (foldr cons lst2 lst1)) (define (foldr-length lst) (foldr (lambda (x y) (+ y 1)) 0 lst)) (define (foldr-sum lst) (foldr + 0 lst)) ;; broken..needs to know the number of digits of the number n (define (nth-digit n i) (let ([f (/ n (expt 10 (+ i 1)))]) (floor (* 10 (- f (floor f)))))) (define (random-list n) (define (randlst i acc) (cond [(<= i 0) acc] [else (randlst (sub1 i) (cons (random n) acc))])) (randlst n '())) (define (append-all a b) (cond [(and (list? a) (list? b)) (append a b)] [(list? a) (append a (list b))] [(list? b) (cons a b)] [else (list a b)])) (define (my-append xs ys) (cond [(empty? xs) ys] [else (cons (first xs) (my-append (rest xs) ys))])) (define (my-append2 xs ys) (define (my-append2-h sx acc) (cond [(empty? sx) acc] [else (my-append2-h (rest sx) (cons (first sx) acc))])) (my-append2-h (reverse xs) ys)) (define (my-append3 xs ys) (foldr cons ys xs)) ;; TODO: do the big-oh analysis of the flatten functions below (define (my-flatten xs) (cond [(empty? xs) '()] [(list? (first xs)) (append (my-flatten (first xs)) (my-flatten (rest xs)))] [else (cons (first xs) (my-flatten (rest xs)))])) (define (my-flatten2 xs) (define (my-flatten2-h xs acc) (cond [(empty? xs) acc] [(list? (first xs)) (my-flatten2-h (rest xs) (append (my-flatten2-h (first xs) '()) acc))] [else (my-flatten2-h (rest xs) (cons (first xs) acc))])) (reverse (my-flatten2-h xs '()))) (define (rpn-calc xs) (define (symbol->operator s) (cond [(eq? s '+) +] [(eq? s '-) -] [(eq? s '*) *] [(eq? s '/) /])) (define (symbol-urinary-op? s) (cond [(eq? s '!) #t] [else #f])) (define (symbol-urinary->op s) (cond [(eq? s '!) (lambda (n) (foldr * 1 (if (>= n 0) (range 1 (+ n 1)) (range n 0))))])) (define/match (rpn ys acc) [('() (cons a '())) a] [('() _) (error "Not a valid RPN expression")] [((cons y ys) acc) #:when (number? y) (rpn ys (cons y acc))] [((cons y ys) (cons a acc)) #:when (symbol-urinary-op? y) (rpn ys (cons ((symbol-urinary->op y) a) acc))] [((cons y ys) (cons a1 (cons a2 acc))) #:when (symbol? y) (rpn ys (cons ((symbol->operator y) a2 a1) acc))]) (rpn xs '()))