#!/usr/bin/env racket
#lang racket/base
; --- callback version (fast)
(define (combis_a stcs lpars callback)
(let ((res '()))
(let loop ((stcs (reverse stcs)) (subres '()))
(if (null? stcs)
(begin
(set! res (cons subres res)) ; ditto
(callback subres))
(for-each
(lambda (lpar) (loop (cdr stcs) (cons (cons (car stcs) lpar) subres)))
lpars)))
res))
; --- generator version (slow)
(require racket/generator)
(define (combis_b_gen stcs lpars)
(generator ()
(let loop ((stcs (reverse stcs)) (res '()))
(if (null? stcs)
(yield res)
(for-each
(lambda (lpar) (loop (cdr stcs) (cons (cons (car stcs) lpar) res)))
lpars)))
'done))
; --- main
(let* ((args (current-command-line-arguments))
(numstcs (string->number (vector-ref args 0)))
(stcs (build-list numstcs (lambda (i) (string-append "S_" (number->string i)))))
(numlpars (string->number (vector-ref args 1)))
(lpars (build-list numlpars (lambda (i) (string-append "L_" (number->string i)))))
(verbose (string=? (vector-ref args 2) "y"))
(algo (vector-ref args 3)))
(cond
((string=? algo "a")
(let ((res (combis_a stcs lpars (lambda (i) (when verbose (printf "combis_a: ~v\n" i))))))
(printf "combis_a: total ~a\n" (length res))))
((string=? algo "b")
(let ((res (for/list ((combi (in-producer (combis_b_gen stcs lpars) 'done)))
(when verbose (printf "combis_b: ~v\n" combi)) combi)))
(printf "combis_b: total ~a\n" (length res))))
(else
(printf "unknown command line arguments ~a\n" args))))