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("@~~~~~@~~+@@~~~~~@@~~") => "@@@~~~~~@@@~~"
The lower the score - the better. It is the shortest solution that wins.
Nickname: janosch-jo Score: 98
def quipu_calculator s "#{eval s.gsub(/@+~?|~~?/) { $&.count ?@}}". chars.map { |c| n = eval c n < 1 ? ?~ : ?@ * n } * ?~ end
Nickname: remi Score: 100
def quipu_calculator s "#{eval s.gsub(/((@+)|~)~?/) { "#$2".size }}" .chars.map { |c| c[?0] ? ?~ : ?@ * c.to_i } * ?~ end
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
Nickname: J-_-L Score: 102
def quipu_calculator a "#{eval a.gsub(/~~|@+/){$&.count ?@}.tr ?~,''}".chars.map{|e|e<?1??~:?@*e.to_i}*?~ end
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