lirtosiast wrote:


Code:
AxesOff:ClrDraw
0->|N
0->I%
~log(.85->PMT
~log(.93->A
~log(.99->B
0->Xmin
12->Xmax
~3->Ymin
3.3->Ymax
For(I,1,1000
  For([recursiven],~log(rand),PMT,~PMT
      Pt-On(I%,|N
    |N.85+I%.04->|N  //use arithmetic to skip saving |N
    |N.047+I%.848+1.6->I%  //(N-.04I%)*.04/.85+.85I%+1.6
    I+1->I
  End
  Pt-On(I%,|N
  |N->PV
  If [recursiven]>A
  Then
    ~PV.15+I%.28->|N
    PV.26+I%.24+.44->I%
  Else
    If [recursiven]>B
    Then
      PV.2-I%.26->|N
      PV.23+I%.22+.44->I%
    Else
      0->|N
      I%.16->I%
    End
  End
End


The Finance variables definitely speed things up, except they can't be used as the var for a For( loop on CE's for some reason. (Or, at least, they can't be used as the var for a For( loop on my CE without a SYNTAX error...)
[recursiven] isn't a finance variable.
MateoConLechuga wrote:
[recursiven] isn't a finance variable.


Oh yeah.... Wrong "n"... (quietly steps out of room)

Why are there so many n's!?
The complex number–based algorithm for the Barnsley fern is fairly well suited to code golf in TI-BASIC. Here's an implementation in 156 bytes.


Code:
AxesOff:ClrDraw
1->Xmax
~.3->Ymin
.32->Ymax
0->Xmin
While 1
  Pt-On(real(Ans),imag(Ans
  sum(imag({Ans[i],Ans,[i]})(1+[i]-2fPart(|E~3int({.07539038042+.4806303605[i],.5203853705+.0754005755[i],.4204204785+5/9.99[i]}10^(3max(1,int((rand-.71)/.07
End


Note that the part that calculates the next point's coordinates is a one-liner. Here is that line, degolfed and commentated:


Code:
//Input: A, a complex number representing the old point in the fractal.
//Output: Ans, the next point.

// First we select which transformation to use out of the 4 in the definition of the fractal.
// Value    Probablility
//    1        .85
//    2        .07
//    3        .07
//    4        .01
max(1,int((rand-.71)/.07->T

// Next, we find the 6 coefficients corresponding to this transformation, here represented as 3 complex numbers.
// The coefficients are stored in base 1000. Luckily fPart( vectorizes over lists of complex numbers, so all we have to do is
fPart(|E~3int({.07539038042+.4806303605[i],.5203853705+.0754005755[i],.4204204785+5/9.99[i]}10^(3T->L1

// The coefficients are now like A+Bi where A and B are in the range [0,1). But some of the coefficients must be negative, so we apply the transformation f(x) = 1-2x to both the real and imaginary parts to put them in the range (-1,1].
1+[i]-2L1->L1


// Next, we calculate the list {real(A),imag(A),1}
imag({A[i],A,[i]})->L2

// Our next point is given by real(A)*L1(1)+imag(A)*L1(2)+1*L1(3).
sum(L2L1


I'm fairly sure 140 bytes is possible; there are places to cut down both the initialization and data decompression. Going much lower than that may require calculating the magic numbers with brute force, which may be computationally infeasible.
Looks pretty good!



Though you could save a byte via:

Code:
:int((rand-.71)/.07  -->  int(0.07⁻¹(rand-.71

Slower, as you have mentioned, but a byte is a byte...
That byte is definitely worth it; I forgot to take it out after testing. So the total is 155 now.

Currently writing better Python code for checking and brute-forcing.
The window you set up for the graph turns out to be pretty square, so you can do:


Code:
:1->Xmax
:~.3->Ymin
:ΔX->ΔY
:0->Xmin


to bring it down to 154. The Ymax becomes just larger than .32

Code:
AxesOff:ClrDraw
ZDecimal
0->Xmin
ZSquare
While 1
  Pt-On(real(Ans),imag(Ans
   sum(imag({Ans[i],Ans,[i]})(1+[i]-2fPart(|E~3int({.07539038042+.4806303605[i],.5203853705+.0754005755[i],29|E~7/8+5/9.99[i]}10^(3max(1,int(.07^^-1(rand-.71
End


136 bytes; window is a bit smaller but the fern is still clearly visible.

EDIT: 125 bytes.


Code:
AxesOff:ClrDraw
ZDecimal
0->Xmin
ZSquare
While 1
  Pt-On(real(Ans),imag(Ans
   ~[i]+sum(imag({Ans[i],Ans,[i]})(1+[i]-2fPart({753903804.2+4806303605[i],5203853705+754005755[i],3062.5}10^(~10+3max(0,int(.07^^-1(rand-.78
End


EDIT: 124 bytes; saved a byte with 10^(~22+3max(4,int(.07^^-1(rand-.5
After a day of work, I finally succeeded at brute-forcing the coefficients, saving another 4 bytes to bring the total to 120. Values in the list are 8-9 digits each and give the Barnsley fern coefficients within a tolerance of 0.006. I thought I'd have to brute-force the real and imaginary parts together (10^18 integers to check), but they can be done separately, so the search is only 10^9 values each and takes only a few minutes.

The exact byte count is heavily dependent on accuracy of the coefficients. Halving the tolerance adds 5 log_10(16) ~= 6 extra bytes and 16x more computing time, and conversely allowing twice the tolerance reduces the byte count by 6 and computing time by 16x. It may seem strange that I changed 2 to 1.3, but this adds an expected 50% precision for 2 bytes, a relative bargain.

List of difficulties / setbacks:

* Brute-forcing was unbearably slow in Python, so I had to rewrite it in C++
* I had C++ set up wrong on my machine, so used repl.it until I found the problem
* Using cosh( at the end instead of ln( worked fine in double precision, but resulted in rounding errors at 14-digit precision on the actual calculator
* Lost several hours on a dead end trying to shorten 1+[i]-1.3fPart(
* Lost a couple of hours on another dead end trying to use base 200


Code:
AxesOff:ClrDraw
ZDecimal
0
While 1
  Pt-On(real(Ans)-3,imag(Ans
  ~[i]+sum(imag({Ans[i],Ans,[i]})(1+[i]-1.3fPart({453278183+253769145[i],446468308+399949082[i],127914241}ln(max(4,int(.07^^-1(rand-.5
End


It's possible to be lucky and find 8-digit coefficients that work at tolerance 0.006. Therefore, changing some free parameters in this solution could shorten this by 2-5 bytes. The byte count can probably theoretically be reduced further by changing 1+[i]-1.3fPart( to something involving e^(, but without a clever technique that would require the full 10^18 operations (tens to thousands of CPU-years).

Edit: I have an idea to save 3-5 more bytes...
Edit: 120 -> 117

Edit: 117-> 116 using a more straightforward method. Coefficients are exact again!


Code:
AxesOff:ClrDraw
ZFrac1/8
0
While 1
  Pt-On(real(Ans)-5,imag(Ans
  {Ans(85+4[i])+160,real(Ans)(39+54[i])-Ans(15+26[i])+44,Ans(20-23[i])+real(Ans)(2-3[i])+160,16real(Ans
  sub(Ans(max(1,int(.07^^-1(rand-.71
End


Edit: 116 -> 103, rearranged coefficients and changed basis from real(Ans),imag(Ans) to Ans,real(Ans)


Code:
AxesOff:ClrDraw
ZDecimal
0
While 1
  Pt-On(real(Ans)-4,imag(Ans
  real(Ans){0,39+54[i],2-3[i],16}+Ans{85+4[i],~15-26[i],20-23[i],0}+pitimeCnv(3498|E3
  sub(Ans(max(1,int(.07^^-1(rand-.71
End
I found this cool platform called Dwitter, where you write JavaScript demos in 140 characters or less. I made Barnsley's fern in it (slow, but only because Dwitter runs iterations at 60FPS).

(This is not a live demo, but this is a small gif. Click on it to direct yourself to the dweet!)



The code behind it (which is compressed to fit on the dweet itself):

Code:
t?[1,85,7,7].map((v,i)=>Math.random()*k<v?[a,b]=[[0,85*a+4*b,20*a-26*b,28*b-15*a][i]/k,[16*b,85*b-4*a+160,23*a+22*b+160,26*a+24*b+44][i]/k]:x.fillRect(a*k+960,b*k,4,4)):a=b=0,k=100
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 2 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement