6
\$\begingroup\$

I've just finished the Reverse Polish Notation task in Julia from rosettacode.com by porting the existing Python code.

There are only a few lines I don't get how to port:

maxcolwidths = [max(len(y) for y in x) for x in zip(*rp)]

and the subsequent lines that use maxcolwidths.

I managed to pretty print the test output anyway, but I'd really love to hear any opinions from you.

ops = [
 :^ => :op_pow,
 :* => :op_mul,
 :/ => :op_div,
 :+ => :op_add,
 :- => :op_sub
]
for (op, func) in ops
 @eval function ($func)(stack)
 b = pop!(stack)
 a = pop!(stack)
 push!(stack, ($op)(a, b))
 end
end
input(prompt::String="") = (print(prompt); inp = chomp(readline()))
get_input(inp::String=input("Expression: ")) = (tokens = split(inp, ' '))
function rpn_calc{T<:String}(tokens::Vector{T}=get_input())
 stack = {}
 table = ["TOKEN" "ACTION" "STACK"]
 for token in tokens
 sym = symbol(token)
 if sym in keys(ops)
 action = "Apply op to top of stack."
 @eval $(ops[sym])($stack)
 else
 action = "Push num onto top of stack."
 push!(stack, parse(token))
 end
 table = [table; token action join([string(s) for s in stack], ' ')]
 end
 return table
end
function test_rpn(rpn::String="3 4 2 * 1 5 - 2 3 ^ ^ / +")
 println("For RPN expression: $rpn")
 table = rpn_calc(get_input(rpn))
 i = 1
 n_rows = length(table[:, 1])
 while i <= n_rows
 if i == 1
 println(join(table[i, 1:2], '\t'), "\t"^4, table[i, 3])
 else
 println(join(table[i, :], '\t'))
 end
 i += 1
 end
 println("\nThe final output value is: $(table[end, 3])")
end
test_rpn()

Output:

For RPN expression: 3 4 2 * 1 5 - 2 3 ^ ^ / +
TOKEN ACTION STACK
3 Push num onto top of stack 3
4 Push num onto top of stack 3 4
2 Push num onto top of stack 3 4 2
* Apply op to top of stack 3 8
1 Push num onto top of stack 3 8 1
5 Push num onto top of stack 3 8 1 5
- Apply op to top of stack 3 8 -4
2 Push num onto top of stack 3 8 -4 2
3 Push num onto top of stack 3 8 -4 2 3
^ Apply op to top of stack 3 8 -4 8
^ Apply op to top of stack 3 8 65536
/ Apply op to top of stack 3 0.0001220703125
+ Apply op to top of stack 3.0001220703125
The final output value is: 3.0001220703125
Pimgd
22.5k5 gold badges68 silver badges144 bronze badges
asked Dec 15, 2014 at 8:12
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

In case you don't already know this ...

Here is what the line [max(len(y) for y in x) for x in zip(*rp)] is doing.

Say that

rp = [('a', 'b', 'c', 'd'), ('aa', 'bbb', 'cccc', 'ddddd')]
unzipped_rp = zip(*rp) # [('a', 'aa'), ('b', 'bbb'), ('c', 'cccc'), ('d', 'ddddd')]

This code does almost the same as what the line above does ...

max_lengths = []
for x in unzipped_rp: 
 lengths = []
 for y in x:
 lengths.append(len(y))
 max_lengths.append(max(lengths))
print max_lengths

Output: [2, 3, 4, 5]

answered Dec 15, 2014 at 16:47
\$\endgroup\$
1
3
\$\begingroup\$

In Julia 0.4, the ops initialization causes a warning: WARNING: deprecated syntax "[a=>b, ...]" See below for preferred syntax. I don't remember if it works for Julia 0.3.

The use of @eval twice, once to create functions and once to call them, seems circuitous. A dictionary that maps symbols to functions would be more direct. E.g.:

ops = Dict(
 :^ => (x,y)->x^y,
 :* => (x,y)->x*y,
 :/ => (x,y)->x/y,
 :+ => (x,y)->x+y,
 :- => (x,y)->x-y
)

The while loop could be written more compactly as for i=1:nrows.

answered Dec 17, 2014 at 3:27
\$\endgroup\$
1
  • \$\begingroup\$ What I wnated to do was to build the functions programmatically to avoid redundancy. One has to use the @compat macro in order to make the Dict(:+ => "plus") syntax work in version 0.3. \$\endgroup\$ Commented Dec 21, 2014 at 5:27

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.