方案:如何创建简单的" Ouija Board" (字符串程序)

时间:2014-03-07 19:36:33

标签: scheme

使用字符串“ABCDEFGHIJKLMNOPQRSTUVWXYZ”。最初从字母表的索引“0”开始,我将跟踪每次“planchette”向左或向右移动。如果planchette盘旋,那么我将记录那封信。我将在我的函数中使用string-length,string-ref和list->字符串。

(define alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

(trace-define ouija
  (lambda (ls1 ls2)
    (ouija-help ls1 alphabet 0)))

(trace-define ouija-help
  (lambda (ls1 ls2 x)
    (cond
      [(and (equal? (car ls1) 'left) (equal? (string-ref ls2 x) 'a)) (list->string (cons 'a (ouija-help (cdr ls1) ls2 x)))]
      [(and (equal? (car ls1) 'right) (equal? (string-ref ls2 x) 'z)) (list->string (cons 'z (ouija-help (cdr ls1) ls2 x)))]
      [(equal? (car ls1) 'right) (string-ref (string-ref ls2 x) (+ x 1))]
      [(equal? (car ls1) 'left) (string-ref (string-ref ls2 x) (+ x 1))]
      [(equal? (car ls1) 'hover) (list->string (cons (string-ref ls2 x) (ouija-help (cdr ls1) ls2 x)))]
      )))

正确的输入/输出示例:

〜(ouija'()字母)
“”

〜(ouija'(悬停)字母)
“A”

〜(ouija'(右悬停悬停悬停悬停)字母表)
“BBBBB”

〜(ouija'(悬停右悬停右侧悬停)字母)
“ABC”

〜(ouija'(右右悬停左侧悬停左侧悬停右侧悬停)字母)
“DCBC”

3 个答案:

答案 0 :(得分:1)

我会选择这样的事情:

(define (ouija actions board)
  (define imax (- (string-length board) 1))
  (define (helper actions i)
    (if (null? actions)
        '()
        (case (car actions)
          ((hover) (cons (string-ref board i) (helper (cdr actions) i)))
          ((left)  (helper (cdr actions) (if (> i 0) (- i 1) i)))
          ((right) (helper (cdr actions) (if (< i imax) (+ i 1) i))))))
  (list->string (helper actions 0)))

(define helper
  (lambda (actions board i)
    (if (null? actions)
        '()
        (case (car actions)
          ((hover) (cons (string-ref board i) (helper (cdr actions) board i)))
          ((left)  (helper (cdr actions) board (if (> i 0) (- i 1) i)))
          ((right) (helper (cdr actions) board (if (< i (- (string-length board) 1)) (+ i 1) i)))))))

(define ouija
  (lambda (actions board)
    (list->string (helper actions board 0))))

答案 1 :(得分:1)

这是实现图灵机磁带时常用的另一种方法:

alphabet变为list,然后取消carcdr将列表拆分为三个部分:left,{{1} },center;从而解压缩列表。这些操作以与列表拉链相同的方式影响列表。

请注意,没有索引甚至数字。

right

答案 2 :(得分:0)

当您走过“悬停”列表时,请勿处理字母表;而是将'悬停'列表视为基于left - &gt;生成指数减1和right - &gt;加一个。有了这个,顶级功能将是:

(define ouija
  (lambda (actions alphabet)
     (list->string (map (lambda (index) (string-ref alphabet index))
                        (actions->indices actions 0)))))

现在,在添加或减去后,执行操作以创建索引列表。

(define actions->indices
  (lambda (actions index)
    (if (null? actions)
        '()
        (let ((rest (cdr actions)))
          (case (car actions)
            ((hover) (cons index (actions->indices rest index)))
            ((left ) (actions->indices rest (- index 1)))
            ((right) (actions->indices rest (+ index 1))))))))


> (actions->indices '(hover hover) 0)
(0 0)
> (actions->indices '(hover right left hover) 0)
(0 0)
> (actions->indices '(right right hover right right hover) 0)
(2 4)

最后:

> (ouija '(hover right right hover) "ABCDEF")
"AC"