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\$
6
  • \$\begingroup\$ is 0 included in positive integers \$\endgroup\$
    – colsw
    Commented May 6, 2017 at 18:57
  • 4
    \$\begingroup\$ No, 0 is not included in positive integers. \$\endgroup\$
    – Adalynn
    Commented May 6, 2017 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
    Commented May 6, 2017 at 22:32
  • \$\begingroup\$ Are other characters syntax errors, or are they ignored? \$\endgroup\$
    – xnor
    Commented May 6, 2017 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\$
    – Wheat Wizard
    Commented May 7, 2017 at 0:27

9 Answers 9

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\$
1
  • \$\begingroup\$ Metagolfing this would be easy, too. Just strip pairs of ~~ \$\endgroup\$ Commented May 7, 2017 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\$
1
  • \$\begingroup\$ Ok I figured this out. Cool! nice job. \$\endgroup\$
    – Wheat Wizard
    Commented May 6, 2017 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\$
2
  • 1
    \$\begingroup\$ How on earth does that <$f work? Some weird functor instance? \$\endgroup\$
    – xnor
    Commented May 8, 2017 at 1:34
  • \$\begingroup\$ @xnor Mwahahaha I guess I should add an explanation then. \$\endgroup\$ Commented May 8, 2017 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\$
4
  • \$\begingroup\$ You can use dup instead of clone iirc \$\endgroup\$
    – Cyoce
    Commented May 6, 2017 at 22:48
  • \$\begingroup\$ Do you even need dup? map doesn't modify its receiver. \$\endgroup\$
    – Cyoce
    Commented May 6, 2017 at 22:53
  • \$\begingroup\$ @Cyoce I think it does \$\endgroup\$ Commented May 6, 2017 at 22:57
  • \$\begingroup\$ Oh I see now. Ruby doesn't like modifying while iterating. \$\endgroup\$
    – Cyoce
    Commented May 6, 2017 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\$
4
  • \$\begingroup\$ You don't need the [ ] around the generator inside of the join. join can take a generator as its argument. \$\endgroup\$
    – Wheat Wizard
    Commented May 7, 2017 at 2:35
  • \$\begingroup\$ I think '>~<~'*int(i) may save you a byte. \$\endgroup\$ Commented May 7, 2017 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\$ Commented May 8, 2017 at 0:32
  • \$\begingroup\$ There, sorry about being late on that. \$\endgroup\$
    – Adalynn
    Commented Jun 12, 2017 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\$
4
  • \$\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
    Commented May 7, 2017 at 21:50
  • \$\begingroup\$ @Adnan Thank you very much! \$\endgroup\$
    – sporkl
    Commented May 7, 2017 at 23:11
  • \$\begingroup\$ @Adnan Just a quick question, how does è work here? \$\endgroup\$
    – sporkl
    Commented May 8, 2017 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
    Commented May 8, 2017 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\$
8
  • \$\begingroup\$ Could you swap the strings and pretend the indexing is 0-based? \$\endgroup\$ Commented May 7, 2017 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\$
    – Adalynn
    Commented May 7, 2017 at 2:55
  • \$\begingroup\$ Try it online! \$\endgroup\$ Commented May 7, 2017 at 11:05
  • \$\begingroup\$ Doesn't work, 1 produces <, which in Wise produces 0 \$\endgroup\$
    – Adalynn
    Commented May 7, 2017 at 12:13
  • \$\begingroup\$ Really? It gives ~<~ for me \$\endgroup\$ Commented May 7, 2017 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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