18
\$\begingroup\$

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 -> ~<~<<<<
\$\endgroup\$
  • \$\begingroup\$ is 0 included in positive integers \$\endgroup\$ – colsw May 6 '17 at 18:57
  • 4
    \$\begingroup\$ No, 0 is not included in positive integers. \$\endgroup\$ – Zacharý May 6 '17 at 18:58
  • \$\begingroup\$ 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 \$\endgroup\$ – Luis Mendo May 6 '17 at 22:32
  • \$\begingroup\$ Are other characters syntax errors, or are they ignored? \$\endgroup\$ – xnor May 6 '17 at 23:07
  • \$\begingroup\$ @Luismendo you do not know the contents of the stack other than that that too if the stack is a zero \$\endgroup\$ – Sriotchilism O'Zaic May 7 '17 at 0:27
8
\$\begingroup\$

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: ~<~<~<~<
\$\endgroup\$
  • \$\begingroup\$ Metagolfing this would be easy, too. Just strip pairs of ~~ \$\endgroup\$ – Draco18s May 7 '17 at 1:21
7
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Ok I figured this out. Cool! nice job. \$\endgroup\$ – Sriotchilism O'Zaic May 6 '17 at 21:01
7
\$\begingroup\$

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

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

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

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

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)

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

05AB1E, 11 bytes

bS'<…~<~‚èJ

Try it online!

Similar to ETHproductions' Japt answer.

Saved 4 bytes thanks to @Adnan!

\$\endgroup\$
  • \$\begingroup\$ 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 :). \$\endgroup\$ – Adnan May 7 '17 at 21:50
  • \$\begingroup\$ @Adnan Thank you very much! \$\endgroup\$ – Comrade SparklePony May 7 '17 at 23:11
  • \$\begingroup\$ @Adnan Just a quick question, how does è work here? \$\endgroup\$ – Comrade SparklePony May 8 '17 at 10:51
  • \$\begingroup\$ 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. \$\endgroup\$ – Adnan May 8 '17 at 10:54
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Japt, 23 bytes

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

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Jelly, 11 10 bytes

Bị“~<~“<”F

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

\$\endgroup\$
  • \$\begingroup\$ Could you swap the strings and pretend the indexing is 0-based? \$\endgroup\$ – ETHproductions May 7 '17 at 0:06
  • \$\begingroup\$ 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. \$\endgroup\$ – Zacharý May 7 '17 at 2:55
  • \$\begingroup\$ Try it online! \$\endgroup\$ – ETHproductions May 7 '17 at 11:05
  • \$\begingroup\$ Doesn't work, 1 produces <, which in Wise produces 0 \$\endgroup\$ – Zacharý May 7 '17 at 12:13
  • \$\begingroup\$ Really? It gives ~<~ for me \$\endgroup\$ – ETHproductions May 7 '17 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.