Scheme 方案:如何创建简单的;“占卜板”;(字符串过程)

Scheme 方案:如何创建简单的;“占卜板”;(字符串过程),scheme,Scheme,使用字符串“abcdefghijklmnopqrstuvxyz”。最初从字母表的索引“0”开始,我将跟踪“planchette”每次向左或向右移动的情况。如果planchette悬停,那么我将记录这封信。我将在函数中使用字符串长度、字符串引用和列表->字符串 (define alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ") (trace-define ouija (lambda (ls1 ls2) (ouija-help ls1 alphabet 0))

使用字符串“abcdefghijklmnopqrstuvxyz”。最初从字母表的索引“0”开始,我将跟踪“planchette”每次向左或向右移动的情况。如果planchette悬停,那么我将记录这封信。我将在函数中使用字符串长度、字符串引用和列表->字符串

(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”

我喜欢这样的东西:

(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)))
(定义(占卜动作板)
(定义imax(-(字符串长度板)1))
(定义(辅助操作i)
(如果(空?操作)
'()
(案例(汽车行动)
((悬停)(cons(字符串参考板i)(助手(cdr操作)i)))
((左)(助手(cdr操作)(如果(>i0)(-i1)i)))
((右)(助手(cdr动作)(如果(字符串(助手操作0)))

(定义助手)
(lambda(行动委员会一)
(如果(空?操作)
'()
(案例(汽车行动)
((悬停)(cons(字符串参考板i)(助手(cdr操作)板i)))
((左)(助手(cdr操作)板(如果(>i0)(-i1)i)))
((右)(助手(cdr动作)板(如果(字符串(助手操作板0)))

在浏览“悬停”列表时,不要处理字母表;相反,“悬停”列表是基于
->减去1和
->添加1生成索引。这样,顶级功能将是:

(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"

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

字母表
变成
列表
,然后取下
汽车
cdr
将列表分成三部分:
左侧
中间
右侧
;从而解压缩列表。这些操作对列表的影响方式与列表拉链相同

请注意,没有索引或偶数

(define (ouija-helper actions left center right)
  (if (null? actions) 
      '()
      (case (car actions)
        ((hover) (cons center (ouija-helper (cdr actions) left center right)))
        ((left) (if (null? left) 
                    (ouija-helper (cdr actions) left center right)
                    (ouija-helper (cdr actions) (cdr left) (car left) (cons center right))))
        ((right) (if (null? right) 
                     (ouija-helper (cdr actions) left center right)
                     (ouija-helper (cdr actions) (cons center left) (car right) (cdr right)))))))

(define (ouija actions alphabet) 
  (let ((alphabet (string->list alphabet)))
    (list->string (ouija-helper actions '() (car alphabet) (cdr alphabet)))))

我真的很抱歉。。。我完全忘了包括我不允许使用内置过程:reverse、length、append或assoc。也不是
string length
?我要在我的过程中使用string length、string ref和list->string。这本身不是循环。这只是一个叫做循环的过程。你可以叫它helper,或者任何东西。我会更新我的答案。另一个
define
内部的
define
只是一个本地定义,这意味着符号
imax
helper
仅在
ouija
内部已知。此外,这种方式在
helper
中是已知的,而无需将其作为参数传递。我添加了一个更像你最初的版本。
(define (ouija-helper actions left center right)
  (if (null? actions) 
      '()
      (case (car actions)
        ((hover) (cons center (ouija-helper (cdr actions) left center right)))
        ((left) (if (null? left) 
                    (ouija-helper (cdr actions) left center right)
                    (ouija-helper (cdr actions) (cdr left) (car left) (cons center right))))
        ((right) (if (null? right) 
                     (ouija-helper (cdr actions) left center right)
                     (ouija-helper (cdr actions) (cons center left) (car right) (cdr right)))))))

(define (ouija actions alphabet) 
  (let ((alphabet (string->list alphabet)))
    (list->string (ouija-helper actions '() (car alphabet) (cdr alphabet)))))