repeat.scm 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #!/usr/bin/guile \
  2. -e main -s
  3. !#
  4. ;; This is a program that checks to see if a string of numbers has
  5. ;; repeatitive numbers...
  6. ;; use these modules to help my process the command line arguments.
  7. (use-modules (ice-9 getopt-long))
  8. (use-modules (ice-9 regex))
  9. ;; This function returns some repeating digits. If its arguments
  10. ;; are "4444" and "4" it will return 4:3. If its arguments are "4444"
  11. ;; and "44", it will return "44:1".
  12. ;; The procedure only returns repeating substrings of length "number".
  13. ;; So (doesANumberRepeat "123123" "2") will return '()
  14. ;; (doesANumberRepeat "123123" "3") will return '("123:1 ")
  15. ;; (doesANumberRepeat "123123" "1" will return '("1:1 " "2:1 " "3:1 ")
  16. ;; It works by first the first repeating digit, then it recurses and removes
  17. ;; those repeating digits.
  18. ;; an example of finding out if a number repeats a single digit.
  19. ;; 123561236
  20. ;; string is longer than 2
  21. ;; 1 is the first digit and it repeats (cons recurse)
  22. ;; 2356236
  23. ;; string is longer than 2
  24. ;; 2 is the first digit and it repeats (cons recurse)
  25. ;; 35636
  26. ;; string is longer than 2
  27. ;; 3 is the first digit and it repeats (cons recurse)
  28. ;; 566
  29. ;; string is longer than 2
  30. ;; 5 is the first digit, but it does not repeat, recurse
  31. ;; 66
  32. ;; string is longer than 2
  33. ;; 6 is the first digit and repeats (cons recurse)
  34. ;; ""
  35. ;; (cons '())
  36. ;; TODO This algorithm fails! (doesANumberRepeat "123123" 2) -> '("12:1")
  37. ;; The correct answer is '("12:1 " "23:1 ")
  38. ;; scheme does allow for default values in functions...((lambda* (x #:optional (y 2) ) (display (number->string (+ x y)))) 1 2)
  39. (define doesANumberRepeat
  40. (lambda* (string number #:optional (ssloc 0)) ;; ssloc -> substring location
  41. ;; If we are looking for a repeating substring that is longer than the string,
  42. ;; then stop looking for repeating digits. As the function recurses the string gets shorter and shorter.
  43. ;; Eventually the string will be less than string.
  44. (let* ((digit (getDigit string number)) ;; digit is the first number characters of the string
  45. (repeat (repetitions digit string))) ;; repeat is how many times digit repeats in the string.
  46. (display (string-append " We are recursing (cons " digit ":" (number->string repeat) " )" "\n"))
  47. ;; if the number repeats in the string, say "1" repeats twice in "11", then store that.
  48. (if (< 0 repeat)
  49. (begin
  50. (cons
  51. (string-append digit ":" (number->string repeat) " ")
  52. ;; recurse, but remove the repeating digits that you've already found.
  53. ;; so (doesANumberRepeat "1122" "1") will eventually call (doesANumberRepeat "22" "1")
  54. (doesANumberRepeat number)))
  55. ;; if the specified digit/s does not repeat, recurse and remove those digit/s from the string.
  56. (doesANumberRepeat number)))))
  57. ;; This function takes a number in a string
  58. ;; number is (ceiling (/ (string-length string) 2))
  59. ;; Here's an example of how it works.
  60. ;; (wNR "1230123445544550666777666777" 14)
  61. ;; list is '()
  62. ;; (wNR "1230123445544550666777666777" 13)
  63. ;; list is '()
  64. ;; (wNR "1230123445544550666777666777" 12)
  65. ;; ...
  66. ;; (wNR "1230123445544550666777666777" 3)
  67. ;; list is '("666:1 " "777:1 ")
  68. ;; (wNR "1230123445544550666777666777" 2)
  69. ;; list is '("44:1 " "55:1 ")
  70. ;; (wNR "1230123445544550666777666777" 1)
  71. ;; list is '("1:1 " "2:1 " "3:1" "0:1 ")
  72. ;; (wNR "" 0)
  73. (define (whichNumbersRepeat string number)
  74. (let* ((number (1- number))
  75. ;; at some point number will be 0;
  76. ;; but (doesANumberRepeat "123123" 0) creates an infinite loop.
  77. ;; So if number == 0, then set list to '().
  78. (list (if (> number 0)
  79. (doesANumberRepeat string number)
  80. '())))
  81. (if (> 0 number)
  82. '()
  83. (if (null? list)
  84. (whichNumbersRepeat string number)
  85. (cons list (whichNumbersRepeat string number))))))
  86. ;; (whichNumbersRepeat "11" (ceiling (/ (string-length "11") 2)))
  87. ;; This function is defunct. The algorithm that uses it fails.
  88. ;; I can probably remove it.
  89. ;; dR 12301237556655668 8
  90. ;; string is longer than 8, 12301237 does not repeat
  91. ;; dR 556655668 8
  92. ;; string is longer than 8, 55665566 does not repeat.
  93. ;; dR 8
  94. ;; string is less than 8.
  95. ;; (stripNumberFromString "5" "5523") --> "23"
  96. (define (stripNumberFromString number string)
  97. (regexp-substitute/global #f number string 'pre "" 'post))
  98. ;; returns the digit at the specified location and length
  99. (define (getDigit string number)
  100. (substring string 0 number))
  101. ;; How Many Times Does the number (substring) Repeat?
  102. ;; "4" repeats 2 times in "444".
  103. ;; "44" repeats once in "44044".
  104. (define (repetitions sstr str)
  105. (1- (length (list-matches sstr str))))
  106. (define (displayListOfLists list)
  107. (if (null? list)
  108. (begin
  109. (display "'()\n"))
  110. (begin
  111. (display (string-append (apply string-append (car list))))
  112. (displayListOfLists (cdr list)))))
  113. (define (main args)
  114. ;;the option specification tells getopt-long how
  115. ;; to parse the command line
  116. (let* ((option-spec '((version (single-char #\v) (value #f))
  117. (help (single-char #\h) (value #f))
  118. (number (single-char #\n) (value #t)
  119. ;; (required #t)
  120. )))
  121. ;; tell getopt-long to parse the command line and put the
  122. ;; data in options
  123. (options (getopt-long args option-spec))
  124. ;; was --help or -h used?
  125. (help-wanted (option-ref options 'help #f))
  126. (version-wanted (option-ref options 'version #f))
  127. ;; was -c or --calc used? If there was no value given,
  128. ;; then return #f
  129. (number-wanted (option-ref options 'number #f)))
  130. (if (or version-wanted help-wanted)
  131. (begin
  132. (if version-wanted
  133. (display "repeat version 0.1\n"))
  134. (if help-wanted
  135. (begin
  136. (display "repeat [options]\n")
  137. (display "-v --version Display version\n")
  138. (display "-h, --help Display this help info\n")
  139. (display "-n, --number Does this number repeat?\n")
  140. )))
  141. (display (string-append (apply string-append (doesANumberRepeat number-wanted 2)) "\n")))))