Receipt Bank Logo

Quipu (Inca counting system) calculator

Quipu Calculator

The Quipu is the numbering system of the ancient Incas. A number is represented by knots in a string, using a positional representation. Since the term “political correctness” was not discovered back then it meant that of all the mathematical bases in the world only base-10 was supported. So, if the number 586 was to be recorded on the string then six touching knots were placed near the right end of the string, a space was left, then eight touching knots for the tenths, another space, and finally 5 touching knots for the hundreds. Zeros are represented using a blank space. And this being maths, not politics, leading zeros are not allowed.

If @ is a knot and ~ is a space, then 12050 would become @~@@~~~@@@@@~~

Incas knew that system very well and possessed the knowledge to sum and multiply those numbers, but only the sailors who worked part time as math professors could tie such fine knots and not get the calculation wrong.

One day, Boko Borisuri, the most egocentric of all Incas, promised to solve this problem by building a calculator so everyone can calculate quickly. He was neither a sailor, nor a professor, though. So, naturally, he could not deliver and is now facing publish shaming (which, for him, is worse than death).

Help him by writing the calculator for him. Also, since the code will be distributed using a different, but equally mad knot system, keep it as short as possible.

Input

A string representing a mathematical expression with operands in the Quipu format above, separated by the plus [+] or the multiplication [*] sign. The expression can also include parenthesis to change order of operation.

Output

A string representing the result of the mathematical expression in Quipu format.

Example:

quipu_calculator("@~@@+@~@@@*@~~~~")
=> "@~@@@~@~@@"
quipu_calculator("@~~~~~@~~+@@~~~~~@@~~")
=> "@@@~~~~~@@@~~"

Leader board

The lower the score - the better. It is the shortest solution that wins.

If you're among the first 5 stop by out booth to claim your reward.
Winner!
Nickname: janosch-jo
   Score: 98 
def quipu_calculator s
  "#{eval s.gsub(/@+~?|~~?/) { $&.count ?@}}".
  chars.map { |c|
    n = eval c
    n < 1 ? ?~ : ?@ * n
  } * ?~
end
Winner!
Nickname: remi
   Score: 100 
def quipu_calculator s
  "#{eval s.gsub(/((@+)|~)~?/) { "#$2".size }}"
    .chars.map { |c| c[?0] ? ?~ : ?@ * c.to_i } * ?~
end
Winner!
Nickname: buhtum
   Score: 101 
def quipu_calculator e
  eval(
      e.gsub(/(@+|~)~?/) { $1.count ?@ }
  ).to_s.chars.map { |d| d=eval d
  d == 0 ? ?~ : ?@ * d } * ?~
end
Winner!
Nickname: J-_-L
   Score: 102 
def quipu_calculator a
"#{eval a.gsub(/~~|@+/){$&.count ?@}.tr ?~,''}".chars.map{|e|e<?1??~:?@*e.to_i}*?~
end
Winner!
Nickname: Joskov
   Score: 102 
def quipu_calculator n
  eval(n.gsub(/(~|@+)~?/) { |i| i.count ?@ }).to_s.chars.map { |i| i == ?0 ? ?~ : ?@ * i.to_i } * ?~
end
Nickname: webit
   Score: 104 
def quipu_calculator(s)
"#{eval s.gsub(/@+|~~/){ $&.count ?@}.tr ?~,''}".chars.map{|i| i < ?1 ? ?~ : ?@*i.to_i }*?~
end
Nickname: Cinti
   Score: 107 
def quipu_calculator d
 eval(
    d.gsub(/@+|~~/) { |f| 
      f.count ?@ 
    }.tr ?~, ''
  ).to_s.chars.map { |n| 
    n == ?0 ? ?~ : ?@ * n.to_i
  } * ?~
end
Nickname: JJ
   Score: 111 
def quipu_calculator s
  eval(s.gsub(/@+/, &:size).gsub(/~~/, ?0).tr ?~, '').to_s.chars.map { |c| c == ?0 ? ?~ : ?@ * c.to_i } * ?~
end
Nickname: yitsushi
   Score: 121 
def quipu_calculator s
  eval(
    s.gsub(/~~/, '0').gsub(/@+/) { |m|
      m.size
    }.tr '~', ''
  ).to_s.chars.map { |n|
    l = n.to_i
    l < 1 ? '~' : '@' * l
  } * "~"
end
Nickname: sashe
   Score: 125 
def quipu_calculator s
  eval(s.gsub(/@+/, &:size).gsub(/~~/, '0').gsub('~', '')).
    to_s.chars.
    map { |e| e != '0' ? '@' * e.to_i : '~' }.join '~'
end
Nickname: rambo
   Score: 129 
def quipu_calculator n
  z = ->(i) { i > 0 ? ?@*i : ?~ }
  10.times { |i| i = 9-i; n.gsub! /~?#{z[i]}~??/, i.to_s }  
  eval(n).to_s.chars.map { |d| z[d.to_i] } * ?~
end
Nickname: timrogers
   Score: 131 
def quipu_calculator q
  "#{eval(
    q.gsub(/(@+)/, &:size).
      gsub('~~', ?0).
      tr ?~, ''
  )}".
    gsub(/([1-9])/) { |d| ?@ * d.to_i + ?~ }.
    gsub(?0,"~~")[0..-2]
end
Nickname: martian
   Score: 147 
def quipu_calculator n
  c = (1..9).reduce({?0=>'~~'}){|o,m|
    o[m.to_s]=?@*m
    o
  }
  eval(n.gsub(/(~~)|(~|@+)/) {|m| c.key(m)}).to_s.chars.map{|i|
    c[?0]=?~
    c[i]
  }*?~
end
Nickname: emrox
   Score: 153 
def quipu_calculator(x)
  eval(x.gsub(/[@~]+/){|q|m=q.gsub(/~~/,'~0').split(?~);m.map{|e|e==?0?0:e.size}.join}).to_s.chars.map{|c|c=c.to_i;c>0??@*c :?~}*?~
end
Nickname: thesnapdragon
   Score: 233 
def quipu_calculator(d)
  d.gsub(/\(|\)/,"").split(/\+|\*/).map{|e|e.gsub(/~~/, "~").split(/~/, -1).map(&:size).join}.each{|r| d = d.gsub(/[\@|~]/, "-").squeeze("-").sub /-/, "#{r}"}
  eval(d).to_s.split(//).map{|c| c == "0" ? "~" : "@"*c.to_i}.join "~"
end