Ciąg fibonacciego rekurencyjnie - kod

0

Witam,
mam w ramach ćwiczeń z BASHa wyznaczyć n-ty element ciągu Fibonacciego iteracyjnie i rekurencyjnie.

Iteracyjnie sobie poradziłem:

echo "Wskaż, dla którego elementu wypisać ciąg Fibonacciego"
read n
if [ $n -le 1 ]; then echo "Wartość ciągu: $n"; fi
x=0
y=1
if [ $n -gt 1 ]; then
for (( i=2; i<=$n; i++))
do
z=$[y+x]
x=$y
y=$z
echo "Wartość ciągu: $z"
done
fi

a rekurencyjnie mam koncepcyjny kłopot jak do tego podejść:

Zacząłem jak poniżej:

echo "Podaj liczbę naturalną"
read LICZBA

if [ $LICZBA -le 1 ]; then echo "Liczba Fibonacciego to: $LICZBA"
else
LICZBA=$[($LICZBA - 1) + ($LICZBA - 2)]
echo "Liczba Fibonacciego to: $LICZBA"
fi

Oczywiście tak liczy mi tylko dla sumy dwóch liczb poprzednich nie odwołując się do tego co było wcześniej.
Jak to naprawić bez posługiwania się pętlą?
A może mam złe podejście oczekując, że wersja rekurencyjna będzie prosta (tak wszędzie piszą:)

Będę wdzięczny za jakąś wskazówkę.

Pozdrawiam,
Arek

0

jako ze trzeba pomagac poczatkujacym programistom zyjacym w totalitarnym kraju (t.j. bez dostepu do google), poswiecilam te 5 sekund na znalezienie dla ciebie super niewydajnego rozwiazania: https://www.rosettacode.org/wiki/Fibonacci_sequence#bash
:)

0

No cóż... Nie lepiej coś ciekawszego np. Fibo 3D?
Nie linux, nie bash, wybacz @arhetyp widziałem często, co robił mój znajomy admin w bashu, ale nie Fibonacciego.

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace fiboApp
{
    public partial class form : Form
    {
        #region form
        public form()
        {
            InitializeComponent();
            systemMenu.removeFromSysMenu(this);
            int x = Screen.GetWorkingArea(this).Top;
            int y = Screen.GetWorkingArea(this).Left;
            int dx = Screen.GetWorkingArea(this).Width;
            int dy = Screen.GetWorkingArea(this).Height;
            Location = new Point(y, x);
            Size = new Size(dx, dy);
            paintBox.Paint += new PaintEventHandler(paint);
            Load += new EventHandler(load);
        }
        #region api
        public enum itemFlags
        {
            mfByCommand = 0x00000000
        }
        public enum windowMessages
        {
            wmSysCommand = 0x0112
        }
        public enum itemCommands
        {
            SC_MAXIMIZE = 0xF030,
            SC_MOVE = 0xF010,
            SC_SIZE = 0xF000
        }
        class systemMenu
        {
            [DllImport("USER32", EntryPoint = "GetSystemMenu", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
            private static extern IntPtr apiGetSystemMenu(IntPtr WindowHandle, int bReset);
            [DllImport("USER32", EntryPoint = "DeleteMenu", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
            private static extern int apiDeleteMenu(IntPtr hMenu, int Position, int Flags);
            public static void removeFromSysMenu(Form f)
            {
                IntPtr hMenu = apiGetSystemMenu(f.Handle, 0);
                systemMenu.apiDeleteMenu(hMenu, (int)itemCommands.SC_MAXIMIZE, (int)itemFlags.mfByCommand);
                systemMenu.apiDeleteMenu(hMenu, (int)itemCommands.SC_MOVE, (int)itemFlags.mfByCommand);
                systemMenu.apiDeleteMenu(hMenu, (int)itemCommands.SC_SIZE, (int)itemFlags.mfByCommand);
            }
        }
        #endregion
        void load(object sender, EventArgs e)
        {
            doBasis();
            doLight();
            doBooln();
            doSlant();
        }
        void paint(object sender, PaintEventArgs e)
        {
            pA = e;
            picture();
            paintBox.Invalidate();
        }
        #endregion
        #region any
        const int a = 0;
        #endregion
        #region space/scale
        const int X = 2 * 4; //space
        const int n = 3 * 4; //scale
        #endregion
        #region struct
        struct line
        {
            public int[,] co;
            public Pen p;
        };
        struct rectangle
        {
            public Rectangle r;
            public Pen p;
        };
        #endregion
        #region points
        line[,] slantL = new line[X, X / 2];
        line[] lightL = new line[X];
        Rectangle[,] basisR = new Rectangle[2, X];
        rectangle[] boolR = new rectangle[X];
        #endregion
        #region math
        int fibo(int i)
        {
            if (i == 0 || i == 1)
                return i;
            else
                return (fibo(i - 1) + fibo(i - 2));
        }
        int power(int x, int p)
        {
            return (int)Math.Pow(x, p);
        }
        int square(int x)
        {
            return x * x;
        }
        #endregion
        #region getCoord
        int getCoByIdxA(Rectangle r, int i)
        {
            int[] co = new int[4];
            co[0] = r.Left;
            co[1] = r.Top;
            co[2] = r.Right;
            co[3] = r.Bottom;
            return co[i];
        }
        int getCoByIdxB(int i)
        {
            if (i > 1)
                return 0;
            else
                return getCoByIdxA(basisR[0, X - 1], i % 2);
        }
        int getCoByIdxC(int i)
        {
            int[,] A =
            {
                {2, 1, 3, 0},
                {0, 1, 1, 0}
            };
            int[] j = new int[2];
            j[0] = A[0, 0] * ((i + A[0, 1]) % 2) + A[0, 2] * ((i + A[0, 3]) % 2);
            j[1] = A[1, 0] * ((i + A[1, 1]) % 2) + A[1, 2] * ((i + A[1, 3]) % 2);
            return getCoByIdxA(basisR[0, X - 1], j[0]) - getCoByIdxA(basisR[0, X - 1], j[1]);
        }
        #endregion
        #region pen
        const int penColor = 0;
        const int penZebra = 1;
        const int penBooln = 2;
        Pen[,] pen =
        {              
            {
                new Pen(Color.FromArgb(128, 128, 128), 3), //gray
                new Pen(Color.FromArgb(255,   0, 255), 3), //fuchsia   
                new Pen(Color.FromArgb(  0, 255, 255), 3), //aqua
                new Pen(Color.FromArgb(  0,   0, 255), 3), //blue   
                
                new Pen(Color.FromArgb(  0, 255,   0), 3), //lime
                new Pen(Color.FromArgb(255, 255,   0), 3), //yellow   
                new Pen(Color.FromArgb(255,   0,   0), 3), //red
                new Pen(Color.FromArgb(128, 128, 128), 3)  //gray   
            },
            {
                new Pen(Color.FromArgb(  0,   0,   0), 3), //black
                new Pen(Color.FromArgb(255, 255, 255), 3), //white
                new Pen(Color.FromArgb(  0,   0,   0), 3), //black
                new Pen(Color.FromArgb(255, 255, 255), 3), //white
                
                new Pen(Color.FromArgb(  0,   0,   0), 3), //black
                new Pen(Color.FromArgb(255, 255, 255), 3), //white
                new Pen(Color.FromArgb(  0,   0,   0), 3), //black
                new Pen(Color.FromArgb(255, 255, 255), 3), //white
            },
            {
                new Pen(Color.FromArgb(255,   0,   0), 3), //red
                new Pen(Color.FromArgb(255,   0,   0), 3), //red
                new Pen(Color.FromArgb(255, 255,   0), 3), //yellow   
                new Pen(Color.FromArgb(255, 255,   0), 3), //yellow   
                
                new Pen(Color.FromArgb(  0, 255,   0), 3), //lime
                new Pen(Color.FromArgb(  0, 255,   0), 3), //lime
                new Pen(Color.FromArgb(  0,   0, 255), 3), //blue   
                new Pen(Color.FromArgb(  0,   0, 255), 3)  //blue   
            }
        };
        #endregion
        #region doPoint
        void doBasis()
        {
            #region A
            int[,] A =
            {
                //0
                {+1, +1, -3, +1},
                {+1, +1, -3, +1},
                {+1, +1, -3, +1},
                {+1, +1, -3, +1}
            };
            #endregion
            #region B
            int[,] B =
            {
                //0
                {+5, +2, -0, +0},
                {+6, +2, -1, +0},
                {+5, +2, -0, +0},
                {+6, +2, -1, +0}
            };
            #endregion
            #region C
            int[,] C =
            {
                //0
                {+1, -1}, {-1, -1},
                {-1, +1}, {+1, +1},
                {+a, +a}, {+a, +a},
                {+a, +a}, {+a, +a}
            };
            #endregion
            #region D
            int[,] D = 
            {   
                //0
                {0,1,0,0}, 
                {0,1,0,0}, 
                {0,0,1,0}, 
                {0,0,0,0},
                //1
                {0,2,1,0}, 
                {0,2,1,0}, 
                {2,1,1,2}, 
                {0,0,0,0},
                //2
                {1,0,0,0}, 
                {0,1,0,0}, 
                {0,1,0,0}, 
                {0,2,0,0},        
                //3
                {2,0,1,0}, 
                {0,1,2,0}, 
                {2,2,2,0}, 
                {0,0,0,0}, 
                //4
                {0,1,0,0}, 
                {2,0,0,0}, 
                {2,2,0,0}, 
                {2,0,0,0},
                //5
                {0,0,2,0}, 
                {1,0,1,0}, 
                {1,0,0,2}, 
                {0,0,0,0}, 
                //6
                {1,0,0,0}, 
                {1,1,0,0}, 
                {2,0,0,0}, 
                {1,1,0,0},
                //7
                {2,1,1,0}, 
                {2,2,2,0},
                {1,1,1,0}, 
                {0,0,0,0}  
            };
            #endregion
            int[] x = new int[2];
            x[0] = n * (square(X) + A[0, 0] * X + A[0, 1]);
            x[1] = n * (square(X) + A[0, 2] * X + A[0, 3]);
            int[,] dfibo = { { 0, 0 }, { 0, 0 } };
            for (int i = 0; i < X; i++)
            {
                Size size = new Size(n * 2 * fibo(i + 1), n * 2 * fibo(i + 1));
                Point[] r = new Point[2];
                for (int j = 0; j < 2; j++)
                {
                    r[j] = new Point(n * (dfibo[j, 0] + B[j, 0]) + B[j, 1] + x[0], n * (dfibo[j, 1] + B[j, 2]) + B[j, 3] + x[1]);
                    basisR[j, i] = new Rectangle(r[j], size);
                }
                for (int j = 0; j < 4; j++)
                {
                    int d = 0;
                    for (int k = 0; k < 4; k++)
                        d += power(3, k) * D[j * X + i, k];
                    dfibo[j / 2, j % 2] += C[i % 4, j % 2] * d;
                }
            }
        }
        void doLight()
        {
            #region A
            int[, ,] A =
            {
                //0
                {
                {a, 0, 0, 0}, 
                {a, 1, 0, 0}, 
                {a, 0, 1, 0}, 
                {a, 0, 0, 1}
                },
                //1
                {
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}, 
                {a, 0, 0, 0}, 
                {a, 1, 0, 0}
                },
                //2
                {
                {a, 0, 0, 0}, 
                {a, 1, 0, 0}, 
                {a, 0, 0, 0}, 
                {a, 1, 0, 0}
                },
                //3
                {
                {a, 0, 0, 0}, 
                {a, 1, 0, 0}, 
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}
                },
                //4
                {
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}, 
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}
                },
                //5
                {
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}, 
                {a, 0, 1, 0}, 
                {a, 1, 0, 0}
                },
                //6
                {
                {a, 0, 1, 0}, 
                {a, 1, 0, 0}, 
                {a, 0, 1, 0}, 
                {a, 1, 0, 0}
                },
                //7
                {
                {a, 0, 1, 0}, 
                {a, 1, 0, 0}, 
                {a, 0, 0, 0}, 
                {a, 0, 0, 1}
                }
            };
            #endregion
            #region B
            int[,] B =
            {
                //0
                {0,0,1,1}, 
                {0,0,0,0},
                {0,0,0,0}, 
                {0,0,0,0},
                //1
                {0,0,0,0}, 
                {0,0,0,0},
                {0,0,0,0}, 
                {0,0,0,0}
            };
            #endregion
            #region C
            int[,] C =
            {
                //0
                {-0,-0,+0,+0}, 
                {-0,-0,+0,+0},
                {-1,-1,+0,+0}, 
                {-1,-1,+0,+0},
                //1
                {-1,-1,+1,+1}, 
                {-0,-0,+0,+0},
                {-1,-1,+0,+0}, 
                {-1,-1,+0,+0}
            };
            #endregion
            #region D
            int[, ,] D =
            {
                //0
                {
                {+0,1,0,0}, 
                {+0,1,0,0}, 
                {+0,1,0,0}, 
                {+0,1,0,0}
                },
                //1
                {
                {-0,1,0,0}, 
                {+0,1,0,0}, 
                {+1,1,3,1}, 
                {-1,1,0,1}
                },
                //2
                {
                {+1,1,3,1}, 
                {-1,1,0,1}, 
                {-0,1,0,0}, 
                {+0,1,0,0}
                },
                //3
                {
                {+0,1,0,0}, 
                {+0,1,0,0}, 
                {+0,1,0,0}, 
                {+0,1,0,0}
                },
                //4
                {
                {+0,2,0,0}, 
                {+0,2,0,0}, 
                {+0,2,0,0}, 
                {+0,2,0,0}
                },
                //5
                {
                {-0,2,0,0}, 
                {+0,2,0,0}, 
                {+1,2,3,0}, 
                {-1,2,3,0}
                },
                //6
                {
                {+1,2,3,0}, 
                {-1,2,3,0}, 
                {-2,2,3,1}, 
                {+0,2,3,1}
                },
                //7
                {
                {-2,2,3,1}, 
                {-0,2,3,1}, 
                {-0,2,3,1}, 
                {-0,2,3,1}
                }
            };
            #endregion
            for (int i = 0; i < X; i++)
            {
                int[] idx = new int[4];
                lightL[i].co = new int[2, 2];
                for (int j = 0; j < 4; j++)
                {
                    idx[j] = A[i, j, 1] + 2 * A[i, j, 2] + 3 * A[i, j, 3];
                    lightL[i].co[j / 2, j % 2] = getCoByIdxA(basisR[B[i, j], i + C[i, j]], idx[j]);
                    lightL[i].co[j / 2, j % 2] += fibo(D[i, j, 1] * D[i, j, 2] + D[i, j, 3]) * D[i, j, 0] * n;
                }
                lightL[i].p = pen[penZebra, 1];
            }
        }
        void doBooln()
        {
            #region A
            int[,] A = 
            {
                //0
                {0,2,2,2}, 
                {0,1,1,2},
                {0,0,2,2}, 
                {1,0,2,1},
                //1
                {2,0,2,2}, 
                {3,1,1,2},
                {2,2,2,2}, 
                {1,3,2,1}
            };
            #endregion
            #region B
            int[,] B = 
            {
                //0
                {-0,+1,-0,-1},
                {-0,+3,-1,-2},
                {-0,-0,-0,+1}, 
                {-1,-0,-1,+3},
                //1
                {-0,+0,+0,+1},
                {-2,+3,+2,-2},
                {-0,+1,-0,-1}, 
                {-1,+1,-1,-1}
            };
            #endregion
            for (int i = 0; i < X; i++)
            {
                boolR[i].r = new Rectangle(
                    A[i, 0] * getCoByIdxC(i + 0) / 4 + B[i, 0] + getCoByIdxB(0),
                    A[i, 1] * getCoByIdxC(i + 1) / 4 + B[i, 1] + getCoByIdxB(1),
                    A[i, 2] * getCoByIdxC(i + 2) / 4 + B[i, 2] + getCoByIdxB(2),
                    A[i, 3] * getCoByIdxC(i + 3) / 4 + B[i, 3] + getCoByIdxB(3)
                    );
                boolR[i].p = pen[penBooln, i];
            }
        }
        void doSlant()
        {
            #region A
            int[,] A =
            {
                //0
                {0, 1, 0, 0}, 
                {2, 1, 0, 0},
                {1, 2, 1, 0}, 
                {3, 2, 0, 0}
            };
            #endregion
            for (int i = 0; i < X; i++)
            {
                for (int j = 0; j < X / 2; j++)
                {
                    int[] idx = new int[2];
                    idx[0] = A[0, 0] * ((j / A[0, 1]) % 2 + A[0, 2]) % 2 + A[1, 0] * ((j / A[1, 1]) % 2 + A[1, 2]);
                    idx[1] = A[2, 0] * ((j / A[2, 1]) % 2 + A[2, 2]) % 2 + A[3, 0] * ((j / A[3, 1]) % 2 + A[3, 2]);
                    slantL[i, j].co = new int[2, 2];
                    for (int k = 0; k < 2; k++)
                        for (int l = 0; l < 2; l++)
                            slantL[i, j].co[k, l] = getCoByIdxA(basisR[k, i], idx[l]);
                    slantL[i, j].p = pen[penColor, i];
                }
            }
        }
        #endregion
        #region paint
        PaintEventArgs pA;
        void picture()
        {
            paintBackg(Color.Black);
            for (int i = X - 1; i >= 0; i--)
            {
                for (int j = 0; j < X / 2; j++)
                    slant(i, j);
                light(i);
                basis(i);
                booln(i);
            }
        }
        void basis(int i)
        {
            paintRect(pen[0, i], basisR[0, i]);
            paintRect(pen[0, i], basisR[1, i]);
        }
        void light(int i)
        {
            paintLine(lightL[i].p, lightL[i].co[0, 0], lightL[i].co[0, 1], lightL[i].co[1, 0], lightL[i].co[1, 1]);
        }
        void booln(int i)
        {
            paintRect(boolR[X - i - 1].p, boolR[X - i - 1].r);
        }
        void slant(int i, int j)
        {
            paintLine(slantL[i, j].p, slantL[i, j].co[0, 0], slantL[i, j].co[0, 1], slantL[i, j].co[1, 0], slantL[i, j].co[1, 1]);
        }
        #region realPaint
        void paintBackg(Color c)
        {
            pA.Graphics.Clear(c);
        }
        void paintPixel(Pen p, int x, int y)
        {
            #region A
            int[,] A =
            {
                //0
                {0, 1, 0, 2},
                {a, a, a, a},
                {a, a, a, a},
                {a, a, a, a}
            };
            #endregion
            paintLine(p, x + A[0, 0], y + A[0, 1], x + A[0, 2], y + A[0, 3]);
        }
        void paintLine(Pen p, int x1, int y1, int x2, int y2)
        {
            pA.Graphics.DrawLine(p, x1, y1, x2, y2);
        }
        void paintRect(Pen p, Rectangle r)
        {
            pA.Graphics.DrawRectangle(p, r);
        }
        #endregion
        #endregion
    }
}

0
katelx napisał(a):

jako ze trzeba pomagac poczatkujacym programistom zyjacym w totalitarnym kraju (t.j. bez dostepu do google), poswiecilam te 5 sekund na znalezienie dla ciebie super niewydajnego rozwiazania: https://www.rosettacode.org/wiki/Fibonacci_sequence#bash
:)

Dziękuję, adres wydaje się warty dodania do ulubionych.
Niestety nie wiem co dalej zrobić z moim kodem - czy mogę prosić jeszcze o 5 sekund?
To nie lenistwo - ewentualnie słaba forma umysłowa.

Pozdrawiam,
Arek

0

no problem - http://lmgtfy.com/?q=fibonacci+bash+recursive
powiedz jeszcze z czym konkretnie masz problem, dalam ci gotowca

1 użytkowników online, w tym zalogowanych: 0, gości: 1