Make Wise Numbers

Wise is a simple bitwise language I designed a while back. It is based around Python's bitwise operations. It has several operations most of these are the same or very similar to the equivalent symbol in Python.

• : Duplicate the top of the stack

• ? Rotate the top of the stack to the bottom

• ! Rotate the bottom of the stack to the top

• [ ] loop while the top of the stack is not zero

• ~ not the top of the stack (-(n+1))

• - negate the top of the stack (-n)

• > bitshift the top of the stack once to the right (n//2)

• < bitshift the top of the stack once to the left (n*2)

• ^ xor the top two items of the stack (Same as Python)

• | or the top two items of the stack (Same as Python)

• & and the top two items of the stack (Same as Python)

Making an integer in Wise is pretty simple you can make zero with ::^ and increment it with ~- so you make zero and increment it a bunch of times. However if we remove the - things become a little more interesting.

We can still make every number using the remaining operations. For example here is 3

~<<~

TIO

This works because ~ turns zero, an infinite string of 0 bits, into negative one, an infinite string of 1 bits, each < appends a 0 bit to the end, when we are done we do ~ which turns each it into a string of 0s followed by a two 1s, or as most people call it 3.

Write a program that when given a positive integer will output a Wise program that will create the number n without any - in its source (the source of the output, you may use - in your own source). You may assume that there is already a zero on the top of the stack.

This is not so you should aim to minimize the generating source code not necessarily the output.

Example outputs

This list is not exhaustive they are simply possible outputs

1  -> ~<~
2  -> ~<~<
3  -> ~<<~
4  -> ~<~<<
5  -> ~<~:<<|
6  -> ~<<~<
7  -> ~<<<~
8  -> ~<~<<<
9  -> ~<~:<<<|
10 -> ~<~:<<|<
11 -> ~<<~:><<<|
12 -> ~<<~<<
13 -> ~<<~:<<<|>
14 -> ~<<<~<
15 -> ~<<<<~
16 -> ~<~<<<<
• is 0 included in positive integers May 6 '17 at 18:57
• No, 0 is not included in positive integers. May 6 '17 at 18:58
• Apparently : applied on an empty stack pushes a 0. I think this should be specified, as it's not obvious that duplicating from an empty stack should give 0 May 6 '17 at 22:32
• Are other characters syntax errors, or are they ignored?
– xnor
May 6 '17 at 23:07
• @Luismendo you do not know the contents of the stack other than that that too if the stack is a zero May 7 '17 at 0:27

Japt, 10 bytes

¤d0'<1"~<~

Try it online!

Basic idea: take the binary representation of the number, and map 0 to < and 1 to ~<~. Outputs for 1-10:

1: ~<~
2: ~<~<
3: ~<~~<~
4: ~<~<<
5: ~<~<~<~
6: ~<~~<~<
7: ~<~~<~~<~
8: ~<~<<<
9: ~<~<<~<~
10: ~<~<~<~<
• Metagolfing this would be easy, too. Just strip pairs of ~~ May 7 '17 at 1:21

JavaScript (ES6), 34 33 bytes

f=n=>n?f(n&1?~n:n/2)+'<~'[n&1]:''
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Works for any 32-bit integer.

• Ok I figured this out. Cool! nice job. May 6 '17 at 21:01

I feel like PPCG is really improving my Haskell. Strokes white cat.

f n=mapM(["<","~<~"]<$f)[1..n]!!n>>=id f takes an Int and returns a String. Try it online! (I'm referring to that <$f by the way. It saves a character over \_->.)

In the Functor instance for (->) a (functions from type a), we have: x <$f = fmap (const x) f = const x . f = const x. The only limitation is that f and the final const x must use the same source type a. The instance is completely lazy so this never even evaluates f. Alternatively, same length but less evil ((l!!) is an anonymous function): (l!!) l=(++)<$>"":tail l<*>["<","~<~"]

Try it online!

Both of these use the same representation as @ETHproductions' Japt answer, although especially the first one may give some redundant <s at the beginning.

The first one calculates all combinations of n "<" and "~<~" strings, then indexes into the resulting list.

The second one recursively calculates an infinite list formed by starting with "" and then constructing new elements by appending "<" and "~<~" strings to each element already in the list (actually it was slightly shorter to also let the "" get turned into "<".)

• How on earth does that <\$f work? Some weird functor instance?
– xnor
May 8 '17 at 1:34
• @xnor Mwahahaha I guess I should add an explanation then. May 8 '17 at 1:45

Ruby, 118116109107105 91 bytes

Saved 2 bytes thanks to cyoce!

->n{o={0=>""}
o.dup.map{|c,k|["~~c","<c*2"].map{|t|o[eval t[1..9]]=k+t}}until o[n]
o[n]}

Try it online!

This is a function that takes the integer as input and returns the string that represents that integer in Wise. You can find an ungolfed version here, which tests this program on all integers from 1 up.

The basic idea is to record a "pool" of constants. Then, with each "step", constants are added to the pool for each possible function. I have chosen the functions ~, <, and >, which I believe are sufficient to represent every number. (At least, every number under 10,000.)

• You can use dup instead of clone iirc May 6 '17 at 22:48
• Do you even need dup? map doesn't modify its receiver. May 6 '17 at 22:53
• @Cyoce I think it does May 6 '17 at 22:57
• Oh I see now. Ruby doesn't like modifying while iterating. May 6 '17 at 22:59

Python2, 5452 51 bytes.

lambda x:'<'.join('>~<~'*int(i)for i in bin(x)[2:])

Thanks to Wheat Wizard for saving 2 bytes, and Ørjan Johansen for one byte! This uses the same idea as ETHproduction's Japt answer, but with different replacement strings (i.e. using the binary representation)

• You don't need the [ ] around the generator inside of the join. join can take a generator as its argument. May 7 '17 at 2:35
• I think '>~<~'*int(i) may save you a byte. May 7 '17 at 15:01
• I believe the newest score is supposed to be listed last, for the benefit of automated scoreboard snippets and the like. May 8 '17 at 0:32
• There, sorry about being late on that. Jun 12 '17 at 15:36

05AB1E, 11 bytes

bS'<…~<~‚èJ

Try it online!

Saved 4 bytes thanks to @Adnan!

• Hey nice! You don't actually need to convert the numbers to strings as they are equal 'types' in 05AB1E. Same for the number literals (you can do without the '). You can also use indexing, which should give you 11 bytes :). May 7 '17 at 21:50
• @Adnan Thank you very much! May 7 '17 at 23:11
• @Adnan Just a quick question, how does è work here? May 8 '17 at 10:51
• First, it swaps the arguments because it would run into an exception if it was evaluated normally. After swapping, it maps 0 to the zeroth element and 1 to the first element (because it vectorizes automatically). Here is a more clear example of how it works. May 8 '17 at 10:54

Python 2, 123 110 bytes

def w(x):a=map(int,bin(x)[2:]);return x%2*("~<~:<"+"<".join(":"*e for e in a[-2::-1])+"|"*sum(a))or w(x/2)+"<"

Try it online!

Also as a lambda

w=lambda x:x%2*("~<~:<"+"<".join(":"*int(e)for e in bin(x)[-2:2:-1])+"|"*sum(map(int,bin(x)[2:])))or w(x/2)+"<"

Try it online!

Could be shorter but here is my solution. It takes the binary representation and turns it into the code.

Japt, 23 bytes

?Uu ?ß~U +'~:ßU/2 +'<:P

Try it online!

Jelly, 11 10 bytes

Bị“~<~“<”F

This is a ported version of ETHproductions' Japt answer. Speaking of ETHproductions, they saved me one byte!

• Could you swap the strings and pretend the indexing is 0-based? May 7 '17 at 0:06
• What do you mean? I'm referring to the fact that I have to increment the binary representation of the number to get usable indexes. May 7 '17 at 2:55
• Try it online! May 7 '17 at 11:05
• Doesn't work, 1 produces <, which in Wise produces 0 May 7 '17 at 12:13
• Really? It gives ~<~ for me May 7 '17 at 12:27