« first day (103 days earlier)      last day (1139 days later) » 

00:31
@DJMcMayhem Writing n choose k function. I'll see how well I can do
00:42
OK cool
What's the shortest current stack safe multiplication?
Actually since it's n * (n -1) I bet n^2 - n is shorter...
01:05
@quartata use Triangle * 2
Oh wait n*(n-1) not n*(n+1)
Unfortunately I think I need to bust out actual multiplication for this
01:23
I want to modify multiplication so that it also pushes a copy of the second operand - 1 on top of the result but I can't really read the multiplication code well enough to figure out where to place it
I think I've got everything else figured out
@quartata I'll take a stab at it
Whoa that was fast
@quartata This one is a little better: brain-flak.tryitonline.net/…
01:39
All right. That should give me an 86 byte answer, I'll post it (I think there was a main challenge for this) later
Thanks
 
4 hours later…
05:40
@WheatWizard made some nice progress on the interpreter
@PhiNotPi Nice. In Java right?
yes
input     (({}()))(([{}<>()])())
processed (((){}))(()([(){}<>]))
Left input arity 1
 [1, 1]
Right input arity 0
 [-1, -1] [-2, -1]
^ output from my program. Each set of numbers in square brackets represents a single number on the stack.
The numbers in the list are coefficients.
It turns out that, ignoring the {n} and [] commands, it is extremely easy to tell if two snippets are identical.
Ok I think I'm starting to understand how this works
05:55
I have stacks of expressions instead of stacks of numbers. Expressions are defined by a list of numbers representing coefficients. An expression of [7] represents the number 7, an expression of [0, 5] represents 5*A, [0, 0, 9] represents 9*B, etc.
The stacks are initially empty. Each time an empty stack is popped, it returns a new expression of the form [0, 0, ..., 1] representing a new variable never before seen.
Expressions can be added or negated, which is really easy to do by just adding the lists of numbers together item-by-item.
What do you mean by coefficients?
The numbers indicate how much each variable is multiplied by in that expression.
can you get A+1
?
A+1 is [1, 1]
oh ok
so it a tuple representing a linear relation
06:04
yes
so what does ({}{}) output?
Left input arity 2
 [0, 1, 1]
Right input arity 0
Wow this should make it quite easy to find replacements
Here's my proposed auto-golfing method for simple snippets: interpret the snippet like the above examples to figure out exactly what it does, and then the auto-golfer attempts to find other snippets that do the same thing.
Yeah we just need to make a good algebra engine.
06:15
The first step will be brute-forcing a lot of short programs to build up a decent table. Then, there are probably intelligent ways to attempt to combine short snippets so that they give the target snippet.
How does it handle push order?
Give me some example code and I'll run it.
e.g. what does ({}<({}<>)<>>)<>({}<>) output?
Left input arity 2
[0, 0, 1] [0, 1]
Right input arity 0
the left-most list should be the top of the stack
what do the two separate lists represent?
06:18
the two values on top of the stack
That program should reverse the order of the top two stack items
What this snippet does is swap the top two items on the stack.
ninja'd
[0, 1] [0, 0, 1] is what the output would be if it didn't swap them
I am still a bit fuzzy on the notation but the concept seems to make sense to me
ok what about (({})<(([{}]({})))>)({}{}<([{}]{})>) ?
06:23
Left input arity 2
 [0, 0, 1] [0, 1, 0]
Right input arity 0
it does the same thing
ok thought so
seems really good all thats left to make a quite decent golfer is the program finder
I need to catch some sleep.
I'll keep working on it tomorrow.
Good night!
good night
Looks like the easiest way to brute force is to convert to binary, pad to a multiple of 3 bits, and taking three bits at a time, take two bits to select paren type, one bit to decide whether to put it beside or inside
@ASCII-only I think we want to be a little more delicate than that. There are lots of ways we can really narrow the scope
06:34
@WheatWizard Like golfing numbers as well and adding numbers as a possibility for the brute forcer?
For instance we can shuffle the braces around a little so that {...} and [] are represented by the same type of brace and then ignore that brace.
 
9 hours later…
15:15
@PhiNotPi Wow, the progress you've made looks really nice! I have a couple quick questions. 1) Is the code on github or something similar yet? I'd like to look at it. 2) I think I understand the array syntax you're using, but I'm not positive. What does (({}){}) output? (Double the TOS) what about (()()())?
@DJMcMayhem I haven't made a GitHub yet.
Left input arity 1
 [0, 2]
Right input arity 0

retval [0, 2]
I've added "retval" to represent the return value of the expression. Two arbitrary snippets typically need to have the same return value to be equivalent, but in some cases (like inside <n>) the return value doesn't matter.
for the second snippet:
processed (()()())
Left input arity 0
 [3]
Right input arity 0

retval [3]
I think I have a cool idea as to how to represent these operations (once again, ignoring [] and {n}): as matrices.
Now I think I'm more confused. What does the first 0 represent?
The first number in each list is a constant, all others are variables.
15:31
So [a, b] represents a + TOS * b?
Does that mean (({}){}()()) would return [2, 2]?
input     (({}){}()())
processed (()()({}){})
Left input arity 1
 [2, 2]
Right input arity 0

retval [2, 2]
yes
[a, b, c, d] = a + TOS * b + 2nd TOS * c + 3rd TOS * d
But... wow, these operations are literal matrix multiplication.
How does that work across multiple stacks? What would ({}<>) give?
input     ({}<>)
processed ({}<>)
Left input arity 1

Right input arity 0
 [0, 1]
retval [0, 1]
Hmm, OK. It makes sense now, but it seems like there needs to be a way to distinguish which stack the retval goes to. Because the TOS in the retval is the top of the left stack, but it's pushed on to the right
yeah... there's actually a few more pieces of state information that aren't currently given in the text output.
15:40
And you could have something like (({}()())<>[()])
Which has multiple retvals on multiple stacks
input     (({}()())<>[()])
processed ((()(){})<>[()])
Left input arity 1
 [2, 1]
Right input arity 0
 [1, 1]
retval [1, 1]
retval is the return value of the entire snippet
so there's only one
Ooooooh I get it know
What I'm going to do next is create a Class file specifically to hold the output above and additional state information.
But the right output is 1 + 1 * LA not 1 + 1 * RA (a == TOS)
That is what is shown. As displayed, there's not a label as to which coefficient represents which stack.
15:50
Oh okay. What if you used that syntax for displaying? [1, 2la, 3lb] etc.
Yeah, I probably should.
Hmm... I'm trying to figure out the best way to represent this information.
Because, given two results, I want a way to combine them to give the result of concatenating the two snippets together.
 
4 hours later…
19:41
Right now I'm screwing around trying to get hashCode() to work right.
finally
20:18
()()()
()(){}
()()<>
()(())
()[()]
()<()>
(()())
[()()]
<()()>
(){}()
(){}{}
(){}<>
()({})
()[{}]
()<{}>
((){})
[(){}]
<(){}>
()<>()
()<>{}
()<><>
()(<>)
()[<>]
()<<>>
(()<>)
[()<>]
<()<>>
(())()
(()){}
(())<>
((()))
[(())]
<(())>
[()]()
[()]{}
[()]<>
([()])
[[()]]
<[()]>
<()>()
<()>{}
<()><>
(<()>)
[<()>]
<<()>>
{}()()
{}(){}
{}()<>
{}(())
{}[()]
{}<()>
({}())
[{}()]
<{}()>
{}{}()
{}{}{}
{}{}<>
{}({})
{}[{}]
{}<{}>
({}{})
[{}{}]
<{}{}>
{}<>()
{}<>{}
{}<><>
{}(<>)
{}[<>]
{}<<>>
({}<>)
[{}<>]
<{}<>>
I found a way to iterate through all simple snippets.
@PhiNotPi Looks nice. Do you have any filters for bad programs? e.g. <<...>>
I need to add filters.
Also, to clarify, I am generating the program in tree form, and then converting to string for output, not the other way around.
20:34
Unfiltered gives 135 programs, for reference.
20:55
FWIW, <<>> is also redundant, since <> already evaluates to 0
Which makes me wonder, is {{...}} ever not redundant?
I've already filtered for stuff like <<>>, now I'm working on eliminating <><> and also choosing a single ordering when multiple orderings are identical, like ()<> instead of <>().
I've gotten the 135 down to 82 length-6 snippets.
I'm pretty sure {{...}} is totally redundant.
But I'm not generating any looping code right now.
I'm bumping it up to length-8 snippets for testing... 1134 unfiltered.
length-10 has 10206 unfiltered
reduced to 3333 when filtered
actually 2258 now
21:25
The number of programs of length n should be 3^n * catalan(n)
In combinatorial mathematics, the Catalan numbers form a sequence of natural numbers that occur in various counting problems, often involving recursively-defined objects. They are named after the Belgian mathematician Eugène Charles Catalan (1814–1894). Using zero-based numbering, the nth Catalan number is given directly in terms of binomial coefficients by C n = 1 n + 1 ...
wouldn't it be 3^n * catalan?
yes my mistake
21:39
I think I have length-10 down to 2122
Are you filtering out <>(...)?
I'm filtering out (<>...) instead
22:16
@WheatWizard current filtering results for short snippets:
1 'empty'
2 ()
3 {}
4 <>
5 ()()
6 (){}
7 ()<>
8 (())
9 [()]
*10 <()>
*11 {}()
12 {}{}
13 {}<>
14 ({})
15 [{}]
16 <{}>
*17 <>()
18 <>{}
*19 <><>
20 (<>)
*21 [<>]
*22 <<>>
23 ()()()
24 ()(){}
25 ()()<>
26 ()(())
27 ()[()] CHECK AGAINST 'empty'
*28 ()<()>
29 (()())
30 [()()]
*31 <()()>
*32 (){}()
33 (){}{}
34 (){}<>
35 ()({})
36 ()[{}]
37 ()<{}>
38 ((){})
39 [(){}]
*40 <(){}>
*41 ()<>()
42 ()<>{}
*43 ()<><>
44 ()(<>)
*45 ()[<>]
*46 ()<<>>
*47 (()<>) POSSIBLE UNIQUE
*48 [()<>] POSSIBLE UNIQUE
*49 <()<>>
The asterisk means that it is filtered out. The "check against" means something got through the filter that shouldn't have (although there is a slim chance of hash collision). The "possible unique" means that something may have been incorrectly blocked. Most of those "uniques" are actually duplicates of snippets that hadn't been tried yet.
looks like I need to implement [...<>] == [...]<> and <...<>> == <...><>
22:43
Craneflak v1.0.0 is out github.com/1000000000/CraneFlak
 
1 hour later…
23:57
Doing some benchmarks on CraneFlak on my crappy netbook, it looks like it runs about 8 times faster than the Ruby Brain-Flak interpreter once initialization time becomes small enough compared to the overall running time.
Doesn't surprise me

« first day (103 days earlier)      last day (1139 days later) »