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).
I'm having vietnam flashbacks to that one javascript program that did the same.
Is that all on the same line btw?
Huh, how does this even work, i don't even see a "disp" >_>
Reminds me of how JSc works. So it works too in Axe or it's something else?
Nice one. Reminds me of this (http://stackoverflow.com/questions/34455427/how-does-this-obfuscated-hello-world-program-using-non-printable-unicode-charact).
Break out the punch cards. :w00t:
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.
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?
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
www.youtube.com/watch?v=KG2M4ttzBnY
Programming scantrons. Ew.
() 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.
What kind of wizardry is that,
@Hayleia ? O.O
@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.
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:
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.
- I was bored. Now my Wii U is back so I "released" this without working too much on it so I am really 100% sure it can be improved drastically
- 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
- and the last one is a longer reason, and it's actually what I wrote in the first post. Axe isn't less readable than Basic. On the contrary, it's a language that supports indentation, functions and custom names for variables (instead of just A-Z) so it's intrinsically more readable than Basic...
Except that some people take my Axe, matref's Axe and Runer112's Axe as an example for what all Axe programs look like. But nope, that's not what all Axe programs look like. If you want readable Axe, you can get it. Have a look at SSBO's source, you'll understand everything except the main menu. And have a look at Weregoose's Basic. You don't understand one line of his one liners.
What this means is that Axe and Basic can become unreadable when the dev doesn't care about readability. Like when they try to optimize for speed/memory, or when they do it on purpose like what I just did. And it doesn't mean these languages are intrinsically unreadable. On the contrary, more Axe devs got their Axe programs to be optimized because thanks to indentation, functions and custom variables, they were still more understandable than an optimized Basic program's seq/cumSum/linearReg(ax+b) unindented lines using one-character variables only.
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.
So yeah, that was kind of my rant and action about that :P
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.
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)
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
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
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
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
cangrats on making an axe code not even other pretty good axe devs can read :ninja:
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).
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:
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.
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.
The load of the address would be one of your weird formulas ofcourse. Also thats PutS, not PutC ;)
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:
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
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:
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.
Yeah fair enough. It still allowed me to see a bit of a pattern, especially for the nesting.
So if I understand correctly, () just stands for Ans?
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.
Using wabbitemu's debugger i found this disassembly:
ld a, l
bcall(_HomeUp)
ld a,h
bcall(_ClrScrnFull)
ld hl, 0x88B0
ret
You're right, I got one byte wrong. Fixed it.
(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
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.
Yep, maybe I'll take a look at it tomorrow. I've had enough of this one for tonight, hehe.