好的,所以我试图将一个数字列表的列表转换为一个图像,其中每个数字代表一个颜色分配给该数字的块。例如:
(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)
))
我想把它变成这样:
(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)))
答案 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)))))
就是这样。