HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Julia RPN calculator algorithm ported from Python version

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
versionrpnalgorithmpythonjuliafromcalculatorported

Problem

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
*

Solution

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]

Code Snippets

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

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

print max_lengths

Context

StackExchange Code Review Q#73685, answer score: 3

Revisions (0)

No revisions yet.