123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #!/usr/bin/guile \
- -e main -s
- !#
- ;; This is a program that checks to see if a string of numbers has
- ;; repeatitive numbers...
- ;; use these modules to help my process the command line arguments.
- (use-modules (ice-9 getopt-long))
- (use-modules (ice-9 regex))
- ;; This function returns some repeating digits. If its arguments
- ;; are "4444" and "4" it will return 4:3. If its arguments are "4444"
- ;; and "44", it will return "44:1".
- ;; The procedure only returns repeating substrings of length "number".
- ;; So (doesANumberRepeat "123123" "2") will return '()
- ;; (doesANumberRepeat "123123" "3") will return '("123:1 ")
- ;; (doesANumberRepeat "123123" "1" will return '("1:1 " "2:1 " "3:1 ")
- ;; It works by first the first repeating digit, then it recurses and removes
- ;; those repeating digits.
- ;; an example of finding out if a number repeats a single digit.
- ;; 123561236
- ;; string is longer than 2
- ;; 1 is the first digit and it repeats (cons recurse)
- ;; 2356236
- ;; string is longer than 2
- ;; 2 is the first digit and it repeats (cons recurse)
- ;; 35636
- ;; string is longer than 2
- ;; 3 is the first digit and it repeats (cons recurse)
- ;; 566
- ;; string is longer than 2
- ;; 5 is the first digit, but it does not repeat, recurse
- ;; 66
- ;; string is longer than 2
- ;; 6 is the first digit and repeats (cons recurse)
- ;; ""
- ;; (cons '())
- ;; TODO This algorithm fails! (doesANumberRepeat "123123" 2) -> '("12:1")
- ;; The correct answer is '("12:1 " "23:1 ")
- ;; scheme does allow for default values in functions...((lambda* (x #:optional (y 2) ) (display (number->string (+ x y)))) 1 2)
- (define doesANumberRepeat
- (lambda* (string number #:optional (ssloc 0)) ;; ssloc -> substring location
- ;; If we are looking for a repeating substring that is longer than the string,
- ;; then stop looking for repeating digits. As the function recurses the string gets shorter and shorter.
- ;; Eventually the string will be less than string.
- (let* ((digit (getDigit string number)) ;; digit is the first number characters of the string
- (repeat (repetitions digit string))) ;; repeat is how many times digit repeats in the string.
- (display (string-append " We are recursing (cons " digit ":" (number->string repeat) " )" "\n"))
- ;; if the number repeats in the string, say "1" repeats twice in "11", then store that.
- (if (< 0 repeat)
- (begin
- (cons
- (string-append digit ":" (number->string repeat) " ")
- ;; recurse, but remove the repeating digits that you've already found.
- ;; so (doesANumberRepeat "1122" "1") will eventually call (doesANumberRepeat "22" "1")
- (doesANumberRepeat number)))
- ;; if the specified digit/s does not repeat, recurse and remove those digit/s from the string.
- (doesANumberRepeat number)))))
- ;; This function takes a number in a string
- ;; number is (ceiling (/ (string-length string) 2))
- ;; Here's an example of how it works.
- ;; (wNR "1230123445544550666777666777" 14)
- ;; list is '()
- ;; (wNR "1230123445544550666777666777" 13)
- ;; list is '()
- ;; (wNR "1230123445544550666777666777" 12)
- ;; ...
- ;; (wNR "1230123445544550666777666777" 3)
- ;; list is '("666:1 " "777:1 ")
- ;; (wNR "1230123445544550666777666777" 2)
- ;; list is '("44:1 " "55:1 ")
- ;; (wNR "1230123445544550666777666777" 1)
- ;; list is '("1:1 " "2:1 " "3:1" "0:1 ")
- ;; (wNR "" 0)
- (define (whichNumbersRepeat string number)
- (let* ((number (1- number))
- ;; at some point number will be 0;
- ;; but (doesANumberRepeat "123123" 0) creates an infinite loop.
- ;; So if number == 0, then set list to '().
- (list (if (> number 0)
- (doesANumberRepeat string number)
- '())))
- (if (> 0 number)
- '()
- (if (null? list)
- (whichNumbersRepeat string number)
- (cons list (whichNumbersRepeat string number))))))
- ;; (whichNumbersRepeat "11" (ceiling (/ (string-length "11") 2)))
- ;; This function is defunct. The algorithm that uses it fails.
- ;; I can probably remove it.
- ;; dR 12301237556655668 8
- ;; string is longer than 8, 12301237 does not repeat
- ;; dR 556655668 8
- ;; string is longer than 8, 55665566 does not repeat.
- ;; dR 8
- ;; string is less than 8.
- ;; (stripNumberFromString "5" "5523") --> "23"
- (define (stripNumberFromString number string)
- (regexp-substitute/global #f number string 'pre "" 'post))
- ;; returns the digit at the specified location and length
- (define (getDigit string number)
- (substring string 0 number))
- ;; How Many Times Does the number (substring) Repeat?
- ;; "4" repeats 2 times in "444".
- ;; "44" repeats once in "44044".
- (define (repetitions sstr str)
- (1- (length (list-matches sstr str))))
- (define (displayListOfLists list)
- (if (null? list)
- (begin
- (display "'()\n"))
- (begin
- (display (string-append (apply string-append (car list))))
- (displayListOfLists (cdr list)))))
- (define (main args)
- ;;the option specification tells getopt-long how
- ;; to parse the command line
- (let* ((option-spec '((version (single-char #\v) (value #f))
- (help (single-char #\h) (value #f))
- (number (single-char #\n) (value #t)
- ;; (required #t)
- )))
- ;; tell getopt-long to parse the command line and put the
- ;; data in options
- (options (getopt-long args option-spec))
- ;; was --help or -h used?
- (help-wanted (option-ref options 'help #f))
- (version-wanted (option-ref options 'version #f))
- ;; was -c or --calc used? If there was no value given,
- ;; then return #f
- (number-wanted (option-ref options 'number #f)))
- (if (or version-wanted help-wanted)
- (begin
- (if version-wanted
- (display "repeat version 0.1\n"))
- (if help-wanted
- (begin
- (display "repeat [options]\n")
- (display "-v --version Display version\n")
- (display "-h, --help Display this help info\n")
- (display "-n, --number Does this number repeat?\n")
- )))
- (display (string-append (apply string-append (doesANumberRepeat number-wanted 2)) "\n")))))
|