Skip to main content
Commonmark migration
Source Link

#Mathematica 86 bytes {1,-1} r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]

Mathematica 86 bytes

{1,-1} r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9] 

#Mathematica 86 bytes {1,-1} r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]

Mathematica 86 bytes

{1,-1} r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9] 
Source Link
Alecto
  • 1.6k
  • 13
  • 24

#Mathematica 86 bytes {1,-1} r=Reverse;Graphics@Line@Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]

How it works: {1,-1} Outputs {1,-1}. It basically "pushes it to the stack". This value can be recalled with %. r=Reverse basically just renames the Reverse function because I use it twice in the code. The Graphics@Line@ just takes a list of points and draws a line connecting them. The real meat of the problem happens in this code segment: Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]. Lemme tell you - that segment is complicated as f******ck. Here's what Nest does: Nest[f,x,9]outputs the result of calling f[f[f[f[f[f[f[f[f[x]]]]]]]]].

In my code, this first argument f is: Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&, the second argument x is {{0,0},%} (which evaluates to {{0,0},{1,-1}}), and the third argument is n, which is just 9 (which will just apply the first argument to the second argument 9 times).

The most complex part of all is this first argument: Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&, which is a giant mess of almost pure syntactic sugar. I was really abusing mathematica's syntactic sugar for this one. That line of code represents mathematica's version of an anonymous function, except to shorten things I actually defined two separate anonymous functions within that anonymous function. Yep, that's legal, folks. Let's break it down.

Join takes two arguments. The first is l=Last@#;h=#-l&/@#, and the second is r[r@#%&/@h].

The first argument of Join: Inside the "main" anonymous function, # is a list of all the points at the current iteration in the curve. So l=Last@#; means "Take the point in the list of points you recieved as input, and assign that point to the variable l. The next segment, h=#-l&/@#, is a little more complex. It means "You have a function. This function takes a point as input, subtracts l from it, and returns the result. Now, apply that function to every element in the list of points you received as input to generate a list of shifted points, and assign that new list to the variable h.

The second argument of Join: r[r@#%&/@h] has literally the most complex syntax I've ever written. I can't believe any code segment could contain something like @#%&/@ - it looks like I'm cursing like a cartoon character in the middle of a program! But it's possible to break it down. Remember - r[x] takes a list of points and returns that list in reverse order. r@#%& is an anonymous function that reverses it's input, then multiplies it by the value storied in % (which is {1,-1}), and returns the result. Basically it rotates it's input 90 degrees, but in code as short as I could possibly write. Then r@#%&/@h means "Output a new list that is every point in h rotated 90 degrees."

So overall, Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]& is a function that takes a list of points as an input, and adds on that same list of points rotated 90 degrees to get the next iteration of the curve. This is repeated 9 times to get the dragon curve. Then it's the resulting list of points is drawn to the screen as a line. And the output:

enter image description here