Make Wise Numbers

18

4

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.


Task

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 -> ~<~<<<<

Post Rock Garf Hunter

Posted 2017-05-06T17:30:03.927

Reputation: 55 382

is 0 included in positive integers – colsw – 2017-05-06T18:57:26.387

4No, 0 is not included in positive integers. – Zacharý – 2017-05-06T18:58:38.350

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 – Luis Mendo – 2017-05-06T22:32:26.130

Are other characters syntax errors, or are they ignored? – xnor – 2017-05-06T23:07:50.797

@Luismendo you do not know the contents of the stack other than that that too if the stack is a zero – Post Rock Garf Hunter – 2017-05-07T00:27:43.220

@xnor they are ignored – Post Rock Garf Hunter – 2017-05-07T00:28:04.363

Answers

8

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: ~<~<~<~<

ETHproductions

Posted 2017-05-06T17:30:03.927

Reputation: 47 880

Metagolfing this would be easy, too. Just strip pairs of ~~ – Draco18s no longer trusts SE – 2017-05-07T01:21:52.660

7

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.

Neil

Posted 2017-05-06T17:30:03.927

Reputation: 95 035

Ok I figured this out. Cool! nice job. – Post Rock Garf Hunter – 2017-05-06T21:01:40.970

7

Haskell, 38 bytes

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 "<".)

Ørjan Johansen

Posted 2017-05-06T17:30:03.927

Reputation: 6 914

1How on earth does that <$f work? Some weird functor instance? – xnor – 2017-05-08T01:34:38.467

@xnor Mwahahaha I guess I should add an explanation then. – Ørjan Johansen – 2017-05-08T01:45:29.327

3

Ruby, 118 116 109 107 105 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[0]}}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.)

Conor O'Brien

Posted 2017-05-06T17:30:03.927

Reputation: 36 228

You can use dup instead of clone iirc – Cyoce – 2017-05-06T22:48:33.203

Do you even need dup? map doesn't modify its receiver. – Cyoce – 2017-05-06T22:53:28.757

@Cyoce I think it does – Conor O'Brien – 2017-05-06T22:57:33.680

Oh I see now. Ruby doesn't like modifying while iterating. – Cyoce – 2017-05-06T22:59:47.453

3

Python2, 54 52 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)

Zacharý

Posted 2017-05-06T17:30:03.927

Reputation: 5 710

You don't need the [ ] around the generator inside of the join. join can take a generator as its argument. – Post Rock Garf Hunter – 2017-05-07T02:35:35.080

I think '>~<~'*int(i) may save you a byte. – Ørjan Johansen – 2017-05-07T15:01:13.340

I believe the newest score is supposed to be listed last, for the benefit of automated scoreboard snippets and the like. – Ørjan Johansen – 2017-05-08T00:32:32.333

There, sorry about being late on that. – Zacharý – 2017-06-12T15:36:02.773

2

05AB1E, 11 bytes

bS'<…~<~‚èJ

Try it online!

Similar to ETHproductions' Japt answer.

Saved 4 bytes thanks to @Adnan!

Comrade SparklePony

Posted 2017-05-06T17:30:03.927

Reputation: 5 784

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 :).

– Adnan – 2017-05-07T21:50:55.167

@Adnan Thank you very much! – Comrade SparklePony – 2017-05-07T23:11:39.723

@Adnan Just a quick question, how does è work here? – Comrade SparklePony – 2017-05-08T10:51:00.453

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.

– Adnan – 2017-05-08T10:54:11.617

1

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.

Post Rock Garf Hunter

Posted 2017-05-06T17:30:03.927

Reputation: 55 382

1

Japt, 23 bytes

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

Try it online!

Luke

Posted 2017-05-06T17:30:03.927

Reputation: 4 675

0

Jelly, 11 10 bytes

Bị“~<~“<”F

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

Zacharý

Posted 2017-05-06T17:30:03.927

Reputation: 5 710

Could you swap the strings and pretend the indexing is 0-based? – ETHproductions – 2017-05-07T00:06:20.657

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. – Zacharý – 2017-05-07T02:55:56.963

Try it online! – ETHproductions – 2017-05-07T11:05:39.480

Doesn't work, 1 produces <, which in Wise produces 0 – Zacharý – 2017-05-07T12:13:59.890

Really? It gives ~<~ for me

– ETHproductions – 2017-05-07T12:27:07.737

OK, thanks for that! – Zacharý – 2017-05-07T12:29:18.283

Oh, I see how it works now! Modular indexing, which was added recently, right? – Zacharý – 2017-05-07T12:33:38.050

I think it's been there from the start, actually – ETHproductions – 2017-05-07T12:37:23.297