Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,60 @@
(require 'hash)
(string-delimiter "")
(define (^ a b ) (expt a b)) ;; add this not-native function
(define-syntax-rule (r-assoc? op) (= op "^"))
(define-syntax-rule (l-assoc? op) (not ( = op "^" )))
(define PRECEDENCES (list->hash
'(("+" . 2) ("-" . 2) ("*" . 3) ("/" . 3) ("//" . 3) ("^" . 4))
(make-hash)))
;; RPN vector or list -> infix tree -> (a op (b op c) d) ..
(define (rpn->infix rpn)
(define S (stack 'S))
(for ((token rpn))
(if (procedure? token)
(let [(op2 (pop S)) (op1 (pop S))]
(unless (and op1 op2) (error "cannot translate expression" rpn))
(push S (list op1 token op2))
)
(push S token ))
(writeln 'token (string token) 'stack (stack->list S)))
(begin0
(pop S) ;; return (top S)
(unless (stack-empty? S) (error "ill-formed rpn" rpn)))
)
;; a node tree is (left op right) or a number
(define-syntax-id _.left (first _)) ; mynode.left expands to (first mynode)
(define-syntax-id _.right (third _))
(define-syntax-id _.op (string (second _ )))
(define-syntax-rule (precedence node) (hash-ref PRECEDENCES (string (second node))))
(define (left-par? node) ; does lhs needs ( lhs ) ?
(cond
[(number? node.left) #f]
[(< (precedence node.left) (precedence node)) #t]
[(and
(r-assoc? node.op)
(= (precedence node.left) (precedence node))) #t]
[else #f]))
(define (right-par? node)
(cond
[(number? node.right) #f]
[(< (precedence node.right) (precedence node)) #t]
[(and
(l-assoc? node.op)
(= (precedence node.right) (precedence node))) #t]
[else #f]))
;; infix tree -> char string
(define (infix->string node)
(cond
[(number? node) (string node)]
[else (let
[(lhs (infix->string node.left))
(rhs (infix->string node.right))]
(when (left-par? node) (set! lhs (string-append "(" lhs ")")))
(when (right-par? node) (set! rhs (string-append "(" rhs ")")))
(string-append lhs " " node.op " " rhs))]))

View file

@ -0,0 +1,45 @@
import tables, strutils
const nPrec = 9
let ops: Table[string, tuple[prec: int, rAssoc: bool]] =
{ "^": (4, true)
, "*": (3, false)
, "/": (3, false)
, "+": (2, false)
, "-": (2, false)
}.toTable
proc parseRPN(e: string) =
echo "postfix: ", e
var stack = newSeq[tuple[prec: int, expr: string]]()
for tok in e.split:
echo "Token: ", tok
if ops.hasKey tok:
let op = ops[tok]
let rhs = stack.pop
var lhs = stack.pop
if lhs.prec < op.prec or (lhs.prec == op.prec and op.rAssoc):
lhs.expr = "(" & lhs.expr & ")"
lhs.expr.add " " & tok & " "
if rhs.prec < op.prec or (rhs.prec == op.prec and not op.rAssoc):
lhs.expr.add "(" & rhs.expr & ")"
else:
lhs.expr.add rhs.expr
lhs.prec = op.prec
stack.add lhs
else:
stack.add((nPrec, tok))
for f in stack:
echo " ", f.prec, " ", f.expr
echo "infix: ", stack[0].expr
for test in ["3 4 2 * 1 5 - 2 3 ^ ^ / +", "1 2 + 3 4 + ^ 5 6 + ^"]:
test.parseRPN

View file

@ -0,0 +1,71 @@
integer show_workings = 1
constant operators = {"^","*","/","+","-"},
precedence = { 4, 3, 3, 2, 2 },
rassoc = {'r', 0 ,'l', 0 ,'l'}
procedure parseRPN(string expr, string expected)
sequence stack = {}
sequence ops = split(expr)
string lhs, rhs
integer lprec,rprec
printf(1,"Postfix input: %-30s%s", {expr,iff(show_workings?'\n':'\t')})
if length(ops)=0 then ?"error" return end if
for i=1 to length(ops) do
string op = ops[i]
integer k = find(op,operators)
if k=0 then
stack = append(stack,{9,op})
else
if length(stack)<2 then ?"error" return end if
{rprec,rhs} = stack[$]; stack = stack[1..$-1]
{lprec,lhs} = stack[$]
integer prec = precedence[k]
integer assoc = rassoc[k]
if lprec<prec or (lprec=prec and assoc='r') then
lhs = "("&lhs&")"
end if
if rprec<prec or (rprec=prec and assoc='l') then
rhs = "("&rhs&")"
end if
stack[$] = {prec,lhs&" "&op&" "&rhs}
end if
if show_workings then
?{op,stack}
end if
end for
string res = stack[1][2]
printf(1,"Infix result: %s [%s]\n", {res,iff(res=expected?"ok","**ERROR**")})
end procedure
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")
show_workings = 0
parseRPN("1 2 + 3 4 + ^ 5 6 + ^","((1 + 2) ^ (3 + 4)) ^ (5 + 6)")
parseRPN("1 2 + 3 4 + 5 6 + ^ ^","(1 + 2) ^ (3 + 4) ^ (5 + 6)")
parseRPN("moon stars mud + * fire soup * ^","(moon * (stars + mud)) ^ (fire * soup)")
parseRPN("3 4 ^ 2 9 ^ ^ 2 5 ^ ^","((3 ^ 4) ^ 2 ^ 9) ^ 2 ^ 5")
parseRPN("5 6 * * + +","error")
parseRPN("","error")
parseRPN("1 4 + 5 3 + 2 3 * * *","(1 + 4) * (5 + 3) * 2 * 3")
parseRPN("1 2 * 3 4 * *","1 * 2 * 3 * 4")
parseRPN("1 2 + 3 4 + +","1 + 2 + 3 + 4")
parseRPN("1 2 + 3 4 + ^","(1 + 2) ^ (3 + 4)")
parseRPN("5 6 ^ 7 ^","(5 ^ 6) ^ 7")
parseRPN("5 4 3 2 ^ ^ ^","5 ^ 4 ^ 3 ^ 2")
parseRPN("1 2 3 + +","1 + 2 + 3")
parseRPN("1 2 + 3 +","1 + 2 + 3")
parseRPN("1 2 3 ^ ^","1 ^ 2 ^ 3")
parseRPN("1 2 ^ 3 ^","(1 ^ 2) ^ 3")
parseRPN("1 1 - 3 +","1 - 1 + 3")
parseRPN("3 1 1 - +","3 + 1 - 1") -- [txr says 3 + (1 - 1)]
parseRPN("1 2 3 + -","1 - (2 + 3)")
parseRPN("4 3 2 + +","4 + 3 + 2")
parseRPN("5 4 3 2 + + +","5 + 4 + 3 + 2")
parseRPN("5 4 3 2 * * *","5 * 4 * 3 * 2")
parseRPN("5 4 3 2 + - +","5 + 4 - (3 + 2)") -- [python says 5 + (4 - (3 + 2))]
parseRPN("3 4 5 * -","3 - 4 * 5")
parseRPN("3 4 5 - *","3 * (4 - 5)") -- [python says (3 - 4) * 5] [!!flagged!!]
parseRPN("3 4 - 5 *","(3 - 4) * 5")
parseRPN("4 2 * 1 5 - +","4 * 2 + 1 - 5") -- [python says 4 * 2 + (1 - 5)]
parseRPN("4 2 * 1 5 - 2 ^ /","4 * 2 / (1 - 5) ^ 2")
parseRPN("3 4 2 * 1 5 - 2 3 ^ ^ / +","3 + 4 * 2 / (1 - 5) ^ 2 ^ 3")

View file

@ -0,0 +1,32 @@
func p(pair, prec) {
pair[0] < prec ? "( #{pair[1]} )" : pair[1];
}
func rpm_to_infix(string) {
say "#{'='*17}\n#{string}";
var stack = [];
string.each_word { |w|
if (w ~~ /\d/) {
stack << [9, w.to_f];
}
else {
var y = stack.pop;
var x = stack.pop;
given(w) {
when ('^') { stack << [4, [p(x,5), w, p(y,4)].join(' ')] }
when (<* />) { stack << [3, [p(x,3), w, p(y,3)].join(' ')] }
when (<+ ->) { stack << [2, [p(x,2), w, p(y,2)].join(' ')] }
}
say stack;
}
};
'-'*17 -> say;
stack.map{_[1]};
}
var tests = [
'3 4 2 * 1 5 - 2 3 ^ ^ / +',
'1 2 + 3 4 + ^ 5 6 + ^',
];
tests.each { say rpm_to_infix(_).join(' ') }