#lang racket ;;; Задача 1 (define (sum-digits n) (define (calc-iter working-n total) (if (= working-n 0) total (calc-iter (quotient working-n 10) (+ total (remainder working-n 10))))) (calc-iter n 0)) (define (count-specials k a b) (if (or (<= k 0) (> a b)) 0 (+ (count-specials k (add1 a) b) (if (and (= 0 (remainder a k)) (= 0 (remainder (sum-digits a) k))) 1 0)))) ; ако е k-специално, добавяме единица към бройката, иначе не ;; Примери (count-specials 3 3 9) (count-specials 5 10 100) (count-specials 8 100 200) (count-specials 15 1000 2000) ;;; Задача 2 (define (^10 n) (define (calc-iter power val) (if (= power 0) val (calc-iter (sub1 power) (* val 10)))) (calc-iter n 1)) (define (numlen n) (define (calc-iter working-n len) (if (= working-n 0) len (calc-iter (quotient working-n 10) (add1 len)))) (calc-iter n 0)) (define (rotate-left n) (define 10^len-1 (^10 (sub1 (numlen n)))) (+ (* (remainder n 10^len-1) 10) ; всичко без най-дясната цифра * 10 (quotient n 10^len-1))) ; най-дясната цифра (define (rotate-left-preserved n d) (define 10^rotatelen (^10 (- (numlen n) d))) (define to-rotate (remainder n 10^rotatelen)) (if (<= n 9) n (+ (- n to-rotate) ; незапазените цифри стават нули (if (< to-rotate (quotient 10^rotatelen 10)) ; ако to-rotate "започва" с нули (- (rotate-left (+ to-rotate 10^rotatelen)) 1) ; временно "долепяме" 1ца до левия край, за да може незапазените да се звъртят правилно (rotate-left to-rotate))))) ; иначе просто завъртаме незапазените (define (max-rot n) (define len-1 (sub1 (numlen n))) (define (calc-iter preserved current biggest) (if (= preserved len-1) ; при равенство ще има само една цифра която ще може да бъде завъртяна biggest (calc-iter (add1 preserved) (rotate-left-preserved current (add1 preserved)) (if (> current biggest) current biggest)))) (calc-iter 0 (rotate-left n) 0)) ;; Примери (max-rot 56789) (max-rot 12490) (max-rot 38458215) (max-rot 195881031) (max-rot 896219342) (max-rot 69418307) (max-rot 257117280)