Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Common lisp Lisp:标签还是单独的全局函数?_Common Lisp - Fatal编程技术网

Common lisp Lisp:标签还是单独的全局函数?

Common lisp Lisp:标签还是单独的全局函数?,common-lisp,Common Lisp,这就是我的在甲板上产生的: ((15 . D) (35 . H) (3 . B) (19 . K) (L . 15) (A . 16) (T . 23) (R . 53) (N . 13) (M . 7) (I . 52) (35 . Q) (S . 19) (Y . 29) (45 . G) (44 . W) (11 . V) (J . 25) (21 . F) (39 . Z) (25 . X) (50 . E) (5 . P) (33 . C) (O . 34)) 这是一个代表甲板

这就是我的
在甲板上产生的:

((15 . D) (35 . H) (3 . B) (19 . K) (L . 15) (A . 16) (T . 23) (R . 53)
 (N . 13) (M . 7) (I . 52) (35 . Q) (S . 19) (Y . 29) (45 . G) (44 . W)
 (11 . V) (J . 25) (21 . F) (39 . Z) (25 . X) (50 . E) (5 . P) (33 . C)
 (O . 34))
这是一个代表甲板上的一对的列表。(参见示例6)。在字母组中,字母表中的所有字母都应该与偶数或奇数相匹配,这取决于是元音还是辅音。你可以看到,我随机洗牌和翻牌。然后,我(可选地)偶尔打破元音:偶数,辅音:奇数规则,随机污染甲板。下面是我想出的代码:

(defun wason-deck (&optional (p 0))
  "This `consolst` and `vowlist` building is unnecessary, but a good exercise"
  (let* ((alphab '(a b c d e f g h i j k l m n o p q r s t u v w x y z))
         (consonents '(b c d f g h j k l m n p q r s t v w x y z))
         (consolst (remove 'NIL (mapcar (lambda (x) (find x consonents)) alphab)))
         (vowlst (remove 'NIL (mapcar (lambda (x) (find x '(a e i o))) alphab)))
         (wdeck '()))

    (labels ((make-consodeck ()
               (mapcar (lambda (x) (let ((num (random 54)))
                                     (cons x (if (evenp num)
                                                 (1+ num)
                                                 num)))) consolst))
             (make-voweldeck () 
               (mapcar (lambda (x) (let ((num (random 54)))
                                     (cons x (if (oddp num)
                                                 (1+ num)
                                                 num)))) vowlst))
             (swap (slst el1 el2)
               (let  ((tmp (elt slst el1)))
                 (setf (elt slst el1) (elt slst el2))
                 (setf (elt slst el2) tmp)))

             (shuffle (slst)
               (loop for i in (reverse (range (length slst) :min 1))
                  do (let ((j (random (+ i 1))))
                       (swap slst i j)))
               slst)
             (flip (flst)
               (mapcar (lambda (x) (let ((num (random 2)))
                                     (if (zerop num)
                                         (cons (cdr x) (car x))
                                         x))) flst)))
      (setf wdeck (flip (shuffle (append (make-consodeck) (make-voweldeck)))))

      (if (zerop p) wdeck
          (mapcar (lambda (x) (let ((num (random 6)))
                                (cond ((and (zerop num) (numberp (car x))) (cons (1+ (car x)) (cdr x)))
                                      ((and (zerop num) (numberp (cdr x))) (cons (car x) (1+ (cdr x))))
                                      (t x)))) wdeck)))))
它是有效的,但我担心的是我并不真正知道我在做什么,也就是说,我在代码中滥用了
标签
,还做了
setf
。如果一些更资深的人能告诉我这是否完全是错误的方向

增编:

以下是我在听取了以下建议后得出的结论:

(defun wason-deck3 (&optional (p 0))
  (let* ((consonents '(b c d f g h j k l m n p q r s t v w x y z))
         (vowels '(a e i o u))
         (conso-deck (mapcar (lambda (x)
                               (cons x (1+ (* 2 (random 27)))))
                             consonents))
         (vowel-deck (mapcar (lambda (x)
                               (cons x (* 2 (random 27))))
                             vowels))
         (wdeck '()))
    (labels
        ((shuffle (slst)
           (loop :for i :from (1- (length slst)) :downto 1
              :do (rotatef (nth i slst)
                           (nth (random (1+ i)) slst)))
                           slst)

         (flip (flst)
           (mapcar (lambda (x) (let ((num (random 2)))
                                 (if (zerop num)
                                     (cons (cdr x) (car x))
                                     x))) flst)))

      (setf wdeck (flip (shuffle (append conso-deck vowel-deck)))))

    (if (zerop p) wdeck
        (mapcar (lambda (x) (let ((num (random 6)))
                              (cond ((and (zerop num) (numberp (car x))) (cons (1+ (car x)) (cdr x)))
                                    ((and (zerop num) (numberp (cdr x))) (cons (car x) (1+ (cdr x))))
                                    (t x)))) wdeck))))

请添加任何新建议。

使用
标签
完全可以,并且您的代码并非完全不合理

几点建议:

  • 我将字符表示为字符:
    ”(#\a\b\c…

  • 我会把我的列表练习带到其他地方,或者至少使用
    set difference

  • 仅为一个调用创建函数时,最好只保存结果:

    (let ((consonant-deck (mapcar (lambda (c)
                                    (cons c (1+ (* 2 (random 27)))))
                                  consonants))
          (vowel-deck (mapcar (lambda (c)
                                (cons c (* 2 (random 27))))
                              vowels)))
      …)
    
  • 对于交换,有
    rotatef
    (rotatef(第n个i列表)(第n个j列表))
    。这样的东西在列表中是相当昂贵的,所以我更喜欢使用向量。然后,字符串只是一个字符向量就很方便了

  • Loop
    可以为您计数,您不需要创建列表:

    (loop :for i :from (1- (length list)) :downto 1
          :do (rotatef (nth i list)
                       (nth (random (1+ i)) list)))
    
    (使用关键字作为循环关键字是可选的,但是缩进应该是这样的。)

  • 如果将
    标签
    放在
    let
    周围,则可以立即绑定
    wdeck
    ,这样以后就不需要
    setf

  • 链接到的练习不需要此函数


使用
标签
是完全可以的,您的代码也并非完全不合理

几点建议:

  • 我将字符表示为字符:
    ”(#\a\b\c…

  • 我会把我的列表练习带到其他地方,或者至少使用
    set difference

  • 仅为一个调用创建函数时,最好只保存结果:

    (let ((consonant-deck (mapcar (lambda (c)
                                    (cons c (1+ (* 2 (random 27)))))
                                  consonants))
          (vowel-deck (mapcar (lambda (c)
                                (cons c (* 2 (random 27))))
                              vowels)))
      …)
    
  • 对于交换,有
    rotatef
    (rotatef(第n个i列表)(第n个j列表))
    。这样的东西在列表中是相当昂贵的,所以我更喜欢使用向量。然后,字符串只是一个字符向量就很方便了

  • Loop
    可以为您计数,您不需要创建列表:

    (loop :for i :from (1- (length list)) :downto 1
          :do (rotatef (nth i list)
                       (nth (random (1+ i)) list)))
    
    (使用关键字作为循环关键字是可选的,但是缩进应该是这样的。)

  • 如果将
    标签
    放在
    let
    周围,则可以立即绑定
    wdeck
    ,这样以后就不需要
    setf

  • 链接到的练习不需要此函数


这个例子没有提到辅音的背面总是有一个奇数。首先,你可以用一个普通的
let
替换
标签中的一些函数。这个例子没有提到辅音的背面总是有一个奇数。你可以替换
标签中的一些函数
标签
带有简单的
作为初学者。感谢Svante提供的详细帮助;时间允许的话,我会把每一点都讲一遍。至于你的最后一点,我想看一整副牌,练习只是一个可能的测试用例。我问了一下math.stackexchange为什么只有四张卡片——似乎没有人知道为什么。这似乎是一个组合问题。但我只是在猜测。不知道你说的倒数第二颗子弹是什么意思。
标签如何绕过
let*
?我的意思是
标签
绑定不依赖于
let*
绑定,所以你可以说
(标签((shuffle…(flip…))(let((辅音…);时间允许的话,我会把每一点都讲一遍。至于你的最后一点,我想看一整副牌,练习只是一个可能的测试用例。我问了一下math.stackexchange为什么只有四张卡片——似乎没有人知道为什么。这似乎是一个组合问题。但我只是在猜测。不知道你说的倒数第二颗子弹是什么意思。
标签如何绕过
let*
?我的意思是
标签
绑定不依赖于
let*
绑定,所以你可以说
(标签((shuffle…(flip…))(let((辅音…)。