将列表列表转换为图像

时间:2015-03-09 03:08:09

标签: scheme racket

好的,所以我试图将一个数字列表的列表转换为一个图像,其中每个数字代表一个颜色分配给该数字的块。例如:

(define allig
  '((1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1)
    (1 1 1 1 1 1 2 4 5 5 5 2 1 1 1 2 2 1 1)
    (1 1 1 1 2 2 2 5 5 3 2 5 2 2 2 5 5 2 1)
    (1 1 2 2 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2)
    (2 2 5 5 2 5 4 5 5 2 3 2 3 2 3 2 3 2 1)
    (5 5 5 5 5 5 5 5 2 1 2 1 2 1 2 1 2 1 1)
    (4 5 2 5 4 5 2 5 2 1 1 1 1 1 1 1 1 1 1)
    (5 5 5 5 5 5 5 5 2 1 1 1 1 1 1 1 1 1 1)
    (2 5 4 5 2 5 4 5 5 2 1 2 1 2 1 2 1 2 1)
    (5 5 5 5 5 5 5 5 5 5 2 3 2 3 2 3 2 3 2)
    (5 5 2 2 2 2 2 2 5 5 5 5 5 5 5 5 5 5 2)
    (5 5 2 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 1)
    (5 5 5 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (2 5 5 5 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 2 5 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    (1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
    ))

我想把它变成这样: picture  (paint-picture allig palette 10) 其中10是构成图像的正方形的大小,调色板是分配给每个数字的颜色(即1是&#34;蓝色&#34;在此图片中),allig是数字列表的列表。< / p>

到目前为止,我有办法获取颜色,制作第一列,并反复重复列以使Col x Row变大。我的问题是,我不知道如何获得每个连续的列,只有第一列。

我已经完成了这项工作,我只是坚持这最后一部分,所以任何帮助都会很棒。

以下是我所拥有的:

    (define (make-column painting)
      (cond
        [(zero? (length painting)) (square 0 "solid" "red")]
        [else (above (square 30 "solid" 
    (get-color (first (first painting)) pal))
                     (make-column (rest painting)))]))


    ;puts images side by side to make a row
    (define (make-row n img1 img2)
      (cond
        [(zero? n ) (square 0 "solid" "red")]
        [else (beside img1 (make-row (sub1 n) img2 img1))]))


    ;makes a row of columns, I'm stuck as to how to make it recursive
    ; to get the next column since it is a list of a list
    (define (paint-picture painting)
      (cond
        [(zero? (length painting) ) (square 0 "solid" "red")]
        [else (make-row (length (first painting)) 
                        (make-column painting)
 ; this should be the recursive next col part  (paint-picture painting))]))

(define pal (list "blue" "dark gray" "white" "green" "dark green"))

(define (get-color n colors) (list-ref colors (- n 1)))

3 个答案:

答案 0 :(得分:1)

这适用于#lang racket

(define pal '(Transparent Blue DarkGray White Green DarkGreen))

(apply above (map (lambda (row)
                    (apply beside (map (lambda (col)
                                         (square 4 'solid (list-ref pal col)))
                                       row)))
                  allig))

(请注意,我已将Transparent添加到pal的前面,这样我就不必将索引移动1。)

它也适用于#lang htdp/isl+(但出于某种原因,它显示结构而不是直接显示图像)。当然,Alexis King之所以询问你是使用ISL +还是普通ISL,是因为我在上面使用的lambda表达式在普通的ISL中是被禁止的。

这是一个适用于普通ISL的版本:

(define pal '(Transparent Blue DarkGray White Green DarkGreen))

(define (make-pixel col)
  (square 4 'solid (list-ref pal col)))

(define (make-row row)
  (apply beside (map make-pixel row)))

(apply above (map make-row allig))

答案 1 :(得分:1)

这是一组函数,它们实现了你在普通ISL中寻找的东西,没有任何全局状态。

; (a b -> c) a -> (b -> c)
(define (partial f x)
  (let ([g (lambda (y) (f x y))])
    g))

; (listof string?) integer? -> image?
(define (pixel palette c)
  (let ([color (list-ref palette (sub1 c))])
    (square 1 "solid" color)))

; (listof string?) (listof integer?) -> image?
(define (row->image palette lst)
  (let* ([pixel/palette (partial pixel palette)]
         [pixels (map pixel/palette lst)])
    (apply beside pixels)))

; (listof string?) (listof (listof integer?)) -> image?
(define (matrix->image palette lst)
  (let* ([row/palette->image (partial row->image palette)]
         [rows (map row/palette->image lst)])
    (apply above rows)))

; (listof (listof integer?)) (listof string?) integer? -> image?
(define (paint-picture matrix palette size)
  (scale size (matrix->image palette matrix)))

棘手的位是partial函数,它在普通ISL中实现二进制函数(即具有arity 2的函数)的部分函数应用。我不确定这是否假设在ISL中工作,但确实如此。也许这是一个错误,哈哈?

答案 2 :(得分:1)

一个直接的版本,没有任何高阶函数或任何花里胡哨 - 非常初学者级别,我希望:

最常见的是递归列表'结构,而不是它们的大小,所以我们会这样做。
如果你习惯于编写for循环,这一开始看起来会让人觉得不舒服,但大多数情况下,列表的确切长度与Racket无关 - 你只关心它是否为空。

首先,可读性助手:

(define nothing (square 0 "solid" "red"))

逐行浏览“图片”,我们要么有空列表,要么我们没有 如果它是空的,不要涂漆。
否则,将第一行绘制在图片的其余部分上方:

(define (paint-picture painting)
  (if (empty? painting)
      nothing
      (above (paint-row (first painting)) 
             (paint-picture (rest painting)))))

接下来,我们需要画一排 这也有两种情况:
如果它是空列表,则不要绘制任何内容 否则,在该行的其余部分旁边绘制第一个像素:

(define (paint-row row)
  (if (empty? row)
      nothing
      (beside (square 30 "solid" (get-color (first row) pal)) 
              (paint-row (rest row)))))

就是这样。