如何划分这些列表?

时间:2010-11-21 10:57:07

标签: scheme racket

示例输入:

((a1 . b) (a1 . c)): 

我有一个包含两个元素的列表,这些元素是列表或具有两个元素的对。我想检查第一对/列表的第一个元素是否等于第二对/列表的第一个元素。

输出:如果是这样,我想创建一个包含两个列表的新列表,第一个是列表: 而(b

我如何在计划中实现这一点:

INPUT:

((1 . 1) (1 . 7))

输出:

(((1 . 2) (1 . 4) (1 . 6)) ((1 . 3) (1 . 5) (1 . 7)))

我有一个包含两个元素的列表。每个元素也是一个包含两个元素的列表,两个元素都是整数> = 0和< 8

我必须创建这个:

input ((a1 . b) (a1 . c)) 

output: (if (and (= a1 a2) (odd? b))
          While < b c
             (list (a1 . b+1) (a1 . b+3) (a1 . b+n)...)) 
             (list (a2 . b) (a2 . b+2) (a2 . b+4)...)

我做过这个,但我找不到我失败的地方,你能帮我吗?....

;;; Verify if absissa0 = absissa1

(define (game-position input)
  (if (= (car (car j)) (cdr (cdr j)))
          (col1_col2 j)
          (error "Not valid"))))
;;; verify if absissa0 is even

(define (col1_col2 gstart)
  (if (even? (cdr (car jstart))) 
      (list (pos-start jstart))
      (list (pos-start (list (cons (car (car jstart)) (- (cdr (car jstart)) 1)) (car (cdr jstart))))))


;;; Loop that creates positions of even's and odd's

(define (pos-start j2)
  (while ( < (cdr (car j2)) (- (cdr (cdr j2)) 2))
      ((cons (car (car j2)) (+ (cdr (car j2)) 2)) (pos-start (list (cons (car (car j2)) (+ (cdr (car j2)) 2)) (car (cdr j2)))))
      (odd_2 (list (cons (car (car j2)) (+ (cdr (car j2)) 1)) (car (cdr j2)))))

(define (odd_2 j3)
  (while ( < (cdr (car j3)) (- (car (cdr j3)) 2))
      ((j3) (odd_2 (list (cons (car (car j3)) (+ (cdr (car j3)) 2)) (car (cdr j3)))
         (value)))

4 个答案:

答案 0 :(得分:2)

对于之前的帖子感到抱歉。这是我的第一篇文章 我发布了一个未注册的用户。我很明显 尚未想出如何格式化文本。

我创建了一个帐户(用户dlm),我正在创建一个帐户 第二次尝试 - 在这里。

我一直在努力学习球拍/方案 现在,这个网站看起来像是一个分享的好地方 向别人学习。

我不是100%肯定这个问题的规范 怀疑我的代码实际上解决了这个问题 在手边,但我认为它足够可读,可以修改 根据需要

可读性是我一直在努力的事情之一 并希望得到其他人的反馈/建议。

DLM。

我的2美分:

(define (process-list? lst)
  (let*([pair-0   (list-ref lst 0)]
        [pair-1   (list-ref lst 1)])
    (and    (=   (car pair-0)  (car pair-1))
            (<   (cdr pair-0)  (cdr pair-1)))))

(define (make-odd/even-sets data) 
  (let*([x         (car (list-ref data 0))]
        [y-start   (cdr (list-ref data 0))]
        [max       (cdr (list-ref data 1))])

    (define (loop y evens odds)
      (if (<= y max)
          (loop (add1 y)
                (if (even? y)   (cons (cons x y) evens)   evens)
                (if (odd?  y)   (cons (cons x y) odds)    odds))
          (list (reverse odds) (reverse evens))))
    (loop  y-start '()  '())))

(define (main data)
  (if (process-list? data)
      (let*([odd/even   (make-odd/even-sets data)])
        (printf "~a~n" (list-ref odd/even 0))
        (printf "~a~n" (list-ref odd/even 1)))
      (printf "Invalid list~n" )))

(main  '((1 . 1) (1 . 7)) )

更新:

嗨gn66,

我不知道在实际上我能做多少 游戏本身,但我可能会给你一些 指针/想法。

在改进代码时需要注意的一件事是 寻找适用于特定情况的重复代码 并试着想办法概括。起初是 当你不这样做时,广义形式可以更难以阅读 看看发生了什么,但一旦你完全理解它 它实际上更容易,不仅是阅读而是修改。

查看代码,“相邻”程序跳出来 作为可以缩短的东西,所以我会用它作为 一个例子。让我们首先忽略边界 条件和寻找的基本模式 操作(例如:你把逻辑放在哪里 条件测试对大小有很大影响 码)。

(define (adjacent p) 
  (list (do-pos  (+ (line-pos p) 1) (column-pos p)) 
        (do-pos  (- (line-pos p) 1) (column-pos p)) 
        (do-pos  (line-pos p)       (+ (column-pos p) 1)) 
        (do-pos  (line-pos p)       (- (column-pos p) 1))) )

这里的问题可以划分为2个不同的 问题:1)改变行位置+ - 1和 2)改变行位置+ - 1.两者都适用 对不同组件的相同操作 位置。所以,让我们只使用一个。

(而不是while循环让我们看一下MAP 喜欢“while list not empty”循环)

使用'map'将操作应用于数据列表 很直接:

(map  (lambda (val)  (+ val 5))
      '(10 20 30))

如果需要,您可以将其包含在procdure范围内 保持状态信息,如柜台:

(define (test lst)
  (let*([i   0])
    (map  (lambda (val)  
            (set!  i  (+ i 1))
            (+ val i)) 
          lst)))
(test '(10 20 30))

或传递要在操作中使用的值:

(define (test lst amount)
    (map   (lambda (val)  (+ val amount))
           lst)) 
(test '(10 20 30) 100)

现在把你的想法彻底改变,并考虑到这一点 它可以让它映射一个操作列表 一些数据而不是数据到操作。

(define (test val operations-lst)
    (map  (lambda (operation)   (operation val))
          operations-lst))
(test  10  (list sub1 add1))

现在我们有了开始创建新工具的工具 '邻近'程序:

(define (adjacent p) 

  (define (up/down p)  ;; operations applied to the line componet
    (map   (lambda (operation)  
               (cons    (operation (line-pos p))   (column-pos p)))
           (list add1 sub1)))

  (define (left/right p)  ;; operations applied to the column componet
    (map   (lambda (operation)  
               (cons    (line-pos p)   (operation (column-pos p))))
           (list add1 sub1)))

  (append  (up/down p)  (left/right p))
  )

(adjacent (do-pos 1 1))

这可以找到不在边界上的位置 但正如那句老话:“有时候这样做更容易 什么,然后为它道歉,而不是先问 许可“。让我们采取相同的方法,让错误 情况发生然后删除它们。 'filter'命令是 只是工作的工具。

'filter'命令与map命令类似 它需要一个值列表并将它们传递给一个函数。该 'map'命令返回包含新元素的新列表 与消耗的每个元素相对应。过滤返回 原始值但只有那些(谓词) function“approves of”(返回true)。

(filter
 (lambda (val) (even? val))
 '(1 2 3 4 5 6 7 8))

将返回列表(2 4 6 8)

因此,我们将其添加到新的“相邻”程序中:

(define (adjacent p)

  (define (up/down p)
    (map   (lambda (operation)  
             (cons    (operation (line-pos p))   (column-pos p)))
           (list add1 sub1))) 

  (define (left/right p)
    (map   (lambda (operation)  
             (cons    (line-pos p)   (operation (column-pos p))))
           (list add1 sub1)))

  (define (select-valid p-lst)
    (filter 
       (lambda (p)  (and (>= (line-pos p) 0)  (>= (column-pos p) 0)
                         (<= (line-pos p) 7)  (<= (column-pos p) 7)))
       p-lst))

     (select-valid
           (append  (up/down p)  (left/right p))))

关于“while cycle”,你问过:你需要 开发“提取”这样的信息的能力 现有的例子。你可以探索不同的方面 通过尝试删除尽可能多的代码来实现现有代码 并且仍然可以为你感兴趣的东西工作 (使用print语句来了解正在发生的事情 上)。这是一种很好的学习方式。

从我的第一篇文章中删除了创建该循环的循环 平均值/赔率列表。当你试图跑步时,你会发现它是什么 从错误消息中丢失(依赖项) 只需根据需要定义它们:

(define x 1)
(define max 5)

(define (loop y evens odds)
  (if (<= y max)
      (loop (add1 y)
            (if (even? y)   (cons (cons x y) evens)   evens)
            (if (odd?  y)   (cons (cons x y) odds)    odds))
      (list (reverse odds) (reverse evens))))
(loop  1 '()  '())

添加一个print语句以获取有关方法的信息 它有效:

(定义x 1) (定义最大5) (定义y-start 1)

(define (loop y evens odds)
  (if (<= y max)
      (begin
        (printf "section 1 :  y=~a~n" y)
        (loop (add1 y)
              (if (even? y)   (cons (cons x y) evens)   evens)
              (if (odd?  y)   (cons (cons x y) odds)    odds)))
      (begin
        (printf "section 2 :  y=~a~n" y)
        (list (reverse odds) (reverse evens))
        )))

(loop  y-start '()  '())

现在删除您不感兴趣或不需要的部分, 这可能需要一些探索:

(let*([max   5])

  (define (loop y)
    (if (<= y max)
        (begin
          (printf "section 1 :  y=~a~n" y)
          (loop (add1 y)))
        (begin
          (printf "section 2 :  y=~a~n" y)
          '()
          )))
  (loop  1))

现在你应该能够更容易地看到一个机制了 递归while循环并将其用作简单模板 适用于其他情况。

我希望这会有所帮助,我希望它不会越界 关于“主观问题”的指导方针 - 我是新手 这个网站,并希望适应,因为它看起来很棒 资源。

答案 1 :(得分:2)

; position l e a coluna c.
(define (do-pos l c)
  (if (and (integer? l) (integer? c) (>= l 0) (>= c 0) (<= l 7) (<= c 7))
      (cons l c)
      (error "insert a valid number between 0 and 7")))


; returns l
(define (line-pos p)
    (car p))

; returns c
(define (column-pos p)
    (cdr p))

; Arg is position.
(define (pos? arg) 
  (and (pair? arg) (integer? (line-pos arg)) (integer? (column-pos arg)) (< (car arg) 8) (>= (car arg) 0) (< (cdr arg) 8) (>= (cdr arg) 0)))

; two positions are equal?
(define (pos=? p1 p2)
  (and (= (line-pos p1)(line-pos p2))(= (column-pos p1)(column-pos p2))))

(define (oper* x y)
  (* (- x y) (- x y)))

; Distance between p1 e p2.
(define (distance p1 p2)
  (sqrt (+ (oper* (line-pos p1) (line-pos p2)) (oper* (column-pos p1) (column-pos p2)))))


; Same directions? if same line and same column
(define (same-direction? p1 p2)
  (or (= (line-pos p1) (line-pos p2)) (= (column-pos p1) (column-pos p2))))

; check if to positions are adjacent
(define (adjacent? p1 p2)
  (and (same-direccao? p1 p2) (= (distance p1 p2) 1)))

; from a position, returns all adjacents moves

(define (adjacent p) (cond ((and (= (line-pos p) 0) (= (column-pos p) 0)) (list (faz-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
                         ((and (= (line-pos p) 7) (= (column-pos p) 7)) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
                         ((= (line-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
                         ((= (column-pos p) 0) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1))))
                         ((= (line-pos p) 7) (list (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))
                         ((= (column-pos p) 7) (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (- (column-pos p) 1))))
                         (else (list (do-pos (+ (line-pos p) 1) (column-pos p)) (do-pos (- (line-pos p) 1) (column-pos p)) (do-pos (line-pos p) (+ (column-pos p) 1)) (do-pos (line-pos p) (- (column-pos p) 1))))))

; returns a move with p1 and p2

(define (do-game p1 p2)
  (if (and (pos? p1) (pos? p2))
      (list p1 p2)
      (error "Insert two valid positions")))


   ; returns the beguining of j.

(define (b-do-game j)
  (car j))

; returns the end of j.

(define (e-do-hame j)
  (car (cdr j)))

; Arg is a do-game?.
(define (do-game? arg)
  (and (list? arg) (pos? (b-do-game arg)) (pos? (e-do-game arg))))

; do game is null?.
(define (do-game-null? j)
  (pos=? (b-do-game j) (e-do-game j)))

; list with two do-game (pc and pl)
(define (play-pos pc pl)
  (if (and (list? pc) (list? pl))
      (list pc pl)
      (error "Insere two valid moves")))

; returns pc.

(define (cap-pieces pj)
  (b-do-game pj))

; returns pj

(define (free_pieces pj)
  (e-do-game pj))



(define (neven n) 
  (if (even? n) 
      n (+ n 1)))

; create sublists

    (define (sublist a mn mx)
      (cond ((<= mn mx) (cons (do-pos a mn) (sublist a (+ mn 2) mx)))
            (else '())))

(define (sublist2 a mn mx)
  (cond ((<= mx (- mn 2)) (cons (do-pos a (- mn 2)) (sublist2 a (- mn 2) mx)))
        (else '())))

(define (sublist3 a mn mx)
  (cond ((<= mn mx) (cons (do-pos mn a) (sublist3 a (+ mn 2) mx)))
        (else '())))

(define (sublist4 a mn mx)
  (cond ((<= mx (- mn 2)) (cons (do-pos (- mn 2) a) (sublist4 a (- mn 2) mx)))
        (else '())))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


; Returns game-positions
(define (game-positions j)
  (if (not (and (do-game? j) (same-direction? (b-do-game j) (e-do-game j)) (even? (distance (b-do-game j) (e-do-game j)))))
      (list)
      (if (= (line-pos (b-do-game j)) (line-pos (e-do-game j)))
             (f_odd_even? j)
             (f_odd_even2? j))))

; Check is starts with odd or even.

(define (f_odd_even? j) (if (even? (column-pos (b-do-game j)))
                           (b_even j)
                           (b_odd j)))

(define (f_odd_even2? j) (if (even? (line-pos (b-do-jogada j)))
                           (b-even1 j)
                           (b_odd1 j)))


; If starts with odd:

(define (b_odd j)
   (if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
       (list (sublist (line-pos (b-do-game j))
                      (neven (column-pos (b-do-game j)))
                      (column-pos (e-do-game j)))

             (sublist (line-pos (b-do-game j)) 
                      (+ 1 (neven (column-pos (b-do-game j)))) 
                      (column-pos (e-do-game j))))

       (list (sublist2 (line-pos (b-do-game j))
                      (+ 1 (column-pos (b-do-game j)))
                      (column-pos (e-do-game j)))

             (sublist2 (line-pos (b-do-game j))
                      (column-pos (b-do-game j))
                      (- 1 (column-pos (e-do-game j)))))))


(define (b_even j)
   (if (< (column-pos (b-do-game j)) (column-pos (e-do-game j)))
       (list (sublist (line-pos (b-do-game j))
                      (+ 2 (neven (column-pos (b-do-game j))))
                      (column-pos (e-do-game j)))

             (sublist (line-pos (b-do-game j)) 
                      (+ 1 (neven (column-pos (b-do-game j)))) 
                      (column-pos (e-do-game j))))

       (list (sublist2 (line-pos (b-do-game j))
                      (column-pos (b-do-game j))
                      (column-pos (e-do-game j)))

             (sublist2 (line-pos (b-do-game j))
                      (+ 1 (column-pos (b-do-game j)))
                      (column-pos (e-do-game j))))))



(define (b_odd1 j)
   (if (< (line-pos (b-do-game j)) (column-pos (e-do-game j)))
       (list (sublist3 (column-pos (b-do-game j))
                      (neven (line-pos (b-do-game j)))
                      (line-pos (e-do-game j)))

             (sublist3 (column-pos (b-do-game j)) 
                      (+ 1 (neven (line-pos (b-do-game j)))) 
                      (line-pos (e-do-game j))))

       (list (sublist4 (column-pos (b-do-game j))
                      (+ 1 (line-pos (b-do-game j)))
                      (line-pos (e-do-game j)))

             (sublist4 (column-pos (b-do-game j)) 
                      (line-pos (b-do-game j))
                      (- 1 (line-pos (e-do-game j)))))))


(define (b_even1 j)
   (if (< (line-pos (b-do-game j)) (line-pos (e-do-game j)))
       (list (sublist3 (column-pos (b-do-game j))
                      (+ 2 (neven (line-pos (b-do-game j))))
                      (line-pos (e-do-game j)))

             (sublist3 (column-pos (b-do-game j)) 
                      (+ 1 (neven (line-pos (b-do-game j)))) 
                      (line-pos (e-do-game j))))

       (list (sublist4 (column-pos (b-do-game j))
                      (line-pos (b-do-game j))
                      (line-pos (e-do-game j)))

             (sublist4 (column-pos (b-do-game j)) 
                      (+ 1 (line-pos (b-do-game j)))
                      (line-pos (e-do-game j))))))
  • 这是我正在制作的游戏的第一部分,我正在将变量从葡萄牙语翻译成英语,所以它可能会有一些错误。

Dlm,您可以使用“while cicles”在代码中执行相同操作吗?

你能检查我的代码并改进它吗?我正在努力提高我的编程技巧,它是从我的代码开始的,Basicaly我希望得到一种编程风格

答案 2 :(得分:0)

我在计划中有点生疏,我已经设法解决了你的问题, 它使用recursion vs while,但我不习惯在scheme中构造:

(define data (list (cons 1 1) (cons 1 7)))

(define (neven n) (if (even? n) n (+ n 1)))

(define (sublist a mn mx) 
  (cond 
    ((<= mn mx ) (cons (cons a mn) (sublist a (+ mn 2) mx)))
    (else '())))

(define (game-position input)
   (if (= (caar input) (caadr input))
       (list (sublist (caar input) 
                      (neven (cdar input)) 
                      (cdadr input))
             (sublist (caar input) 
                      (+ 1 (neven (cdar input))) 
                      (cdadr input)))
       (error "no match")))

(game-position data)

编辑:它适用于guile和drscheme。希望它也适用于plt-scheme。 编辑:子列表内部工作

首先是参数:

  • a是包含在列表中的对的汽车
  • mn是第一对的cdr
  • mx是系列的上限。

功能的主体非常简单:

如果当前对的cdr小于或等于上限,则返回一个列表 由一对(a.mn)和由mn参数调用的子列表创建的列表组成,以反映下一个可能的对。 如果当前对将具有高于上限的cdr,则返回null(空列表)以关闭先前调用子列表发出的缺点。

答案 3 :(得分:0)

我一直在努力学习球拍/方案 现在,这个网站看起来像是一个分享的好地方 向别人学习。

我不是100%肯定这个问题的规范 怀疑我的代码实际上解决了这个问题 在手边,但我认为它足够可读,可以修改 根据需要

可读性是我一直在努力的事情之一 并希望得到其他人的反馈/建议。

DLM。

我的2美分:

(define (process-list? lst)
  (let*([pair-0   (list-ref lst 0)]
        [pair-1   (list-ref lst 1)])
    (and    (=   (car pair-0)  (car pair-1))
            (<   (cdr pair-0)  (cdr pair-1)))))

(define (make-odd/even-sets data) 
  (let*([x         (car (list-ref data 0))]
        [y-start   (cdr (list-ref data 0))]
        [max       (cdr (list-ref data 1))])

    (define (loop y evens odds)
      (if (<= y max)
          (loop (add1 y)
                (if (even? y)   (cons (cons x y) evens)   evens)
                (if (odd?  y)   (cons (cons x y) odds)    odds))
          (list (reverse odds) (reverse evens))))
    (loop  y-start '()  '())))

(define (main data)
  (if (process-list? data)
      (let*([odd/even   (make-odd/even-sets data)])
        (printf "~a~n" (list-ref odd/even 0))
        (printf "~a~n" (list-ref odd/even 1)))
      (printf "Invalid list~n" )))

(main  '((1 . 1) (1 . 7)) )