Есть много способов сделать то, что вы пытаетесь сделать!Одним из способов является использование «кругового списка».В списке каждый элемент также имеет указатель на следующий элемент.В циклическом списке последний элемент указывает на первый элемент, так что вы просто продолжаете оборачиваться, пока просматриваете список!
Написание собственной реализации циклического списка не слишком сложно, но, к счастью, циклические спискидоступно через библиотеку srfi/1
.Одна из возможных реализаций с использованием этой библиотеки выглядит следующим образом:
#lang racket
(require srfi/1)
; function we will apply distributively to values in list
(define (1+ val) (+ val 1))
(define (distribute function l n)
; we define an inner function so we can take list l
; and convert it to a "circular" list
(define (inner-distribute func circular-l n count)
(if (> count 0)
(cons (func (list-ref circular-l n))
(inner-distribute func circular-l (+ n 1) (- count 1)))
'()))
(inner-distribute function (apply circular-list l) n n))
(distribute 1+ '(1 2 3 4 5 6) 4)
; this returns the list '(6 7 2 3)
; just like you specified in your question!
Эта функция distribute
выполняет свою работу, но, как я уже сказал, существует много, много способов сделать это.Я настоятельно рекомендую вам изучить приведенный выше код и понять его - с небольшими усилиями вы сможете найти некоторые решения, значительно превосходящие приведенные выше.Удачи!
edit: В комментарии OP чувствовалось, что вышеприведенный код слишком сложен для понимания.Вот альтернативный подход:
(require srfi/1)
; function we will apply distributively to values in list
(define (1+ val) (+ val 1))
(define (distribute func l n)
(map (lambda (x)
(func (list-ref (apply circular-list l) x)))
(range n (+ n n))))
(distribute 1+ '(1 2 3 4 5 6) 4) ; works!
Идея этого решения заключается в том, что мы составляем список чисел от n до n * 2, а затем получаем элемент в нашем круговом списке, проиндексированный каждым из них.номера и применить к нему функцию (в данном случае 1+).