W aplikacji, nad którą pracuję w Racket, muszę wziąć listę liczb i podzielić listę na pod-listy kolejnych numerów: (W aktualnym zgłoszeniu, będę faktycznie partycjonowanie par składających się z szeregu, a niektóre dane, ale zasada jest taka sama)Partycjonowanie listy w Rakiecie
czyli jeśli mój procedura nazywa chunkify
potem.
(chunkify '(1 2 3 5 6 7 9 10 11)) -> '((1 2 3) (5 6 7) (9 10 11))
(chunkify '(1 2 3)) -> '((1 2 3))
(chunkify '(1 3 4 5 7 9 10 11 13)) -> '((1) (3 4 5) (7) (9 10 11) (13))
(chunkify '(1)) -> '((1))
(chunkify '()) -> '(())
itp
mam wymyślić następujące w Rakiecie:
#lang racket
(define (chunkify lst)
(call-with-values
(lambda()
(for/fold ([chunk '()] [tail '()]) ([cell (reverse lst)])
(cond
[(empty? chunk) (values (cons cell chunk) tail)]
[(equal? (add1 cell) (first chunk)) (values (cons cell chunk) tail)]
[else (values (list cell) (cons chunk tail))])))
cons))
Działa to dobrze, ale zastanawiam względu na wyrazistość rakiety, jeśli nie jest to bardziej oczywiste prostszy sposób to zrobić, jakiś sposób, aby pozbyć się „wartości nazywają-z” i konieczność odwrócenia listy w procedurze itp., być może w pewien sposób zupełnie odmienny.
Moja pierwsza próba była oparta na bardzo luźno wzór z kolektora w "The Little Schemer" i to nawet mniej oczywiste niż powyższe:
(define (chunkify-list lst)
(define (lambda-to-chunkify-list chunk) (list chunk))
(let chunkify1 ([list-of-chunks '()]
[lst lst]
[collector lambda-to-chunkify-list])
(cond
[(empty? (rest lst)) (append list-of-chunks (collector (list (first lst))))]
[(equal? (add1 (first lst)) (second lst))
(chunkify1 list-of-chunks (rest lst)
(lambda (chunk) (collector (cons (first lst) chunk))))]
[else
(chunkify1 (append list-of-chunks
(collector (list (first lst)))) (rest lst) list)])))
Co szukam jest coś proste, zwięzłe i jednoznaczne.
To jest bardziej "proszę przejrzyj mój kod", a nie "co jest nie tak z moim kodem", więc myślę, że należałoby na www.codereview.stackexchange.com –