2014-09-11 4 views
-2
(define (diagonal? col a) 
(cond 
    [(null? a) #f] 
    [(= (abs(- (car a) col)) (abs (- (+ (length a) 1) (length a))))] 
    [else #f])) 

Я хочу, чтобы это повторное повторение второго условия в списке a и возвращалось только true или false, если оно достигло конца списка. Я также не хочу, чтобы он вообще менял список.Racket Iterations and Recursion

Я хочу, чтобы получить

>(iQueens '(1 2 3 4) '()) 
> (iQueens '(2 3 4) '(1)) 
> >(iQueens '(2 4) '(3 1)) 
< <'() 
> >(iQueens '(2 3) '(4 1)) 
> >(iQueens '(3) '(2 4 1)) 
< < '() 
< <'() 
< '() 

Но я получаю

>(iQueens '(1 2 3 4) '()) 
> (iQueens '(2 3 4) '(1)) 
> >(iQueens '(2 4) '(3 1)) 
< <'() 
> >(iQueens '(2 3) '(4 1)) 
< <'() 
< '() 

ввода/вывода, включая "диагонали?"

>(iQueens '(1 2 3 4) '()) 
> (diagonal? 1 '()) 
< #f 
> (iQueens '(2 3 4) '(1)) 
> >(diagonal? 2 '(1)) 
< <#t 
> >(diagonal? 3 '(1)) 
> >(diagonal? 3 '()) 
< <#f 
> >(iQueens '(2 4) '(3 1)) 
> > (diagonal? 2 '(3 1)) 
< < #t 
> > (diagonal? 4 '(3 1)) 
< < #t 
< <'() 
> >(diagonal? 4 '(1)) 
> >(diagonal? 4 '()) 
< <#f 
> >(iQueens '(2 3) '(4 1)) 
> > (diagonal? 2 '(4 1)) 
> > (diagonal? 2 '(1)) 
< < #t 
> > (diagonal? 3 '(4 1)) 
< < #t 
< <'() 
< '() 
> (diagonal? 2 '()) 
< #f 
> (iQueens '(1 3 4) '(2)) 
> >(diagonal? 1 '(2)) 
< <#t 
> >(diagonal? 3 '(2)) 
< <#t 
> >(diagonal? 4 '(2)) 
> >(diagonal? 4 '()) 
< <#f 
> >(iQueens '(1 3) '(4 2)) 
> > (diagonal? 1 '(4 2)) 
> > (diagonal? 1 '(2)) 
< < #t 
> > (diagonal? 3 '(4 2)) 
< < #t 
< <'() 
< '() 
> (diagonal? 3 '()) 
< #f 
> (iQueens '(1 2 4) '(3)) 
> >(diagonal? 1 '(3)) 
> >(diagonal? 1 '()) 
< <#f 
> >(iQueens '(2 4) '(1 3)) 
> > (diagonal? 2 '(1 3)) 
< < #t 
> > (diagonal? 4 '(1 3)) 
> > (diagonal? 4 '(3)) 
< < #t 
< <'() 
> >(diagonal? 2 '(3)) 
< <#t 
> >(diagonal? 4 '(3)) 
< <#t 
< '() 
> (diagonal? 4 '()) 
< #f 
> (iQueens '(1 2 3) '(4)) 
> >(diagonal? 1 '(4)) 
> >(diagonal? 1 '()) 
< <#f 
> >(iQueens '(2 3) '(1 4)) 
> > (diagonal? 2 '(1 4)) 
< < #t 
> > (diagonal? 3 '(1 4)) 
> > (diagonal? 3 '(4)) 
< < #t 
< <'() 
> >(diagonal? 2 '(4)) 
> >(diagonal? 2 '()) 
< <#f 
> >(iQueens '(1 3) '(2 4)) 
> > (diagonal? 1 '(2 4)) 
< < #t 
> > (diagonal? 3 '(2 4)) 
< < #t 
< <'() 
> >(diagonal? 3 '(4)) 
< <#t 
< '() 
<'() 
0 

Я думаю, что, наконец, понимаю, что моя логика этого состояния неверна. Но логика имеет смысл для меня на бумаге. Можете ли вы предложить мне намек на то, где я ошибаюсь в логике во второй части условия? Я был настолько восприимчив к тому, что выход был настолько похож на тот ответ, который мне нужен. Я понял, что мой код должен быть неправильным, а не моей логикой.

* Редактировать

(define (diagonal? col a count) 
(if 
    (null? a) 
    #f 
    (if(or (= (car a) (+ col count)) (= (car a) (- col count))) 
    #t 
(diagonal? col (cdr a) (+ 1 count)) 
))) 

Эта логика работает ... но я был вынужден использовать подсчет ... Я до сих пор не могу понять, как я могу изменить это, чтобы не использовать третий параметр, я пытался избегать.

* Редактировать

Чтобы получить вышеуказанные диагоналей работы я использовал

(λ(x) (if(not (diagonal? x a 1)) 
       (iQueens (remove x l) (cons x a)) 
       '())) 
       l))) 

ВЫЗОВ МАСТЕРА за то, что я хочу, это

(λ(x) (cond 
      [(diagonal? x a) (cdr l) '()] 
      [else (iQueens (remove x l) (cons x a))]))l))) 
+0

Можете ли вы объяснить на словах, что должно делать второе условие? это должно быть верно для всех элементов в списке, или это достаточно, если это правда только для одного? Мы не знаем содержимое 'a', вы должны отправить образец ввода с ожидаемым выходом для одного случая, когда эта процедура вернет true, а другая - при возврате false –

+0

Вы имеете в виду, что процедура' diagonal' не называет себя? В действительности это не так, поскольку в процедуре нет вызова диагонали. Является ли 'a' списком? – uselpa

+1

Пожалуйста, отредактируйте свой вопрос и отредактируйте его до * essential *: одно или ограниченное количество репрезентативных входных данных, которые у вас есть, ваша процедура, и для каждого ввода ожидаемый результат и полученный результат. – uselpa

ответ

0

Вы до сих пор не дали пример ввода и вывода для diagonal?, но вот моя попытка:

(define (diagonal? col len elt) 
    (= (abs (- elt col)) 
    (abs (- (+ len 1) len)))) ; this is constant 1 

(define (diagonals? col lst) 
    (define len (length lst)) 
    (andmap (lambda (elt) (diagonal? len col elt)) lst)) 

diagonal? работает только с одним элементом, а diagonals? обрабатывает весь список.

Как вы видите, выражение (abs (- (+ len 1) len))) на самом деле является константой 1, так что это, вероятно, неверно в вашей первоначальной процедуре. Кроме того, я предположил, что вы хотите, чтобы все Элементы списка должны проверять предикат, в противном случае вам нужно будет использовать ormap вместо andmap.

> (diagonals? 2 '(4 1)) 
#f 

EDIT

Я могу только догадываться, учитывая, что вам не дают достаточно информации, но, возможно, это помогает, если предположить, отсчет начинается с 0 (если нет, то просто изменить in-naturals вызов):

(define (diagonal? col a) 
    (for/or ((i (in-list a)) (count (in-naturals))) 
    (or (= i (+ col count)) (= i (- col count))))) 
+0

Хорошо, я понял это с помощью третьего параметра. Могу ли я изменить это для работы в ракетке только с двумя исходными параметрами? – ThisGuy

+0

Смотрите мое обновление, пожалуйста. – uselpa

0

Поскольку вы используете Racket (язык) и не Scheme или Common Lisp (какая схема и сюсюкать ваши метки указывают), вы можете просто указать значение по умолчанию:

(define (diagonal? col a (count 0)) 
    (cond ((null? a) #f) 
     ((or (= (car a) (+ col count)) 
      (= (car a) (- col count))) 
     #t) 
     (else (diagonal? col (cdr a) (+ 1 count))))) 

В Scheme (другой язык, чем ракетку также поддерживается за счет внедрения ракеток) есть 2 способа экспонировать процедуру с меньшим количеством аргументов, чем то, что вы используете в вашей рекурсивной процедуры. Одним из них являются местными процедурами:

(define (diagonal? col a) 
    (define (diagonal? col a count) 
    (cond ((null? a) #f) 
      ((or (= (car a) (+ col count)) 
       (= (car a) (- col count))) 
      #t) 
      (else (diagonal? col (cdr a) (+ 1 count))))) 
    (diagonal? col a 0)) ;; add default values 

Или вы можете использовать именованные аренды:

(define (diagonal? col a) 
    (let diagonal? ((col col) (a a) (count 0)) 
    (cond ((null? a) #f) 
      ((or (= (car a) (+ col count)) 
       (= (car a) (- col count))) 
      #t) 
      (else (diagonal? col (cdr a) (+ 1 count)))))) 

Это просто синтаксический сахар для первого примера схемы. Ракетка (язык) поддерживает оба этих параметра.

В Lisp у вас есть дополнительные аргументы снова:

(defun diagonalp (col a &optional (count 0)) 
    (cond ((null a) nil) 
     ((or (= (car a) (+ col count)) 
      (= (car a) (- col count))) 
     t) 
     (t (diagonalp col (cdr a) (+ 1 count))))) 

Это просто более простой способ сделать и использовать процедуру. В обоих случаях вы делаете локальную процедуру с тем же именем, что и открытая процедура. Некоторые люди хотят использовать разные имена или использовать aux postfix. Это просто разница во вкусе, если вам не нужно вызывать как локальную, так и глобальную версию.