条件付き確率の問題をモンテカルロ法で解く

30分プログラム、その768。http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_269にインスパイアされました。

こういう打ち切り所をカチっと決めれない問題は、無限リストを使ってやるのがいいですよね。

使い方

gosh> (calc 10)
0.6
gosh> (calc 100)
0.34285714285714286

ソースコード

#! /opt/local/bin/gosh
;; -*- mode:scheme; coding:utf-8 -*-

(use srfi-27)
(use util.stream)
(define (rand-child)
  (if (= (random-integer 2) 0)
      'boy
      'girl))

(define (child-stream)
  (stream-map (lambda (_) (rand-child))
	      (stream-iota -1)))
(define try-stream
  (let ([xs (child-stream)]
	[ys (child-stream)])
    (stream-map cons xs ys)))

(define (peek s)
  (stream->list (stream-take s 2)))

(define (either-boy? pair)
  (or (eq? (car pair) 'boy)
      (eq? (cdr pair) 'boy)))

(define (both-boy? pair)
  (and (eq? (car pair) 'boy)
       (eq? (cdr pair) 'boy)))

(define (calc n)
  (let1 xs (stream-filter either-boy? (stream-take try-stream n))
	(/. (stream-length (stream-filter both-boy? xs))
	    (stream-length xs))))