Повышение производительности при преобразовании чисел в списки и от base10 до base2
МногоПроект Эйлера проблемы требуют манипулирования целыми числами и их цифрами, как в base10, так и в base2. Хотя у меня нет проблем с преобразованием целых чисел в списках цифр или преобразованием base10 в base2 (или списки их цифр), я часто нахожу, что производительность при повторном выполнении таких преобразований низкая.
Вот'Вот пример:
Во-первых, вот мои типичные преобразования:
#lang racket
(define (10->bin num)
(define (10->bin-help num count)
(define sq
(expt 2 count))
(cond
[(zero? count) (list num)]
[else (cons (quotient num sq) (10->bin-help (remainder num sq) (sub1 count)))]
)
)
(member 1 (10->bin-help num 19)))
(define (integer->lon int)
(cond
[(zero? int) empty]
[else (append (integer->lon (quotient int 10)) (list (remainder int 10)))]
)
)
Далее мне нужна функция, чтобы проверить, является ли список цифр палиндромом.
(define (is-palindrome? lon)
(equal? lon (reverse lon)))
Наконец, мне нужно сложить все целые числа base10 ниже некоторого максимума, которые являются палиндромами в base2 и base10. Вот's аккумуляторная функция:
(define (sum-them max)
(define (sum-acc count acc)
(define base10
(integer->lon count))
(define base2
(10->bin count))
(cond
[(= count max) acc]
[(and
(is-palindrome? base10)
(is-palindrome? base2))
(sum-acc (add1 count) (+ acc count))]
[else (sum-acc (add1 count) acc)]))
(sum-acc 1 0))
И обычная рекурсивная версия:
(define (sum-them* max)
(define base10
(integer->lon max))
(define base2
(10->bin max))
(cond
[(zero? max) 0]
[(and
(is-palindrome? base10)
(is-palindrome? base2))
(+ (sum-them* (sub1 max)) max)]
[else (sum-them* (sub1 max))]
)
)
Когда я применяю одну из этих двух последних функций к 1000000, мне требуется более 10 секунд для завершения. Рекурсивная версия кажется немного быстрее, чем версия с аккумулятором, но разница незначительна.
Можно ли как-нибудь улучшить этот код, или я просто должен признать, что это стиль обработки чисел, для которого Racket не подходит?Т особенно подходит?
До сих пор я рассмотрел возможность замены целого числа->LON с похожим целым числом->вектор, как я ожидаю, вектор-добавление будет быстрее, чем добавление, но тогда яЯ застрял с необходимостью применить обратное позже.