From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Ian Price Newsgroups: gmane.lisp.guile.devel,gmane.lisp.guile.user Subject: Re: Fun with guile, Erastones + goldbach conjecture Date: Wed, 10 Apr 2013 01:11:13 +0100 Message-ID: <87txnf1bz2.fsf@Kagami.home> References: <1551498.g80VkUsTQo@warperdoze> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1365552691 16099 80.91.229.3 (10 Apr 2013 00:11:31 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 10 Apr 2013 00:11:31 +0000 (UTC) Cc: guile-user@gnu.org, guile-devel@gnu.org To: Stefan Israelsson Tampe Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Wed Apr 10 02:11:34 2013 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1UPidS-00010P-5U for guile-devel@m.gmane.org; Wed, 10 Apr 2013 02:11:34 +0200 Original-Received: from localhost ([::1]:39773 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UPidR-0005uw-M7 for guile-devel@m.gmane.org; Tue, 09 Apr 2013 20:11:33 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:60917) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UPidK-0005rk-TH for guile-devel@gnu.org; Tue, 09 Apr 2013 20:11:27 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UPidJ-0001mw-Oo for guile-devel@gnu.org; Tue, 09 Apr 2013 20:11:26 -0400 Original-Received: from mail-wi0-x230.google.com ([2a00:1450:400c:c05::230]:38121) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UPidF-0001lt-G0; Tue, 09 Apr 2013 20:11:21 -0400 Original-Received: by mail-wi0-f176.google.com with SMTP id hm14so4276918wib.15 for ; Tue, 09 Apr 2013 17:11:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=x-received:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=oxLDNhCPCcUv17CQz9r5p5NWnHsia+WLDYQxMgvJiSE=; b=tHMJ/HnkUSwwsqivjWTmumomXMzyltctPKPmMgVNdyRm3qwo/0eqyL8iHRMRQj3ehZ Bw0viJ+EycfAvtPFy0Mbonlaf6GV59b2h6NctSa3oDO7tOymbEdVoxOHmmQDqLFC3A+h l3v3nhrKVpfD5B+r2yB70/p+8CFg/P4X2pGaZMOQhNva4xPW5fZopHziZDh7+DVTittU oGNjwAdUkgtpidHX5YRN1mhz/exHu/X+xngT7Ma53T7futAOOKW7VcSm/qRy739dy0wi iqK8CAI4t0fhZ6oI8FvYfu/URwAsyG/xnRedv9mCOeEzsGJnsEpzHzDgRjFWC8oZfGI+ tihA== X-Received: by 10.180.90.116 with SMTP id bv20mr22700501wib.32.1365552680090; Tue, 09 Apr 2013 17:11:20 -0700 (PDT) Original-Received: from Kagami.home (host86-184-183-126.range86-184.btcentralplus.com. [86.184.183.126]) by mx.google.com with ESMTPS id o5sm32138217wix.3.2013.04.09.17.11.17 (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 09 Apr 2013 17:11:18 -0700 (PDT) In-Reply-To: <1551498.g80VkUsTQo@warperdoze> (Stefan Israelsson Tampe's message of "Tue, 09 Apr 2013 00:03:11 +0200") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::230 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:16210 gmane.lisp.guile.user:10255 Archived-At: Stefan Israelsson Tampe writes: > Hi all, > > The program below is an interesting variant of a sieve that given an > even number seams to constructs two primes that added together becomes > the even > number, the file below does this construction for n = 3 ... 1000. Amusing, but I feel that code like that needs a big massive disclaimer at the top saying "CAUTION: DO NOT ACTUALLY WRITE SCHEME LIKE THIS". Mutable circular lists? No thank you :) Actually, I think you understand this yourself, since the circularity infected all the procedures, and made them a little more complex than they'd usually be. For the newer Schemers, I've added a bunch of annotations. > (use-modules (srfi srfi-1)) > > (define (analyze k) > (define n (* k 2)) > (define l (apply circular-list (map (lambda (X) #f) (iota n)))) Personally, I would move l down closer to where it is being mutated, rather than having a bunch of procedures in the way. > (define (shift l k) > (let loop ((l l) (k k)) > (if (= k 0) > l > (loop (cdr l) (- k 1))))) (define shift drop) > (define (next loop) > (let lp ((ll l) (i 0)) > (if (= i n) > l > (if (car ll) > (lp (cdr ll) (+ i 1)) > (loop i l 0))))) The continuation passing here is a bit weird, I would do two mutually recursive procedures instead. The additional state makes it harder to break into separate procedures, but it feels to me like you should be able change this into a drop-while. > > (define (M) > (let lp ((l l) (k n) (M -1)) > (if (= k 0) > M > (let ((c (caar l))) > (if (< M c) > (lp (cdr l) (- k 1) c) > (lp (cdr l) (- k 1) M)))))) M was a terrible name. :) I'd either suggest moving the if into the third clause of loop, or rewriting this as (define (M) ;; maybe factor into procedure 'maximum-by' (fold-right (lambda (x prev) (max (car x) prev)) -1 (take l n))) Yeah it allocates, but it was either that or write a foldr for cyclic lists. > (define (place x) > (let loop ((ll l) (i 0)) > (if (equal? (car ll) x) > i > (loop (cdr ll) (+ i 1))))) (define (place x) (list-index (lambda (y) (eqv? x y)) l)) > (set-car! (cdr l) (cons 1 0)) > (set-car! (shift l (- n 1)) (cons 1 0)) > (let loop ((m 2) (ll l) (k 0)) > (let ((ll (shift ll m))) > (if (and (pair? (car ll)) (eq? (caar ll) m)) > (next loop) > (begin > (unless (car ll) (set-car! ll (cons m k)) (set! k (+ k 1))) > (loop m ll k))))) Not quite sure what to make of this. > (let* ((M (M)) > (ll (let lp ((ll l) (k n)) > (if (= k 0) > '() > (cons (car ll) (lp (cdr ll) (- k 1)))))) (ll (take l n)) > (ll (fold (lambda (k r)(if (eq? (car k) M) (cons k r) r)) '() ll)) (ll (filter (lambda (x) (eq? (car x) M)) ll)) Granted, that doesn't have the same ordering, but you are sorting the result anyway. > (ll (sort ll (lambda (x y) (< (cdr x) (cdr y)))))) > > (cond > ((= (length ll) 1) > (* (place (car ll)) 2)) > (else > (+ (place (car ll)) (place (car (last-pair ll)))))))) (+ (place (car l1)) (place (last l1))) For the purposes of your demonstration, it doesn't really matter, but it would be a better idea to return those two values, rather than the sum. Otherwise, analyze just becomes a very long-winded doubling function :) > (let lp ((i 3)) > (if (= i 1000) > (pk 'ok) > (begin > (if (not (= (* 2 i) (analyze i))) > (format #t "~a != (analyze ~a) == ~a~%" (* 2 i) (* 2 i) > (analyze (* 2i)))) btw, Typo here ^^^^^^ > (lp (+ i 1))))) > Maybe I'll meditate on this more, and post a "schemier" version. -- Ian Price -- shift-reset.com "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled"