4.3BSD/usr/contrib/icon/src/cmd/parens.icn

#	PARENS(1)
#
#	Produce parenthesis-balanced strings
#
#	Ralph E. Griswold
#
#	Last modified 8/11/84
#

global r, k, lp, rp

procedure main(a)
   local string, i, s, bound, limit, varying
   bound := limit := 10			# default bound and limit
   lp := "("				# default left paren
   rp := ")"				# default right paren
   i := 0
   while s := a[i +:= 1] do
      if s[1] == "-" then
         case s of {
            "-b":   bound := integer(a[i +:= 1]) | Usage()	# bound
            "-n":   limit := integer(a[i +:= 1]) | Usage()	# total number
            "-l":   lp := a[i +:= 1] | Usage()			# left paren
            "-r":   rp := a[i +:= 1] | Usage()			# right paren
            "-v":   varying := 1				# varying length
            default: Usage()
            }
   every 1 to limit do {
      if \varying then k := 2 * ?bound else k := 2 * bound
      string := ""
      r := 0
      while k ~= r do {
         if r = 0 then string ||:= Open()
         else if ?0 < probClose()
            then string ||:= Close() else string ||:= Open()
         }
      while k > 0 do string ||:= Close()
      write(string)
      }
end

procedure Open()
   r +:= 1
   k -:= 1
   return lp
end

procedure Close()
   r -:= 1
   k -:= 1
   return rp
end

procedure probClose()
   return ((r * (r + k + 2)) / (2.0 * k * (r + 1)))
end

procedure Usage()
   stop("usage: parens [-n i -b i -l s -r s]")
end