object PartitionInteger {

  def sieve(nums: LazyList[Int]): LazyList[Int] =
    LazyList.cons(nums.head, sieve((nums.tail) filter (_ % nums.head != 0)))

  // An 'infinite' stream of primes, lazy evaluation and memo-ized
  private val oddPrimes = sieve(LazyList.from(3, 2))
  private val primes = sieve(2 #:: oddPrimes).take(3600 /*50_000*/)

  private def findCombo(k: Int, x: Int, m: Int, n: Int, combo: Array[Int]): Boolean = {
    var foundCombo = combo.map(i => primes(i)).sum == x
    if (k >= m) {
      if (foundCombo) {
        val s: String = if (m > 1) "s" else ""
        printf("Partitioned %5d with %2d prime%s: ", x, m, s)
        for (i <- 0 until m) {
          print(primes(combo(i)))
          if (i < m - 1) print('+') else println()
        }
      }
    } else for (j <- 0 until n if k == 0 || j > combo(k - 1)) {
      combo(k) = j
      if (!foundCombo) foundCombo = findCombo(k + 1, x, m, n, combo)
    }
    foundCombo
  }

  private def partition(x: Int, m: Int): Unit = {
    val n: Int = primes.count(it => it <= x)
    if (n < m) throw new IllegalArgumentException("Not enough primes")

    if (!findCombo(0, x, m, n, new Array[Int](m)))
      printf("Partitioned %5d with %2d prime%s: (not possible)\n", x, m, if (m > 1) "s" else " ")
  }

  def main(args: Array[String]): Unit = {
    partition(99809, 1)
    partition(18, 2)
    partition(19, 3)
    partition(20, 4)
    partition(2017, 24)
    partition(22699, 1)
    partition(22699, 2)
    partition(22699, 3)
    partition(22699, 4)
    partition(40355, 3)
  }

}


# Generic functions

# Note: 'transpose' is defined in recent versions of jq
def transpose:
  if (.[0] | length) == 0 then []
  else [map(.[0])] + (map(.[1:]) | transpose)
  end ;

# Create an m x n matrix with init as the initial value
def matrix(m; n; init):
  if m == 0 then []
  elif m == 1 then [range(0;n) | init]
  elif m > 0 then
    matrix(1;n;init) as $row
    | [range(0;m) | $row ]
  else error("matrix\(m);_;_) invalid")
  end ;

# A simple pretty-printer for a 2-d matrix
def pp:
  def pad(n): tostring | (n - length) * " " + .;
  def row: reduce .[] as $x (""; . + ($x|pad(4)));
  reduce .[] as $row (""; . + "\n\($row|row)");


func prime_partition(num, parts) {

    if (parts == 1) {
        return (num.is_prime ? [num] : [])
    }

    num.primes.combinations(parts, {|*c|
        return c if (c.sum == num)
    })

    return []
}

var tests = [
    [   18, 2], [   19, 3], [   20,  4],
    [99807, 1], [99809, 1], [ 2017, 24],
    [22699, 1], [22699, 2], [22699,  3],
    [22699, 4], [40355, 3],
]

for num,parts (tests) {
    say ("Partition %5d into %2d prime piece" % (num, parts),
    parts == 1 ? ':  ' : 's: ', prime_partition(num, parts).join('+') || 'not possible')
}


import Foundation

class BitArray {
    var array: [UInt32]

    init(size: Int) {
        array = Array(repeating: 0, count: (size + 31)/32)
    }

    func get(index: Int) -> Bool {
        let bit = UInt32(1) << (index & 31)
        return (array[index >> 5] & bit) != 0
    }

    func set(index: Int, value: Bool) {
        let bit = UInt32(1) << (index & 31)
        if value {
            array[index >> 5] |= bit
        } else {
            array[index >> 5] &= ~bit
        }
    }
}

class PrimeSieve {
    let composite: BitArray

    init(size: Int) {
        composite = BitArray(size: size/2)
        var p = 3
        while p * p <= size {
            if !composite.get(index: p/2 - 1) {
                let inc = p * 2
                var q = p * p
                while q <= size {
                    composite.set(index: q/2 - 1, value: true)
                    q += inc
                }
            }
            p += 2
        }
    }

    func isPrime(number: Int) -> Bool {
        if number < 2 {
            return false
        }
        if (number & 1) == 0 {
            return number == 2
        }
        return !composite.get(index: number/2 - 1)
    }
}

func findPrimePartition(sieve: PrimeSieve, number: Int,
                        count: Int, minPrime: Int,
                        primes: inout [Int], index: Int) -> Bool {
    if count == 1 {
        if number >= minPrime && sieve.isPrime(number: number) {
            primes[index] = number
            return true
        }
        return false
    }
    if minPrime >= number {
        return false
    }
    for p in minPrime..<number {
        if sieve.isPrime(number: p)
            && findPrimePartition(sieve: sieve, number: number - p,
                                  count: count - 1, minPrime: p + 1,
                                  primes: &primes, index: index + 1) {
            primes[index] = p
            return true
        }
    }
    return false
}

func printPrimePartition(sieve: PrimeSieve, number: Int, count: Int) {
    var primes = Array(repeating: 0, count: count)
    if !findPrimePartition(sieve: sieve, number: number, count: count,
                           minPrime: 2, primes: &primes, index: 0) {
        print("\(number) cannot be partitioned into \(count) primes.")
    } else {
        print("\(number) = \(primes[0])", terminator: "")
        for i in 1..<count {
            print(" + \(primes[i])", terminator: "")
        }
        print()
    }
}

let sieve = PrimeSieve(size: 100000)
printPrimePartition(sieve: sieve, number: 99809, count: 1)
printPrimePartition(sieve: sieve, number: 18, count: 2)
printPrimePartition(sieve: sieve, number: 19, count: 3)
printPrimePartition(sieve: sieve, number: 20, count: 4)
printPrimePartition(sieve: sieve, number: 2017, count: 24)
printPrimePartition(sieve: sieve, number: 22699, count: 1)
printPrimePartition(sieve: sieve, number: 22699, count: 2)
printPrimePartition(sieve: sieve, number: 22699, count: 3)
printPrimePartition(sieve: sieve, number: 22699, count: 4)
printPrimePartition(sieve: sieve, number: 40355, count: 3)


' Partition an integer X into N primes
    dim p(),a(32),b(32),v,g: redim p(64)
    what="99809 1  18 2  19 3  20 4  2017 24  22699 1-4  40355 3"
    t1=split(what,"  ")
    for j=0 to ubound(t1)
        t2=split(t1(j)): x=t2(0): n=t2(1)
        t3=split(x,"-"): x=clng(t3(0))
        if ubound(t3)=1 then y=clng(t3(1)) else y=x
        t3=split(n,"-"): n=clng(t3(0))
        if ubound(t3)=1 then m=clng(t3(1)) else m=n
        genp y 'generate primes in p
        for g=x to y
            for q=n to m: part: next 'q
        next 'g
    next 'j

sub genp(high)
    p(1)=2: p(2)=3: c=2: i=p(c)+2
    do 'i
        k=2: bk=false
        do while k*k<=i and not bk 'k
            if i mod p(k)=0 then bk=true
            k=k+1
        loop 'k
        if not bk then
            c=c+1: if c>ubound(p) then redim preserve p(ubound(p)+8)
            p(c)=i
        end if
        i=i+2
    loop until p(c)>high 'i
end sub 'genp

sub getp(z)
    if a(z)=0 then w=z-1: a(z)=a(w)
    a(z)=a(z)+1: w=a(z): b(z)=p(w)
end sub 'getp

function list()
    w=b(1)
    if v=g then for i=2 to q: w=w&"+"&b(i): next else w="(not possible)"
    list="primes: "&w
end function 'list

sub part()
    for i=lbound(a) to ubound(a): a(i)=0: next 'i
    for i=1 to q: call getp(i): next 'i
    do while true: v=0: bu=false
        for s=1 to q
            v=v+b(s)
            if v>g then
                if s=1 then exit do
                for k=s to q: a(k)=0: next 'k
                for r=s-1 to q: call getp(r): next 'r
                bu=true: exit for
            end if
        next 's
        if not bu then
            if v=g then exit do
            if v<g then call getp(q)
        end if
    loop
    wscript.echo "partition "&g&" into "&q&" "&list
end sub 'part


// version 1.1.3

fun binomial(n: Int, k: Int): Int {
    if (n < k) return 0
    if (n == 0 || k == 0) return 1
    val num = (k + 1..n).fold(1) { acc, i -> acc * i }
    val den = (2..n - k).fold(1) { acc, i -> acc * i }
    return num / den
}

fun pascalUpperTriangular(n: Int) = List(n) { i -> IntArray(n) { j -> binomial(j, i) } }

fun pascalLowerTriangular(n: Int) = List(n) { i -> IntArray(n) { j -> binomial(i, j) } }

fun pascalSymmetric(n: Int)       = List(n) { i -> IntArray(n) { j -> binomial(i + j, i) } }

fun printMatrix(title: String, m: List<IntArray>) {
    val n = m.size
    println(title)
    print("[")
    for (i in 0 until n) {
        if (i > 0) print(" ")
        print(m[i].contentToString())
        if (i < n - 1) println(",") else println("]\n")
    }
}

fun main(args: Array<String>) {
    printMatrix("Pascal upper-triangular matrix", pascalUpperTriangular(5))
    printMatrix("Pascal lower-triangular matrix", pascalLowerTriangular(5))
    printMatrix("Pascal symmetric matrix", pascalSymmetric(5))
}


' Partition an integer X into N primes - 29/03/2017
Option Explicit On

Module PartitionIntoPrimes
    Dim p(8), a(32), b(32), v, g, q As Long

    Sub Main()
        Dim what, t1(), t2(), t3(), xx, nn As String
        Dim x, y, n, m As Long
        what = "99809 1  18 2  19 3  20 4  2017 24  22699 1-4  40355 3"
        t1 = Split(what, "  ")
        For j = 0 To UBound(t1)
            t2 = Split(t1(j)) : xx = t2(0) : nn = t2(1)
            t3 = Split(xx, "-") : x = CLng(t3(0))
            If UBound(t3) = 1 Then y = CLng(t3(1)) Else y = x
            t3 = Split(nn, "-") : n = CLng(t3(0))
            If UBound(t3) = 1 Then m = CLng(t3(1)) Else m = n
            genp(y) 'generate primes in p
            For g = x To y
                For q = n To m : part() : Next 'q
            Next 'g
        Next 'j
    End Sub 'Main

    Sub genp(high As Long)
        Dim c, i, k As Long
        Dim bk As Boolean
        p(1) = 2 : p(2) = 3 : c = 2 : i = p(c) + 2
        Do 'i
            k = 2 : bk = False
            Do While k * k <= i And Not bk 'k
                If i Mod p(k) = 0 Then bk = True
                k = k + 1
            Loop 'k
            If Not bk Then
                c = c + 1 : If c > UBound(p) Then ReDim Preserve p(UBound(p) + 8)
                p(c) = i
            End If
            i = i + 2
        Loop Until p(c) > high 'i
    End Sub 'genp

    Sub getp(z As Long)
        Dim w As Long
        If a(z) = 0 Then w = z - 1 : a(z) = a(w)
        a(z) = a(z) + 1 : w = a(z) : b(z) = p(w)
    End Sub 'getp

    Function list()
        Dim w As String
        w = b(1)
        If v = g Then
            For i = 2 To q : w = w & "+" & b(i) : Next
        Else
            w = "(not possible)"
        End If
        Return "primes: " & w
    End Function 'list

    Sub part()
        For i = LBound(a) To UBound(a) : a(i) = 0 : Next 'i
        For i = 1 To q : Call getp(i) : Next 'i
        Do While True : v = 0
            For s = 1 To q
                v = v + b(s)
                If v > g Then
                    If s = 1 Then Exit Do
                    For k = s To q : a(k) = 0 : Next 'k
                    For r = s - 1 To q : Call getp(r) : Next 'r
                    Continue Do
                End If
            Next 's
            If v = g Then Exit Do
            If v < g Then Call getp(q)
        Loop
        Console.WriteLine("partition " & g & " into " & q & " " & list())
    End Sub 'part

End Module 'PartitionIntoPrimes


function factorial (n)
    local f = 1
    for i = 2, n do
        f = f * i
    end
    return f
end

function binomial (n, k)
    if k > n then return 0 end
    return factorial(n) / (factorial(k) * factorial(n - k))
end

function pascalMatrix (form, size)
    local matrix = {}
    for row = 1, size do
        matrix[row] = {}
        for col = 1, size do
            if form == "upper" then
                matrix[row][col] = binomial(col - 1, row - 1)
            end
            if form == "lower" then
                matrix[row][col] = binomial(row - 1, col - 1)
            end
            if form == "symmetric" then
                matrix[row][col] = binomial(row + col - 2, col - 1)
            end
        end
    end
    matrix.form = form:sub(1, 1):upper() .. form:sub(2, -1)
    return matrix
end

function show (mat)
    print(mat.form .. ":")
    for i = 1, #mat do
        for j = 1, #mat[i] do
            io.write(mat[i][j] .. "\t")
        end
        print()
    end
    print()
end

for _, form in pairs({"upper", "lower", "symmetric"}) do
    show(pascalMatrix(form, 5))
end


import "/math" for Int, Nums
import "/fmt" for Fmt

var primes = Int.primeSieve(1e5)
var foundCombo = false

var findCombo // recursive
findCombo = Fn.new { |k, x, m, n, combo|
    if (k >= m) {
        if (Nums.sum(combo.map { |i| primes[i] }.toList) == x) {
            var s = (m > 1) ? "s" : ""
            Fmt.write("Partitioned $5d with $2d prime$s: ", x, m, s)
            for (i in 0...m) {
                System.write(primes[combo[i]])
                System.write((i < m - 1) ? "+" : "\n")
            }
            foundCombo = true
        }
    } else {
        for (j in 0...n) {
            if (k == 0 || j > combo[k - 1]) {
                combo[k] = j
                if (!foundCombo) findCombo.call(k + 1, x, m, n, combo)
            }
        }
    }
}

var partition = Fn.new { |x, m|
    if (x < 2 || m < 1 || m >= x) Fiber.abort("Invalid argument(s)")
    var n = primes.where { |p| p <= x }.count
    if (n < m) Fiber.abort("Not enough primes")
    var combo = List.filled(m, 0)
    foundCombo = false
    findCombo.call(0, x, m, n, combo)
    if (!foundCombo) {
        var s = (m > 1) ? "s" : ""
        Fmt.print("Partitioned $5d with $2d prime$s: (not possible)", x, m, s)
    }
}

var a = [
    [99809, 1],
    [18, 2],
    [19, 3],
    [20, 4],
    [2017, 24],
    [22699, 1],
    [22699, 2],
    [22699, 3],
    [22699, 4],
    [40355, 3]
]
for (p in a) partition.call(p[0], p[1])


PascalUT := proc(n::integer)
 local M := Matrix(n,n):
 local i:
 local j:
 M[1,1..n] := 1:
 for j from 2 to n do
  for i from 2 to n do
   M[i,j] := M[i,j-1] + M[i-1,j-1]:
  end:
 end:
 return M:
end proc:

PascalUT(5);

PascalLT := proc(n::integer)
 local M := Matrix(n,n):
 local i:
 local j:
 M[1..n,1] := 1:
 for i from 2 to n do
  for j from 2 to n do
   M[i,j] := M[i-1,j] + M[i-1,j-1]:
  end:
 end:
 return M:
end proc:

PascalLT(5);

Pascal := proc(n::integer)
 local M := Matrix(n,n):
 local i:
 local j:
 M[1..n,1] := 1:
 M[1,2..n] := 1:
 for i from 2 to n do
  for j from 2 to n do
   M[i,j] := M[i,j-1] + M[i-1,j]:
  end:
 end:
 return M:
end proc:

Pascal(5);


symPascal[size_] := NestList[Accumulate, Table[1, {k, size}], size - 1]

upperPascal[size_] := CholeskyDecomposition[[email protected]]

lowerPascal[size_] := [email protected][[email protected]]

Column[MapThread[
  Labeled[Grid[#[email protected]], #2, Top] &, {{upperPascal, lowerPascal,
    symPascal}, {"Upper", "Lower", "Symmetric"}}]]


F infix_to_postfix(infix)
   -V ops = ‘-+/*^’
   V sb = ‘’
   [Int] s

   L(token) infix.split(re:‘\s’)
      I token.empty
         L.continue

      V c = token[0]
      V? idx = ops.find(c)
      I idx != N
         I s.empty
            s.append(idx)
         E
            L !s.empty
               V prec2 = s.last I/ 2
               V prec1 = idx I/ 2
               I prec2 > prec1 | (prec2 == prec1 & c != ‘^’)
                  sb ‘’= ops[s.pop()]‘ ’
               E
                  L.break
            s.append(idx)

      E I c == ‘(’
         s.append(-2)

      E I c == ‘)’
         L s.last != -2
            sb ‘’= ops[s.pop()]‘ ’
         s.pop()

      E
         sb ‘’= token‘ ’

   L !s.empty
      sb ‘’= ops[s.pop()]‘ ’

   R sb

V infix = ‘3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3’
print(‘infix:   ’infix)
print(‘postfix: ’infix_to_postfix(infix))


   // Partition integer N into M unique primes
fcn partition(N,M,idx=0,ps=List()){
   var [const] sieve=Utils.Generator(Import("sieve").postponed_sieve);
   var [const] primes=List();
   while(sieve.peek()<=N){ primes.append(sieve.next()) }
   if(M<2){
      z:=primes.find(N);
      return(if(Void!=z and z>=idx) ps.append(N) else Void);
   }
   foreach z in ([idx..primes.len()-1]){
      p:=primes[z];
      if(p<=N and self.fcn(N-p,M-1,z+1,ps)) return(ps.insert(0,p));
      if(p>N) break;
   }
   Void		// no solution
}


import math, sequtils, strutils

type SquareMatrix = seq[seq[Natural]]

func newSquareMatrix(n: Positive): SquareMatrix =
  ## Create a square matrix.
  newSeqWith(n, newSeq[Natural](n))

func pascalUpperTriangular(n: Positive): SquareMatrix =
  ## Create an upper Pascal matrix.
  result = newSquareMatrix(n)
  for i in 0..<n:
    for j in i..<n:
      result[i][j] = binom(j, i)

func pascalLowerTriangular(n: Positive): SquareMatrix =
  ## Create a lower Pascal matrix.
  result = newSquareMatrix(n)
  for i in 0..<n:
    for j in i..<n:
      result[j][i] = binom(j, i)

func pascalSymmetric(n: Positive): SquareMatrix =
  ## Create a symmetric Pascal matrix.
  result = newSquareMatrix(n)
  for i in 0..<n:
    for j in 0..<n:
      result[i][j] = binom(i + j, i)

proc print(m: SquareMatrix) =
  ## Print a square matrix.
  let matMax = max(m.mapIt(max(it)))
  let length = ($matMax).len
  for i in 0..m.high:
    echo "| ", m[i].mapIt(($it).align(length)).join(" "), " |"

echo "Upper:"
print pascalUpperTriangular(5)
echo "\nLower:"
print pascalLowerTriangular(5)
echo "\nSymmetric:"
print pascalSymmetric(5)


\ Convert infix expression to postfix, using 'shunting-yard' algorithm
\ https://en.wikipedia.org/wiki/Shunting-yard_algorithm

\ precedence of infix tokens.  negative means 'right-associative', otherwise left:
with: n
{
  "+" : 2,
  "-" : 2,
  "/" : 3,
  "*" : 3,
  "^" : -4,
  "(" : 1,
  ")" : -1
} var, tokens

: precedence \ s -- s n
  tokens @ over m:@ nip
  null? if drop 0 then ;

var ops
var out

: >out \ x --
  out @ swap
  a:push drop ;

: >ops \ op prec --
  2 a:close
  ops @ swap
  a:push drop ;

: a:peek -1 a:@ ;

\ Check the array for items with greater or equal precedence,
\ and move them to the out queue:
: pop-ops \ op prec ops -- op prec ops
  \ empty array, do nothing:
  a:len not if ;; then

  \ Look at top of ops stack:
  a:peek a:open            \ op p ops[] op2 p2

  \ if the 'p2' is not less p (meaning item on top of stack is greater or equal
  \ in precedence), then pop the item from the ops stack and push onto the out:
  3 pick \ p2 p
  < not if
    \ op p ops[] op2
    >out a:pop drop recurse ;;
  then
  drop ;

: right-paren
  "RIGHTPAREN" . cr
  2drop
  \ move non-left-paren from ops and move to out:
  ops @
  repeat
    a:len not if
      break
    else
      a:pop a:open
      1 = if
        2drop ;;
      else
        >out
      then
    then
  again drop ;

: .state \ n --
drop \  "Token: %s\n" s:strfmt .
  "Out:   " .
    out @  ( . space drop ) a:each drop cr
  "ops:   " .  ops @ ( 0 a:@ . space 2drop ) a:each drop cr cr ;

: handle-number \ s n --
  "NUMBER " . over . cr
  drop >out ;

: left-paren \ s n --
  "LEFTPAREN" .  cr
  >ops ;

: handle-op \ s n --
    "OPERATOR " . over . cr
    \ op precedence
    \ Is the current op left-associative?
    dup sgn 1 = if
      \ it is, so check the ops array for items with greater or equal precedence,
      \ and move them to the out queue:
      ops @ pop-ops drop
    then
    \ push the operator
    >ops ;

: handle-token \ s --
  precedence dup not if
    \ it's a number:
    handle-number
  else
    dup 1 = if        left-paren
    else dup -1 = if  right-paren
    else              handle-op
    then then
  then ;

: infix>postfix \ s -- s
  /\s+/ s:/           \ split to indiviual whitespace-delimited tokens

  \ Initialize our data structures
  a:new ops !   a:new out !

  (
    nip dup >r
    handle-token
    r> .state
  ) a:each drop
  \ remove all remaining ops and put on output:
  out @
  ops @ a:rev
  ( nip a:open drop a:push ) a:each drop
  \ final string:
  " " a:join ;

"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3" infix>postfix . cr

"Expected: \n" . "3 4 2 * 1 5 - 2 3 ^ ^ / +" .  cr
bye


BEGIN
    # parses s and returns an RPN expression using Dijkstra's "Shunting Yard" algorithm #
    # s is expected to contain a valid infix expression containing single-digit numbers and single-character operators #
    PROC parse = ( STRING s )STRING:
    BEGIN
        # add to the output #
        PROC output element = ( CHAR c )VOID:
        BEGIN
            output[ output pos +:= 1 ] := c;
            output pos +:= 1
        END # output element # ;
        PROC stack op = ( CHAR c )VOID: stack[ stack pos +:= 1 ] := c;
        # unstacks and returns the top operator on the stack - stops the program if the stack is empty #
        PROC unstack = CHAR:
            IF stack pos < 1 THEN
                # empty stack #
                print( ( "Stack underflow", newline ) );
                stop
            ELSE
                # still something on the stack to unstack #
                CHAR    result = stack[ stack pos ];
                stack[ stack pos ] := " ";
                stack pos         -:=  1;
                result
            FI # unstack # ;
        # returns the priority of the operator o - which must be one of "(", "^", "*", "/", "+" or "-" #
        PROC priority of = ( CHAR o )INT: IF o = "(" THEN -1 ELIF o = "^" THEN 4 ELIF o = "*" OR o = "/" THEN 3 ELSE 2 FI;
        # returns TRUE if o is a right-associative operator, FALSE otherwise #
        PROC right = ( CHAR c )BOOL: c = "^";
        PROC lower or equal priority = ( CHAR c )BOOL:
            IF stack pos < 1 THEN FALSE # empty stack #
            ELSE priority of( c ) <= priority of( stack[ stack pos ] )
            FI # lower or equal priority # ;
        PROC lower priority = ( CHAR c )BOOL:
            IF stack pos < 1 THEN FALSE # empty stack #
            ELSE priority of( c ) < priority of( stack[ stack pos ] )
            FI # lower priority # ;
        # max stack size and output size #
        INT    max stack = 32;
        # stack and output queue #
        [ 1 : max stack ]CHAR stack;
        [ 1 : max stack ]CHAR output;
        FOR c pos TO max stack DO stack[ c pos ] := output[ c pos ] := " " OD;
        # stack pointer and output queue pointer #
        INT    stack pos  := 0;
        INT    output pos := 0;
        print( ( "Parsing: ", s, newline ) );
        print( ( "token   output                               stack", newline ) );
        FOR s pos FROM LWB s TO UPB s DO
            CHAR c = s[ s pos ];
            IF c /= " " THEN
                IF c >= "0" AND c <= "9" THEN output element( c )
                ELIF c = "(" THEN stack op( c )
                ELIF c = ")" THEN
                    # close bracket - unstack to the matching "(" and unstack the "(" #
                    WHILE CHAR op char = unstack;
                          op char /= "("
                    DO
                        output element( op char )
                    OD
                ELIF right( c ) THEN
                    # right associative operator #
                    WHILE lower priority( c )          DO output element( unstack ) OD;
                    stack op( c )
                ELSE
                    # must be left associative #
                    WHILE lower or equal priority( c ) DO output element( unstack ) OD;
                    stack op( c )
                FI;
                print( ( c, "       ", output, "     ", stack, newline ) )
            FI
        OD;
        WHILE stack pos >= 1 DO output element( unstack ) OD;
        output[ 1 : output pos ]
    END # parse # ;

    print( ( "result: ", parse( "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3" ), newline ) )
END


program Pascal_matrix(Output);

const N = 5;

type NxN_Matrix = array[0..N,0..N] of integer;

var PM,PX : NxN_Matrix;

function Pascal_sym(x : integer; p : NxN_Matrix) : NxN_Matrix;
var I,J : integer;
  begin
    for I := 1 to x do
    begin
      for J := 1 to x do p[I,J] := p[I-1,J]+p[I,J-1]
    end;
    Pascal_sym := p;
  end;

function Pascal_upp(x : integer; p : NxN_Matrix) : NxN_Matrix;
var I,J : integer;
  begin
    for I := 1 to x do
    begin
      for J := 1 to x do p[I,J] := p[I-1,J-1]+p[I,J-1]
    end;
    Pascal_upp := p
  end;

function Pascal_low(x : integer; p : NxN_Matrix) : NxN_Matrix;
var p1,p2 : NxN_Matrix;
  I,J : integer;
  begin
    p1 := Pascal_upp(x,p);
    p2 := p1;
    for I := 1 to x do
    begin
      for J := 1 to x do p1[J,I] := p2[I,J]
    end;
    Pascal_low := p1
  end;

procedure PrintMatrix(titel : ansistring; x : integer; p : NxN_Matrix);
var I,J : integer;
  begin
    writeln(titel);
    for I := 1 to x do
    begin
      for J := 1 to x do write(p[I,J]:5);
      writeln('');
    end;
  end;

begin
  PX[0,0] := 0;
  PM[0,0] := 1;
  PM := Pascal_upp(N, PM);
  PrintMatrix('Upper:', N, PM);
  writeln('');
  PM := PX;
  PM[0,0] := 1;
  PM := Pascal_low(N, PM);
  PrintMatrix('Lower:', N, PM);
  writeln('');
  PM := PX;
  PM[1,0] := 1;
  PM := Pascal_sym(N, PM);
  PrintMatrix('Symmetric', N, PM);
  writeln('');
  readln;
end.


SetBatchLines -1
#NoEnv

expr := "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"

output := "Testing string '" expr "'`r`n`r`nToken`tOutput Queue"
           . Space(StrLen(expr)-StrLen("Output Queue")+2) "OP Stack"

; define a stack with semantic .push() and .pop() funcs
stack := {push: func("ObjInsert"), pop: func("ObjRemove"), peek: func("Peek")}

Loop Parse, expr, %A_Space%
{
       token := A_LoopField
       if token is number
               Q .= token A_Space
       if isOp(token){
               o1 := token
               while   isOp(o2 := stack.peek())
                       and ((isLeft(o1)  and Precedence(o1) <= Precedence(o2))
                       or  (isRight(o1) and Precedence(o1) <  Precedence(o2)))
                   Q .= stack.pop() A_Space
               stack.push(o1)
       }
       If ( token = "(" )
               stack.push(token)
       If ( token = ")" )
       {
               While ((t := stack.pop()) != "(") && (t != "")
                       Q .= t A_Space
               if (t = "")
                       throw Exception("Unmatched parenthesis. "
                          . "Character number " A_Index)
       }
       output .= "`r`n" token Space(7) Q Space(StrLen(expr)+2-StrLen(Q))
               . Disp(stack)
}
output .= "`r`n(empty stack to output)"
While (t := stack.pop()) != ""
       if InStr("()", t)
               throw Exception("Unmatched parenthesis.")
       else    Q .= t A_Space, output .= "`r`n" Space(8) Q
                       . Space(StrLen(expr)+2-StrLen(Q)) Disp(stack)
output .= "`r`n`r`nFinal string: '" Q "'"
clipboard := output

isOp(t){
       return (!!InStr("+-*/^", t) && t)
}
Peek(this){
       r := this.Remove(), this.Insert(r)
       return r
}
IsLeft(o){
       return !!InStr("*/+-", o)
}
IsRight(o){
       return o = "^"
}
Precedence(o){
       return (InStr("+-/*^", o)+3)//2
}
Disp(obj){
       for each, val in obj
               o := val . o
       return  o
}
Space(n){
       return n>0 ? A_Space Space(n-1) : ""
}


#include <sys/types.h>
#include <regex.h>
#include <stdio.h>

typedef struct {
	const char *s;
	int len, prec, assoc;
} str_tok_t;

typedef struct {
	const char * str;
	int assoc, prec;
	regex_t re;
} pat_t;

enum assoc { A_NONE, A_L, A_R };
pat_t pat_eos = {"", A_NONE, 0};

pat_t pat_ops[] = {
	{"^\\)",	A_NONE, -1},
	{"^\\*\\*",	A_R, 3},
	{"^\\^",	A_R, 3},
	{"^\\*",	A_L, 2},
	{"^/",		A_L, 2},
	{"^\\+",	A_L, 1},
	{"^-",		A_L, 1},
	{0}
};

pat_t pat_arg[] = {
	{"^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?"},
	{"^[a-zA-Z_][a-zA-Z_0-9]*"},
	{"^\\(", A_L, -1},
	{0}
};

str_tok_t stack[256]; /* assume these are big enough */
str_tok_t queue[256];
int l_queue, l_stack;
#define qpush(x) queue[l_queue++] = x
#define spush(x) stack[l_stack++] = x
#define spop()   stack[--l_stack]

void display(const char *s)
{
	int i;
	printf("\033[1;1H\033[JText | %s", s);
	printf("\nStack| ");
	for (i = 0; i < l_stack; i++)
		printf("%.*s ", stack[i].len, stack[i].s); // uses C99 format strings
	printf("\nQueue| ");
	for (i = 0; i < l_queue; i++)
		printf("%.*s ", queue[i].len, queue[i].s);
	puts("\n\n<press enter>");
	getchar();
}

int prec_booster;

#define fail(s1, s2) {fprintf(stderr, "[Error %s] %s\n", s1, s2); return 0;}

int init(void)
{
	int i;
	pat_t *p;

	for (i = 0, p = pat_ops; p[i].str; i++)
		if (regcomp(&(p[i].re), p[i].str, REG_NEWLINE|REG_EXTENDED))
			fail("comp", p[i].str);

	for (i = 0, p = pat_arg; p[i].str; i++)
		if (regcomp(&(p[i].re), p[i].str, REG_NEWLINE|REG_EXTENDED))
			fail("comp", p[i].str);

	return 1;
}

pat_t* match(const char *s, pat_t *p, str_tok_t * t, const char **e)
{
	int i;
	regmatch_t m;

	while (*s == ' ') s++;
	*e = s;

	if (!*s) return &pat_eos;

	for (i = 0; p[i].str; i++) {
		if (regexec(&(p[i].re), s, 1, &m, REG_NOTEOL))
			continue;
		t->s = s;
		*e = s + (t->len = m.rm_eo - m.rm_so);
		return p + i;
	}
	return 0;
}

int parse(const char *s) {
	pat_t *p;
	str_tok_t *t, tok;

	prec_booster = l_queue = l_stack = 0;
	display(s);
	while (*s) {
		p = match(s, pat_arg, &tok, &s);
		if (!p || p == &pat_eos) fail("parse arg", s);

		/* Odd logic here. Don't actually stack the parens: don't need to. */
		if (p->prec == -1) {
			prec_booster += 100;
			continue;
		}
		qpush(tok);
		display(s);

re_op:		p = match(s, pat_ops, &tok, &s);
		if (!p) fail("parse op", s);

		tok.assoc = p->assoc;
		tok.prec = p->prec;

		if (p->prec > 0)
			tok.prec = p->prec + prec_booster;
		else if (p->prec == -1) {
			if (prec_booster < 100)
				fail("unmatched )", s);
			tok.prec = prec_booster;
		}

		while (l_stack) {
			t = stack + l_stack - 1;
			if (!(t->prec == tok.prec && t->assoc == A_L)
					&& t->prec <= tok.prec)
				break;
			qpush(spop());
			display(s);
		}

		if (p->prec == -1) {
			prec_booster -= 100;
			goto re_op;
		}

		if (!p->prec) {
			display(s);
			if (prec_booster)
				fail("unmatched (", s);
			return 1;
		}

		spush(tok);
		display(s);
	}

	if (p->prec > 0)
		fail("unexpected eol", s);

	return 1;
}

int main()
{
	int i;
	const char *tests[] = {
		"3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3",	/* RC mandated: OK */
		"123",					/* OK */
		"3+4 * 2 / ( 1 - 5 ) ^ 2 ^ 3.14",	/* OK */
		"(((((((1+2+3**(4 + 5))))))",		/* bad parens */
		"a^(b + c/d * .1e5)!",			/* unknown op */
		"(1**2)**3",				/* OK */
		"2 + 2 *",				/* unexpected eol */
		0
	};

	if (!init()) return 1;
	for (i = 0; tests[i]; i++) {
		printf("Testing string `%s'   <enter>\n", tests[i]);
		getchar();

		printf("string `%s': %s\n\n", tests[i],
			parse(tests[i]) ? "Ok" : "Error");
	}

	return 0;
}


function pascal_upper(integer n)
    sequence res = repeat(repeat(0,n),n)
    res[1] = repeat(1,n)
    for i=2 to n do
        for j=2 to i do
            res[j,i] = res[j,i-1]+res[j-1,i-1]
        end for
    end for
    return res
end function

function pascal_lower(integer n)
    sequence res = repeat(repeat(0,n),n)
    for i=1 to n do
        res[i,1] = 1
    end for
    for i=2 to n do
        for j=2 to i do
            res[i,j] = res[i-1,j]+res[i-1,j-1]
        end for
    end for
    return res
end function

function pascal_symmetric(integer n)
    sequence res = repeat(repeat(0,n),n)
    for i=1 to n do
        res[i,1] = 1
        res[1,i] = 1
    end for
    for i=2 to n do
        for j = 2 to n do
            res[i,j] = res[i-1,j]+res[i,j-1]
        end for
    end for
    return res
end function

ppOpt({pp_Nest,1,pp_IntCh,false,pp_IntFmt,"%2d"})
puts(1,"=== Pascal upper matrix ===\n")
pp(pascal_upper(5))
puts(1,"=== Pascal lower matrix ===\n")
pp(pascal_lower(5))
puts(1,"=== Pascal symmetrical matrix ===\n")
pp(pascal_symmetric(5))


using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main() {
        string infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
        Console.WriteLine(infix.ToPostfix());
    }
}

public static class ShuntingYard
{
    private static readonly Dictionary<string, (string symbol, int precedence, bool rightAssociative)> operators
        = new (string symbol, int precedence, bool rightAssociative) [] {
            ("^", 4, true),
            ("*", 3, false),
            ("/", 3, false),
            ("+", 2, false),
            ("-", 2, false)
    }.ToDictionary(op => op.symbol);

    public static string ToPostfix(this string infix) {
        string[] tokens = infix.Split(' ');
        var stack = new Stack<string>();
        var output = new List<string>();
        foreach (string token in tokens) {
            if (int.TryParse(token, out _)) {
                output.Add(token);
                Print(token);
            } else if (operators.TryGetValue(token, out var op1)) {
                while (stack.Count > 0 && operators.TryGetValue(stack.Peek(), out var op2)) {
                    int c = op1.precedence.CompareTo(op2.precedence);
                    if (c < 0 || !op1.rightAssociative && c <= 0) {
                        output.Add(stack.Pop());
                    } else {
                        break;
                    }
                }
                stack.Push(token);
                Print(token);
            } else if (token == "(") {
                stack.Push(token);
                Print(token);
            } else if (token == ")") {
                string top = "";
                while (stack.Count > 0 && (top = stack.Pop()) != "(") {
                    output.Add(top);
                }
                if (top != "(") throw new ArgumentException("No matching left parenthesis.");
                Print(token);
            }
        }
        while (stack.Count > 0) {
            var top = stack.Pop();
            if (!operators.ContainsKey(top)) throw new ArgumentException("No matching right parenthesis.");
            output.Add(top);
        }
        Print("pop");
        return string.Join(" ", output);

        //Yikes!
        void Print(string action) => Console.WriteLine($"{action + ":",-4} {$"stack[ {string.Join(" ", stack.Reverse())} ]",-18} {$"out[ {string.Join(" ", output)} ]"}");
        //A little more readable?
        void Print(string action) => Console.WriteLine("{0,-4} {1,-18} {2}", action + ":", $"stack[ {string.Join(" ", stack.Reverse())} ]", $"out[ {string.Join(" ", output)} ]");
    }
}


(setq
   Low '(A B)
   Upp '(B A)
   Sym '((+ A B) A) )

(de binomial (N K)
   (let f
      '((N)
         (if (=0 N) 1 (apply * (range 1 N))) )
      (if (> K N)
         0
         (/
            (f N)
            (* (f (- N K)) (f K)) ) ) ) )
(de pascal (N Z)
   (for Lst
      (mapcar
         '((A)
            (mapcar
               '((B) (apply binomial (mapcar eval Z)))
               (range 0 N) ) )
         (range 0 N) )
      (for L Lst
         (prin (align 2 L) " ") )
      (prinl) )
   (prinl) )

(pascal 4 Low)
(pascal 4 Upp)
(pascal 4 Sym)


PASCAL_MATRIX: PROCEDURE OPTIONS (MAIN); /* derived from Fortran version 18 Decenber 2021 */

    pascal_lower: procedure(a);
        declare a(*,*) fixed binary;
        declare (n, i, j) fixed binary;
        n = hbound(a,1);
        a = 0;
        a(*, 1) = 1;
        do i = 2 to n;
            do j = 2 to i;
                a(i, j) = a(i - 1, j) + a(i - 1, j - 1);
            end;
        end;
    end pascal_lower;

    pascal_upper: procedure(a);
        declare a(*,*) fixed binary;
        declare (n, i, j) fixed binary;
        n = hbound(a,1);
        a = 0;
        a(1, *) = 1;
        do i = 2 to n;
            do j = 2 to i;
                a(j, i) = a(j, i - 1) + a(j - 1, i - 1);
            end;
        end;
    end pascal_upper;

    pascal_symmetric: procedure(a);
        declare a(*,*) fixed binary;
        declare (n, i, j) fixed binary;
        n = hbound(a,1);
        a = 0;
        a(*, 1) = 1;
        a(1, *) = 1;
        do i = 2 to n;
            do j = 2 to n;
                a(i, j) = a(i - 1, j) + a(i, j - 1);
            end;
        end;
    end pascal_symmetric;

    declare n fixed binary;
    put ('Size of matrix?');
    get (n);
    begin;
       declare a(n, n) fixed binary;

       put skip list ('Lower Pascal Matrix');
       call pascal_lower(a);
       put edit (a) (skip, (n) f(3) );

       put skip list ('Upper Pascal Matrix');
       call pascal_upper(a);
       put edit (a) (skip, (n) f(3) );

       put skip list ('Symmetric Pascal Matrix');
       call pascal_symmetric(a);
       put edit (a) (skip, (n) f(3) );
    end;

end PASCAL_MATRIX;


   cl /EHsc /W4 /Ox /std:c++17 /utf-8 a.cpp
   clang++ -Wall -pedantic-errors -O3 -std=c++17 a.cpp


EnableExplicit
Define.i x=5, I, J

Macro Print_Pascal_matrix(typ)
  PrintN(typ)
  For I=1 To x
    For J=1 To x : Print(RSet(Str(p(I,J)),3," ")+Space(3)) : Next
    PrintN("")
  Next
  Print(~"\n\n")
EndMacro

Procedure Pascal_sym(n.i,Array p.i(2))
  Define.i I,J
  p(1,0)=1
  For I=1 To n
    For J=1 To n : p(I,J)=p(I-1,J)+p(I,J-1) : Next
  Next
EndProcedure

Procedure Pascal_upp(n.i,Array p.i(2))
  Define.i I,J
  p(0,0)=1
  For I=1 To n
    For J=1 To n : p(I,J)=p(I-1,J-1)+p(I,J-1) : Next
  Next
EndProcedure

Procedure Pascal_low(n.i,Array p.i(2))
  Define.i I,J
  Pascal_upp(n,p())
  Dim p2.i(n,n)
  CopyArray(p(),p2())
  For I=1 To n
    For J=1 To n : Swap p(J,I),p2(I,J) : Next
  Next
EndProcedure

OpenConsole()

Dim p.i(x,x)
Pascal_upp(x,p())
Print_Pascal_matrix("Upper:")

Dim p.i(x,x)
Pascal_low(x,p())
Print_Pascal_matrix("Lower:")

Dim p.i(x,x)
Pascal_sym(x,p())
Print_Pascal_matrix("Symmetric:")

Input()
End


import ceylon.collection {

	ArrayList
}

abstract class Token(String|Integer data) of IntegerLiteral | Operator | leftParen | rightParen {
	string => data.string;
}
class IntegerLiteral(shared Integer integer) extends Token(integer) {}
class Operator  extends Token {

	shared Integer precedence;
	shared Boolean rightAssoc;

	shared new plus extends Token("+") {
		precedence = 2;
		rightAssoc = false;
	}
	shared new minus extends Token("-") {
		precedence = 2;
		rightAssoc = false;
	}
	shared new times extends Token("*") {
		precedence = 3;
		rightAssoc = false;
	}
	shared new divides extends Token("/") {
		precedence = 3;
		rightAssoc = false;
	}
	shared new power extends Token("^") {
		precedence = 4;
		rightAssoc = true;
	}

	shared Boolean below(Operator other) =>
			!rightAssoc && precedence <= other.precedence || rightAssoc && precedence < other.precedence;
}
object leftParen extends Token("(") {}
object rightParen extends Token(")") {}

shared void run() {

	function shunt(String input) {

		function tokenize(String input) =>
				input.split().map((String element) =>
					switch(element.trimmed)
					case("(") leftParen
					case(")") rightParen
					case("+") Operator.plus
					case("-") Operator.minus
					case("*") Operator.times
					case("/") Operator.divides
					case("^") Operator.power
					else IntegerLiteral(parseInteger(element) else 0)); // no error handling

		value outputQueue = ArrayList<Token>();
		value operatorStack = ArrayList<Token>();

		void report(String action) {
			print("``action.padTrailing(22)`` | ``" ".join(outputQueue).padTrailing(25)`` | ``" ".join(operatorStack).padTrailing(10)``");
		}

		print("input is ``input``\n");
		print("Action                 | Output Queue              | Operators' Stack
		       -----------------------|---------------------------|-----------------");

		for(token in tokenize(input)) {
			switch(token)
			case(is IntegerLiteral) {
				outputQueue.offer(token);
				report("``token`` from input to queue");
			}
			case(leftParen) {
				operatorStack.push(token);
				report("``token`` from input to stack");
			}
			case(rightParen){
				while(exists top = operatorStack.pop(), top != leftParen) {
					outputQueue.offer(top);
					report("``top`` from stack to queue");
				}
			}
			case(is Operator) {
				while(exists top = operatorStack.top, is Operator top, token.below(top)) {
					operatorStack.pop();
					outputQueue.offer(top);
					report("``top`` from stack to queue");
				}
				operatorStack.push(token);
				report("``token`` from input to stack");
			}
		}
		while(exists top = operatorStack.pop()) {
			outputQueue.offer(top);
			report("``top`` from stack to queue");
		}
		return " ".join(outputQueue);
	}

	value rpn = shunt("3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3");
	assert(rpn == "3 4 2 * 1 5 - 2 3 ^ ^ / +");
	print("\nthe result is ``rpn``");
}


;;;; Parsing/infix to RPN conversion
(defconstant operators "^*/+-")
(defconstant precedence '(-4 3 3 2 2))

(defun operator-p (op)
  "string->integer|nil: Returns operator precedence index or nil if not operator."
  (and (= (length op) 1) (position (char op 0) operators)))

(defun has-priority (op2 op1)
  "(string,string)->boolean: True if op2 has output priority over op1."
  (defun prec (op) (nth (operator-p op) precedence))
  (or (and (plusp (prec op1))  (<= (prec op1) (abs (prec op2))))
      (and (minusp (prec op1)) (< (- (prec op1)) (abs (prec op2))))))

(defun string-split (expr)
  "string->list: Tokenize a space separated string."
  (let* ((p (position #\Space expr))
         (tok (if p (subseq expr 0 p) expr)))
    (if p (append (list tok) (string-split (subseq expr (1+ p)))) (list tok))))

(defun classify (tok)
  "nil|string->symbol: Classify a token."
  (cond
   ((null tok) 'NOL)
   ((operator-p tok) 'OPR)
   ((string= tok "(") 'LPR)
   ((string= tok ")") 'RPR)
   (t 'LIT)))

;;; transitions when op2 is dont care
(defconstant trans1D '((LIT GO) (LPR ENTER)))
;;; transitions when we check op2 also
(defconstant trans2D
  '((OPR ((NOL ENTER)
          (LPR ENTER)
          (OPR (lambda (op1 op2) (if (has-priority op2 op1) 'LEAVE 'ENTER)))))
    (RPR ((NOL "mismatched parentheses")
          (LPR CLEAR)
          (OPR LEAVE)))
    (NOL ((NOL nil)
          (LPR "mismatched parentheses")
          (OPR LEAVE)))))

(defun do-signal (op1 op2)
  "(nil|string,nil|string)->symbol|string|nil: Emit a signal based on state of inputq and opstack.
   A nil return is a successful lookup (on nil,nil) because all input combinations are specified."
  (let ((sig (or (cadr (assoc (classify op1) trans1D))
                 (cadr (assoc (classify op2) (cadr (assoc (classify op1) trans2D)))))))
    (if (or (null sig) (symbolp sig) (stringp sig)) sig
        (funcall (coerce sig 'function) op1 op2))))

(defun rpn (expr)
  "string->string: Parse infix expression into rpn."
  (format t "TOKEN  TOS    SIGNAL     OPSTACK       OUTPUTQ~%")

  ;; iterate until both stacks empty
  (do* ((input (string-split expr)) (opstack nil) (outputq "")
        (sig (do-signal (first input) (first opstack)) (do-signal (first input) (first opstack))))
       ((null sig) ; until
        ;; print last closing frame
        (format t "~A~7,T~A~14,T~A~25,T~A~38,T~A~%" nil nil nil opstack outputq)
        (subseq outputq 1)) ; return final infix expression

    ;; print opening frame
    (format t "~A~7,T~A~14,T" (first input) (first opstack))
    (format t (if (stringp sig) "\"~A\"" "~A") sig)

    ;; switch state
    (let ((output (case sig
                    (GO     (pop input))
                    (ENTER  (push (pop input) opstack) nil)
                    (LEAVE  (pop opstack))
                    (CLEAR  (pop input) (pop opstack) nil)
                    (otherwise (pop input) (pop opstack)
                               (if (stringp sig) sig "unknown signal")))))
      (when output (setf outputq (concatenate 'string outputq " " output))))

    ;; print closing frame
    (format t "~25,T~A~38,T~A~%" opstack outputq))) ; end-do

(defun main (&optional (xtra nil))
  "nil->[printed rpn expressions]: Main function."
  (let ((expressions '("3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
                       "( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )"
                       "( ( 3 ^ 4 ) ^ 2 ^ 9 ) ^ 2 ^ 5"
                       "3 + 4 * ( 5 - 6 ) ) 4 * 9")))
    (dolist (expr (if xtra expressions (list (car expressions))))
      (format t "~%INFIX:\"~A\"~%" expr)
      (format t "RPN:\"~A\"~%" (rpn expr)))))


from pprint import pprint as pp

def pascal_upp(n):
    s = [[0] * n for _ in range(n)]
    s[0] = [1] * n
    for i in range(1, n):
        for j in range(i, n):
            s[i][j] = s[i-1][j-1] + s[i][j-1]
    return s

def pascal_low(n):
    # transpose of pascal_upp(n)
    return [list(x) for x in zip(*pascal_upp(n))]

def pascal_sym(n):
    s = [[1] * n for _ in range(n)]
    for i in range(1, n):
        for j in range(1, n):
            s[i][j] = s[i-1][j] + s[i][j-1]
    return s

if __name__ == "__main__":
    n = 5
    print("\nUpper:")
    pp(pascal_upp(n))
    print("\nLower:")
    pp(pascal_low(n))
    print("\nSymmetric:")
    pp(pascal_sym(n))


import std.container;
import std.stdio;

void main() {
    string infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
    writeln("infix:   ", infix);
    writeln("postfix: ", infixToPostfix(infix));
}

string infixToPostfix(string infix) {
    import std.array;

    /* To find out the precedence, we take the index of the
       token in the ops string and divide by 2 (rounding down).
       This will give us: 0, 0, 1, 1, 2 */
    immutable ops = ["+", "-", "/", "*", "^"];

    auto sb = appender!string;
    SList!int stack;

    // split the input on whitespace
    foreach (token; infix.split) {
        if (token.empty) {
            continue;
        }

        int idx = ops.indexOf(token);

        // check for operator
        if (idx != -1) {
            while (!stack.empty) {
                int prec2 = stack.peek / 2;
                int prec1 = idx / 2;
                if (prec2 > prec1 || (prec2 == prec1 && token != "^")) {
                    sb.put(ops[stack.pop]);
                    sb.put(' ');
                } else {
                    break;
                }
            }
            stack.push(idx);
        } else if (token == "(") {
            stack.push(-2); // -2 stands for '('
        } else if (token == ")") {
            // until '(' on stack, pop operators.
            while (stack.peek != -2) {
                sb.put(ops[stack.pop]);
                sb.put(' ');
            }
            stack.pop();
        } else {
            sb.put(token);
            sb.put(' ');
        }
    }

    while (!stack.empty) {
        sb.put(ops[stack.pop]);
        sb.put(' ');
    }

    return sb.data;
}

// Find the first index of the specified value, or -1 if not found.
int indexOf(T)(const T[] a, const T v) {
    foreach(i,e; a) {
        if (e == v) {
            return i;
        }
    }
    return -1;
}

// Convienience for adding a new element
void push(T)(ref SList!T s, T v) {
    s.insertFront(v);
}

// Convienience for accessing the top element
auto peek(T)(SList!T s) {
    return s.front;
}

// Convienience for removing and returning the top element
auto pop(T)(ref SList!T s) {
    auto v = s.front;
    s.removeFront;
    return v;
}


lower.pascal <- function(n) {
  a <- matrix(0, n, n)
  a[, 1] <- 1
  if (n > 1) {
    for (i in 2:n) {
      j <- 2:i
      a[i, j] <- a[i - 1, j - 1] + a[i - 1, j]
    }
  }
  a
}

# Alternate version
lower.pascal.alt <- function(n) {
  a <- matrix(0, n, n)
  a[, 1] <- 1
  if (n > 1) {
    for (j in 2:n) {
      i <- j:n
      a[i, j] <- cumsum(a[i - 1, j - 1])
    }
  }
  a
}

# While it's possible to modify lower.pascal to get the upper matrix,
# here we simply transpose the lower one.
upper.pascal <- function(n) t(lower.pascal(n))

symm.pascal <- function(n) {
  a <- matrix(0, n, n)
  a[, 1] <- 1
  for (i in 2:n) {
    a[, i] <- cumsum(a[, i - 1])
  }
  a
}


#lang racket
(require math/number-theory)

(define (pascal-upper-matrix n)
  (for/list ((i n)) (for/list ((j n)) (j . binomial . i))))

(define (pascal-lower-matrix n)
  (for/list ((i n)) (for/list ((j n)) (i . binomial . j))))

(define (pascal-symmetric-matrix n)
  (for/list ((i n)) (for/list ((j n)) ((+ i j) . binomial . j))))

(define (matrix->string m)
  (define col-width
    (for*/fold ((rv 1)) ((r m) (c r))
      (if (zero? c) rv (max rv (+ 1 (order-of-magnitude c))))))
  (string-append
   (string-join
   (for/list ((r m))
     (string-join (map (λ (c) (~a #:width col-width #:align 'right c)) r) " ")) "\n")
   "\n"))

(printf "Upper:~%~a~%" (matrix->string (pascal-upper-matrix 5)))
(printf "Lower:~%~a~%" (matrix->string (pascal-lower-matrix 5)))
(printf "Symmetric:~%~a~%" (matrix->string (pascal-symmetric-matrix 5)))


(require 'hash)
(require 'tree)

(define OPS (make-hash))
(hash-set OPS "^" '(  4 #f)) ;; right assoc
(hash-set OPS "*" '(  3 #t)) ;; left assoc
(hash-set OPS "/" '(  3 #t))
(hash-set OPS "+" '(  2 #t))
(hash-set OPS "-" '(  2 #t))

;; helpers
(define (is-right-par? token) (string=? token ")"))
(define (is-left-par? token)  (string=? token "("))
(define (is-num? op)   (not (hash-ref OPS op))) ;; crude
(define (is-op? op)    (hash-ref OPS op))
(define (is-left? op)  (second (hash-ref OPS op)))
(define (is-right? op) (not (is-left? op)))
(define (op-prec op)   (first (hash-ref OPS op)))

;; Wikipedia algorithm, translated as it is

(define (shunt tokens S Q)
    (for ((token tokens))
     (writeln "S: " (stack->list S) "Q: " (queue->list Q) "token: "token)
    (cond
    [(is-left-par? token) (push S token) ]
    [(is-right-par? token)
        (while (and (stack-top S) (not (is-left-par? (stack-top S))))
               (q-push Q ( pop S)))
        (when (stack-empty? S) (error 'misplaced-parenthesis "()" ))
        (pop S)] ; // left par

    [(is-op? token)
            (while (and
                (is-op? (stack-top S))
                (or
                  (and (is-left? token) (<= (op-prec token) (op-prec (stack-top S))))
                  (and (is-right? token) (< (op-prec token) (op-prec (stack-top S))))))
                (q-push Q (pop S)))
        (push S token)]

    [(is-num? token) (q-push Q token)]
    [else (error 'bad-token token)])) ; for
    (while (stack-top S) (q-push Q (pop S))))

(string-delimiter "")
(define (task infix)
    (define S (stack 'S))
    (define Q (queue 'Q))
        (shunt (text-parse infix) S Q)
        (writeln 'infix infix)
        (writeln 'RPN (queue->list Q)))


# Extend a matrix in 2 dimensions based on 3 neighbors.
sub grow-matrix(@matrix, &func) {
    my $n = @matrix.shape eq '*' ?? 1 !! @matrix.shape[0];
    my @m[$n+1;$n+1];
    for ^$n X ^$n -> ($i, $j) {
       @m[$i;$j] = @matrix[$i;$j];
    }
#                     West         North        NorthWest
    @m[$n; 0] = func( 0,           @m[$n-1;0],  0            );
    @m[ 0;$n] = func( @m[0;$n-1],  0,           0            );
    @m[$_;$n] = func( @m[$_;$n-1], @m[$_-1;$n], @m[$_-1;$n-1]) for 1 ..^ $n;
    @m[$n;$_] = func( @m[$n;$_-1], @m[$n-1;$_], @m[$n-1;$_-1]) for 1 ..  $n;
    @m;
}

# I am but mad north-northwest...
sub madd-n-nw(@m) { grow-matrix @m, -> $w, $n, $nw {  $n + $nw } }
sub madd-w-nw(@m) { grow-matrix @m, -> $w, $n, $nw {  $w + $nw } }
sub madd-w-n (@m) { grow-matrix @m, -> $w, $n, $nw {  $w + $n  } }

# Define 3 infinite sequences of Pascal matrices.
constant upper-tri = [1], &madd-w-nw ... *;
constant lower-tri = [1], &madd-n-nw ... *;
constant symmetric = [1], &madd-w-n  ... *;

show_m upper-tri[4];
show_m lower-tri[4];
show_m symmetric[4];

sub show_m (@m) {
my \n = @m.shape[0];
for ^n X ^n -> (\i, \j) {
    print @m[i;j].fmt("%{1+max(@m).chars}d");
    print "\n" if j+1 eq n;
}
say '';
}


open System

type action = Shift | ReduceStack | ReduceInput

type State (input : string list, stack : string list, output : string list) =
    member x.Input with get() = input
    member x.Stack with get() = stack
    member x.Output with get() = output

    member x.report act =
        let markTop = function | [] -> [] | x::xs -> ("["+x+"]")::xs
        let (s, text) =
            if x.Stack = [] && x.Input = [] then x, ""
            else
                match act with
                | Shift -> State((markTop x.Input), x.Stack, x.Output), "shift"
                | ReduceStack -> State(x.Input, (markTop x.Stack), x.Output), "reduce"
                | ReduceInput -> State((markTop x.Input), x.Stack, x.Output), "reduce"

        let lstr (x :string list) = String.Join(" ", (List.toArray x))
        printfn "%25s    %-9s %6s %s" (lstr (List.rev s.Output)) (lstr (List.rev s.Stack)) text (lstr s.Input)

    member x.shift =
        x.report Shift
        State(x.Input.Tail, (x.Input.Head)::x.Stack, x.Output)

    member x.reduce =
        x.report ReduceStack
        State (x.Input, (x.Stack.Tail), (x.Stack.Head)::x.Output)

    member x.reduceNumber =
        x.report ReduceInput
        State(x.Input.Tail, x.Stack, (x.Input.Head)::x.Output)

let prec = function
| "^" -> 4 | "*" | "/" -> 3 | "+" | "-" -> 2 | "(" -> 1
| x -> failwith ("No precedence! Not an operator: " + x)

type assocKind = | Left | Right
let assoc = function | "^" -> Right | _ -> Left

let (|Number|Open|Close|Operator|) x =
    if (Double.TryParse >> fst) x then Number
    elif x = "(" then Open
    elif x = ")" then Close
    else Operator

let rec shunting_yard (s : State) =

    let rec reduce_to_Open (s : State) =
        match s.Stack with
        | [] -> failwith "mismatched parentheses!"
        | "("::xs -> State(s.Input.Tail, xs, s.Output)
        | _ ->
            reduce_to_Open s.reduce

    let reduce_by_prec_and_shift x s =
        let (xPrec, xAssoc) = (prec x, assoc x)
        let rec loop (s : State) =
            match s.Stack with
            | [] -> s
            | x::xs ->
                let topPrec = prec x
                if xAssoc = Left && xPrec <= topPrec || xAssoc = Right && xPrec < topPrec then
                    loop s.reduce
                else
                    s
        (loop s).shift

    let rec reduce_rest (s : State) =
        match s.Stack with
        | [] -> s
        | "("::_ -> failwith "mismatched parentheses!"
        | x::_ ->
            reduce_rest s.reduce

    match s.Input with
    | x::inputRest ->
        match x with
        | Number ->
            shunting_yard s.reduceNumber
        | Open ->
            shunting_yard s.shift
        | Close ->
            shunting_yard (reduce_to_Open s)
        | Operator ->
            shunting_yard (reduce_by_prec_and_shift x s)
    | [] -> reduce_rest s

[<EntryPoint>]
let main argv =
    let input = if argv.Length = 0 then "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3".Split() else argv
    shunting_yard (State((Array.toList input), [], []))
    |> (fun s -> s.report ReduceStack)
    0


/*REXX program  generates and displays  three forms of an   NxN   Pascal matrix.        */
numeric digits 50                                /*be able to calculate huge factorials.*/
parse arg N .                                    /*obtain the optional matrix size  (N).*/
if N==''  | N==","  then N= 5                    /*Not specified?  Then use the default.*/
                               call show  N,  upp(N),  'Pascal upper triangular matrix'
                               call show  N,  low(N),  'Pascal lower triangular matrix'
                               call show  N,  sym(N),  'Pascal symmetric matrix'
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
upp:  procedure; parse arg N;  $=                /*gen Pascal upper triangular matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(j,   i);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
low:  procedure; parse arg N;  $=                /*gen Pascal lower triangular matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(i,   j);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
sym:  procedure; parse arg N;  $=                /*generate  Pascal symmetric  matrix.  */
            do i=0  for N;  do j=0  for N; $=$ comb(i+j, i);   end; end;   return $
/*──────────────────────────────────────────────────────────────────────────────────────*/
!:    procedure; parse arg x;  !=1;    do j=2  to x;  != !*j;  end;        return !
/*──────────────────────────────────────────────────────────────────────────────────────*/
comb: procedure; parse arg x,y;        if x=y  then return 1                /* {=} case.*/
                                       if y>x  then return 0                /* {>} case.*/
      if x-y<y  then y= x-y;  _= 1;    do j=x-y+1  to x;  _= _*j;  end;    return _ / !(y)
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: procedure; parse arg s,@;   w=0;    #=0                               /*get args. */
                       do x=1  for s**2;  w= max(w, 1 + length( word(@,x) ) );    end
      say;   say center( arg(3), 50, '─')                                   /*show title*/
                       do    r=1  for s;  if r==1  then $= '[['             /*row  1    */
                                                   else $= ' ['             /*rows 2   N*/
                          do c=1  for s;  #= #+1;   e= (c==s)               /*e ≡ "end".*/
                          $=$ || right( word(@, #), w) || left(',', \e) || left("]", e)
                          end   /*c*/                                       /* [↑]  row.*/
                       say $ || left(',', r\==s)left("]", r==s)             /*show row. */
                       end     /*r*/
      return


      MODULE COMPILER	!At least of arithmetic expressions.
       INTEGER KBD,MSG		!I/O units.

       INTEGER ENUFF		!How long s a piece of string?
       PARAMETER (ENUFF = 66)	!This long.
       CHARACTER*(ENUFF) RP	!Holds the Reverse Polish Notation.
       INTEGER LR		!And this is its length.

       INTEGER		OPSYMBOLS		!Recognised operator symbols.
       PARAMETER	(OPSYMBOLS = 11)	!There are also some associates.
       TYPE SYMB		!To recognise symbols and carry associated information.
        CHARACTER*1	IS		!Its text. Careful with the trailing space and comparisons.
        INTEGER*1	PRECEDENCE	!Controls the order of evaluation.
        CHARACTER*48	USAGE		!Description.
       END TYPE SYMB		!The cross-linkage of precedences is tricky.
       TYPE(SYMB) SYMBOL(0:OPSYMBOLS)	!Righto, I'll have some.
       PARAMETER (SYMBOL =(/	!Note that "*" is not to be seen as a match to "**".
     o  SYMB(" ", 0,"Not recognised as an operator's symbol."),
     1  SYMB(" ", 1,"separates symbols and aids legibility."),
     2  SYMB(")", 4,"opened with ( to bracket a sub-expression."),
     3  SYMB("]", 4,"opened with [ to bracket a sub-expression."),
     4  SYMB("}", 4,"opened with { to bracket a sub-expression."),
     5  SYMB("+",11,"addition, and unary + to no effect."),
     6  SYMB("-",11,"subtraction, and unary - for neg. numbers."),
     7  SYMB("*",12,"multiplication."),
     8  SYMB("×",12,"multiplication, if you can find this."),
     9  SYMB("/",12,"division."),
     o  SYMB("÷",12,"division for those with a fancy keyboard."),
C                13 is used so that stacked ^ will have lower priority than incoming ^, thus delivering right-to-left evaluation.
     1  SYMB("^",14,"raise to power. Not recognised is **.")/))
       CHARACTER*3	BRAOPEN,BRACLOSE	!Three types are allowed.
       PARAMETER	(BRAOPEN = "([{", BRACLOSE = ")]}")	!These.
       INTEGER		BRALEVEL		!In and out, in and out. That's the game.
       INTEGER		PRBRA,PRPOW		!Special double values.
       PARAMETER (PRBRA = SYMBOL( 3).PRECEDENCE)	!Bracketing
       PARAMETER (PRPOW = SYMBOL(11).PRECEDENCE)	!And powers refer leftwards.

       CHARACTER*10 DIGIT		!Numberish is a bit more complex.
       PARAMETER (DIGIT = "0123456789")	!But this will do for integers.

       INTEGER STACKLIMIT		!How high is a stack?
       PARAMETER (STACKLIMIT = 66)	!This should suffice.
       TYPE DEFERRED			!I need a siding for lower-precedence operations.
        CHARACTER*1	OPC		!The operation code.
        INTEGER*1	PRECEDENCE	!Its precedence in the siding may differ.
       END TYPE DEFERRED		!Anyway, that's enough.
       TYPE(DEFERRED) OPSTACK(0:STACKLIMIT)	!One siding, please.
       INTEGER OSP			!The operation stack pointer.

       INTEGER INCOMING,TOKENTYPE,NOTHING,ANUMBER,OPENBRA,HUH		!Some mnemonics.
       PARAMETER (NOTHING = 0, ANUMBER = -1, OPENBRA = -2, HUH = -3)	!The ordering is not arbitrary.
       CONTAINS	!Now to mess about.
        SUBROUTINE EMIT(STUFF)	!The objective is to produce some RPN text.
         CHARACTER*(*) STUFF	!The term of the moment.
         INTEGER L		!A length.
          WRITE (MSG,1) STUFF	!Announce.
    1     FORMAT ("Emit  ",A)	!Whatever it is.
          IF (STUFF.EQ."") RETURN	!Ha ha.
          L = LEN(STUFF)	!So, how much is there to append?
          IF (LR + L.GE.ENUFF) STOP "Too much RPN for RP!"	!Perhaps too much.
          IF (LR.GT.0) THEN	!Is there existing stuff?
            LR = LR + 1			!Yes. Advance one,
            RP(LR:LR) = " "		!And place a space.
          END IF		!So much for separators.
          RP(LR + 1:LR + L) = STUFF	!Place the stuff.
          LR = LR + L			!Count it in.
        END SUBROUTINE EMIT	!Simple enough, if a bit finicky.

        SUBROUTINE STACKOP(C,P)	!Push an item into the siding.
         CHARACTER*1 C	!The operation code.
         INTEGER P	!Its precedence.
          OSP = OSP + 1		!Stacking up...
          IF (OSP.GT.STACKLIMIT) STOP "OSP overtopped!"	!Perhaps not.
          OPSTACK(OSP).OPC = C		!Righto,
          OPSTACK(OSP).PRECEDENCE = P	!The deed is simple.
          WRITE (MSG,1) C,OPSTACK(1:OSP)	!Announce.
    1     FORMAT ("Stack ",A1,9X,",OpStk=",33(A1,I2:","))
        END SUBROUTINE STACKOP	!So this is more for mnemonic ease.

        LOGICAL FUNCTION COMPILE(TEXT)	!A compiler confronts a compiler!
         CHARACTER*(*) TEXT	!To be inspected.
         INTEGER L1,L2		!Fingers for the scan.
         CHARACTER*1 C		!Character of the moment.
         INTEGER HAPPY		!Ah, shades of mood.
          LR = 0		!No output yet.
          OSP = 0		!Nothing stacked.
          OPSTACK(0).OPC = ""		!Prepare a bouncer.
          OPSTACK(0).PRECEDENCE = 0	!So that loops won't go past.
          BRALEVEL = 0		!None seen.
          HAPPY = +1		!Nor any problems.
          L2 = 1		!Syncopation: one past the end of the previous token.
Chew into an operand, possibly obstructed by an open bracket.
  100     CALL FORASIGN		!Find something to inspect.
          IF (TOKENTYPE.EQ.NOTHING) THEN	!Run off the end?
            IF (OSP.GT.0) CALL GRUMP("Another operand or one of "	!E.g. "1 +".
     1       //BRAOPEN//" is expected.")				!Give a hint, because stacked stuff awaits.
          ELSE IF (TOKENTYPE.EQ.ANUMBER) THEN	!If a number,
            CALL EMIT(TEXT(L1:L2 - 1))			!Roll all its digits.
          ELSE IF (TOKENTYPE.EQ.OPENBRA) THEN	!Starting a sub-expression?
            CALL STACKOP(C,PRBRA - 1)			!Thus ( has less precedence than ).
            GO TO 100					!And I still want an operand.
C         ELSE IF (TOKENTYPE.EQ.ANAME) THEN	!Name of something?
C           CALL EMIT(TEXT(L1:L2 - 1))			!Roll it.
          ELSE					!No further options.
            CALL GRUMP("Huh? Unexpected "//C)		!Probably something like "1 + +"
          END IF				!Righto, finished with operands.
Chase after an operator, possibly interrupted by a close bracket,.
  200     CALL FORASIGN		!Find something to inspect.
          IF (TOKENTYPE.LT.0) THEN	!But, have I an operand-like token instead?
            CALL GRUMP("Operator expected, not "//C)	!It seems so.
           ELSE			!Normally, an operator is to hand. Possibly a NOTHING, though.
            WRITE (MSG,201) C,INCOMING,OPSTACK(1:OSP)	!Document it.
  201       FORMAT ("Oprn=>",A1,"< Prec=",I2,		!Try to align with other output.
     1       ",OpStk=",33(A1,I2:","))			!So as not to clutter the display.
            DO WHILE(OPSTACK(OSP).PRECEDENCE .GE. INCOMING)	!Shunt higher-precedence stuff out.
              IF (OPSTACK(OSP).PRECEDENCE .EQ. PRBRA - 1)		!Only opening brackets have this  precedence.
     1         CALL GRUMP("Unbalanced "//OPSTACK(OSP).OPC)		!And they vanish only when meeting their closing bracket.
              CALL EMIT(OPSTACK(OSP).OPC)				!Otherwise we have an operator.
              OSP = OSP - 1						!It has gone forth.
            END DO						!On to the next.
            IF (TOKENTYPE.GT.NOTHING) THEN	!Now, only lower-precedence items are still in the stack.
              IF (INCOMING.EQ.PRBRA) THEN		!And this is a special arrival.
                CALL BALANCEBRA(C)			!It should match an earlier entry.
                BRALEVEL = BRALEVEL - 1			!Count it out.
                GO TO 200				!And I still haven't got an operator.
               ELSE				!All others are normal operators.
                IF (C.EQ."^") INCOMING = PRPOW - 1	!Special trick to cause leftwards association of x^2^3.
                CALL STACKOP(C,INCOMING)		!Shunt aside, to await the next arrival.
              END IF			!So much for that operator.
            END IF			!Providing it was not just an end-of-input flusher.
          END IF		!And not a misplaced operand.
Carry on?
          IF (HAPPY .GT. 0) GO TO 100 	!No problems, and not a nothing from the end of the text.
Completed.
          COMPILE = HAPPY.GE.0	!One hopes so.
         CONTAINS	!Now for some assistants.
          SUBROUTINE GRUMP(GROWL)	!There might be a problem.
           CHARACTER*(*) GROWL	!The fault.
            WRITE (MSG,1) GROWL	!Say it.
            IF (L1.GT. 1)        WRITE (MSG,1) "Tasty:",TEXT( 1:L1 - 1)	!Now explain the context.
            IF (L2.GT.L1)        WRITE (MSG,1) "Nasty:",TEXT(L1:L2 - 1)	!This is the token when trouble was found.
            IF (L2.LE.LEN(TEXT)) WRITE (MSG,1) "Misty:",TEXT(L2:)	!And this remains to be seen.
    1       FORMAT (4X,A,1X,A)	!A simple layout works nicely for reasonable-length texts.
            HAPPY = -1	.	!Just so.
          END SUBROUTINE GRUMP	!Enuogh said.

          SUBROUTINE BALANCEBRA(B)	!Perhaps a happy meeting.
           CHARACTER*1 B	!The closer.
           CHARACTER*1 O	!The putative opener.
           INTEGER IT,L		!Fingers.
           CHARACTER*88 GROWL	!A scratchpad.
            O = OPSTACK(OSP).OPC	!This should match B.
            WRITE (MSG,1) O,B		!Perhaps.
    1       FORMAT ("Match ",2A)	!Show what I've got, anyway.
            IT = INDEX(BRAOPEN,O)	!So, what sort did I save?
            IF (IT .EQ. INDEX(BRACLOSE,B)) THEN	!A friend?
              OSP = OSP - 1			!Yes. They vanish together.
             ELSE	!Otherwise, something is out of place.
              GROWL = "Unbalanced {[(...)]} bracketing! The closing "	!Alas.
     1         //B//" is unmatched."				!So, a mess.
              IF (IT.GT.0) GROWL(62:) =  "A "//BRACLOSE(IT:IT)	!Perhaps there had been no opening bracket.
     1         //" would be better."		!But if there had, this would be its friend.
              CALL GRUMP(GROWL)		!Take that!
            END IF			!So much for discrepancies.
          END SUBROUTINE BALANCEBRA	!But, hopefully, amity prevails.

          SUBROUTINE FORASIGN	!See what comes next.
           INTEGER I	!A stepper.
            L1 = L2		!Pick up where the previous scan left off.
   10       IF (L1.GT.LEN(TEXT)) THEN	!Are we off the end yet?
              C = ""			!Yes. Scrub the marker.
              L2 = L1			!TEXT(L1:L2 - 1) will be null.
              TOKENTYPE = NOTHING	!But this is to be checked first.
              INCOMING = SYMBOL(1).PRECEDENCE	!For flushing sidetracked operators.
              HAPPY = 0			!Fading away.
             ELSE	!Otherwise, there is grist.
Check for spaces and move past them.
              C = TEXT(L1:L1)	!Grab the first character of the prospective token.
              IF (C.LE." ") THEN	!Boring?
                L1 = L1 + 1		!Yes. Step past it.
                GO TO 10		!And look afresh.
              END IF		!Otherwise, L1 now fingers the start.
Caught something to inspect.
              L2 = L1 + 1		!This is one beyond. Just for digit strings.
              IF (INDEX(DIGIT,C).GT.0) THEN	!So, has one started?
                TOKENTYPE = ANUMBER 		!Yep.
   20           IF (L2.LE.LEN(TEXT)) THEN	!Probe ahead.
                  IF (INDEX(DIGIT,TEXT(L2:L2)).GT.0) THEN	!Another digit?
                    L2 = L2 + 1			!Yes. Leaving L1 fingering its start,
                    GO TO 20			!Chase its end.
                  END IF			!So much for another digit.
                END IF			!And checking against the end.
C             ELSE IF (INDEX(LETTERS,C).GT.0) THEN	!Some sort of name?
C               advance L2 while in NAMEISH.
              ELSE IF (INDEX(BRAOPEN,C).GT.0) THEN	!An open bracket?
                TOKENTYPE = OPENBRA			!Yep.
              ELSE			!Otherwise, anything else.
                DO I = OPSYMBOLS,1,-1	!Scan backwards, to find ** before *, if present.
                  IF (SYMBOL(I).IS .EQ. C) EXIT	!Found?
                END DO			!On to the next. A linear search will do.
                IF (I.LE.0) THEN	!Is it identified?
                  TOKENTYPE = HUH		!No.
                  INCOMING = SYMBOL(0).PRECEDENCE	!And this might provoke a flush.
                 ELSE			!If it is identified,
                  TOKENTYPE = I			!Then this is a positive number.
                  INCOMING = SYMBOL(I).PRECEDENCE	!And this is of interest.
                END IF			!Righto, anything has been identified, possibly as HUH.
              END IF		!So much for classification.
            END IF	!If there is something to see.
            WRITE (MSG,30) C,INCOMING,TOKENTYPE		!Announce.
   30       FORMAT ("Next=>",A1,"< Prec=",I2,",Ttype=",I2)	!C might be blank.
          END SUBROUTINE FORASIGN	!I call for a sign, and I see what?
        END FUNCTION COMPILE	!That's the main activity.
      END MODULE COMPILER	!So, enough of this.

      PROGRAM POKE
      USE COMPILER
      CHARACTER*66 TEXT
      LOGICAL HIC
      MSG = 6
      KBD = 5
      WRITE (MSG,1)
    1 FORMAT ("Produce RPN from infix...",/)

   10 WRITE (MSG,11)
   11 FORMAT("Infix: ",$)
      READ(KBD,12) TEXT
   12 FORMAT (A)
      IF (TEXT.EQ."") STOP "Enough."
      HIC = COMPILE(TEXT)
      WRITE (MSG,13) HIC,RP(1:LR)
   13 FORMAT (L6," RPN: >",A,"<")
      GO TO 10
      END


# Project : Pascal matrix generation

load "stdlib.ring"
res = newlist(5,5)

see "=== Pascal upper matrix ===" + nl
result = pascalupper(5)
showarray(result)

see nl + "=== Pascal lower matrix ===" + nl
result = pascallower(5)
showarray(result)

see nl + "=== Pascal symmetrical matrix ===" + nl
result = pascalsymmetric(5)
showarray(result)

func pascalupper(n)
    for m=1 to n
          for p=1 to n
               res[m][p] = 0
          next
    next
    for p=1 to n
         res[1][p] = 1
    next
    for i=2 to n
        for j=2 to i
            res[j][i] = res[j][i-1]+res[j-1][i-1]
        end
    end
    return res

func pascallower(n)
        for m=1 to n
              for p=1 to n
                   res[m][p] = 0
              next
        next
       for p=1 to n
             res[p][1] = 1
       next
       for i=2 to n
            for j=2 to i
                 res[i][j] = res[i-1][j]+res[i-1][j-1]
            next
        next
        return res

func pascalsymmetric(n)
        for m=1 to n
              for p=1 to n
                   res[m][p] = 0
              next
        next
        for p=1 to n
              res[p][1] = 1
              res[1][p] = 1
        next
        for i=2 to n
             for j = 2 to n
                  res[i][j] = res[i-1][j]+res[i][j-1]
             next
        next
        return res

func showarray(result)
        for n=1 to 5
              for m=1 to 5
                   see "" + result[n][m] + " "
              next
             see nl
        next


#Upper, lower, and symetric Pascal Matrix - Nigel Galloway: May 3rd., 21015
require 'pp'

ng = (g = 0..4).collect{[]}
g.each{|i| g.each{|j| ng[i][j] = i==0 ? 1 : j<i ? 0 : ng[i-1][j-1]+ng[i][j-1]}}
pp ng; puts
g.each{|i| g.each{|j| ng[i][j] = j==0 ? 1 : i<j ? 0 : ng[i-1][j-1]+ng[i-1][j]}}
pp ng; puts
g.each{|i| g.each{|j| ng[i][j] = (i==0 or j==0) ? 1 : ng[i-1][j  ]+ng[i][j-1]}}
pp ng


package main

import (
    "fmt"
    "strings"
)

var input = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"

var opa = map[string]struct {
    prec   int
    rAssoc bool
}{
    "^": {4, true},
    "*": {3, false},
    "/": {3, false},
    "+": {2, false},
    "-": {2, false},
}

func main() {
    fmt.Println("infix:  ", input)
    fmt.Println("postfix:", parseInfix(input))
}

func parseInfix(e string) (rpn string) {
    var stack []string // holds operators and left parenthesis
    for _, tok := range strings.Fields(e) {
        switch tok {
        case "(":
            stack = append(stack, tok) // push "(" to stack
        case ")":
            var op string
            for {
                // pop item ("(" or operator) from stack
                op, stack = stack[len(stack)-1], stack[:len(stack)-1]
                if op == "(" {
                    break // discard "("
                }
                rpn += " " + op // add operator to result
            }
        default:
            if o1, isOp := opa[tok]; isOp {
                // token is an operator
                for len(stack) > 0 {
                    // consider top item on stack
                    op := stack[len(stack)-1]
                    if o2, isOp := opa[op]; !isOp || o1.prec > o2.prec ||
                        o1.prec == o2.prec && o1.rAssoc {
                        break
                    }
                    // top item is an operator that needs to come off
                    stack = stack[:len(stack)-1] // pop it
                    rpn += " " + op              // add it to result
                }
                // push operator (the new one) to stack
                stack = append(stack, tok)
            } else { // token is an operand
                if rpn > "" {
                    rpn += " "
                }
                rpn += tok // add operand to result
            }
        }
    }
    // drain stack to result
    for len(stack) > 0 {
        rpn += " " + stack[len(stack)-1]
        stack = stack[:len(stack)-1]
    }
    return
}


//Pascal Matrix Generator

object pascal{
	def main( args:Array[String] ){

		println("Enter the order of matrix")
		val n = scala.io.StdIn.readInt()

		var F = new Factorial()

		var mx = Array.ofDim[Int](n,n)

		for( i <- 0 to (n-1); j <- 0 to (n-1) ){

			if( i>=j ){			//iCj
				mx(i)(j) = F.fact(i) / ( ( F.fact(j) )*( F.fact(i-j) ) )
			}
		}

		println("iCj:")
		for( i <- 0 to (n-1) ){		//iCj print
			for( j <- 0 to (n-1) ){
				print( mx(i)(j)+" " )
			}
			println("")
		}

		println("jCi:")
		for( i <- 0 to (n-1) ){		//jCi print
			for( j <- 0 to (n-1) ){
				print( mx(j)(i)+" " )
			}
			println("")
		}

		//(i+j)C j
		for( i <- 0 to (n-1); j <- 0 to (n-1) ){

			mx(i)(j) = F.fact(i+j) / ( ( F.fact(j) )*( F.fact(i) ) )
		}
		//print (i+j)Cj
		println("(i+j)Cj:")
		for( i <- 0 to (n-1) ){
			for( j <- 0 to (n-1) ){
				print( mx(i)(j)+" " )
			}
			println("")
		}

	}
}

class Factorial(){

	def fact( a:Int ): Int = {

		var b:Int = 1

		for( i <- 2 to a ){
			b = b*i
		}
		return b
	}
}


import Text.Printf

prec :: String -> Int
prec "^" = 4
prec "*" = 3
prec "/" = 3
prec "+" = 2
prec "-" = 2

leftAssoc :: String -> Bool
leftAssoc "^" = False
leftAssoc _ = True

isOp :: String -> Bool
isOp [t] = t `elem` "-+/*^"
isOp _ = False

simSYA :: [String] -> [([String], [String], String)]
simSYA xs = final <> [lastStep]
  where
    final = scanl f ([], [], "") xs
    lastStep =
      ( \(x, y, _) ->
          (reverse y <> x, [], "")
      )
        $ last final
    f (out, st, _) t
      | isOp t =
        ( reverse (takeWhile testOp st) <> out,
          (t :) (dropWhile testOp st),
          t
        )
      | t == "(" = (out, "(" : st, t)
      | t == ")" =
        ( reverse (takeWhile (/= "(") st) <> out,
          tail $ dropWhile (/= "(") st,
          t
        )
      | otherwise = (t : out, st, t)
      where
        testOp x =
          isOp x
            && ( leftAssoc t && prec t == prec x
                   || prec t < prec x
               )

main :: IO ()
main = do
  a <- getLine
  printf "%30s%20s%7s" "Output" "Stack" "Token"
  mapM_
    ( \(x, y, z) ->
        printf
          "%30s%20s%7s\n"
          (unwords $ reverse x)
          (unwords y)
          z
    )
    $ simSYA $ words a


(import (srfi 25))

(define-syntax dotimes
  (syntax-rules ()
    ((_ (i n) body ...)
     (do ((i 0 (+ i 1)))
         ((>= i n))
       body ...))))

(define (pascal-upper n)
  (let ((p (make-array (shape 0 n 0 n) 0)))
    (dotimes (i n)
      (array-set! p 0 i 1))
     (dotimes (i (- n 1))
       (dotimes (j (- n 1))
         (array-set! p (+ 1 i) (+ 1 j)
                     (+ (array-ref p i j)
                        (array-ref p (+ 1 i) j)))))
     p))

(define (pascal-lower n)
  (let ((p (make-array (shape 0 n 0 n) 0)))
    (dotimes (i n)
      (array-set! p i 0 1))
     (dotimes (i (- n 1))
       (dotimes (j (- n 1))
         (array-set! p (+ 1 i) (+ 1 j)
                     (+ (array-ref p i j)
                        (array-ref p i (+ 1 j))))))
     p))
(define (pascal-symmetric n)
  (let ((p (make-array (shape 0 n 0 n) 0)))
    (dotimes (i n)
      (array-set! p i 0 1)
      (array-set! p 0 i 1))
     (dotimes (i (- n 1))
       (dotimes (j (- n 1))
         (array-set! p (+ 1 i) (+ 1 j)
                     (+ (array-ref p (+ 1 i) j)
                        (array-ref p i (+ 1 j))))))
     p))

(define (print-array a)
  (let ((r (array-end a 0))
        (c (array-end a 1)))
    (dotimes (row (- r 1))
      (dotimes (col (- c 1))
        (display (array-ref a row col))
        (display #\space))
      (newline))))


procedure main()
   infix := "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
   printf("Infix = %i\n",infix)
   printf("RPN   = %i\n",Infix2RPN(infix))
end

link printf

record op_info(pr,as)            # p=precedence, a=associativity (left=null)

procedure Infix2RPN(expr)        #: Infix to RPN parser - shunting yard
static oi
initial {
   oi := table()                                # precedence & associativity
   every oi[!"+-"]   := op_info(2)                    # 2L
   every oi[!"*/"]   := op_info(3)                    # 3L
   oi["^"]           := op_info(4,1)                  # 4R
   }

   ostack := []                                       # operator stack
   rpn    := ""                                       # rpn

   pat := sprintf("%%5s  :  %%-%ds  :  %%s\n",*expr)  # fmt
   printf(pat,"Token","Output","Op Stack")            # header

   expr ? until pos(0) do {                     # while tokens
      tab(many(' '))                                  # consume any seperator
      token := tab(upto(' ')|0)                       # get token
      printf(pat,token,rpn,list2string(ostack))       # report
      if token := numeric(token) then           # ... numeric
         rpn ||:= token || " "
      else
         if member(oi,token) then {             # ... operator
            while member(oi,op2 := ostack[1]) &
                  ( /oi[token].as & oi[token].pr <= oi[op2].pr ) |
                  ( \oi[token].as & oi[token].pr <  oi[op2].pr ) do
               rpn ||:= pop(ostack) || " "
            push(ostack,token)
            }
         else                                   # ... parenthesis
            if token == "(" then
               push(ostack,token)
            else if token == ")" then {
               until ostack[1] == "(" do
                  rpn ||:= pop(ostack) || " " |
                     stop("Unbalanced parenthesis")
               pop(ostack)                            # discard "("
               }
      }

   while token := pop(ostack) do                # ... input exhausted
      if token == ("("|")") then stop("Unbalanced parenthesis")
      else {
         rpn ||:= token || " "
         printf(pat,"",rpn,list2string(ostack))
         }

   return rpn
end

procedure list2string(L)         #: format list as a string
   every (s := "[ ") ||:= !L || " "
   return s || "]"
end


func grow_matrix(matrix, callback) {
    var m = matrix
    var s = m.len
    m[s][0] = callback(0, m[s-1][0], 0)
    m[0][s] = callback(m[0][s-1], 0, 0)
    {|i| m[i+1][s] = callback(m[i+1][s-1], m[i][s], m[i][s-1])} * (s-1)
    {|i| m[s][i+1] = callback(m[s][i], m[s-1][i+1], m[s-1][i])} * (s)
    return m
}

func transpose(matrix) {
    matrix[0].range.map{|i| matrix.map{_[i]} }
}

func madd_n_nw(m) { grow_matrix(m, ->(_, n, nw) { n + nw }) }
func madd_w_nw(m) { grow_matrix(m, ->(w, _, nw) { w + nw }) }
func madd_w_n(m)  { grow_matrix(m, ->(w, n, _)  { w + n  }) }

var functions = [madd_n_nw, madd_w_nw, madd_w_n].map { |f|
    func(n) {
        var r = [[1]]
        { f(r) } * n
        transpose(r)
    }
}

functions.map { |f|
    f(4).map { .map{ '%2s' % _ }.join(' ') }.join("\n")
}.join("\n\n").say


NB. j does not have a verb based precedence.
NB. j evaluates verb noun sequences from right to left.
NB. Seriously.  18 precedence levels in C++ .

display=: ([: : ([email protected]:(, [: ; ' '&,&.>@:{:@:|:))) :: empty

Display=: adverb define
:
m display^:(0 [email protected]:-: x)y
)

NB. Queue, Stack, Pop: m literal name of vector to use.  verbose unless x is 0.
NB. Implementation includes display, group push and pop not available in the RC FIFO & LIFO pages
NB. As adverbs, these definitions work with any global variable.
NB. Pop needs the feature, and it helps with display as well.
Queue=: adverb define                   NB. enqueue y
('m'~)=: y ,~ (m~)
EMPTY
:
x (m,' queue')Display y
m Queue y
)

Stack=: adverb define                   NB. Stack y
('m'~)=: (|.y) , (m~)
EMPTY
:
x (m,' stack')Display y
m Stack y
)

Pop=: adverb define                     NB. Pop y items
0 m Pop y
:
y=. 0 {:@:, y                          NB. if y is empty use 0 instead
rv=. y {. (m~)
('m'~)=: y }. (m~)
x (m,' pop') Display rv
rv
)

NB. tests
TEST=: ''
'TEST'Stack'abc'
'TEST'Stack'de'
assert 'edc' -: 'TEST'Pop 3
assert 'ba' -: 'TEST'Pop 2
assert 0 (= #) TEST
'TEST'Queue'abc'
'TEST'Queue'de'
assert 'ab' -: 'TEST'Pop 2
assert 'cde' -: 'TEST'Pop 3
assert 0 (= #) TEST

any=: +./

DIGITS=: a. {~ 48+i.10                  NB. ASCII 48--57
precedence_oppression=: <;._1' +- */ ^ ( ) ',DIGITS
associativity=: 'xLLRxxL'

classify=: {:@:[email protected]:(1 , [email protected]&>)&precedence_oppression

NB. The required tokens are also tokens in j.
NB. Use the default sequential machine ;: for lexical analysis.
rclex=: (;~ classify)"0@:;:

NB. numbers can be treated as highest precedence operators
number=: Q Queue                 NB. put numbers onto the output queue
left=: S Stack                   NB. push left paren onto the stack

NB. Until the token at the top of the stack is (, pop
NB. operators off the stack onto the output queue.
NB. Pop the left parenthesis from the stack, but not onto the output queue.
right=: 4 : 0    NB. If the token is a right parenthesis:
i=. (S~) (i. rclex) '('
if. i (= #) S~ do.
 smoutput'Check your parens!'
 throw.
end.
x Q Queue x S Pop i
x S Pop 1
EMPTY
)

NB. If the token is an operator, o1, then:
NB.
NB.  while there is  an operator token, o2, at the top  of the stack, and
NB.  either o1  is [[left-associative  and its precedence  is less  than or
NB.  equal to that  of o2]]"L*.<:", or o1 is  [[right-associative and its precedence
NB.  is less than that of o2]]"R*.<", pop o2 off the stack, onto the output queue;
NB.  [[the tally of adjacent leading truths]]"NCT"
NB.
NB.  push o1 onto the stack.
o=: 4 : 0
P=. 0 0 {:: y
L=. 'L' = P { associativity
operators=. ({.~ i.&(rclex'(')) S~
NB.    NCT          L*.<:     or       R*.<
i=. (+/@:(*./\)@:((L *. P&<:) +. ((-.L) *. P&<))@:(0&{::"1)) :: 0: operators
x Q Queue x S Pop i
x (S Stack) y
EMPTY
)

NB. terminating version of invalid
invalid=: 4 : 0
smoutput 'invalid token ',0 1 {:: y
throw.
)

NB. demonstrated invalid
invalid=: [: smoutput 'discarding invalid token ' , 0 1 {:: ]

NB. shunt_yard is a verb to implement shunt-yard parsing.
NB. verbose defaults to 0.  (quiet)
NB. use: verbosity shunt_yard_parse algebraic_string
shunt_yard_parse=: 0&$: : (4 : 0)

NB. j's data structure is array.  Rank 1 arrays (vectors)
NB. are just right for the stack and output queue.

'S Q'=: ;: 'OPERATOR OUTPUT'
('S'~)=:('Q'~)=: i.0 2

NB. Follow agenda for all tokens, result saved on global OUTPUT variable
x (invalid`o`o`o`left`right`[email protected](0 0 {:: ])"2 ,:"1@:rclex) y
NB. x (invalid`o`o`o`left`right`[email protected](0 0 {:: ])"2 ,:"[email protected]:rclex) y  NB. numbers can be treated as operators
NB. check for junk on stack
if. (rclex'(') e. S~ do.
 smoutput'Check your other parens!'
 throw.
end.

NB. shift remaining operators onto the output queue
x Q Queue x S Pop # S~

NB. return the output queue
Q~
)

algebra_to_rpn=: {:@:|:@:shunt_yard_parse

fulfill_requirement=: ;@:(' '&,&.>)@:algebra_to_rpn


package require math

namespace eval pascal {
    proc upper {n} {
        for {set i 0} {$i < $n} {incr i} {
            for {set j 0} {$j < $n} {incr j} {
                puts -nonewline \t[::math::choose $j $i]
            }
            puts ""
        }
    }
    proc lower {n} {
        for {set i 0} {$i < $n} {incr i} {
            for {set j 0} {$j < $n} {incr j} {
                puts -nonewline \t[::math::choose $i $j]
            }
            puts ""
        }
    }
    proc symmetric {n} {
        for {set i 0} {$i < $n} {incr i} {
            for {set j 0} {$j < $n} {incr j} {
                puts -nonewline \t[::math::choose [expr {$i+$j}] $i]
            }
            puts ""
        }
    }
}

foreach type {upper lower symmetric} {
    puts "\n* $type"
    pascal::$type 5
}


import java.util.Stack;

public class ShuntingYard {

    public static void main(String[] args) {
        String infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
        System.out.printf("infix:   %s%n", infix);
        System.out.printf("postfix: %s%n", infixToPostfix(infix));
    }

    static String infixToPostfix(String infix) {
        /* To find out the precedence, we take the index of the
           token in the ops string and divide by 2 (rounding down).
           This will give us: 0, 0, 1, 1, 2 */
        final String ops = "-+/*^";

        StringBuilder sb = new StringBuilder();
        Stack<Integer> s = new Stack<>();

        for (String token : infix.split("\\s")) {
            if (token.isEmpty())
                continue;
            char c = token.charAt(0);
            int idx = ops.indexOf(c);

            // check for operator
            if (idx != -1) {
                if (s.isEmpty())
                    s.push(idx);

                else {
                    while (!s.isEmpty()) {
                        int prec2 = s.peek() / 2;
                        int prec1 = idx / 2;
                        if (prec2 > prec1 || (prec2 == prec1 && c != '^'))
                            sb.append(ops.charAt(s.pop())).append(' ');
                        else break;
                    }
                    s.push(idx);
                }
            }
            else if (c == '(') {
                s.push(-2); // -2 stands for '('
            }
            else if (c == ')') {
                // until '(' on stack, pop operators.
                while (s.peek() != -2)
                    sb.append(ops.charAt(s.pop())).append(' ');
                s.pop();
            }
            else {
                sb.append(token).append(' ');
            }
        }
        while (!s.isEmpty())
            sb.append(ops.charAt(s.pop())).append(' ');
        return sb.toString();
    }
}


Option Base 1
Private Function pascal_upper(n As Integer)
    Dim res As Variant: ReDim res(n, n)
    For j = 1 To n
        res(1, j) = 1
    Next j
    For i = 2 To n
        res(i, 1) = 0
        For j = 2 To i
            res(j, i) = res(j, i - 1) + res(j - 1, i - 1)
        Next j
        For j = i + 1 To n
            res(j, i) = 0
        Next j
    Next i
    pascal_upper = res
End Function

Private Function pascal_symmetric(n As Integer)
    Dim res As Variant: ReDim res(n, n)
    For i = 1 To n
        res(i, 1) = 1
        res(1, i) = 1
    Next i
    For i = 2 To n
        For j = 2 To n
            res(i, j) = res(i - 1, j) + res(i, j - 1)
        Next j
    Next i
    pascal_symmetric = res
End Function

Private Sub pp(m As Variant)
    For i = 1 To UBound(m)
        For j = 1 To UBound(m, 2)
            Debug.Print Format(m(i, j), "@@@");
        Next j
        Debug.Print
    Next i
End Sub

Public Sub main()
    Debug.Print "=== Pascal upper matrix ==="
    pp pascal_upper(5)
    Debug.Print "=== Pascal lower matrix ==="
    pp WorksheetFunction.Transpose(pascal_upper(5))
    Debug.Print "=== Pascal symmetrical matrix ==="
    pp pascal_symmetric(5)
End Sub


Function pascal_upper(i,j)
	WScript.StdOut.Write "Pascal Upper"
	WScript.StdOut.WriteLine
	For l = i To j
		For m = i To j
			If l <= m Then
				WScript.StdOut.Write binomial(m,l) & vbTab
			Else
				WScript.StdOut.Write 0 & vbTab
			End If
		Next
		WScript.StdOut.WriteLine
	Next
	WScript.StdOut.WriteLine
End Function

Function pascal_lower(i,j)
	WScript.StdOut.Write "Pascal Lower"
	WScript.StdOut.WriteLine
	For l = i To j
		For m = i To j
			If l >= m Then
				WScript.StdOut.Write binomial(l,m) & vbTab
			Else
				WScript.StdOut.Write 0 & vbTab
			End If
		Next
		WScript.StdOut.WriteLine
	Next
	WScript.StdOut.WriteLine
End Function

Function pascal_symmetric(i,j)
	WScript.StdOut.Write "Pascal Symmetric"
	WScript.StdOut.WriteLine
	For l = i To j
		For m = i To j
			WScript.StdOut.Write binomial(l+m,m) & vbTab
		Next
		WScript.StdOut.WriteLine
	Next
End Function

Function binomial(n,k)
	binomial = factorial(n)/(factorial(n-k)*factorial(k))
End Function

Function factorial(n)
	If n = 0 Then
		factorial = 1
	Else
		For i = n To 1 Step -1
			If i = n Then
				factorial = n
			Else
				factorial = factorial * i
			End If
		Next
	End If
End Function

'Test driving
Call pascal_upper(0,4)
Call pascal_lower(0,4)
Call pascal_symmetric(0,4)


function Stack() {
  this.dataStore = [];
  this.top = 0;
  this.push = push;
  this.pop = pop;
  this.peek = peek;
  this.length = length;
}

function push(element) {
  this.dataStore[this.top++] = element;
}

function pop() {
  return this.dataStore[--this.top];
}

function peek() {
  return this.dataStore[this.top-1];
}

function length() {
  return this.top;
}

var infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
infix = infix.replace(/\s+/g, ''); // remove spaces, so infix[i]!=" "

var s = new Stack();
var ops = "-+/*^";
var precedence = {"^":4, "*":3, "/":3, "+":2, "-":2};
var associativity = {"^":"Right", "*":"Left", "/":"Left", "+":"Left", "-":"Left"};
var token;
var postfix = "";
var o1, o2;

for (var i = 0; i < infix.length; i++) {
  token = infix[i];
  if (token >= "0" && token <= "9") { // if token is operand (here limited to 0 <= x <= 9)
    postfix += token + " ";
  }
  else if (ops.indexOf(token) != -1) { // if token is an operator
    o1 = token;
    o2 = s.peek();
    while (ops.indexOf(o2)!=-1 && ( // while operator token, o2, on top of the stack
      // and o1 is left-associative and its precedence is less than or equal to that of o2
      (associativity[o1] == "Left" && (precedence[o1] <= precedence[o2]) ) ||
      // the algorithm on wikipedia says: or o1 precedence < o2 precedence, but I think it should be
      // or o1 is right-associative and its precedence is less than that of o2
      (associativity[o1] == "Right" && (precedence[o1] < precedence[o2]))
      )){
        postfix += o2 + " "; // add o2 to output queue
        s.pop(); // pop o2 of the stack
        o2 = s.peek(); // next round
    }
    s.push(o1); // push o1 onto the stack
  }
  else if (token == "(") { // if token is left parenthesis
    s.push(token); // then push it onto the stack
  }
  else if (token == ")") { // if token is right parenthesis
    while (s.peek() != "("){ // until token at top is (
      postfix += s.pop() + " ";
    }
    s.pop(); // pop (, but not onto the output queue
  }
}
postfix += s.dataStore.reverse().join(" ");
print(postfix);


import "/fmt" for Fmt
import "/math" for Int
import "/matrix" for Matrix

var binomial = Fn.new { |n, k|
    if (n == k) return 1
    var prod = 1
    var i = n - k + 1
    while (i <= n) {
        prod = prod * i
        i = i + 1
    }
    return prod / Int.factorial(k)
}

var pascalUpperTriangular = Fn.new { |n|
    var m = List.filled(n, null)
    for (i in 0...n) {
        m[i] = List.filled(n, 0)
        for (j in 0...n) m[i][j] = binomial.call(j, i)
    }
    return Matrix.new(m)
}

var pascalSymmetric = Fn.new { |n|
    var m = List.filled(n, null)
    for (i in 0...n) {
        m[i] = List.filled(n, 0)
        for (j in 0...n) m[i][j] = binomial.call(i+j, i)
    }
    return Matrix.new(m)
}

var pascalLowerTriangular = Fn.new { |n| pascalSymmetric.call(n).cholesky() }

var n = 5
System.print("Pascal upper-triangular matrix:")
Fmt.mprint(pascalUpperTriangular.call(n), 2, 0)
System.print("\nPascal lower-triangular matrix:")
Fmt.mprint(pascalLowerTriangular.call(n), 2, 0)
System.print("\nPascal symmetric matrix:")
Fmt.mprint(pascalSymmetric.call(n), 2, 0)


function parseinfix2rpn(s)
    outputq = []
    opstack = []
    infix = split(s)
    for tok in infix
        if all(isnumber, tok)
            push!(outputq, tok)
        elseif tok == "("
            push!(opstack, tok)
        elseif tok == ")"
            while !isempty(opstack) && (op = pop!(opstack)) != "("
               push!(outputq, op)
            end
        else # operator
            while !isempty(opstack)
                op = pop!(opstack)
                if Base.operator_precedence(Symbol(op)) > Base.operator_precedence(Symbol(tok)) ||
                   (Base.operator_precedence(Symbol(op)) ==
                     Base.operator_precedence(Symbol(tok)) && op != "^")
                    push!(outputq, op)
                else
                    push!(opstack, op)  # undo peek
                    break
                end
            end
            push!(opstack, tok)
        end
        println("The working output stack is $outputq")
    end
    while !isempty(opstack)
        if (op = pop!(opstack)) == "("
            throw("mismatched parentheses")
        else
            push!(outputq, op)
        end
    end
    outputq
end

teststring = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
println("\nResult: $teststring becomes $(join(parseinfix2rpn(teststring), ' '))")


// version 1.2.0

import java.util.Stack

/* To find out the precedence, we take the index of the
   token in the OPS string and divide by 2 (rounding down).
   This will give us: 0, 0, 1, 1, 2 */
const val OPS = "-+/*^"

fun infixToPostfix(infix: String): String {
    val sb = StringBuilder()
    val s = Stack<Int>()
    val rx = Regex("""\s""")
    for (token in infix.split(rx)) {
        if (token.isEmpty()) continue
        val c = token[0]
        val idx = OPS.indexOf(c)

        // check for operator
        if (idx != - 1) {
            if (s.isEmpty()) {
                s.push(idx)
            }
            else {
                while (!s.isEmpty()) {
                    val prec2 = s.peek() / 2
                    val prec1 = idx / 2
                    if (prec2 > prec1 || (prec2 == prec1 && c != '^')) {
                        sb.append(OPS[s.pop()]).append(' ')
                    }
                    else break
                }
                s.push(idx)
            }
        }
        else if (c == '(') {
            s.push(-2)  // -2 stands for '('
        }
        else if (c == ')') {
            // until '(' on stack, pop operators.
            while (s.peek() != -2) sb.append(OPS[s.pop()]).append(' ')
            s.pop()
        }
        else {
            sb.append(token).append(' ')
        }
    }
    while (!s.isEmpty()) sb.append(OPS[s.pop()]).append(' ')
    return sb.toString()
}

fun main(args: Array<String>) {
    val es = listOf(
        "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3",
        "( ( 1 + 2 ) ^ ( 3 + 4 ) ) ^ ( 5 + 6 )"
    )
    for (e in es) {
        println("Infix : $e")
        println("Postfix : ${infixToPostfix(e)}\n")
    }
}


fcn binomial(n,k){ (1).reduce(k,fcn(p,i,n){ p*(n-i+1)/i },1,n) }
fcn pascal_upp(n){ [[(i,j); n; n; '{ binomial(j,i) }]]:toMatrix(_) } // [[..]] is list comprehension
fcn pascal_low(n){ [[(i,j); n; n; binomial]]:toMatrix(_) }
fcn pascal_sym(n){ [[(i,j); n; n; '{ binomial(i+j,i) }]]:toMatrix(_) }
fcn toMatrix(ns){ // turn a string of numbers into a square matrix (list of lists)
   cols:=ns.len().toFloat().sqrt().toInt();
   ns.pump(List,T(Void.Read,cols-1),List.create)
}


global stack$,queue$
stack$=""
queue$=""

in$ = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
print "Input:"
print in$

token$ = "#"
print "No", "token", "stack", "queue"

while 1
    i=i+1
    token$ = word$(in$, i)
    if token$ = "" then i=i-1: exit while
    print i, token$, reverse$(stack$), queue$

    select case
    case token$ = "("
        call stack.push token$

    case token$ = ")"
        while stack.peek$() <> "("
            'if stack is empty
            if stack$="" then print "Error: no matching '(' for token ";i: end
            call queue.push stack.pop$()
        wend
        discard$=stack.pop$()   'discard "("

    case isOperator(token$)
        op1$=token$
        while(isOperator(stack.peek$()))
            op2$=stack.peek$()
            select case
            case op2$<>"^" and precedence(op1$) = precedence(op2$)
                '"^" is the only right-associative operator
                call queue.push stack.pop$()
            case precedence(op1$) < precedence(op2$)
                call queue.push stack.pop$()
            case else
                exit while
            end select
        wend
        call stack.push op1$

    case else   'number
        'actually, wrong operator could end up here, like say %
        'If the token is a number, then add it to the output queue.
        call queue.push token$
    end select

wend

while stack$<>""
    if stack.peek$() = "(" then print "no matching ')'": end
    call queue.push stack.pop$()
wend

print "Output:"
while queue$<>""
    print queue.pop$();" ";
wend
print

end

'------------------------------------------
function isOperator(op$)
    isOperator = instr("+-*/^", op$)<>0 AND len(op$)=1
end function

function precedence(op$)
    if isOperator(op$) then
        precedence = 1 _
            + (instr("+-*/^", op$)<>0) _
            + (instr("*/^", op$)<>0) _
            + (instr("^", op$)<>0)
    end if
end function

'------------------------------------------
sub stack.push s$
    stack$=s$+"|"+stack$
end sub

sub queue.push s$
    queue$=queue$+s$+"|"
end sub

function queue.pop$()
    'it does return empty on empty stack or queue
    queue.pop$=word$(queue$,1,"|")
    queue$=mid$(queue$,instr(queue$,"|")+1)
end function

function stack.pop$()
    'it does return empty on empty stack or queue
    stack.pop$=word$(stack$,1,"|")
    stack$=mid$(stack$,instr(stack$,"|")+1)
end function

function stack.peek$()
    'it does return empty on empty stack or queue
    stack.peek$=word$(stack$,1,"|")
end function

function reverse$(s$)
    reverse$ = ""
    token$="#"
    while token$<>""
        i=i+1
        token$=word$(s$,i,"|")
        reverse$ = token$;" ";reverse$
    wend
end function