CodeWalrus

Development => Calculators => Calc Projects, Programming & Tutorials => Topic started by: Hayleia on March 25, 2017, 10:57:31 PM

Title: [Axe] Having some fun, you can join too
Post by: Hayleia on March 25, 2017, 10:57:31 PM
I had that idea when one too many person said that Axe was intrinsically unreadable (even though nope, a "noob's" Axe is as readable as a "noob's" Basic, and an "expert's" Axe is as unreadable as an "expert's" Basic, it's just that many more Axe programmers were into optimization, thus making more unreadable Axe programs than unreadable Basic programs).

Anyway, here's the source for a Hello World.

.AA
/()/()+(+())*()+()*()+(+())+(/())+(+(+())+())+(/())+(+())+(+())+(/())->{/()/()+()+(+())*()+(+())*()+(+())}^^r/()/()+()*()+(+())+(/())*()+(+())+(+()+())+(/())+(+(+())+())->{/()/()+(+())*()+()*(*())+(+())+(/())+()}^^r/()/()+(+())*()+()*()+(+())+(/())+(+(+())+())+(/())+(+())+(+())->{/()/()+(+())*(*())+()*()+(+())+(/())+()+()}^^r/()/()+()+(+(+())+())*()+(/())+()+(+())+(+()+())+(/())+(+())+(/())->{/()/()+(+())*()+()*(*())+(/())+()+(+())}^^r/()/()+()*()*()*(*())+(/())+(/())+(/())+(+(+()+())+())->{/()/()+(+()+())*()+()*()+()+(+(+())+())}^^r/()/()+()+(+()+())*()+()+(/())+()+(/())+()+()+()+()+(/())+()+()+()->{/()/()+(+()+())*()+()*()+(+(+())+())+(/())+()}^^r(/()/()+()+(+())*()+(+())*()+(+()))()
/()/()+(+())*(*())+(/())+(/())*()+(+())+(/())+(+(+())+())->{/()/()+(+())*()+()*(*())+(+())+(/())+()}^^r/()/()+(+())*(*())+(/())+(/())*()+(+())+(/())+(+(+())+())->{/()/()+(+())*()+()*(*())+(/())+()+(+())}^^r/()/()+()+(+())*()+(+())*()+(+())
()(/()/()+()+(+())*()*()+(+()+())+(/())+(/())+()+())
()(/()/()+()*()*()*()+(/())+()+()+(+())+(+())+(+()))
()(/()/()+()+(+())*()+(/())+()+()+()+()+(/())+()+(+(+())+())+(/()))
()(/()/()+(+()+())*()+(+())+(/())+(+()+())+(+()+())+(+()+())+(/())+(+()))
()(/()/()+()*()*()*()+(/())+()+(+())+(+())+(/())+()+(+()))
(+(/()+()+()))(/()/()+()*()*()+()+(+()+())*())

(https://tiplanet.org/forum/images/forum_uploads/6947_1490478977_58d6e78111e05.gif)

The challenge is to produce the same output but with a smaller program... and obviously without using any other character than the ones already in use (not counting ".AA") :P
Note, -> is the sto arrow, and ^^r is the superscript r.

For those who would like the 8xp directly for the source, you can download it here (https://tiplanet.org/forum/download/file.php?id=3260).
Title: Re: [Axe] Having some fun, you can join too
Post by: Snektron on March 26, 2017, 12:31:32 AM
I'm having vietnam flashbacks to that one javascript program that did the same.
Is that all on the same line btw?
Title: Re: [Axe] Having some fun, you can join too
Post by: c4ooo on March 26, 2017, 12:47:00 AM
Huh, how does this even work, i don't even see a "disp" >_>
Title: Re: Having some fun, you can join too
Post by: Yuki on March 26, 2017, 01:02:52 AM
Reminds me of how JSc works. So it works too in Axe or it's something else?
Title: Re: Having some fun, you can join too
Post by: novenary on March 26, 2017, 01:14:38 AM
Nice one. Reminds me of this (http://stackoverflow.com/questions/34455427/how-does-this-obfuscated-hello-world-program-using-non-printable-unicode-charact).
Title: Re: [Axe] Having some fun, you can join too
Post by: Ranman on March 26, 2017, 01:40:30 AM
Break out the punch cards. :w00t:
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 26, 2017, 07:00:55 AM
Quote from: Snektron on March 26, 2017, 12:31:32 AM
I'm having vietnam flashbacks to that one javascript program that did the same.
Is that all on the same line btw?
No, it's 9 lines. And actually, putting them on the same line makes the program crash :P

Quote from: c4ooo on March 26, 2017, 12:47:00 AM
Huh, how does this even work, i don't even see a "disp" >_>
HAxe

Quote from: Juju on March 26, 2017, 01:02:52 AM
Reminds me of how JSf*** works. So it works too in Axe or it's something else?
Of course here I'm not playing with arrays and types since Axe has neither of both :P
But it's kind of the same idea yeah.

Quote from: Streetwalrus on March 26, 2017, 01:14:38 AM
Nice one. Reminds me of this (http://stackoverflow.com/questions/34455427/how-does-this-obfuscated-hello-world-program-using-non-printable-unicode-charact).
Not impressed. I still see print and chr :trollface:

Quote from: Ranman on March 26, 2017, 01:40:30 AM
Break out the punch cards. :w00t:
Sorry about that but I have no idea what you mean. Might be because I'm French and you're using some idiom we don't learn in schools.
Title: Re: [Axe] Having some fun, you can join too
Post by: JWinslow23 on March 26, 2017, 09:12:49 AM
Hayleia, punch cards used to be (as the name implies) cards you punch holes in, used in the old (no, older than that) days of computers for data input, data output, data storage, and (most esoterically) programming.

Also lol at your Axe source. What the heck is going on there?
Title: Re: [Axe] Having some fun, you can join too
Post by: p2 on March 26, 2017, 10:17:23 AM
Yeah I remember the good old punchcards had to carry a hundred of them around for the most simple programs, and if you dropped them and messed up their order, you were basically screwed.
My father used to learn programming with them ^^

@Hayleia: those thick paper cards with holes in them, I'm sure you know them :)

Also wow, have fun debugging such a code x.x
Title: Re: Having some fun, you can join too
Post by: WholeWheatBagels on March 26, 2017, 06:25:43 PM
www.youtube.com/watch?v=KG2M4ttzBnY

Programming scantrons. Ew.
Title: Re: [Axe] Having some fun, you can join too
Post by: c4ooo on March 26, 2017, 06:56:45 PM
() basically returns the previous value of HL, so you can do something like /() which would be HL/HL and thus one.
(foo)() also calls the address of foo.
Title: Re: Having some fun, you can join too
Post by: Dream of Omnimaga on March 26, 2017, 07:01:04 PM
What kind of wizardry is that, @Hayleia ? O.O
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 27, 2017, 04:47:22 AM
@Ranman @p2 @JWinslow23 Ok about the punch cards, but I still have no idea about "Break out" :P

Quote from: p2 on March 26, 2017, 10:17:23 AM
Also wow, have fun debugging such a code x.x
No need to debug it when it works at first try.
(lol)

Quote from: c4ooo on March 26, 2017, 06:56:45 PM
() basically returns the previous value of HL, so you can do something like /() which would be HL/HL and thus one.
(foo)() also calls the address of foo.
Ah, finally a challenger :D
You're right about routine calling. And you're half right about your first sentence :P
/() is often one, but not always. Though it does not always matter, depending on what's next.
Title: Re: [Axe] Having some fun, you can join too
Post by: p2 on March 27, 2017, 07:35:06 AM
then I have one last question @Hayleia:
Why?
Why on earth would you ever want to write a code like that???
writing such terribly ugly code should be considered a crime against humanity :ninja:
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 27, 2017, 08:29:37 AM
Quote from: p2 on March 27, 2017, 07:35:06 AM
then I have one last question @Hayleia:
Why?
Why on earth would you ever want to write a code like that???
For several reasons, more or less important.

Quote from: p2 on March 27, 2017, 07:35:06 AM
writing such terribly ugly code should be considered a crime against humanity :ninja:
Not as long as I do it on purpose. If a company used Axe as their language for a product (lol) and I wrote such ugly code, yeah, I'd understand I'd get fired.
Title: Re: Having some fun, you can join too
Post by: p2 on March 27, 2017, 08:47:17 AM
Quote from: Hayleia on March 27, 2017, 08:29:37 AM
  • I wanted to code something in C++ and to get my TI-dev environment on my "new" linux partition. Yeah, of course that code is generated, did you really think I wrote that all by hand? :P
Erm.... ::) Only a little bit I did  :thumbsup:

is this way of writing code really faster than a regular display output using a string...?  O.O
(if it is, how big would be the speed differences)

or did u only mean that speed-optifined code is ugly to read as well?
(I can hardly imagine ur above code to be faster than regular code)
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 27, 2017, 08:55:10 AM
No, it's obviously not faster (nor smaller) than just a ClrHome and a Disp. I meant that
- readability is not the goal when people optimize
- readability is not my goal when writing unreadable code on purpose (obviously)
But these cases are not the same case, my unreadable code here isn't optimized. It's just unreadable. Optimization often makes code unreadable, but unreadability not often makes code optimized :P
Title: Re: [Axe] Having some fun, you can join too
Post by: Snektron on March 27, 2017, 08:56:49 AM
The only thing i dont get is how you actually print the value, or does (x)() work on bcalls? Other than that you might be able to compress it with smc
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 27, 2017, 12:01:08 PM
Quote from: Snektron on March 27, 2017, 08:56:49 AM
The only thing i dont get is how you actually print the value, or does (x)() work on bcalls? Other than that you might be able to compress it with smc
It does not as far as I know. And I already use smc :P
Title: Re: Having some fun, you can join too
Post by: c4ooo on March 28, 2017, 03:32:46 AM
Quote from: Hayleia on March 27, 2017, 12:01:08 PM
Quote from: Snektron on March 27, 2017, 08:56:49 AM
The only thing i dont get is how you actually print the value, or does (x)() work on bcalls? Other than that you might be able to compress it with smc
It does not as far as I know. And I already use smc :P
We need more hints :3
Title: Re: [Axe] Having some fun, you can join too
Post by: p2 on March 28, 2017, 07:46:51 AM
cangrats on making an axe code not even other pretty good axe devs can read  :ninja:
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 28, 2017, 07:56:19 AM
Quote from: c4ooo on March 28, 2017, 03:32:46 AM
We need more hints :3
Ah come on, you can't give up now :P
You already found out what /() meant (you missed its special case but still, if you understand that even without the special case, you can understand 90% of the program... plus, the special case is easy to find and quick to test) and noticed the use of (foo)(), so really, you can at least transform that unreadable Axe code into a readable Axe code (I mean with numbers :P). Then you'll need basic Asm skills to progress but we're not there yet (and if you're not into Asm, anyone who is can help, it's really basic).
Title: Re: Having some fun, you can join too
Post by: novenary on March 28, 2017, 08:28:14 AM
Quote from: Hayleia on March 27, 2017, 08:29:37 AM
And another invalid argument is like Axe vs Lua or Axe vs C++ or Axe vs Java or whatever. Because Lua, C++ and Java don't run on 6MHz z80s. So you don't need to optimize anything and you can keep your code readable. If you had to run Java on a z80, you'd end up writing bytecode, so it would be less readable than any Axe code and still slower.
Also keep in mind that these languages have much, much better compiler optimizations than what Axe is capable of, especially considering the increased complexity of modern architectures.

Quote from: Hayleia on March 27, 2017, 08:29:37 AM
Not as long as I do it on purpose. If a company used Axe as their language for a product (lol) and I wrote such ugly code, yeah, I'd understand I'd get fired.
I think you're overestimating the quality of corporate code by a long shot. :trollface:
Title: Re: Having some fun, you can join too
Post by: Snektron on March 28, 2017, 08:52:17 AM
Okay, so i count 8 pairs of ->{x}^^r. That means you wrote 16 bytes, im guessing:
0xEF, 0x45, 0x0A, H, e, l, l, o, , w, o, r, l, d, 0x00
Also known as

    bcall(_PutS)
    ret
.db "Hello world", 0

You probable wrote them to saferam or something, which means after writing you probably call the address where you wrote your code.
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 28, 2017, 10:14:29 AM
Quote from: Streetwalrus on March 28, 2017, 08:28:14 AM
I think you're overestimating the quality of corporate code by a long shot. :trollface:
Nope, I've seen it :P
But it's just the "wait what?" type of code, not brainf*ck type of code on purpose.

Quote from: Snektron on March 28, 2017, 08:52:17 AM
Okay, so i count 8 pairs of ->{x}^^r. That means you wrote 16 bytes, im guessing:
0xEF, 0x45, 0x0A, H, e, l, l, o, , w, o, r, l, d, 0x00
Also known as

    bcall(_PutS)
    ret
.db "Hello world", 0

You probable wrote them to saferam or something, which means after writing you probably call the address where you wrote your code.
Ah, another challenger :D
Well, this would lack a ld to load the address of the string (plus PutC only puts one character, but just change that bcall and you can write a string for the same amount of bytes).
But glad you noticed there were a lot of __->{__}^^r, combine that with what @c4ooo finds as number values (values stored, addresses stored to, addresses called) and you could understand everything, for real.
Title: Re: [Axe] Having some fun, you can join too
Post by: Snektron on March 28, 2017, 10:22:39 AM
The load of the address would be one of your weird formulas ofcourse. Also thats PutS, not PutC ;)
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 28, 2017, 01:44:18 PM
Quote from: Snektron on March 28, 2017, 10:22:39 AM
The load of the address would be one of your weird formulas ofcourse.
That could definitely have been possible indeed. And probably much smaller in the case of the Hello World. Not sure about other cases (longer strings).

Quote from: Snektron on March 28, 2017, 10:22:39 AM
Also thats PutS, not PutC ;)
Sorry, I had problems reading your code. Too many alphanumeric characters and not enough operators and parentheses :trollface:
Title: Re: Having some fun, you can join too
Post by: novenary on March 29, 2017, 03:23:26 PM
Let's start by formatting this a little (https://wank.party/SKF0.txt), so we can see clearer.
Now, for the edge case of /() that you mentioned, it's simply that if HL is 0, the result will be 65535. So the first two in the program ensure that we start at 1.
So now we can already see that each +() will double HL, +(+()) will triple, etc. *() is square, +(/()) is +1 (or -1 if HL==0), and so forth. I can't actually find more than two levels of parenthesis nesting, so that will simplify things a little. Brb writing a quick python script. :P
Title: Re: [Axe] Having some fun, you can join too
Post by: p2 on March 29, 2017, 03:28:49 PM
Quote from: IRC*   Walrified post by Streetwalrus on Re: Having some fun, you can join too https://codewalr.us/1965/54822   17:23:27
Streetwal   I cracked the code  :P   17:24:19
JWinslow23   How insane ARE you?   17:26:53
pretty much sums it ip  :ninja:
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 29, 2017, 03:34:59 PM
Quote from: Streetwalrus on March 29, 2017, 03:23:26 PM
Let's start by formatting this a little (https://wank.party/SKF0.txt), so we can see clearer.
Now, for the edge case of /() that you mentioned, it's simply that if HL is 0, the result will be 65535. So the first two in the program ensure that we start at 1.
So now we can already see that each +() will double HL, +(+()) will triple, etc. *() is square, +(/()) is +1 (or -1 if HL==0), and so forth. I can't actually find more than two levels of parenthesis nesting, so that will simplify things a little. Brb writing a quick python script. :P
Yes everywhere :P
Especially about the python script :trollface:

Except maybe about the formatting. I'm not so sure I find this more readable. The only thing I would have done to make it more readable is putting the __->{__}^^r on separate lines rather than all on one.
Title: Re: Having some fun, you can join too
Post by: novenary on March 29, 2017, 03:43:31 PM
Yeah fair enough. It still allowed me to see a bit of a pattern, especially for the nesting.
Title: Re: Having some fun, you can join too
Post by: aetios on March 29, 2017, 03:52:59 PM
So if I understand correctly, () just stands for Ans?
Title: Re: Having some fun, you can join too
Post by: novenary on March 29, 2017, 05:11:08 PM
Yeah, pretty much.

So here's a first attempt:
#!/usr/bin/env python3

haxmap = {
    "/()/()": "1",
    "+()": "*2",
    "+(+())": "*3",
    "*()": "**2",
    "*(*())": "**3",
    "+(/())": "+1"
}

hax = "/()/()+(+())*()+()*()+(+())+(/())+(+(+())+())+(/())+(+())+(+())+(/())->{/()/()+()+(+())*()+(+())*()+(+())}^^r/()/()+()*()+(+())+(/())*()+(+())+(+()+())+(/())+(+(+())+())->{/()/()+(+())*()+()*(*())+(+())+(/())+()}^^r/()/()+(+())*()+()*()+(+())+(/())+(+(+())+())+(/())+(+())+(+())->{/()/()+(+())*(*())+()*()+(+())+(/())+()+()}^^r/()/()+()+(+(+())+())*()+(/())+()+(+())+(+()+())+(/())+(+())+(/())->{/()/()+(+())*()+()*(*())+(/())+()+(+())}^^r/()/()+()*()*()*(*())+(/())+(/())+(/())+(+(+()+())+())->{/()/()+(+()+())*()+()*()+()+(+(+())+())}^^r/()/()+()+(+()+())*()+()+(/())+()+(/())+()+()+()+()+(/())+()+()+()->{/()/()+(+()+())*()+()*()+(+(+())+())+(/())+()}^^r(/()/()+()+(+())*()+(+())*()+(+()))()"
decodedhax = ""

while hax:
    for pattern, op in haxmap.items():
        if hax.startswith(pattern):
            decodedhax += op
            hax = hax[len(pattern):]
            break
    else:
        decodedhax += hax[0]
        hax = hax[1:]

print(decodedhax)


The first line decodes to the following (after adding new lines where it makes sense :P):
1*3**2*2**2*3+1+(*3*2)+1*3*3+1->{1*2*3**2*3**2*3}^^r
1*2**2*3+1**2*3+(*2*2)+1+(*3*2)->{1*3**2*2**3*3+1*2}^^r
1*3**2*2**2*3+1+(*3*2)+1*3*3->{1*3**3*2**2*3+1*2*2}^^r
1*2+(*3*2)**2+1*2*3+(*2*2)+1*3+1->{1*3**2*2**3+1*2*3}^^r
1*2**2**2**3+1+1+1+(+(*2*2)*2)->{1+(*2*2)**2*2**2*2+(*3*2)}^^r
1*2+(*2*2)**2*2+1*2+1*2*2*2*2+1*2*2*2->{1+(*2*2)**2*2**2+(*3*2)+1*2}^^r
(1*2*3**2*3**2*3)()


Which can be interpreted (by hand) as:
0xEF7D->{0x88B0}^^r
0x4558->{0x88B2}^^r
0xEF7C->{0x88B4}^^r
0x4546->{0x88B6}^^r
0xB021->{0x88B8}^^r
0xC988->{0x88BA}^^r
(0x88B0)()


So I'm seeing a pattern here already. We're placing code at 0x88B0 and then calling it. :P

Disassembly:
ld a, l
b_call(HomeUp) ; Not sure about this one
ld a, h
b_call(ClrScrnFull) ; Now we're talking
ld hl, 0x88B0
ret


Not 100% sure what the hell that is for, besides clearing the screen. I'm far from being done.
Title: Re: [Axe] Having some fun, you can join too
Post by: Snektron on March 29, 2017, 05:25:26 PM
Using wabbitemu's debugger i found this disassembly:


ld a, l
bcall(_HomeUp)
ld a,h
bcall(_ClrScrnFull)
ld hl, 0x88B0
ret


Title: Re: Having some fun, you can join too
Post by: novenary on March 29, 2017, 06:00:53 PM
You're right, I got one byte wrong. Fixed it.
Title: Re: [Axe] Having some fun, you can join too
Post by: novenary on March 29, 2017, 06:58:39 PM
(This should be alright for a double post)

Alright, second line:
1*3**3+1+1**2*3+1+(*3*2)->{1*3**2*2**3*3+1*2}^^r
1*3**3+1+1**2*3+1+(*3*2)->{1*3**2*2**3+1*2*3}^^r
1*2*3**2*3**2*3


AKA:
0x4504->{0x88B2}^^r
0x4504->{0x88B6}^^r
0x88B0


Our disassembly becomes:
ld a, l
b_call(PutC)
ld a, h
b_call(PutC)
ld hl, 0x88B0
ret




Line 3:
()(1*2*3**2**2+(*2*2)+1+1*2*2)

Or:
()(0x6548)

So we call our little saferam routine, abusing HL once more to pass it 'H' (0x48) and e (0x65).



Line 4:
()(1*2**2**2**2+1*2*2*3*3*3)

()(0x6C6C)

"ll"



Line 5:
()(1*2*3**2+1*2*2*2*2+1*2+(*3*2)+1)

()(0x206F)

"o "



Line 6:
()(1+(*2*2)**2*3+1+(*2*2)+(*2*2)+(*2*2)+1*3)

()(0x6F57)

"Wo"



Line 7:
()(1*2**2**2**2+1*2*3*3+1*2*3)

()(0x6C72)

"rl"



And finally, line 8:
(+(/()*2*2))(1*2**2**2*2+(*2*2)**2)

(+4)(0x6400)

Here we skip the first 4 bytes (ld a, l // b_call(PutC)) of the routine, and load H with the character 'd' for the finale.



And we have our result on screen: "Hello World".

That was a beautiful hack and a very fun challenge, @Hayleia, thanks a lot. :D
Title: Re: Having some fun, you can join too
Post by: Hayleia on March 29, 2017, 07:15:37 PM
Hehe, well done :D

Quote from: Streetwalrus on March 29, 2017, 06:58:39 PM
That was a beautiful hack and a very fun challenge, @Hayleia, thanks a lot. :D
Well if you're not fed up with this, you could try to produce the same output with the same restrictions but with less characters :P
For example, IAMISSAM on TI Planet noticed that the first /() is useless. And indeed, I only put two of them to be sure I get 1 so that the following calculation gives what I want... except that there is a *() not so far from there, so it works with -1 too. And there are probably other ways to save space, not sure how yet but probably. Like not using the same ram area for the asm code but one that is shorter to get, if that exists.
Title: Re: Having some fun, you can join too
Post by: novenary on March 29, 2017, 07:25:09 PM
Yep, maybe I'll take a look at it tomorrow. I've had enough of this one for tonight, hehe.