Unary arithmetic

Once upon a time at a past employer far far away....
Our product had a scripting capability with a very limited homegrown language. The biggest limitation? It couldn't do arithmetic. Makes looping somewhat difficult.
So the support people who wrote these scripts begged for some arithmetic, so they could write some loops. My manager, the development manager, told me something like, "don't fix this, the product's obsolete anyway". (Naturally, the product is still in active development some 45 years later.)
So what do I do? I had to help the support guys out somehow. Then my warped mind went "click"! Unary arithmetic!!! "1" == 1, "11" == 2, "111" == 3, etc. The limited language had string manipulation  concatenation, substring, and length functions. So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....

Oh wow.... lol; I understand how you feel. On both accounts. Not sure if the proper term for it is Unary Arithmetic tho; looks more like a numbertheoretical view of the interger (ring? field? cant remember the exact term): [url=http://en.wikipedia.org/wiki/Typographical_Number_Theory]http://en.wikipedia.org/wiki/Typographical_Number_Theory[/url]. You could, if you were so inclined, develop an entire mathematical library using that...

lol, the language had string manipulation functions but no arithmetic. I feel for you.

I just got this forwarded to me. I read the line about the biggest limitation and almost spit out my water all over my monitor!

[quote user="AssimilatedByBorg"]
So what do I do? I had to help the support guys out somehow. Then my warped mind went "click"! Unary arithmetic!!! "1" == 1, "11" == 2, "111" == 3, etc. The limited language had string manipulation  concatenation, substring, and length functions. So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....
[/quote]Further exercises:1) (easy) Write a routine to print out all prime numbers.2) (hard) Determine if the language is Turingcomplete.

It can do string manipulation and length calculations but not even a simple x = y + 1?
I say, WTF?

[quote user="AssimilatedByBorg"]
So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....
[/quote]
Yeah. It's kinda like opening a beer bottle with a screwdriver. It just feels good to approximate a tool.
(Bonus if it's a twistoff!)

@marvin_rabbit said:
[quote user="AssimilatedByBorg"]
So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....
Yeah. It's kinda like opening a beer bottle with a screwdriver. It just feels good to approximate a tool.
(Bonus if it's a twistoff!)
[/quote]I'd say it's more like hammering in nails with a belt sander.

[quote user="Carnildo"][quote user="AssimilatedByBorg"]
So what do I do? I had to help the support guys out somehow. Then my warped mind went "click"! Unary arithmetic!!! "1" == 1, "11" == 2, "111" == 3, etc. The limited language had string manipulation  concatenation, substring, and length functions. So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....
[/quote]Further exercises:1) (easy) Write a routine to print out all prime numbers.2) (hard) Determine if the language is Turingcomplete.[/quote]
You can test for primality with a single regular expression. (ObPuzzle: Find the regular expression.)

[quote user="emurphy"]You can test for primality with a single regular expression. (ObPuzzle: Find the regular expression.)[/quote]
!Regex.IsMatch( number, @"^(?:1?(11+?)\1+)$" ); // Courtesy of Abigail

[quote user="AssimilatedByBorg"]
So what do I do? I had to help the support guys out somehow. Then my warped mind went "click"! Unary arithmetic!!! "1" == 1, "11" == 2, "111" == 3, etc. The limited language had string manipulation  concatenation, substring, and length functions. So I went off and wrote a little howto on doing unary arithmetic solely with these string functions. I've rarely been more proud and embarrassed at the same time....
[/quote]
I love it! If you can change individual characters from 1 to 0 in the strings as well, you've got youself the basis of a Turing machine.

[quote user="bullseye"]
[quote user="emurphy"]You can test for primality with a single regular expression. (ObPuzzle: Find the regular expression.)[/quote]
!Regex.IsMatch( number, @"^(?:1?(11+?)\1+)$" ); // Courtesy of Abigail
[/quote]
Can somebody explain this? It looks like a Perl regex, which I don't know much about.
Thanks

[quote user="savar"][quote user="bullseye"]
[quote user="emurphy"]You can test for primality with a single regular expression. (ObPuzzle: Find the regular expression.)[/quote]
!Regex.IsMatch( number, @"^(?:1?(11+?)\1+)$" ); // Courtesy of Abigail
[/quote]
Can somebody explain this? It looks like a Perl regex, which I don't know much about.
Thanks
[/quote]Basically it breaks down into the following pieces:^  The match must start at the beginning of the input(?:  This is just a grouping parentheses1?  Optionally match a single "1"  or(11+?)  Minimal match of any sequencence of two or more "1"s, and store as variable 1\1+  Match the contents of variable 1 one or more times)  end of the groupingonly parentheses$  Whatever you match, it must reach the end of the input exactly: you can't have trailing "1"s that the regex didn't matchWhat it's testing is to see if the input string is either a single 1, or it can be broken down into a number of equalsized groups of "1"s. Using minimal match (try small groups first) is an optimization, and the choice of matching a single "1" is something of a personal preference: 1 is neither prime nor composite.

Let's break it up: (analysed to the best of my regexp abilities.. YMMV)
^...$: The whole string must match ...
Now, the outer parens contain two cases and a special ?: operator in the beginning:
(`) ?: makes it so that the string matched by the enclosing parens isn't captured as \1  I guess this one's optional, but makes the (b) subexpression less confusing
(a) 1?  matches 0 or 1 '1'  i.e. the two special nonprimes.
(b) (11+?)\1+  This one finds n(n>=2)multiples of strings of 2 or more ones using a backreference. i.e. for 42*'1', this part of the regexp would match \1 = "11" followed by 20 copies of \1. By using (11+?), the shortest sequence of ones (minimum length 2) is chosen for the backreference  i.e. the smallest factor of the number is in the \1 and the largest factor is the number of times it is matched by backreference. Which is why 42 matches 221 instead of 76. I can only guess that it is done like that for efficiency.
Now that I almost understand it, it doesn't seem that awesome anymore, but kindofa neat trick to have up one's sleeve  should impress the coworkers.
Edit: Whatever... the previous poster probably said it better

Terrific. I remember once I did something similar for DOS.
Using environment variables (strings) and batch commands it is possible to manipulate (with some limitations) strings. For example string concatenation is easy, while cutting a string in pieces is much harder. Anyhow, I also implemented unary arithmetics, and I agree, it is a very crazy and empowering sensation
I think I still have the batch scripts somewhere and I seem to recall that especially subtraction and division were tricky