やってみた: (1 2 3 4 5)が与えられたとき( (1 2) (2 3) (3 4) (4 5) )を返すような関数の定義
答え見ないでやってみた
vallog: [1,2,3,4,5] が与えられたとき [[1,2][2,3][3,4][4,5]] を返すような関数を定義せよ
#!/usr/bin/env gosh (use srfi-1) (use util.list) (use gauche.test) ;; 1 だけならこれ (define (slices* lis) (zip lis (cdr lis))) ;; 2 だとこれ。効率わるいかも。 (define (slices* lis :optional (n 2)) (let loop ((lis lis) (r '())) (if (or (null? lis) (null? (cdr lis))) (reverse r) (loop (drop* lis (- n 1)) (cons (take* lis n) r))))) (test* "1" '((1 2) (2 3) (3 4) (4 5)) (slices* (list 1 2 3 4 5))) (test* "2" '((0 1) (1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8) (8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 2)) (test* "3" '((0 1 2) (2 3 4) (4 5 6) (6 7 8) (8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 3)) (test* "4" '((0 1 2 3) (3 4 5 6) (6 7 8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 4))
答えみたけど素敵な解法いろいろある!
それよりtransposeってこんなに簡単に書けるのか!に感動した。
(define (transpose m) (apply map list m)) (transpose '((0 1 2 3)(4 5 6 7)(8 9 10 11)(12 13 14 15))) ;; -> ((0 4 8 12) (1 5 9 13) (2 6 10 14) (3 7 11 15))