A variable independent of its local scope.

huangapple go评论61阅读模式
英文:

A varaible independent its local scope

问题

I tried to solve the twoSum Problem with primitive tools of car and cdr

给定一个整数数组,返回两个数字的索引,使它们的和等于特定目标。

您可以假设每个输入都只有一个解决方案,并且不能重复使用相同的元素。

例子:

给定 nums = [2, 7, 11, 15],target = 9,

因为 nums[0] + nums[1] = 2 + 7 = 9,返回 [0, 1]。

The idea is to take a x from nums, then check if x's complement (target - x) is a member of set nums - x

The key logic is

if ((memberp complement (remove-first x nums))
then (list x complement))

Begin with a helper function try nums

(defun two-sum (nums target)
(try nums))

The main function:

(defun try (nums)
(let ((x (car nums))
(complement (- target x)))
(cond
((null x) '())
((memberp complement (remove-first x nums))
(list x complement))
(t (try (cdr nums)))
)))

Then I realize that nums in ((memberp complement (remove-first x nums)) should stay unchanged and independent from the local scope of let.

How could I get such nums?

memberp and `remove-first':

(defun remove-first (item sequence)
(filter (lambda (x) (not (= x item)))
sequence))

(defun filter (predicate sequence)
(cond ((null sequence) nil)
((funcall predicate (car sequence))
(cons (car sequence)
(filter predicate
(cdr sequence))))
(t (filter predicate
(cdr sequence)))))

(defun memberp (item x)
(cond ((null x) 'false)
((equal item (car x)) x)
(t (memq item (cdr x)))))

英文:

I tried to solve the twoSum Problem with primitive tools of car and cdr

> Given an array of integers, return indices of the two numbers such
> that they add up to a specific target.
>
> You may assume that each input would have exactly one solution, and
> you may not use the same element twice.
>
> Example:
>
> Given nums = [2, 7, 11, 15], target = 9,
>
> Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

The idea is to take a x from nums, then check if x's complement (target -x) is member of set nums-x

The key logic is

if ((memberp complement (remove-first x nums)) 
then  (list x complement))

Begin with a helper function try nums

(defun two-sum (nums target)
 (try nums))

The main function:

(defun try (nums)
  (let ((x (car nums))
        (complement (- target x)))
    (cond
     ((null x) '())
     ((memberp complement (remove-first x nums))
      (list x complement))
     (t (try (cdr nums)))
     )))

Then I realize that nums in ((memberp complement (remove-first x nums)) should be stay unchanged and independent from the local scope of let.

How could get such a nums?

memberp and `remove-first'

(defun remove-first (item sequence)
  (filter (lambda (x) (not (= x item)))
          sequence))

(defun filter (predicate sequence)
  (cond ((null sequence) nil)
        ((funcall predicate (car sequence))
         (cons (car sequence)
               (filter predicate
                       (cdr sequence))))
        (t  (filter predicate
                    (cdr sequence)))))

(defun memberp(item x)
  (cond ((null x) 'false)
        ((equal item (car x)) x)
        (t (memq item (cdr x)))))

答案1

得分: 1

以下是用于计算索引的简单递归函数:

(defun two-sum (list target &optional (pos 0))
  (if (null (cdr list))
      nil
      (let ((p (my-position (- target (car list)) list)))
    	(if p
    	    (list pos (+ pos p))
    	    (two-sum (cdr list) target (1+ pos))))))

(defun my-position (element list &optional (pos 0))
  (cond ((null list) nil)
	    ((eql element (car list)) pos)
	    (t (my-position element (cdr list) (1+ pos)))))

该函数最初使用列表和目标调用。初始时未传递给函数的参数 pos 会自动分配为0,在后续调用中,它将递增一次,以跟踪列表当前元素的索引。

第一个条件检查列表是否少于两个元素:如果为空(或其 cdr 为空),则结果为 nil,因为没有可能的解决方案(请注意,在Common Lisp中,(cdr nil)nil)。

否则,我们计算在列表的其余部分中“补数”(请注意,position 是一个原始函数,所以我称其重写为 my-position)。如果元素存在,我们返回 pos(+ pos p)(因为找到的位置是相对于当前位置的),否则(当没有找到元素时,my-position 返回 nil)我们对列表的其余部分进行递归。

请注意,使用这种方法,无需每次考虑列表的所有元素。

英文:

Here is a simple recursive function to compute the indexes:

(defun two-sum (list target &optional (pos 0))
  (if (null (cdr list))
      nil
      (let ((p (my-position (- target (car list)) list)))
	    (if p
	        (list pos (+ pos p))
	        (two-sum (cdr list) target (1+ pos))))))

(defun my-position (element list &optional (pos 0))
  (cond ((null list) nil)
	    ((eql element (car list)) pos)
	    (t (my-position element (cdr list) (1+ pos))))) 

The function is initially called with the list and the target. The parameter pos, which initially is not passed to the function, is assigned automatically to 0, and in the subsequent calls it will be incremented by one, so that it tracks the index of the current element of the list.

The first condition checks if the list has less than two elements: if it is empty (or its cdr is empty) the result is nil since no solution is possibile (note that in Common Lisp (cdr nil) is nil).

Otherwise we compute the position of the “complement” of the number in the rest of the list (note that position is a primitive function, so I called my-position its rewriting). If the element is present, we return both pos and (+ pos p) (since the position found is relative to the current position), otherwise (my-position returns nil when no element is found) we recur on the rest of the list.

Note that with this method there is no need to consider every time all the elements of the list.

huangapple
  • 本文由 发表于 2020年1月6日 22:50:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/59614143.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定