├── .checkmakerc ├── .clang-format ├── .github └── workflows │ ├── actionlint.yml │ ├── checkmake.yml │ ├── copyrights.yml │ ├── local.yml │ ├── make.yml │ ├── markdown-lint.yml │ ├── pdd.yml │ ├── quick.yml │ ├── reuse.yml │ ├── sa.yml │ ├── shellcheck.yml │ ├── typos.yml │ ├── xcop.yml │ └── yamllint.yml ├── .gitignore ├── .yamllint.yml ├── LICENSE.txt ├── LICENSES └── MIT.txt ├── Makefile ├── README.md ├── REUSE.toml ├── ada └── recursion.adb ├── cpp ├── binpow-matrix.cpp ├── classes.cpp ├── decorators.cpp ├── functions.cpp ├── functions_with_new.cpp ├── inlines.cpp ├── interpreter.cpp ├── lambdas.cpp ├── loop.cpp ├── main.h ├── matrixes.cpp ├── novirtual.cpp ├── objects.cpp ├── recursion.cpp ├── stack_objects.cpp └── static_member_functions.cpp ├── csharp ├── .gitignore ├── Functions │ ├── Functions.csproj │ └── Program.cs ├── Objects │ ├── Objects.csproj │ └── Program.cs ├── Recursion │ ├── Program.cs │ └── Recursion.csproj └── Structs │ ├── Program.cs │ └── Structs.csproj ├── eiffel ├── application.e └── recursion.e ├── go ├── README.md ├── cmd │ ├── fast │ │ └── main.go │ ├── recursion │ │ └── main.go │ └── structs │ │ └── main.go ├── fibo.go ├── go.mod ├── loop.go └── recursive.go ├── haskell ├── .gitignore ├── Mainlib │ ├── objects.hs │ └── report.hs ├── adt.hs ├── iterate.hs ├── object_dynamic.hs ├── objects.hs ├── polymorphic_recursion.hs ├── recursion.hs ├── tail_recursion.hs └── zipwith.hs ├── java ├── Functions.java ├── Objects.java ├── Records.java └── Recursion.java ├── latex.xsl ├── lisp └── recursion.lisp ├── logo.svg ├── main.xsl ├── pascal ├── Objects.pp └── recursion.pp ├── renovate.json └── rust ├── recursion.rs └── structs.rs /.checkmakerc: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | ignore_rules = maxbodylength 3 | 4 | [maxbodylength] 5 | maxBodyLength = 50 6 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: Google 4 | 5 | AccessModifierOffset: -2 6 | ConstructorInitializerIndentWidth: 2 7 | ContinuationIndentWidth: 2 8 | IndentWidth: 2 9 | PPIndentWidth: 0 10 | TabWidth: 4 11 | AlignAfterOpenBracket: DontAlign 12 | -------------------------------------------------------------------------------- /.github/workflows/actionlint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: actionlint 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | actionlint: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Download actionlint 20 | id: get_actionlint 21 | run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 22 | shell: bash 23 | - name: Check workflow files 24 | run: ${{ steps.get_actionlint.outputs.executable }} -color 25 | shell: bash 26 | -------------------------------------------------------------------------------- /.github/workflows/checkmake.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: checkmake 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | checkmake: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: Uno-Takashi/checkmake-action@v2 20 | with: 21 | config: .checkmakerc 22 | -------------------------------------------------------------------------------- /.github/workflows/copyrights.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: copyrights 6 | 'on': 7 | push: 8 | pull_request: 9 | jobs: 10 | copyrights: 11 | timeout-minutes: 15 12 | runs-on: ubuntu-24.04 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: yegor256/copyrights-action@0.0.8 16 | with: 17 | globs: >- 18 | **/LICENSE.txt 19 | **/Makefile 20 | **/*.sh 21 | **/*.yml 22 | **/*.yaml 23 | **/*.java 24 | **/*.xml 25 | **/*.hs 26 | **/*.hi 27 | **/*.cpp 28 | **/*.hpp 29 | **/*.h 30 | **/*.c 31 | **/*.adb 32 | **/*.e 33 | **/*.go 34 | **/*.lisp 35 | **/*.pp 36 | **/*.rs 37 | **/*.xsl 38 | -------------------------------------------------------------------------------- /.github/workflows/local.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: local 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | local: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - run: sudo make install 20 | - run: make env 21 | - run: make -e FAST=1 INPUT=7 22 | -------------------------------------------------------------------------------- /.github/workflows/make.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: make 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | paths-ignore: [ 'README.md', 'LICENSE.txt' ] 11 | concurrency: 12 | group: ${{ github.ref }} 13 | cancel-in-progress: true 14 | jobs: 15 | start-instance: 16 | runs-on: ubuntu-24.04 17 | outputs: 18 | label: ${{ steps.start.outputs.label }} 19 | ec2-instance-id: ${{ steps.start.outputs.ec2-instance-id }} 20 | steps: 21 | - uses: aws-actions/configure-aws-credentials@v4 22 | with: 23 | aws-access-key-id: ${{ secrets.AWS_KEY }} 24 | aws-secret-access-key: ${{ secrets.AWS_SECRET }} 25 | aws-region: us-east-1 26 | - id: start 27 | uses: machulav/ec2-github-runner@v2 28 | with: 29 | mode: start 30 | github-token: ${{ secrets.GH_PAT }} 31 | ec2-image-id: ${{ secrets.AWS_AMI }} 32 | ec2-instance-type: c5.metal # it must be "metal", otherwise won't work 33 | subnet-id: ${{ secrets.AWS_SUBNET }} 34 | security-group-id: ${{ secrets.AWS_SGROUP }} 35 | make: 36 | needs: start-instance 37 | runs-on: ${{ needs.start-instance.outputs.label }} 38 | timeout-minutes: 120 39 | steps: 40 | - uses: actions/checkout@v4 41 | - run: sudo make install 42 | - run: make env 43 | - run: mkdir www 44 | - run: make -e WANTED=256 INPUT=7 index.html 45 | - run: mv index.html www/seven.html 46 | - run: rm -rf reports 47 | - run: make -e WANTED=256 INPUT=16 index.html 48 | - run: mv index.html www/sixteen.html 49 | - run: rm -rf reports 50 | - run: make -e WANTED=256 index.html summary.tex 51 | - run: cp index.html www 52 | - run: cp summary.tex www 53 | - run: cp index.xml www 54 | - run: cp -r reports www 55 | - run: cp -r asm www 56 | - uses: JamesIves/github-pages-deploy-action@v4.7.3 57 | with: 58 | branch: gh-pages 59 | folder: www 60 | clean: false 61 | terminate-instance: 62 | needs: 63 | - start-instance 64 | - make 65 | runs-on: ubuntu-24.04 66 | if: ${{ always() }} 67 | steps: 68 | - uses: aws-actions/configure-aws-credentials@v4 69 | with: 70 | aws-access-key-id: ${{ secrets.AWS_KEY }} 71 | aws-secret-access-key: ${{ secrets.AWS_SECRET }} 72 | aws-region: us-east-1 73 | - uses: machulav/ec2-github-runner@v2 74 | with: 75 | mode: stop 76 | github-token: ${{ secrets.GH_PAT }} 77 | label: ${{ needs.start-instance.outputs.label }} 78 | ec2-instance-id: ${{ needs.start-instance.outputs.ec2-instance-id }} 79 | -------------------------------------------------------------------------------- /.github/workflows/markdown-lint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: markdown-lint 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | paths-ignore: ['paper/**', 'sandbox/**'] 14 | concurrency: 15 | group: markdown-lint-${{ github.ref }} 16 | cancel-in-progress: true 17 | jobs: 18 | markdown-lint: 19 | timeout-minutes: 15 20 | runs-on: ubuntu-24.04 21 | steps: 22 | - uses: actions/checkout@v4 23 | - uses: DavidAnson/markdownlint-cli2-action@v20.0.0 24 | -------------------------------------------------------------------------------- /.github/workflows/pdd.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: pdd 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | pdd: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: volodya-lombrozo/pdd-action@master 20 | -------------------------------------------------------------------------------- /.github/workflows/quick.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: quick 6 | 'on': 7 | pull_request: 8 | branches: 9 | - master 10 | jobs: 11 | start-instance: 12 | timeout-minutes: 15 13 | runs-on: ubuntu-24.04 14 | outputs: 15 | label: ${{ steps.start.outputs.label }} 16 | ec2-instance-id: ${{ steps.start.outputs.ec2-instance-id }} 17 | steps: 18 | - uses: aws-actions/configure-aws-credentials@v4 19 | with: 20 | aws-access-key-id: ${{ secrets.AWS_KEY }} 21 | aws-secret-access-key: ${{ secrets.AWS_SECRET }} 22 | aws-region: us-east-1 23 | - id: start 24 | uses: machulav/ec2-github-runner@v2 25 | with: 26 | mode: start 27 | github-token: ${{ secrets.GH_PAT }} 28 | ec2-image-id: ${{ secrets.AWS_AMI }} 29 | ec2-instance-type: t2.medium 30 | subnet-id: ${{ secrets.AWS_SUBNET }} 31 | security-group-id: ${{ secrets.AWS_SGROUP }} 32 | make: 33 | needs: start-instance 34 | runs-on: ${{ needs.start-instance.outputs.label }} 35 | steps: 36 | - uses: actions/checkout@v4 37 | - run: sudo make install 38 | - run: make env 39 | - run: make -e FAST=1 INPUT=7 40 | terminate-instance: 41 | needs: 42 | - start-instance 43 | - make 44 | runs-on: ubuntu-24.04 45 | if: ${{ always() }} 46 | steps: 47 | - uses: aws-actions/configure-aws-credentials@v4 48 | with: 49 | aws-access-key-id: ${{ secrets.AWS_KEY }} 50 | aws-secret-access-key: ${{ secrets.AWS_SECRET }} 51 | aws-region: us-east-1 52 | - uses: machulav/ec2-github-runner@v2 53 | with: 54 | mode: stop 55 | github-token: ${{ secrets.GH_PAT }} 56 | label: ${{ needs.start-instance.outputs.label }} 57 | ec2-instance-id: ${{ needs.start-instance.outputs.ec2-instance-id }} 58 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: reuse 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | reuse: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: fsfe/reuse-action@v5 20 | -------------------------------------------------------------------------------- /.github/workflows/sa.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: sa 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | sa: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - run: sudo make install 20 | - run: make sa 21 | -------------------------------------------------------------------------------- /.github/workflows/shellcheck.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: shellcheck 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | shellcheck: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: ludeeus/action-shellcheck@master 20 | -------------------------------------------------------------------------------- /.github/workflows/typos.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: typos 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | typos: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: crate-ci/typos@v1.32.0 20 | -------------------------------------------------------------------------------- /.github/workflows/xcop.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: xcop 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | xcop: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: g4s8/xcop-action@master 20 | -------------------------------------------------------------------------------- /.github/workflows/yamllint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | # yamllint disable rule:line-length 5 | name: yamllint 6 | 'on': 7 | push: 8 | branches: 9 | - master 10 | pull_request: 11 | branches: 12 | - master 13 | jobs: 14 | yamllint: 15 | timeout-minutes: 15 16 | runs-on: ubuntu-24.04 17 | steps: 18 | - uses: actions/checkout@v4 19 | - uses: ibiqlik/action-yamllint@v3 20 | with: 21 | config_file: .yamllint.yml 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | *.class 4 | *.ecf 5 | *.hi 6 | asm/ 7 | bin/ 8 | EIFGENs/ 9 | index.html 10 | index.xml 11 | node_modules/ 12 | reports/ 13 | summary.csv 14 | summary.tex 15 | summary.txt 16 | tmp/ 17 | -------------------------------------------------------------------------------- /.yamllint.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | --- 4 | rules: 5 | line-length: 6 | max: 999 7 | allow-non-breakable-words: true 8 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022-2025 Yegor Bugayenko 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022-2025 Yegor Bugayenko 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | 4 | .PHONY: clean sa env lint all test install 5 | .ONESHELL: 6 | .SHELLFLAGS := -ex -o pipefail -c 7 | SHELL := bash 8 | 9 | # The input to the Fibonacci function: 10 | INPUT = 32 11 | 12 | # How many cycles are needed: 13 | WANTED = 8 14 | 15 | CC = clang++ 16 | CCFLAGS = -mllvm --x86-asm-syntax=intel -O3 17 | 18 | GNAT = gnat 19 | GNATFLAGS = -O3 20 | 21 | GO = go 22 | GO_FLAGS = -gcflags '-N -l' 23 | 24 | RUSTC = rustc 25 | RUSTFLAGS = -C opt-level=3 26 | 27 | FPC = fpc 28 | FPCFLAGS = -O3 29 | 30 | SBCL = sbcl 31 | EC = ec 32 | JAVAC = javac 33 | DOTNET = dotnet 34 | 35 | GHC = ghc 36 | GHCFLAGS = -dynamic -Wall -Werror -O3 37 | GHCLIBDIR = haskell/Mainlib 38 | GHCLIBS = $(wildcard $(GHCLIBDIR)/*.hs) 39 | 40 | NIFLAGS = -H:Optimize=3 41 | NI = native-image 42 | 43 | SAXON = "/usr/local/opt/Saxon.jar" 44 | 45 | DIRS = asm bin reports tmp 46 | CPPS = $(wildcard cpp/*.cpp) 47 | RUSTS = $(wildcard rust/*.rs) 48 | PASCALS = $(wildcard pascal/*.pp) 49 | # LISPS = $(wildcard lisp/*.lisp) 50 | HASKELLS = $(wildcard haskell/*.hs) 51 | JAVAS = $(wildcard java/*.java) 52 | CSHARPS = $(subst /Program.cs,.cs,$(wildcard csharp/*/Program.cs)) 53 | # Eiffel doesn't work, this may help: https://github.com/eiffel-docker/eiffel/issues/3 54 | # EIFFELS = eiffel/application.e 55 | GOS = $(wildcard go/cmd/*/main.go) 56 | # I can't figure out how to install Ada on macOS with Homebrew :( 57 | # ADAS = $(wildcard ada/*.adb) 58 | ASMS = $(subst csharp/,asm/csharp-,$(subst ada/,asm/ada-,$(subst pascal/,asm/pascal-,$(subst eiffel/,asm/eiffel-,$(subst go/cmd/,asm/go-,$(subst haskell/,asm/haskell-,$(subst java/,asm/java-,$(subst lisp/,asm/lisp-,$(subst rust/,asm/rust-,$(subst cpp/,asm/cpp-,${CPPS:.cpp=.asm} ${RUSTS:.rs=.asm} ${LISPS:.lisp=.asm} ${HASKELLS:.hs=.asm} ${GOS:/main.go=.asm} ${JAVAS:.java=.asm} ${EIFFELS:.e=.asm} ${PASCALS:.pp=.asm} ${ADAS:.adb=.asm} ${CSHARPS:.cs=.asm})))))))))) 59 | BINS = $(subst asm/,bin/,${ASMS:.asm=.bin}) 60 | REPORTS = $(subst bin/,reports/,${BINS:.bin=.txt}) 61 | GOCACHE = /tmp/gocache 62 | 63 | export 64 | 65 | all: summary.txt summary.tex 66 | 67 | summary.tex: index.xml latex.xsl 68 | java -jar $(SAXON) '-s:index.xml' -xsl:latex.xsl '-o:summary.tex' 69 | cat summary.tex 70 | 71 | summary.txt: $(DIRS) $(ASMS) $(BINS) $(REPORTS) Makefile 72 | if [ ! $$( { for r in $(REPORTS:.txt=.stdout); do cat "$${r}"; done ; } | uniq | wc -l) == 1 ]; then 73 | set +x 74 | echo "Not all reports are the same" 75 | for r in $(REPORTS:.txt=.stdout); do echo "$${r}"; cat "$${r}"; done 76 | exit 1 77 | fi 78 | { 79 | date 80 | $(CC) --version | head -1 81 | echo "INPUT=$(INPUT)" 82 | echo 83 | for r in $(REPORTS); do cat $${r}; done 84 | } > summary.txt 85 | cat "$@" 86 | 87 | summary.csv: $(DIRS) $(REPORTS) 88 | { for r in $(REPORTS:.txt=.csv); do cat $${r}; done } > summary.csv 89 | cat summary.csv | sort -k5 -g -t, 90 | 91 | index.xml: $(DIRS) $(REPORTS) Makefile 92 | { 93 | printf "" 94 | printf '' 95 | printf "File name as it's seen in the source code repository" 96 | printf "Total number of Assembly instructions seen in the compiled .asm file; not every compiler provides this information though" 97 | printf "How many times the Fibonacci number has been calculated" 98 | printf "How many seconds it took to execute all calculations" 99 | printf "How many seconds per each calculation" 100 | printf "How many total CPU ticks it took to execute all calculations, according to perf" 101 | printf "How many ticks per a single calculation" 102 | printf "TPC divided by SPC and divided by one billion; this is approximately how fast is the CPU; this metric for all programs is expected to have almost the same values, otherwise something is wrong with the method" 103 | printf '' 104 | printf '' 105 | for r in $(REPORTS:.txt=.xml); do cat $${r}; done 106 | printf "" 107 | } > index.xml 108 | 109 | index.html: index.xml main.xsl Makefile 110 | java -jar $(SAXON) '-s:index.xml' -xsl:main.xsl '-o:index.html' 111 | 112 | install: Makefile 113 | if [[ "$${OSTYPE}" == "darwin"* ]]; then 114 | echo "This is macOS, installing necessary components (not all of them):" 115 | brew install fpc sbcl go 116 | brew install --cask graalvm/tap/graalvm-ce-lts-java11 117 | brew install --cask dotnet-sdk 118 | elif [[ "$${OSTYPE}" == "linux-gnu"* ]]; then 119 | echo "This is Linux, installing all necessary components:" 120 | systemctl stop unattended-upgrades || echo 'it is OK' 121 | apt-get -y update --fix-missing 122 | apt-get -y install --no-install-recommends \ 123 | clang clang-tidy \ 124 | openjdk-21-jdk-headless \ 125 | rustc ghc sbcl golang build-essential \ 126 | curl wget git-core zlib1g zlib1g-dev libssl-dev \ 127 | snapd python3 python3-pip \ 128 | libyaml-dev libxml2-dev autoconf libc6-dev ncurses-dev \ 129 | automake libtool lsb-release \ 130 | gnat jq bc fpc linux-tools-generic \ 131 | ruby-full \ 132 | dotnet-sdk-8.0 133 | apt-get clean 134 | if ! native-image --version; then 135 | tgz=graalvm-community-jdk-23.0.0_linux-x64_bin.tar.gz 136 | wget "https://github.com/graalvm/graalvm-ce-builds/releases/download/jdk-23.0.0/$${tgz}" 137 | tar xzf "$${tgz}" 138 | dir=graalvm-community-openjdk-23+37.1 139 | cp -R "$${dir}" /usr/local/graalvm 140 | rm "$${tgz}" 141 | fi 142 | # see https://stackoverflow.com/a/76641565/187141 143 | rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED 144 | if ! cpplint --version; then pip install cpplint; fi 145 | snap install powershell --classic 146 | if ! xcop --version; then gem install xcop; fi 147 | if [ ! -e /usr/bin/perf ]; then 148 | ln -s "$(ls /usr/lib/linux-tools/*/perf | head -1)" /usr/bin/perf 149 | fi 150 | else 151 | echo "This is neither macOS nor Liux, can't install :(" 152 | exit 1 153 | fi 154 | if [ ! -e /usr/local/opt/Saxon.jar ]; then 155 | sudo mkdir -p /usr/local/opt 156 | sudo wget --no-verbose https://repo.maven.apache.org/maven2/net/sf/saxon/Saxon-HE/9.8.0-5/Saxon-HE-9.8.0-5.jar -O /usr/local/opt/Saxon.jar 157 | fi 158 | 159 | env: Makefile 160 | $(CC) --version 161 | clang-tidy --version 162 | cpplint --version 163 | $(RUSTC) --version 164 | $(MAKE) -version 165 | $(GHC) --version 166 | $(FPC) -h >/dev/null 167 | $(JAVAC) --version 168 | $(DOTNET) --version 169 | if [ -n "$(LISPS)" ]; then $(SBCL) --version; fi 170 | if [ -n "$(EIFFELS)" ]; then $(EC) --version; fi 171 | if [ -n "$(ADAS)" ]; then $(GNAT) --version; fi 172 | $(GO) version 173 | 174 | sa: Makefile 175 | cpplint --extensions=cpp --filter=-whitespace/indent,-runtime/explicit $(CPPS) 176 | clang-tidy -header-filter=none \ 177 | '-warnings-as-errors=*' \ 178 | '-checks=*,-modernize-use-nodiscard,-readability-identifier-length,-readability-magic-numbers,-altera-id-dependent-backward-branch,-cert-err34-c,-cppcoreguidelines-avoid-non-const-global-variables,-readability-function-cognitive-complexity,-misc-no-recursion,-llvm-header-guard,-cppcoreguidelines-init-variables,-altera-unroll-loops,-clang-analyzer-valist.Uninitialized,-llvmlibc-callee-namespace,-cppcoreguidelines-no-malloc,-hicpp-no-malloc,-llvmlibc-implementation-in-namespace,-bugprone-easily-swappable-parameters,-llvmlibc-restrict-system-libc-headers,-llvm-include-order,-modernize-use-trailing-return-type,-cppcoreguidelines-special-member-functions,-hicpp-special-member-functions,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg' \ 179 | $(CPPS) 180 | xcop $$(find . -name *.xsl) 181 | echo "All clean, thanks!" 182 | 183 | asm/cpp-%.asm: cpp/%.cpp | asm 184 | $(CC) $(CCFLAGS) -S -o "$@" "$<" 185 | 186 | asm/rust-%.asm: rust/%.rs | asm 187 | $(RUSTC) $(RUSTFLAGS) --emit=asm -o "$@" "$<" 188 | 189 | asm/lisp-%.asm: lisp/%.lisp | asm 190 | echo " no asm here" > "$@" 191 | 192 | asm/ada-%.asm: ada/%.adb | asm 193 | echo " no asm here" > "$@" 194 | 195 | asm/pascal-%.asm: pascal/%.pp | asm 196 | echo " no asm here" > "$@" 197 | 198 | asm/eiffel-%.asm: eiffel/%.e | asm 199 | echo " no asm here" > "$@" 200 | 201 | asm/go-%.asm: go/cmd/%/main.go | asm 202 | echo " no asm here" > "$@" 203 | 204 | asm/csharp-%.asm: csharp/%/Program.cs | asm 205 | echo " no asm here" > "$@" 206 | 207 | asm/haskell-%.asm: haskell/%.hs $(GHCLIBS) | asm 208 | source=$$( echo "$<" | sed 's/\.hs$$//' ) 209 | $(GHC) $(GHCFLAGS) -S $(GHCLIBS) "$<" 210 | mv $${source}.s "$@" 211 | cat $(GHCLIBDIR)/*.s >> "$@" 212 | rm $(GHCLIBDIR)/*.s 213 | 214 | asm/java-%.asm: java/%.java | asm 215 | echo " no asm here" > "$@" 216 | 217 | bin/cpp-%.bin: cpp/%.cpp | bin 218 | $(CC) $(CCFLAGS) -o "$@" "$<" 219 | 220 | bin/ada-%.bin: ada/%.adb | bin tmp 221 | $(GNAT) make $(GNATFLAGS) -o "$@" "$<" 222 | rm *.o 223 | rm *.ali 224 | 225 | bin/rust-%.bin: rust/%.rs | bin 226 | $(RUSTC) $(RUSTFLAGS) -o "$@" "$<" 227 | 228 | bin/lisp-%.bin: lisp/%.lisp | bin 229 | $(SBCL) --load "$<" --dynamic-space-start=0x800000000 230 | 231 | bin/eiffel-%.bin: eiffel/%.e | bin 232 | $(EC) "$<" -batch 233 | mv application "$@" 234 | chmod a+x "$@" 235 | 236 | bin/csharp-%.bin: csharp/%/Program.cs | bin 237 | if [ -z "${HOME}" ]; then 238 | HOME=$$(pwd) 239 | export HOME 240 | fi 241 | if [[ "$${OSTYPE}" == "darwin"* ]]; then 242 | arch=osx-x64 243 | elif [[ "$${OSTYPE}" == "linux-gnu"* ]]; then 244 | arch=linux-x64 245 | else 246 | echo "This is neither macOS nor Liux, can't build .Net binary :(" 247 | exit 1 248 | fi 249 | d=$$(dirname "$<") 250 | ( cd "$${d}" && $(DOTNET) publish -c Release -r "$${arch}" --self-contained --output bins --nologo ) 251 | bin=$$(basename "$$(dirname "$<")") 252 | rm -f "$@" 253 | ln -s "$$(realpath "$${d}/bins/$${bin}")" "$@" 254 | 255 | bin/pascal-%.bin: pascal/%.pp | bin 256 | fpc "$<" "-FEbin" "-o$@" 257 | 258 | bin/go-%.bin: go/cmd/%/main.go | bin 259 | cd go 260 | $(GO) build $(GO_FLAGS) -o "../$@" "$(subst go/,./,${<:/main.go=})" 261 | 262 | bin/haskell-%.bin: haskell/%.hs $(GHCLIBS) | bin 263 | source=$$( echo "$<" | sed 's/\.hs$$//' ) 264 | $(GHC) $(GHCFLAGS) $(GHCLIBS) "$<" 265 | mv $${source} "$@" 266 | rm $${source}.o 267 | rm $${source}.hi 268 | rm $(GHCLIBDIR)/*.o 269 | rm $(GHCLIBDIR)/*.hi 270 | 271 | bin/java-%.bin: java/%.java | bin 272 | if [ -z "$${JAVA_HOME}" ]; then 273 | JAVA_HOME=$$(find /usr/lib/jvm -name 'java-*' | head -1) 274 | export JAVA_HOME 275 | fi 276 | nimage=$(NI) 277 | if ! "$${nimage}" --version; then 278 | nimage=/usr/local/graalvm/bin/native-image 279 | fi 280 | if ! "$${nimage}" --version; then 281 | nimage=$$(realpath /Library/Java/JavaVirtualMachines/*/Contents/Home/bin/native-image) 282 | fi 283 | if ! "$${nimage}" --version; then 284 | echo "Most probably you don't have GraalVM installed" 285 | exit 1 286 | fi 287 | name=$(subst java/,,$(<:.java=)) 288 | mkdir -p "tmp/$${name}" 289 | "$(JAVAC)" -d "tmp/$${name}" "$<" 290 | if [ "$$(uname)" == "Darwin" ]; then 291 | jar -c -e "$${name}" -f "tmp/$${name}.jar" -C "tmp/$${name}" . 292 | else 293 | jar cfe "tmp/$${name}.jar" "$${name}" -C "tmp/$${name}" . 294 | fi 295 | "$${nimage}" $(NIFLAGS) -jar "tmp/$${name}.jar" "$@" 296 | 297 | reports/%.txt: bin/%.bin asm/%.asm | reports 298 | "$<" 7 1 299 | cycles=1 300 | attempt=1 301 | while true; do 302 | time=$$(set +x; { time -p "$<" $(INPUT) $${cycles} | tail -n +1 | head -1 > "${@:.txt=.stdout}" ; } 2>&1 | head -1 | cut -f2 -d' ') 303 | if [[ ! "$${time}" =~ ^[0-9.]+$$ ]]; then 304 | time -p "$<" $(INPUT) $${cycles} 2>&1 305 | echo "For some reason, \$$time is not an integer: $${time}" 306 | exit 1 307 | fi 308 | echo $${time} > "${@:.txt=.time}" 309 | if [ "$(FAST)" != "" ]; then break; fi 310 | seconds=$$(echo $${time} | cut -f1 -d.) 311 | if [ "$${seconds}" -gt "10" ]; then break; fi 312 | if [ "$${seconds}" -gt "0" ] && [ "$${cycles}" -ge "$(WANTED)" ]; then break; fi 313 | echo "cycles=$${cycles}; time=$${time} -> too fast, need more cycles (attempt #$${attempt})..." 314 | cycles=$$(expr $${cycles} \* 2) 315 | if [ "$${cycles}" -gt "2147483647" ]; then break; fi 316 | if [ "$${cycles}" -lt "$(WANTED)" ] && [ "$${seconds}" -lt "1" ]; then cycles=$(WANTED); fi 317 | attempt=$$(expr $${attempt} + 1) 318 | done 319 | if [ "$$(uname)" == "Darwin" ]; then 320 | echo "No perf on MacOS" > "${@:.txt=.perf}" 321 | else 322 | sudo perf stat "$<" $(INPUT) $${cycles} > "${@:.txt=.perf}" 2>&1 323 | fi 324 | ticks=$$(cat "${@:.txt=.perf}" | sed 's/ \+/ /g' | (grep ' cycles #' || echo 0) | cut -f 2 -d ' ' | tr -d ,) 325 | if [[ ! "$${ticks}" =~ ^[0-9.]+$$ ]]; then 326 | ticks=1 327 | fi 328 | ticks_per_cycle=$$(echo "scale = 0 ; $${ticks} / $${cycles}" | bc) 329 | instructions=$$(grep -e $$'^\(\t\| \)\+[a-z]\+' "$(subst bin/,asm/,${<:.bin=.asm})" | wc -l | xargs) 330 | time_per_cycle=$$(echo "scale = 16 ; $${time} / $${cycles}" | bc) 331 | { 332 | echo "$<:" 333 | echo "CPU ticks: $${ticks}" 334 | echo "CPU ticks per cycle: $${ticks_per_cycle}" 335 | echo "Instructions: $${instructions}" 336 | echo "Cycles: $${cycles}" 337 | echo "Total Time: $${time}" 338 | echo "Time per cycle: $${time_per_cycle}" 339 | echo "Ticks: $${ticks}" 340 | echo "Ticks per cycle: $${ticks_per_cycle}" 341 | } > "$@" 342 | echo "${subst bin/,,$<},$${instructions},$${ticks_per_cycle},$${cycles},$${time},$${time_per_cycle}" > "${@:.txt=.csv}" 343 | name=$(subst bin/,,${<:.bin=}) 344 | file=$$(ls $$(echo $${name} | cut -f1 -d-)/$$(echo $${name} | cut -f2- -d-).* || echo $${name}) 345 | if [[ "$${name}" =~ ^cpp- ]]; then 346 | compiler=$$($(CC) --version | head -1) 347 | elif [[ "$${name}" =~ ^java- ]]; then 348 | compiler=$$($(JAVAC) -version | head -1) 349 | elif [[ "$${name}" =~ ^csharp- ]]; then 350 | compiler=$$($(DOTNET) --version | head -1) 351 | file=$$(echo $${name} | cut -f1 -d-)/$$(echo $${name} | cut -f2- -d-)/Program.cs 352 | elif [[ "$${name}" =~ ^pascal- ]]; then 353 | compiler=$$($(FPC) -iV | head -1) 354 | elif [[ "$${name}" =~ ^haskell- ]]; then 355 | compiler=$$($(GHC) --version | head -1) 356 | file=$$(echo $${name} | cut -f1 -d-)/$$(echo $${name} | cut -f2- -d-).hs 357 | elif [[ "$${name}" =~ ^rust- ]]; then 358 | compiler=$$($(RUSTC) --version | head -1) 359 | elif [[ "$${name}" =~ ^go- ]]; then 360 | compiler=$$($(GO) version | head -1) 361 | file=$$(echo $${name} | cut -f1 -d-)/cmd/$$(echo $${name} | cut -f2- -d-)/main.go 362 | else 363 | compiler='unknown' 364 | fi 365 | echo " \ 366 | $$(echo "$${file}" | jq -Rr @html) \ 367 | $$(echo "$${name}" | jq -Rr @html) \ 368 | $$(echo "$${compiler}" | jq -Rr @html) \ 369 | $$(echo "$${instructions}" | jq -Rr @html) \ 370 | $$(echo "$${cycles}" | jq -Rr @html) \ 371 | \ 372 | $$(echo "$${time_per_cycle}" | jq -Rr @html) \ 373 | $$(echo "$${ticks}" | jq -Rr @html) \ 374 | $$(echo "$${ticks_per_cycle}" | jq -Rr @html) \ 375 | " > "${@:.txt=.xml}" 376 | 377 | clean: 378 | rm -rf $(DIRS) 379 | rm -f summary.txt summary.csv 380 | rm -rf EIFGENs 381 | 382 | $(DIRS): 383 | mkdir "$@" 384 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fibonacci Algorithm in a Few Languages 2 | 3 | ![mr. Fibonacci](https://raw.githubusercontent.com/yegor256/fibonacci/master/logo.svg) 4 | 5 | [![new](https://github.com/yegor256/fibonacci/actions/workflows/make.yml/badge.svg)](https://github.com/yegor256/fibonacci/actions/workflows/make.yml) 6 | 7 | Here we compare [Fibonacci](https://en.wikipedia.org/wiki/Fibonacci_number) 8 | algorithm implemented in C++, Java, Rust, Lisp, Haskell, Eiffel, and some other 9 | [compiled](https://en.wikipedia.org/wiki/Compiled_language) programing languages 10 | in different programming styles, like object-oriented, procedural, functional, 11 | etc. We are trying to understand which style compiles to shorter binary code and 12 | works faster. If you can imagine some other way how this algorithm 13 | could be implemented in C++ or other languages, 14 | don't hesitate to submit a pull request. 15 | 16 | Recent results are published here: 17 | 18 | * [32nd Fibonacci number](https://yegor256.github.io/fibonacci/index.html) 19 | * [16th](https://yegor256.github.io/fibonacci/sixteen.html) 20 | * [7th](https://yegor256.github.io/fibonacci/seven.html) 21 | 22 | To build it locally, just run: 23 | 24 | ```bash 25 | make 26 | ``` 27 | 28 | The result will be in `summary.txt` file. 29 | 30 | To analyze the quality of the code in this repo and make sure 31 | there are no hidden defects, run all static analyzers and style checkers: 32 | 33 | ```bash 34 | make sa 35 | ``` 36 | 37 | You need to have [Clang](https://clang.llvm.org), 38 | [Make](https://www.gnu.org/software/make/), 39 | [Rust](https://www.rust-lang.org/tools/install), 40 | [Common Lisp](https://lisp-lang.org/learn/getting-started/), 41 | [Haskell](https://www.haskell.org/), 42 | [GraalVM](https://www.graalvm.org/java/quickstart/), 43 | [Ruby](https://www.ruby-lang.org/en/documentation/installation/), 44 | [Go](https://go.dev/doc/install), 45 | [Clang-Tidy](https://clang.llvm.org/extra/clang-tidy/), 46 | [Clang-Format](https://clang.llvm.org/docs/ClangFormat.html), 47 | [cppcheck](https://github.com/danmar/cppcheck), 48 | and [cpplint](https://github.com/cpplint/cpplint) installed. 49 | It's better to check [this file][pr] for the full list of 50 | dependencies. 51 | 52 | [pr]: https://github.com/yegor256/fibonacci/blob/master/.github/workflows/pr.yml 53 | -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: Copyright (c) 2025 Yegor Bugayenko 2 | # SPDX-License-Identifier: MIT 3 | 4 | version = 1 5 | [[annotations]] 6 | path = [ 7 | ".checkmakerc", 8 | ".clang-format", 9 | ".DS_Store", 10 | ".gitattributes", 11 | ".gitignore", 12 | "**.csv", 13 | "**.json", 14 | "**.md", 15 | "**.svg", 16 | "**.txt", 17 | "**/.DS_Store", 18 | "**/.gitignore", 19 | "**/*.csv", 20 | "**/*.jpg", 21 | "**/*.json", 22 | "**/*.md", 23 | "**/*.pdf", 24 | "**/*.png", 25 | "**/*.svg", 26 | "**/*.txt", 27 | "**/*.vm", 28 | "**/CNAME", 29 | "README.md", 30 | "renovate.json", 31 | ] 32 | precedence = "override" 33 | SPDX-FileCopyrightText = "Copyright (c) 2025 Yegor Bugayenko" 34 | SPDX-License-Identifier = "MIT" 35 | -------------------------------------------------------------------------------- /ada/recursion.adb: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | with Ada.Text_IO; 5 | with Ada.Integer_Text_IO; 6 | with Ada.Command_Line; 7 | with Ada.Strings.Fixed; 8 | 9 | procedure Recursion is 10 | 11 | use Ada.Strings.Fixed; 12 | 13 | Input, Cycles, Total, F: Integer; 14 | 15 | function Fib(P: Integer) return Integer is 16 | begin 17 | if P < 2 then 18 | return 1; 19 | else 20 | return Fib(P-1) + Fib(P-2); 21 | end if; 22 | end Fib; 23 | 24 | begin 25 | Input := Integer'Value(Ada.Command_Line.Argument(1)); 26 | Cycles := Integer'Value(Ada.Command_Line.Argument(2)); 27 | F := 0; 28 | Total := 0; 29 | for I in 0 .. Cycles loop 30 | F := Fib(Input); 31 | Total := Total + F; 32 | end loop; 33 | Ada.Text_IO.Put(Trim(Integer'Image(Input), Ada.Strings.Left)); 34 | Ada.Text_IO.Put("-th Fibonacci number is "); 35 | Ada.Text_IO.Put_Line(Trim(Integer'Image(F), Ada.Strings.Left)); 36 | Ada.Text_IO.Put("Total is "); 37 | Ada.Text_IO.Put_Line(Trim(Integer'Image(Total), Ada.Strings.Left)); 38 | end Recursion; 39 | -------------------------------------------------------------------------------- /cpp/binpow-matrix.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include 5 | 6 | #include "./main.h" 7 | using matrix2on2 = std::array; 8 | matrix2on2 mul(const matrix2on2 &first, const matrix2on2 &second) { 9 | matrix2on2 res; 10 | res[0] = first[0] * second[0] + first[1] * second[2]; 11 | res[1] = first[0] * second[1] + first[1] * second[3]; 12 | res[2] = first[2] * second[0] + first[3] * second[2]; 13 | res[3] = first[2] * second[1] + first[3] * second[3]; 14 | return res; 15 | } 16 | const matrix2on2 IDENTITY_MATRIX = {1, 0, 0, 1}; 17 | // See https://e-maxx.ru/algo/binary_pow 18 | matrix2on2 binpow(const matrix2on2 &a, int n) { 19 | matrix2on2 result{}; 20 | if (n == 0) { 21 | result = IDENTITY_MATRIX; 22 | } else if (n % 2 == 1) { 23 | result = mul(binpow(a, n - 1), a); 24 | } else { 25 | const matrix2on2 b = binpow(a, n / 2); 26 | result = mul(b, b); 27 | } 28 | return result; 29 | } 30 | // See https://e-maxx.ru/algo/fibonacci_numbers#8 31 | int calc(int n) { 32 | n += 1; 33 | const matrix2on2 factor = {0, 1, 1, 1}; 34 | const matrix2on2 multiplier = binpow(factor, n); 35 | const matrix2on2 base = {0, 1, 0, 0}; 36 | const int result = mul(base, multiplier)[0]; 37 | return result; 38 | } 39 | -------------------------------------------------------------------------------- /cpp/classes.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Add { 7 | int left; 8 | int right; 9 | 10 | public: 11 | explicit Add(int x, int y) : left(x), right(y) {} 12 | int get() const { return left + right; } 13 | }; 14 | 15 | class Sub { 16 | int left; 17 | int right; 18 | 19 | public: 20 | explicit Sub(int x, int y) : left(x), right(y) {} 21 | int get() const { return left - right; } 22 | }; 23 | 24 | class Less { 25 | int left; 26 | int right; 27 | 28 | public: 29 | explicit Less(int x, int y) : left(x), right(y) {} 30 | bool get() const { return left < right; } 31 | }; 32 | 33 | class Fibo { 34 | int res; 35 | 36 | public: 37 | explicit Fibo(int num) 38 | : res(Less(num, 2).get() 39 | ? 1 40 | : Add(Fibo(Sub(num, 1).get()).get(), Fibo(Sub(num, 2).get()).get()) 41 | .get()) {} 42 | int get() const { return res; } 43 | }; 44 | 45 | int calc(int x) { return Fibo(x).get(); } 46 | -------------------------------------------------------------------------------- /cpp/decorators.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Fibo { 7 | public: 8 | virtual ~Fibo() = default; 9 | virtual int get() = 0; 10 | virtual Fibo* next() = 0; 11 | }; 12 | 13 | class Other : public Fibo { 14 | public: 15 | explicit Other(Fibo* a, Fibo* b) : first(a), second(b) {} 16 | ~Other() override { delete second; } 17 | int get() override { return first->get() + second->get(); } 18 | Fibo* next() override { return new Other(second, this); } 19 | 20 | private: 21 | Fibo* first; 22 | Fibo* second; 23 | }; 24 | 25 | class Second : public Fibo { 26 | public: 27 | explicit Second(Fibo* f) : first(f) {} 28 | ~Second() override { delete first; } 29 | int get() override { return 1; } 30 | Fibo* next() override { return new Other(first, this); } 31 | 32 | private: 33 | Fibo* first; 34 | }; 35 | 36 | class First : public Fibo { 37 | public: 38 | int get() override { return 1; } 39 | Fibo* next() override { return new Second(this); } 40 | }; 41 | 42 | int calc(int x) { 43 | Fibo* f = new First(); 44 | for (int i = 0; i < x; ++i) { 45 | f = f->next(); 46 | } 47 | const int r = f->get(); 48 | delete f; 49 | return r; 50 | } 51 | -------------------------------------------------------------------------------- /cpp/functions.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | bool __attribute__((noinline)) less(int a, int b) { return a < b; } 7 | 8 | int __attribute__((noinline)) sub(int a, int b) { return a - b; } 9 | 10 | int __attribute__((noinline)) add(int a, int b) { return a + b; } 11 | 12 | int __attribute__((noinline)) fibo(int x) { 13 | if (less(x, 2)) { 14 | return 1; 15 | } 16 | return add(fibo(sub(x, 1)), fibo(sub(x, 2))); 17 | } 18 | 19 | int __attribute__((noinline)) calc(int x) { return fibo(x); } 20 | -------------------------------------------------------------------------------- /cpp/functions_with_new.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | template 7 | int __attribute__((noinline)) op(Foo impl, int left_arg, int right_arg) { 8 | int *pl = new int(left_arg); 9 | int *pr = new int(right_arg); 10 | const int result = impl(pl, pr); 11 | delete pl; 12 | delete pr; 13 | return result; 14 | } 15 | 16 | bool __attribute__((noinline)) 17 | less_impl(int const *const a, int const *const b) { 18 | return *a < *b; 19 | } 20 | 21 | int __attribute__((noinline)) sub_impl(int const *const a, int const *const b) { 22 | return *a - *b; 23 | } 24 | 25 | int __attribute__((noinline)) add_impl(int const *const a, int const *const b) { 26 | return *a + *b; 27 | } 28 | 29 | int __attribute__((noinline)) fibo(int x); 30 | 31 | int __attribute__((noinline)) 32 | fibo_impl(int const *const px, int const *const p1, int const *const p2) { 33 | if (op(less_impl, *px, *p2) != 0) { 34 | return *p1; 35 | } 36 | return op( 37 | add_impl, fibo(op(sub_impl, *px, *p1)), fibo(op(sub_impl, *px, *p2))); 38 | } 39 | 40 | int __attribute__((noinline)) fibo(int x) { 41 | int *px = new int(x); 42 | int *p1 = new int(1); 43 | const int *p2 = new int(2); 44 | const int result = fibo_impl(px, p1, p2); 45 | delete px; 46 | delete p1; 47 | delete p2; 48 | return result; 49 | } 50 | 51 | int __attribute__((noinline)) calc(int x) { return fibo(x); } 52 | -------------------------------------------------------------------------------- /cpp/inlines.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | inline bool less(int a, int b) { return a < b; } 7 | 8 | inline int sub(int a, int b) { return a - b; } 9 | 10 | inline int add(int a, int b) { return a + b; } 11 | 12 | int calc(int x) { 13 | if (less(x, 2)) { 14 | return 1; 15 | } 16 | return add(calc(sub(x, 1)), calc(sub(x, 2))); 17 | } 18 | -------------------------------------------------------------------------------- /cpp/interpreter.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include 5 | #include 6 | 7 | #include "./main.h" 8 | 9 | template 10 | class Computation { 11 | public: 12 | using ptr = std::shared_ptr>; 13 | bool finished() { return m_finished; } 14 | virtual ~Computation() = default; 15 | virtual Computation::ptr eval() { 16 | return std::shared_ptr>(this); 17 | } 18 | T result() { return m_result; } 19 | 20 | protected: 21 | Computation() = default; 22 | explicit Computation(T res) : m_result(res), m_finished(true) {} 23 | 24 | private: 25 | T m_result = T(); 26 | bool m_finished = false; 27 | }; 28 | 29 | template 30 | inline typename Computation::ptr cptr(Computation *c) { 31 | return typename Computation::ptr(c); 32 | } 33 | 34 | template 35 | class Interpret { 36 | public: 37 | explicit Interpret(typename Computation::ptr c) 38 | : entrypoint(std::move(c)) {} 39 | ~Interpret() = default; 40 | T get() { 41 | typename Computation::ptr cur = entrypoint; 42 | while (true) { 43 | if ((*cur).finished()) { 44 | break; 45 | } 46 | cur = (*cur).eval(); 47 | } 48 | return (*cur).result(); 49 | } 50 | 51 | private: 52 | typename Computation::ptr entrypoint; 53 | }; 54 | 55 | template 56 | class Value : public Computation { 57 | public: 58 | explicit Value(T val) : m_val(val), Computation(val) {} 59 | ~Value() override = default; 60 | typename Computation::ptr eval() override { 61 | return cptr(new Value(m_val)); 62 | }; 63 | 64 | private: 65 | T m_val; 66 | }; 67 | 68 | template 69 | class Force : public Interpret { 70 | public: 71 | explicit Force(typename Computation::ptr c) : Interpret(c) {} 72 | explicit Force(Computation *c) : Interpret(cptr(c)) {} 73 | 74 | typename Computation::ptr ptr() { return cptr(new Value(this->get())); } 75 | }; 76 | 77 | class Bool : public Value { 78 | public: 79 | explicit Bool(bool b) : Value(b) {} 80 | }; 81 | 82 | class Int : public Value { 83 | public: 84 | explicit Int(int i) : Value(i) {} 85 | }; 86 | 87 | template 88 | class If : public Computation { 89 | public: 90 | If(Computation::ptr pred, typename Computation::ptr thn, 91 | typename Computation::ptr els) 92 | : m_pred(std::move(pred)), 93 | m_thn(std::move(thn)), 94 | m_els(std::move(els)), 95 | Computation() {} 96 | typename Computation::ptr eval() override { 97 | typename Computation::ptr res; 98 | if (Force(m_pred).get()) { 99 | res = m_thn; 100 | } else { 101 | res = m_els; 102 | } 103 | return res; 104 | }; 105 | ~If() override = default; 106 | 107 | private: 108 | Computation::ptr m_pred; 109 | typename Computation::ptr m_thn; 110 | typename Computation::ptr m_els; 111 | }; 112 | 113 | template 114 | class BinaryOp : public Computation { 115 | public: 116 | ~BinaryOp() override = default; 117 | typename Computation::ptr eval() override { 118 | return cptr(op(Force(m_left).get(), Force(m_right).get())); 119 | } 120 | 121 | protected: 122 | BinaryOp( 123 | typename Computation::ptr left, typename Computation::ptr right) 124 | : m_left(std::move(left)), m_right(std::move(right)), Computation() {} 125 | virtual Computation *op(A /* l */, A /* r */) { return nullptr; } 126 | 127 | private: 128 | typename Computation::ptr m_left; 129 | typename Computation::ptr m_right; 130 | }; 131 | 132 | template 133 | class LT : public BinaryOp { 134 | public: 135 | LT(typename Computation::ptr left, typename Computation::ptr right) 136 | : BinaryOp(left, right) {} 137 | 138 | protected: 139 | Bool *op(T l, T r) override { return new Bool(l < r); } 140 | }; 141 | 142 | template 143 | class Sum : public BinaryOp { 144 | public: 145 | Sum(typename Computation::ptr left, typename Computation::ptr right) 146 | : BinaryOp(left, right) {} 147 | 148 | protected: 149 | Value *op(T l, T r) override { return new Value(l + r); }; 150 | }; 151 | 152 | class FiboDyn : public Computation { 153 | public: 154 | FiboDyn( 155 | Computation::ptr n, Computation::ptr a, Computation::ptr b) 156 | : m_n(std::move(n)), m_a(std::move(a)), m_b(std::move(b)) {} 157 | Computation::ptr eval() override { 158 | return cptr(new If(cptr(new LT(m_n, cptr(new Int(1)))), m_a, 159 | cptr(new FiboDyn(Force(new Sum(m_n, cptr(new Int(-1)))).ptr(), 160 | m_b, Force(new Sum(m_a, m_b)).ptr())))); 161 | } 162 | ~FiboDyn() override = default; 163 | 164 | private: 165 | Computation::ptr m_n; 166 | Computation::ptr m_a; 167 | Computation::ptr m_b; 168 | }; 169 | 170 | class Fibo : public Computation { 171 | public: 172 | explicit Fibo(Computation::ptr n) : m_n(std::move(n)) {} 173 | Computation::ptr eval() override { 174 | return cptr(new FiboDyn(m_n, cptr(new Int(0)), cptr(new Int(1)))); 175 | }; 176 | ~Fibo() override = default; 177 | 178 | private: 179 | Computation::ptr m_n; 180 | }; 181 | 182 | int calc(int x) { 183 | Interpret result = 184 | Interpret(cptr(new Fibo(cptr(new Value(x + 1))))); 185 | return result.get(); 186 | } 187 | -------------------------------------------------------------------------------- /cpp/lambdas.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include 5 | 6 | #include "./main.h" 7 | constexpr size_t PROPER_ALIGMENT = 64; 8 | struct lambda; 9 | using func = int (*)(struct lambda*); 10 | struct __attribute__((aligned(PROPER_ALIGMENT))) lambda { 11 | func body; 12 | int data; 13 | struct lambda* first; 14 | struct lambda* second; 15 | struct lambda* third; 16 | }; 17 | 18 | int call(struct lambda* l) { 19 | int ret; 20 | if (l->body == nullptr) { 21 | ret = l->data; 22 | } else { 23 | ret = l->body(l); 24 | } 25 | free(l); 26 | return ret; 27 | } 28 | 29 | struct lambda* make( 30 | func body, struct lambda* a, struct lambda* b, struct lambda* c) { 31 | auto* l = static_cast(malloc(sizeof(lambda))); 32 | l->body = body; 33 | l->first = a; 34 | l->second = b; 35 | l->third = c; 36 | return l; 37 | } 38 | 39 | struct lambda* integer(int x) { 40 | auto* l = make(nullptr, nullptr, nullptr, nullptr); 41 | l->data = x; 42 | return l; 43 | } 44 | 45 | void release(struct lambda* l) { 46 | if (l == nullptr) { 47 | return; 48 | } 49 | release(l->first); 50 | release(l->second); 51 | release(l->third); 52 | free(l); 53 | } 54 | 55 | int iff(struct lambda* arg) { 56 | int ret; 57 | if (call(arg->first) == 1) { 58 | ret = call(arg->second); 59 | release(arg->third); 60 | } else { 61 | ret = call(arg->third); 62 | release(arg->second); 63 | } 64 | return ret; 65 | } 66 | int less(struct lambda* arg) { 67 | return static_cast(call(arg->first) < call(arg->second)); 68 | } 69 | int sub(struct lambda* arg) { return call(arg->first) - call(arg->second); } 70 | int add(struct lambda* arg) { return call(arg->first) + call(arg->second); } 71 | 72 | int fibo(struct lambda* arg) { 73 | const int x = call(arg->first); 74 | return call(make(iff, make(less, integer(x), integer(2), nullptr), integer(1), 75 | make(add, 76 | make(fibo, make(sub, integer(x), integer(1), nullptr), nullptr, nullptr), 77 | make(fibo, make(sub, integer(x), integer(2), nullptr), nullptr, nullptr), 78 | nullptr))); 79 | } 80 | 81 | int calc(int x) { return call(make(fibo, integer(x), nullptr, nullptr)); } 82 | -------------------------------------------------------------------------------- /cpp/loop.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | int calc(int x) { 7 | int p1 = 0; 8 | int p2 = 1; 9 | for (int i = 1; i < x; ++i) { 10 | const int t = p2; 11 | p2 = p1 + p2; 12 | p1 = t; 13 | } 14 | return p1 + p2; 15 | } 16 | -------------------------------------------------------------------------------- /cpp/main.h: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #ifndef INCLUDE_MAIN_H__ 5 | #define INCLUDE_MAIN_H__ 6 | 7 | #include 8 | #include 9 | 10 | int calc(int); 11 | 12 | // see https://stackoverflow.com/questions/70686140 13 | volatile int dummy = 0; 14 | 15 | int main(int argc, const char* argv[]) { 16 | if (argc != 3) { 17 | printf("Two args required: INPUT and CYCLES\n"); 18 | return 1; 19 | } 20 | int total = 0; 21 | int f = 0; 22 | int input = atoi(argv[1]); 23 | int cycles = atoi(argv[2]); 24 | for (int i = 0; i < cycles; ++i) { 25 | f = calc(input + dummy); 26 | total += f; 27 | } 28 | printf("%d-th Fibonacci number is %d\nTotal is %d\n", input, f, total); 29 | } 30 | 31 | #endif // INCLUDE_MAIN_H__ 32 | -------------------------------------------------------------------------------- /cpp/matrixes.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include 5 | #include 6 | 7 | #include "./main.h" 8 | 9 | int fibonacci(unsigned int n) { 10 | const size_t size = 2; 11 | std::array, size> fib = {{{{1, 1}}, {{1, 0}}}}; 12 | std::array, size> ret = {{{{1, 0}}, {{0, 1}}}}; 13 | std::array, size> tmp = {{{{0, 0}}, {{0, 0}}}}; 14 | while (n != 0) { 15 | if ((n & 1U) != 0) { 16 | tmp.at(0).fill(0); 17 | tmp.at(1).fill(0); 18 | for (size_t i = 0; i < size; i++) { 19 | for (size_t j = 0; j < size; j++) { 20 | for (int k = 0; k < size; k++) { 21 | tmp.at(i).at(j) = 22 | tmp.at(i).at(j) + ret.at(i).at(k) * fib.at(k).at(j); 23 | } 24 | } 25 | } 26 | for (size_t i = 0; i < size; i++) { 27 | for (size_t j = 0; j < size; j++) { 28 | ret.at(i).at(j) = tmp.at(i).at(j); 29 | } 30 | } 31 | } 32 | tmp.at(0).fill(0); 33 | tmp.at(1).fill(0); 34 | for (size_t i = 0; i < size; i++) { 35 | for (size_t j = 0; j < size; j++) { 36 | for (size_t k = 0; k < size; k++) { 37 | tmp.at(i).at(j) = tmp.at(i).at(j) + fib.at(i).at(k) * fib.at(k).at(j); 38 | } 39 | } 40 | } 41 | for (size_t i = 0; i < size; i++) { 42 | for (size_t j = 0; j < size; j++) { 43 | fib.at(i).at(j) = tmp.at(i).at(j); 44 | } 45 | } 46 | n /= 2; 47 | } 48 | return ret.at(0).at(1); 49 | } 50 | 51 | int calc(int x) { return fibonacci(x + 1); } 52 | -------------------------------------------------------------------------------- /cpp/novirtual.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Base { 7 | public: 8 | }; 9 | 10 | class Integer : public Base { 11 | public: 12 | explicit Integer(int v) : value(new int(v)) {} 13 | ~Integer() { delete value; } 14 | int get() { return *value; } 15 | 16 | private: 17 | int* value; 18 | }; 19 | 20 | class Less : public Base { 21 | public: 22 | Less(int l, int r) : left(new int(l)), right(new int(r)) {} 23 | ~Less() { 24 | delete left; 25 | delete right; 26 | } 27 | bool get() { return *left < *right; } 28 | 29 | private: 30 | int* left; 31 | int* right; 32 | }; 33 | 34 | class Add : public Base { 35 | public: 36 | Add(int l, int r) : left(new int(l)), right(new int(r)) {} 37 | ~Add() { 38 | delete left; 39 | delete right; 40 | } 41 | int get() { return *left + *right; } 42 | 43 | private: 44 | int* left; 45 | int* right; 46 | }; 47 | 48 | class Sub : public Base { 49 | public: 50 | Sub(int l, int r) : left(new int(l)), right(new int(r)) {} 51 | ~Sub() { 52 | delete left; 53 | delete right; 54 | } 55 | int get() { return *left - *right; } 56 | 57 | private: 58 | int* left; 59 | int* right; 60 | }; 61 | 62 | class Fibo : public Base { 63 | public: 64 | explicit Fibo(int v) : value(new int(v)) {} 65 | ~Fibo() { delete value; } 66 | int get() { 67 | if (Less(*value, 2).get()) { 68 | return 1; 69 | } 70 | return Add( 71 | Fibo(Sub(*value, 1).get()).get(), Fibo(Sub(*value, 2).get()).get()) 72 | .get(); 73 | } 74 | 75 | private: 76 | int* value; 77 | }; 78 | 79 | int calc(int x) { return Fibo(x).get(); } 80 | -------------------------------------------------------------------------------- /cpp/objects.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Bool { 7 | public: 8 | virtual ~Bool() = default; 9 | virtual bool get() = 0; 10 | }; 11 | 12 | class Int { 13 | public: 14 | virtual ~Int() = default; 15 | virtual int get() = 0; 16 | }; 17 | 18 | class Integer : public Int { 19 | public: 20 | explicit Integer(int v) : value(v) {} 21 | explicit Integer(Int* i) : value(i->get()) {} 22 | ~Integer() override = default; 23 | int get() override { return value; } 24 | 25 | private: 26 | int value; 27 | }; 28 | 29 | class Less : public Bool { 30 | public: 31 | Less(Int* l, Int* r) : left(l), right(r) {} 32 | ~Less() override { 33 | delete left; 34 | delete right; 35 | } 36 | bool get() override { return left->get() < right->get(); } 37 | 38 | private: 39 | Int* left; 40 | Int* right; 41 | }; 42 | 43 | class Add : public Int { 44 | public: 45 | Add(Int* l, Int* r) : left(l), right(r) {} 46 | ~Add() override { 47 | delete left; 48 | delete right; 49 | } 50 | int get() override { return left->get() + right->get(); } 51 | 52 | private: 53 | Int* left; 54 | Int* right; 55 | }; 56 | 57 | class Sub : public Int { 58 | public: 59 | Sub(Int* l, Int* r) : left(l), right(r) {} 60 | ~Sub() override { 61 | delete left; 62 | delete right; 63 | } 64 | int get() override { return left->get() - right->get(); } 65 | 66 | private: 67 | Int* left; 68 | Int* right; 69 | }; 70 | 71 | class If : public Int { 72 | public: 73 | If(Bool* t, Int* l, Int* r) : term(t), left(l), right(r) {} 74 | ~If() override { 75 | delete term; 76 | delete left; 77 | delete right; 78 | } 79 | int get() override { 80 | if (term->get()) { 81 | return left->get(); 82 | } 83 | return right->get(); 84 | } 85 | 86 | private: 87 | Bool* term; 88 | Int* left; 89 | Int* right; 90 | }; 91 | 92 | class Fibo : public Int { 93 | public: 94 | explicit Fibo(Int* v) : value(v) {} 95 | ~Fibo() override { delete value; } 96 | int get() override { 97 | Int* iff = 98 | new If(new Less(new Integer(value), new Integer(2)), new Integer(1), 99 | new Add(new Fibo(new Sub(new Integer(value), new Integer(1))), 100 | new Fibo(new Sub(new Integer(value), new Integer(2))))); 101 | const int result = iff->get(); 102 | delete iff; 103 | return result; 104 | } 105 | 106 | private: 107 | Int* value; 108 | }; 109 | 110 | int calc(int x) { 111 | Int* fibo = new Fibo(new Integer(x)); 112 | const int f = fibo->get(); 113 | delete fibo; 114 | return f; 115 | } 116 | -------------------------------------------------------------------------------- /cpp/recursion.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | int calc(int x) { 7 | if (x < 2) { 8 | return 1; 9 | } 10 | return calc(x - 1) + calc(x - 2); 11 | } 12 | -------------------------------------------------------------------------------- /cpp/stack_objects.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Operation { 7 | int result_; 8 | 9 | public: 10 | explicit Operation(int x) : result_(x) {} 11 | int get() const { return result_; } 12 | }; 13 | 14 | class Add : public Operation { 15 | public: 16 | explicit Add(int x, int y) : Operation(x + y) {} 17 | }; 18 | 19 | class Sub : public Operation { 20 | public: 21 | explicit Sub(int first, int second) : Operation(first - second) {} 22 | }; 23 | 24 | class Less : public Operation { 25 | public: 26 | explicit Less(int first, int second) 27 | : Operation(static_cast(first < second)) {} 28 | }; 29 | 30 | class Fibo : public Operation { 31 | public: 32 | explicit Fibo(int num) 33 | : Operation(Less(num, 2).get() != 0 ? 1 34 | : Add(Fibo(Sub(num, 1).get()).get(), 35 | Fibo(Sub(num, 2).get()).get()) 36 | .get()) {} 37 | }; 38 | 39 | int calc(int x) { return Fibo(x).get(); } 40 | -------------------------------------------------------------------------------- /cpp/static_member_functions.cpp: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | #include "./main.h" 5 | 6 | class Adder { 7 | public: 8 | static int Solve(int a, int b) { return a + b; } 9 | }; 10 | 11 | class Substructor { 12 | public: 13 | static int Solve(int a, int b) { return a - b; } 14 | }; 15 | 16 | class Comparer { 17 | public: 18 | static bool Solve(int a, int b) { return a < b; } 19 | }; 20 | 21 | class If { 22 | public: 23 | static int Solve(bool term, int a, int b) { return term ? a : b; } 24 | }; 25 | 26 | class Fibo { 27 | public: 28 | static int Solve(int num) { 29 | if (Comparer::Solve(num, 2)) { 30 | return 1; 31 | } 32 | return Adder::Solve(Fibo::Solve(Substructor::Solve(num, 1)), 33 | Fibo::Solve(Substructor::Solve(num, 2))); 34 | } 35 | }; 36 | 37 | int calc(int x) { return Fibo::Solve(x); } 38 | -------------------------------------------------------------------------------- /csharp/.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | bins/ 4 | -------------------------------------------------------------------------------- /csharp/Functions/Functions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Exe 9 | net8.0 10 | enable 11 | enable 12 | true 13 | 14 | 15 | -------------------------------------------------------------------------------- /csharp/Functions/Program.cs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | class Program 7 | { 8 | static bool Less(int left, int right) 9 | { 10 | return left < right; 11 | } 12 | 13 | static int Sub(int left, int right) 14 | { 15 | return left - right; 16 | } 17 | 18 | static int Add(int left, int right) 19 | { 20 | return left + right; 21 | } 22 | 23 | static int Fibo(int v) 24 | { 25 | if (Less(v, 2)) 26 | { 27 | return 1; 28 | } 29 | return Add(Fibo(Sub(v, 1)), Fibo(Sub(v, 2))); 30 | } 31 | 32 | public static void Main(string[] args) 33 | { 34 | if (args.Length != 2) 35 | { 36 | Console.Write("Two args required: INPUT and CYCLES\n"); 37 | return; 38 | } 39 | int total = 0; 40 | int f = 0; 41 | int input = int.Parse(args[0]); 42 | int cycles = int.Parse(args[1]); 43 | for (int i = 0; i < cycles; ++i) 44 | { 45 | f = Fibo(input); 46 | total += f; 47 | } 48 | Console.Write( 49 | string.Format( 50 | "{0}-th Fibonacci number is {1}\nTotal is {2}\n", 51 | input, f, total 52 | ) 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /csharp/Objects/Objects.csproj: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Exe 9 | net8.0 10 | enable 11 | enable 12 | true 13 | 14 | 15 | -------------------------------------------------------------------------------- /csharp/Objects/Program.cs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | class Program 7 | { 8 | interface IBool 9 | { 10 | bool Get(); 11 | } 12 | 13 | interface IInt 14 | { 15 | int Get(); 16 | } 17 | 18 | class Integer : IInt 19 | { 20 | private readonly int value; 21 | 22 | public Integer(int v) 23 | { 24 | this.value = v; 25 | } 26 | 27 | public int Get() 28 | { 29 | return this.value; 30 | } 31 | } 32 | 33 | class Less : IBool 34 | { 35 | private readonly IInt left; 36 | private readonly IInt right; 37 | 38 | public Less(IInt l, IInt r) 39 | { 40 | this.left = l; 41 | this.right = r; 42 | } 43 | 44 | public bool Get() 45 | { 46 | return this.left.Get() < this.right.Get(); 47 | } 48 | } 49 | 50 | class Sub : IInt 51 | { 52 | private readonly IInt left; 53 | private readonly IInt right; 54 | 55 | public Sub(IInt l, IInt r) 56 | { 57 | this.left = l; 58 | this.right = r; 59 | } 60 | 61 | public int Get() 62 | { 63 | return this.left.Get() - this.right.Get(); 64 | } 65 | } 66 | 67 | class Add : IInt 68 | { 69 | private readonly IInt left; 70 | private readonly IInt right; 71 | 72 | public Add(IInt l, IInt r) 73 | { 74 | this.left = l; 75 | this.right = r; 76 | } 77 | 78 | public int Get() 79 | { 80 | return this.left.Get() + this.right.Get(); 81 | } 82 | } 83 | 84 | class If : IInt 85 | { 86 | private readonly IBool term; 87 | private readonly IInt left; 88 | private readonly IInt right; 89 | 90 | public If(IBool t, IInt l, IInt r) 91 | { 92 | this.term = t; 93 | this.left = l; 94 | this.right = r; 95 | } 96 | 97 | public int Get() 98 | { 99 | if (this.term.Get()) 100 | { 101 | return this.left.Get(); 102 | } 103 | return this.right.Get(); 104 | } 105 | } 106 | 107 | class Fibo : IInt 108 | { 109 | private readonly IInt value; 110 | 111 | public Fibo(IInt v) 112 | { 113 | this.value = v; 114 | } 115 | 116 | public int Get() 117 | { 118 | return new If( 119 | new Less(this.value, new Integer(2)), 120 | new Integer(1), 121 | new Add( 122 | new Fibo(new Sub(this.value, new Integer(1))), 123 | new Fibo(new Sub(this.value, new Integer(2))) 124 | ) 125 | ).Get(); 126 | } 127 | } 128 | 129 | public static void Main(string[] args) 130 | { 131 | if (args.Length != 2) 132 | { 133 | Console.Write("Two args required: INPUT and CYCLES\n"); 134 | return; 135 | } 136 | int total = 0; 137 | int f = 0; 138 | Integer input = new Integer(int.Parse(args[0])); 139 | int cycles = int.Parse(args[1]); 140 | for (int i = 0; i < cycles; ++i) 141 | { 142 | f = new Fibo(input).Get(); 143 | total += f; 144 | } 145 | Console.Write( 146 | string.Format( 147 | "{0}-th Fibonacci number is {1}\nTotal is {2}\n", 148 | input.Get(), f, total 149 | ) 150 | ); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /csharp/Recursion/Program.cs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | class Program 7 | { 8 | public static int Fibo(int x) 9 | { 10 | if (x < 2) 11 | { 12 | return 1; 13 | } 14 | return Fibo(x - 1) + Fibo(x - 2); 15 | } 16 | 17 | public static void Main(string[] args) 18 | { 19 | if (args.Length != 2) 20 | { 21 | Console.Write("Two args required: INPUT and CYCLES\n"); 22 | return; 23 | } 24 | int total = 0; 25 | int f = 0; 26 | int input = int.Parse(args[0]); 27 | int cycles = int.Parse(args[1]); 28 | for (int i = 0; i < cycles; ++i) 29 | { 30 | f = Fibo(input); 31 | total += f; 32 | } 33 | Console.Write( 34 | string.Format( 35 | "{0}-th Fibonacci number is {1}\nTotal is {2}\n", 36 | input, f, total 37 | ) 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /csharp/Recursion/Recursion.csproj: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Exe 9 | net8.0 10 | enable 11 | enable 12 | true 13 | 14 | 15 | -------------------------------------------------------------------------------- /csharp/Structs/Program.cs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | using System; 5 | 6 | class Program 7 | { 8 | interface IBool 9 | { 10 | bool Get(); 11 | } 12 | 13 | interface IInt 14 | { 15 | int Get(); 16 | } 17 | 18 | struct Integer : IInt 19 | { 20 | private readonly int value; 21 | 22 | public Integer(int v) 23 | { 24 | this.value = v; 25 | } 26 | 27 | public int Get() 28 | { 29 | return this.value; 30 | } 31 | } 32 | 33 | struct Less : IBool 34 | { 35 | private readonly IInt left; 36 | private readonly IInt right; 37 | 38 | public Less(IInt l, IInt r) 39 | { 40 | this.left = l; 41 | this.right = r; 42 | } 43 | 44 | public bool Get() 45 | { 46 | return this.left.Get() < this.right.Get(); 47 | } 48 | } 49 | 50 | struct Sub : IInt 51 | { 52 | private readonly IInt left; 53 | private readonly IInt right; 54 | 55 | public Sub(IInt l, IInt r) 56 | { 57 | this.left = l; 58 | this.right = r; 59 | } 60 | 61 | public int Get() 62 | { 63 | return this.left.Get() - this.right.Get(); 64 | } 65 | } 66 | 67 | struct Add : IInt 68 | { 69 | private readonly IInt left; 70 | private readonly IInt right; 71 | 72 | public Add(IInt l, IInt r) 73 | { 74 | this.left = l; 75 | this.right = r; 76 | } 77 | 78 | public int Get() 79 | { 80 | return this.left.Get() + this.right.Get(); 81 | } 82 | } 83 | 84 | struct If : IInt 85 | { 86 | private readonly IBool term; 87 | private readonly IInt left; 88 | private readonly IInt right; 89 | 90 | public If(IBool t, IInt l, IInt r) 91 | { 92 | this.term = t; 93 | this.left = l; 94 | this.right = r; 95 | } 96 | 97 | public int Get() 98 | { 99 | if (this.term.Get()) 100 | { 101 | return this.left.Get(); 102 | } 103 | return this.right.Get(); 104 | } 105 | } 106 | 107 | struct Fibo : IInt 108 | { 109 | private readonly IInt value; 110 | 111 | public Fibo(IInt v) 112 | { 113 | this.value = v; 114 | } 115 | 116 | public int Get() 117 | { 118 | return new If( 119 | new Less(this.value, new Integer(2)), 120 | new Integer(1), 121 | new Add( 122 | new Fibo(new Sub(this.value, new Integer(1))), 123 | new Fibo(new Sub(this.value, new Integer(2))) 124 | ) 125 | ).Get(); 126 | } 127 | } 128 | 129 | public static void Main(string[] args) 130 | { 131 | if (args.Length != 2) 132 | { 133 | Console.Write("Two args required: INPUT and CYCLES\n"); 134 | return; 135 | } 136 | int total = 0; 137 | int f = 0; 138 | Integer input = new Integer(int.Parse(args[0])); 139 | int cycles = int.Parse(args[1]); 140 | for (int i = 0; i < cycles; ++i) 141 | { 142 | f = new Fibo(input).Get(); 143 | total += f; 144 | } 145 | Console.Write( 146 | string.Format( 147 | "{0}-th Fibonacci number is {1}\nTotal is {2}\n", 148 | input.Get(), f, total 149 | ) 150 | ); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /csharp/Structs/Structs.csproj: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | Exe 9 | net8.0 10 | enable 11 | enable 12 | true 13 | 14 | 15 | -------------------------------------------------------------------------------- /eiffel/application.e: -------------------------------------------------------------------------------- 1 | --- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | --- SPDX-License-Identifier: MIT 3 | 4 | class APPLICATION 5 | inherit 6 | ARGUMENTS 7 | create 8 | make 9 | feature 10 | make 11 | local 12 | input: Integer 13 | cycles: Integer 14 | fibo: Integer 15 | i: Integer 16 | total: Integer 17 | f: RECURSION 18 | do 19 | input := argument(1).to_integer 20 | cycles := argument(2).to_integer 21 | total := 0 22 | from 23 | i := cycles 24 | until 25 | i <= 0 26 | loop 27 | fibo := f.fib(input) 28 | total := total + fibo 29 | i := i - 1 30 | end 31 | io.put_integer(input) 32 | io.put_string("-th Fibonacci number is ") 33 | io.put_integer(fibo) 34 | io.put_new_line() 35 | io.put_string("Total is ") 36 | io.put_integer(total) 37 | io.put_new_line() 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /eiffel/recursion.e: -------------------------------------------------------------------------------- 1 | --- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | --- SPDX-License-Identifier: MIT 3 | 4 | expanded class 5 | RECURSION 6 | feature 7 | fib (n: INTEGER): INTEGER 8 | require 9 | number_must_be_positive: n >= 0 10 | do 11 | inspect 12 | n 13 | when 0 then 14 | Result := 1 15 | when 1 then 16 | Result := 1 17 | else 18 | Result := fib (n-1) + fib (n-2) 19 | end -- inspect 20 | ensure 21 | n = 0 implies Result = 1 22 | n = 1 implies Result = 1 23 | n > 1 implies Result = fib (n-1) + fib (n-2) 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /go/README.md: -------------------------------------------------------------------------------- 1 | # Go Fibonacci Implementations 2 | 3 | There are three implementations: 4 | 5 | * Recursive standard implementation 6 | * Fast implementation with loop 7 | * Implementation using `struct`s and `interface`s 8 | 9 | Known issues: `struct`s implementation has interfaces as struct fields, 10 | this mean its fields' memory will be allocated in heap instead of stack, 11 | so it has GC overhead; other implementations can compute fibonacci number 12 | in stack. 13 | -------------------------------------------------------------------------------- /go/cmd/fast/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "strconv" 10 | 11 | "github.com/yegor256/fibonacci/go" 12 | ) 13 | 14 | func main() { 15 | inp, err := strconv.Atoi(os.Args[1]) 16 | if err != nil { 17 | panic(err) 18 | } 19 | cycles, err := strconv.Atoi(os.Args[2]) 20 | if err != nil { 21 | panic(err) 22 | } 23 | var sum int64 24 | var r int64 25 | for i := 0; i < cycles; i++ { 26 | r = fibo.Fast(int64(inp)) 27 | sum += r 28 | } 29 | fmt.Printf("%d-th Fibonacci number is %d\nTotal is %d\n", inp, r, sum) 30 | } 31 | -------------------------------------------------------------------------------- /go/cmd/recursion/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "strconv" 10 | 11 | "github.com/yegor256/fibonacci/go" 12 | ) 13 | 14 | func main() { 15 | inp, err := strconv.Atoi(os.Args[1]) 16 | if err != nil { 17 | panic(err) 18 | } 19 | cycles, err := strconv.Atoi(os.Args[2]) 20 | if err != nil { 21 | panic(err) 22 | } 23 | var sum int64 24 | var r int64 25 | for i := 0; i < cycles; i++ { 26 | r = fibo.Calculate(int64(inp)) 27 | sum += r 28 | } 29 | fmt.Printf("%d-th Fibonacci number is %d\nTotal is %d\n", inp, r, sum) 30 | } 31 | -------------------------------------------------------------------------------- /go/cmd/structs/main.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "strconv" 10 | 11 | "github.com/yegor256/fibonacci/go" 12 | ) 13 | 14 | func main() { 15 | inp, err := strconv.Atoi(os.Args[1]) 16 | if err != nil { 17 | panic(err) 18 | } 19 | cycles, err := strconv.Atoi(os.Args[2]) 20 | if err != nil { 21 | panic(err) 22 | } 23 | var sum int64 24 | var r int64 25 | for i := 0; i < cycles; i++ { 26 | r = fibo.New(int64(inp)).Value() 27 | sum += r 28 | } 29 | fmt.Printf("%d-th Fibonacci number is %d\nTotal is %d\n", inp, r, sum) 30 | } 31 | -------------------------------------------------------------------------------- /go/fibo.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package fibo 5 | 6 | type int64number int64 7 | 8 | func (n int64number) intVal() int64 { 9 | return int64(n) 10 | } 11 | 12 | type number interface { 13 | intVal() int64 14 | } 15 | 16 | type boolean interface { 17 | boolVal() bool 18 | } 19 | 20 | type less struct { 21 | left, right number 22 | } 23 | 24 | func (l less) boolVal() bool { 25 | return l.left.intVal() < l.right.intVal() 26 | } 27 | 28 | type sub struct { 29 | left, right number 30 | } 31 | 32 | func (s sub) intVal() int64 { 33 | return s.left.intVal() - s.right.intVal() 34 | } 35 | 36 | type add struct { 37 | left, right number 38 | } 39 | 40 | func (a add) intVal() int64 { 41 | return a.left.intVal() + a.right.intVal() 42 | } 43 | 44 | type condition struct { 45 | pred boolean 46 | yes, no number 47 | } 48 | 49 | func (c condition) intVal() int64 { 50 | if c.pred.boolVal() { 51 | return c.yes.intVal() 52 | } 53 | return c.no.intVal() 54 | } 55 | 56 | 57 | func (f Fibo) intVal() int64 { 58 | const ( 59 | one = int64number(1) 60 | two = int64number(2) 61 | ) 62 | cnd := condition{ 63 | pred: less{f.n, two}, 64 | yes: one, 65 | no: add{ 66 | Fibo{sub{f.n, one}}, 67 | Fibo{sub{f.n, two}}, 68 | }, 69 | } 70 | return cnd.intVal() 71 | } 72 | 73 | // Fibo nacci 74 | type Fibo struct { 75 | n number 76 | } 77 | 78 | // Value of fibonacci 79 | func (f Fibo) Value() int64 { 80 | return f.intVal() 81 | } 82 | 83 | // New fibonacci number 84 | func New(inp int64) Fibo { 85 | return Fibo{int64number(inp)} 86 | } 87 | -------------------------------------------------------------------------------- /go/go.mod: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | module github.com/yegor256/fibonacci/go 5 | 6 | go 1.19 7 | -------------------------------------------------------------------------------- /go/loop.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package fibo 5 | 6 | // Fast fibonacci calculation 7 | func Fast(n int64) int64 { 8 | if n <= 1 { 9 | return 1 10 | } 11 | var x, p, pp int64 12 | pp, p = 0, 1 13 | for x = 2; x <= n; x++ { 14 | pp, p = p, p + pp 15 | } 16 | return p + pp 17 | } 18 | -------------------------------------------------------------------------------- /go/recursive.go: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | package fibo 5 | 6 | // Calculate fibonacci for input 7 | func Calculate(x int64) int64 { 8 | if x < 2 { 9 | return 1 10 | } 11 | return Calculate(x - 1) + Calculate(x - 2) 12 | } 13 | -------------------------------------------------------------------------------- /haskell/.gitignore: -------------------------------------------------------------------------------- 1 | *.s 2 | -------------------------------------------------------------------------------- /haskell/Mainlib/objects.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Mainlib.Objects (Object, oInt, oIf, oLt, oAdd, oSub, get) where 6 | 7 | data Object a = Object { get :: a } 8 | 9 | oInt :: Int -> Object Int 10 | oInt = Object 11 | 12 | oIf :: Object Bool -> Object a -> Object a -> Object a 13 | oIf p a b = Object $ if get p then get a else get b 14 | 15 | oLt :: (Ord a) => Object a -> Object a -> Object Bool 16 | oLt a b = Object $ get a < get b 17 | 18 | oAdd :: (Num a) => Object a -> Object a -> Object a 19 | oAdd a b = Object $ get a + get b 20 | 21 | oSub :: (Num a) => Object a -> Object a -> Object a 22 | oSub a b = Object $ get a - get b 23 | -------------------------------------------------------------------------------- /haskell/Mainlib/report.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Mainlib.Report (run) where 6 | 7 | import System.Environment (getArgs, getProgName) 8 | 9 | readNat :: String -> Maybe Int 10 | readNat s = case reads s of 11 | [(i, "")] | i >= 0 -> Just i 12 | _ -> Nothing 13 | 14 | parseArgs :: [String] -> Maybe (Int, Int) 15 | parseArgs [s1, s2] = (,) <$> readNat s1 <*> readNat s2 16 | parseArgs _ = Nothing 17 | 18 | run :: (Int -> Int) -> IO () 19 | run f = do 20 | args <- getArgs 21 | maybe usage (report . runF f 0 0) (parseArgs args) 22 | 23 | runF :: (Int -> Int) -> Int -> Int -> (Int, Int) -> (Int, Int, Int) 24 | runF _f result total (input, 0) = (input, result, total) 25 | runF f _result total (input, n) = runF f r (r + total) (input, n - 1) where r = f input 26 | 27 | report :: (Int, Int, Int) -> IO () 28 | report (input, answer, total) = do 29 | putStr $ show input 30 | putStr $ "-th Fibonacci number is " 31 | print answer 32 | putStr $ "Total is " 33 | print total 34 | 35 | usage :: IO () 36 | usage = do 37 | putStrLn "Usage:" 38 | name <- getProgName 39 | putStrLn $ name ++ " INPUT CYCLES" 40 | -------------------------------------------------------------------------------- /haskell/adt.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Main where 6 | import Mainlib.Report (run) 7 | 8 | data Fibo = First | Second | Other Fibo Fibo 9 | 10 | get :: Fibo -> Int 11 | get First = 1 12 | get Second = 1 13 | get (Other a b) = get a + get b 14 | 15 | newFibo :: Int -> Fibo 16 | newFibo 0 = First 17 | newFibo 1 = Second 18 | newFibo n = Other (newFibo (n - 1)) (newFibo (n - 2)) 19 | 20 | main :: IO () 21 | main = run $ get . newFibo 22 | -------------------------------------------------------------------------------- /haskell/iterate.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Main where 6 | import Mainlib.Report (run) 7 | 8 | 9 | fibo :: Int -> Int 10 | fibo n = fst $ iterate step (1, 1) !! n where 11 | step (a, b) = (b, a + b) 12 | 13 | 14 | main :: IO () 15 | main = run fibo 16 | -------------------------------------------------------------------------------- /haskell/object_dynamic.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Main where 6 | import Mainlib.Report (run) 7 | import Mainlib.Objects 8 | 9 | fibo :: Object Int -> Object Int 10 | fibo n = fibo' n (oInt 1) (oInt 1) where 11 | fibo' m a b = 12 | oIf (oLt m $ oInt 1) 13 | a 14 | (fibo' (oSub m $ oInt 1) 15 | b 16 | (oAdd a b)) 17 | 18 | main :: IO () 19 | main = run $ get . fibo . oInt 20 | -------------------------------------------------------------------------------- /haskell/objects.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | module Main where 5 | 6 | import Mainlib.Report (run) 7 | import Mainlib.Objects 8 | 9 | fibo :: Object Int -> Object Int 10 | fibo x = 11 | oIf (oLt x $ oInt 2) 12 | (oInt 1) 13 | (oAdd (fibo $ oSub x $ oInt 1) 14 | (fibo $ oSub x $ oInt 2)) 15 | 16 | main :: IO () 17 | main = run $ get . fibo . oInt 18 | -------------------------------------------------------------------------------- /haskell/polymorphic_recursion.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | module Main where 5 | import Mainlib.Report (run) 6 | 7 | data Number a = Number {getNumber :: a} 8 | 9 | instance Num a => Num (Number a) where 10 | a + b = Number $ getNumber a + getNumber b 11 | a * b = Number $ getNumber a * getNumber b 12 | abs = Number . abs . getNumber 13 | signum = Number . signum . getNumber 14 | fromInteger = Number . fromInteger 15 | negate = Number . negate . getNumber 16 | 17 | instance Eq a => Eq (Number a) where 18 | a == b = getNumber a == getNumber b 19 | 20 | instance Ord a => Ord (Number a) where 21 | a <= b = getNumber a <= getNumber b 22 | 23 | fibo :: (Ord a, Num a) => a -> a 24 | fibo n 25 | | n <= fromInteger 1 = fromInteger 1 26 | | otherwise = fibo (n - fromInteger 1) + fibo (n - fromInteger 2) 27 | 28 | main :: IO () 29 | main = run $ getNumber . fibo . fromIntegral 30 | -------------------------------------------------------------------------------- /haskell/recursion.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Main where 6 | import Mainlib.Report (run) 7 | 8 | 9 | fibo :: Int -> Int 10 | fibo 0 = 1 11 | fibo 1 = 1 12 | fibo n = fibo (n - 1) + fibo (n - 2) 13 | 14 | main :: IO () 15 | main = run fibo 16 | -------------------------------------------------------------------------------- /haskell/tail_recursion.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | 5 | module Main where 6 | import Mainlib.Report (run) 7 | 8 | fibo :: Int -> Int 9 | fibo = fibo' 1 1 where 10 | fibo' a _b 0 = a 11 | fibo' a b n = fibo' b (a + b) (n - 1) 12 | 13 | main :: IO () 14 | main = run fibo 15 | -------------------------------------------------------------------------------- /haskell/zipwith.hs: -------------------------------------------------------------------------------- 1 | -- SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | -- SPDX-License-Identifier: MIT 3 | 4 | module Main where 5 | import Mainlib.Report (run) 6 | 7 | fibs :: [Int] 8 | fibs = 1:1:zipWith (+) fibs (drop 1 fibs) 9 | 10 | fibo :: Int -> Int 11 | fibo = (fibs !!) 12 | 13 | main :: IO () 14 | main = run fibo 15 | -------------------------------------------------------------------------------- /java/Functions.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | class Functions { 5 | static boolean Less(int left, int right) { 6 | return left < right; 7 | } 8 | static int Sub(int left, int right) { 9 | return left - right; 10 | } 11 | static int Add(int left, int right) { 12 | return left + right; 13 | } 14 | static int Fibo(int v) { 15 | if (Less(v, 2)) { 16 | return 1; 17 | } 18 | return Add(Fibo(Sub(v, 1)), Fibo(Sub(v, 2))); 19 | } 20 | public static void main(final String... args) { 21 | if (args.length != 2) { 22 | System.out.print("Two args required: INPUT and CYCLES\n"); 23 | return; 24 | } 25 | int total = 0; 26 | int f = 0; 27 | int input = java.lang.Integer.parseInt(args[0]); 28 | int cycles = java.lang.Integer.parseInt(args[1]); 29 | for (int i = 0; i < cycles; ++i) { 30 | f = Fibo(input); 31 | total += f; 32 | } 33 | System.out.print( 34 | String.format( 35 | "%d-th Fibonacci number is %d\nTotal is %d\n", 36 | input, f, total 37 | ) 38 | ); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /java/Objects.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | class Objects { 5 | interface Bool { 6 | boolean get(); 7 | } 8 | interface Int { 9 | int get(); 10 | } 11 | static class Integer implements Int { 12 | private final int value; 13 | Integer(int v) { 14 | this.value = v; 15 | } 16 | @Override 17 | public int get() { 18 | return this.value; 19 | } 20 | } 21 | static class Less implements Bool { 22 | private final Int left; 23 | private final Int right; 24 | Less(Int l, Int r) { 25 | this.left = l; 26 | this.right = r; 27 | } 28 | @Override 29 | public boolean get() { 30 | return this.left.get() < this.right.get(); 31 | } 32 | } 33 | static class Sub implements Int { 34 | private final Int left; 35 | private final Int right; 36 | Sub(Int l, Int r) { 37 | this.left = l; 38 | this.right = r; 39 | } 40 | @Override 41 | public int get() { 42 | return this.left.get() - this.right.get(); 43 | } 44 | } 45 | static class Add implements Int { 46 | private final Int left; 47 | private final Int right; 48 | Add(Int l, Int r) { 49 | this.left = l; 50 | this.right = r; 51 | } 52 | @Override 53 | public int get() { 54 | return this.left.get() + this.right.get(); 55 | } 56 | } 57 | static class If implements Int { 58 | private final Bool term; 59 | private final Int left; 60 | private final Int right; 61 | If(Bool t, Int l, Int r) { 62 | this.term = t; 63 | this.left = l; 64 | this.right = r; 65 | } 66 | @Override 67 | public int get() { 68 | if (this.term.get()) { 69 | return this.left.get(); 70 | } 71 | return this.right.get(); 72 | } 73 | } 74 | static class Fibo implements Int { 75 | private final Int value; 76 | Fibo(Int v) { 77 | this.value = v; 78 | } 79 | @Override 80 | public int get() { 81 | return new If( 82 | new Less(this.value, new Integer(2)), 83 | new Integer(1), 84 | new Add( 85 | new Fibo(new Sub(this.value, new Integer(1))), 86 | new Fibo(new Sub(this.value, new Integer(2))) 87 | ) 88 | ).get(); 89 | } 90 | } 91 | public static void main(final String... args) { 92 | if (args.length != 2) { 93 | System.out.print("Two args required: INPUT and CYCLES\n"); 94 | return; 95 | } 96 | int total = 0; 97 | int f = 0; 98 | Integer input = new Integer(java.lang.Integer.parseInt(args[0])); 99 | int cycles = java.lang.Integer.parseInt(args[1]); 100 | for (int i = 0; i < cycles; ++i) { 101 | f = new Fibo(input).get(); 102 | total += f; 103 | } 104 | System.out.print( 105 | String.format( 106 | "%d-th Fibonacci number is %d\nTotal is %d\n", 107 | input.get(), f, total 108 | ) 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /java/Records.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | class Records { 5 | interface Bool { 6 | boolean get(); 7 | } 8 | interface Int { 9 | int get(); 10 | } 11 | static record Integer(int value) implements Int { 12 | @Override 13 | public int get() { 14 | return this.value; 15 | } 16 | } 17 | static record Less(Int left, Int right) implements Bool { 18 | @Override 19 | public boolean get() { 20 | return this.left.get() < this.right.get(); 21 | } 22 | } 23 | static record Sub(Int left, Int right) implements Int { 24 | @Override 25 | public int get() { 26 | return this.left.get() - this.right.get(); 27 | } 28 | } 29 | static record Add(Int left, Int right) implements Int { 30 | @Override 31 | public int get() { 32 | return this.left.get() + this.right.get(); 33 | } 34 | } 35 | static record If(Bool term, Int left, Int right) implements Int { 36 | @Override 37 | public int get() { 38 | if (this.term.get()) { 39 | return this.left.get(); 40 | } 41 | return this.right.get(); 42 | } 43 | } 44 | static record Fibo(Int value) implements Int { 45 | @Override 46 | public int get() { 47 | return new If( 48 | new Less(this.value, new Integer(2)), 49 | new Integer(1), 50 | new Add( 51 | new Fibo(new Sub(this.value, new Integer(1))), 52 | new Fibo(new Sub(this.value, new Integer(2))) 53 | ) 54 | ).get(); 55 | } 56 | } 57 | public static void main(final String... args) { 58 | if (args.length != 2) { 59 | System.out.print("Two args required: INPUT and CYCLES\n"); 60 | return; 61 | } 62 | int total = 0; 63 | int f = 0; 64 | Integer input = new Integer(java.lang.Integer.parseInt(args[0])); 65 | int cycles = java.lang.Integer.parseInt(args[1]); 66 | for (int i = 0; i < cycles; ++i) { 67 | f = new Fibo(input).get(); 68 | total += f; 69 | } 70 | System.out.print( 71 | String.format( 72 | "%d-th Fibonacci number is %d\nTotal is %d\n", 73 | input.get(), f, total 74 | ) 75 | ); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /java/Recursion.java: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | class Recursion { 5 | public static int fibo(int x) { 6 | if (x < 2) { 7 | return 1; 8 | } 9 | return fibo(x - 1) + fibo(x - 2); 10 | } 11 | public static void main(final String... args) { 12 | if (args.length != 2) { 13 | System.out.print("Two args required: INPUT and CYCLES\n"); 14 | return; 15 | } 16 | int total = 0; 17 | int f = 0; 18 | int input = java.lang.Integer.parseInt(args[0]); 19 | int cycles = java.lang.Integer.parseInt(args[1]); 20 | for (int i = 0; i < cycles; ++i) { 21 | f = fibo(input); 22 | total += f; 23 | } 24 | System.out.print( 25 | String.format( 26 | "%d-th Fibonacci number is %d\nTotal is %d\n", 27 | input, f, total 28 | ) 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /latex.xsl: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | \documentclass{article} 12 | \usepackage{booktabs} 13 | \usepackage{tabularx} 14 | \begin{document} 15 | \begin{tabularx}{\linewidth}{lXrrr} 16 | \toprule 17 | & & \multicolumn{2}{c}{CPU mInstructions} & \\ 18 | Language & Compiler & w/functions & w/objects & Ratio \\ 19 | \midrule 20 | 21 | 22 | 23 | \bottomrule 24 | \end{tabularx} 25 | \end{document} 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | & 39 | 40 | & 41 | 42 | & 43 | 44 | & 45 | 46 | 47 | 48 | x 49 | 50 | 51 | --- 52 | 53 | 54 | \\ 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /lisp/recursion.lisp: -------------------------------------------------------------------------------- 1 | ; SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | ; SPDX-License-Identifier: MIT 3 | 4 | (defun fibo (x) 5 | (if 6 | (< x 2) 7 | 1 8 | (+ 9 | (fibo (- x 1)) 10 | (fibo (- x 2))))) 11 | 12 | (defvar x) 13 | 14 | (defvar cycles) 15 | 16 | (defvar f 0) 17 | 18 | (defvar total 0) 19 | 20 | (defun main () 21 | (progn 22 | (setq x (parse-integer (nth 1 sb-ext:*posix-argv*))) 23 | (setq cycles (parse-integer (nth 2 sb-ext:*posix-argv*))) 24 | (loop for c from 1 to cycles do 25 | (progn 26 | (setq f (fibo x))) 27 | (setq total (+ total f))) 28 | (format T 29 | "~d-th Fibonacci number is ~d~%Total is ~d~%" 30 | x 31 | f 32 | total))) 33 | 34 | (sb-ext:save-lisp-and-die 35 | "bin/lisp-recursion.bin" 36 | :toplevel 37 | #'main 38 | :executable 39 | t) 40 | -------------------------------------------------------------------------------- /logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Group 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /main.xsl: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 |

10 | This is what it takes to calculate the 11 | 12 | 13 | 14 | 15 | 16 | st 17 | 18 | 19 | nd 20 | 21 | 22 | rd 23 | 24 | 25 | th 26 | 27 | 28 | 29 | 30 | 31 | Fibonacci number 32 | 33 | using different algorithms: 34 |

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
47 | 48 | sorter 49 | 50 | data 51 | 52 | 53 | 54 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | https://github.com/yegor256/fibonacci/blob/master/ 71 | 72 | 73 | 74 | / 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | n/a 83 | 84 | 85 | 86 | 87 | 88 | https://raw.githubusercontent.com/yegor256/fibonacci/gh-pages/asm/ 89 | 90 | .asm 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | MAX 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | https://raw.githubusercontent.com/yegor256/fibonacci/gh-pages/reports/ 119 | 120 | .perf 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 |

136 | This is how much functions are faster than objects: 137 |

138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 153 | 155 | 156 | 159 | 162 | 165 | 168 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 185 | 188 | 191 | 194 | 205 | 206 | 207 | 208 |
149 | 150 | 151 | TPC 152 | 154 |
157 | Language 158 | 160 | Compiler 161 | 163 | w/functions 164 | 166 | w/objects 167 | 169 | Ratio 170 |
183 | 184 | 186 | 187 | 189 | 190 | 192 | 193 | 195 | 196 | 197 | 198 | x 199 | 200 | 201 | 202 | 203 | 204 |
209 |
210 | 211 | 212 | 213 | Fibonacci 214 | 215 | 216 | 217 | 218 | 219 | 226 | 233 | 234 | 235 |

236 | 237 | 238 | 239 |

240 | 241 | 242 | 243 |

244 | Maximum optimization is enabled in all compilers. 245 |

246 |

247 | If you want to add another program to the list, just submit a pull request to 248 | 249 | yegor256/fibonacci 250 | 251 | . 252 |

253 |

254 | Here is 255 | 256 | index.xml 257 | 258 | with the data. This is TeX 259 | 260 | summary.tex 261 | 262 | . 263 |

264 |

265 | Built on 266 | 267 | by 268 | 269 | @yegor256 270 | 271 | at " 272 | 273 | " machine. 274 |

275 | 276 | 277 |
278 | 279 |

280 | 281 |

282 |
283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | : 291 | 292 | . 293 | 294 | 295 | -------------------------------------------------------------------------------- /pascal/Objects.pp: -------------------------------------------------------------------------------- 1 | (* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 3 | * SPDX-License-Identifier: MIT 4 | *) 5 | 6 | program Objects; 7 | 8 | {$mode objfpc} 9 | 10 | uses 11 | SysUtils; 12 | 13 | type 14 | TBool = interface 15 | function Get:Boolean; 16 | end; 17 | 18 | TInt = interface 19 | function Get:Int32; 20 | end; 21 | 22 | TInteger = class(TInterfacedObject, TInt) 23 | private 24 | value:Int32; 25 | 26 | public 27 | constructor Create(v:Int32); overload; 28 | function Get:Int32; 29 | end; 30 | 31 | TLess = class(TInterfacedObject, TBool) 32 | private 33 | left:TInt; 34 | right:TInt; 35 | 36 | public 37 | constructor Create(l:TInt; r:TInt); overload; 38 | function Get:Boolean; 39 | end; 40 | 41 | TSub = class(TInterfacedObject, TInt) 42 | private 43 | left:TInt; 44 | right:TInt; 45 | 46 | public 47 | constructor Create(l:TInt; r:TInt); overload; 48 | function Get:Int32; 49 | end; 50 | 51 | TAdd = class(TInterfacedObject, TInt) 52 | private 53 | left:TInt; 54 | right:TInt; 55 | 56 | public 57 | constructor Create(l:TInt; r:TInt); overload; 58 | function Get:Int32; 59 | end; 60 | 61 | TIf = class(TInterfacedObject, TInt) 62 | private 63 | term:TBool; 64 | left:TInt; 65 | right:TInt; 66 | 67 | public 68 | constructor Create(t:TBool; l:TInt; r:TInt); overload; 69 | function Get:Int32; 70 | end; 71 | 72 | TFibo = class(TInterfacedObject, TInt) 73 | private 74 | value:TInt; 75 | 76 | public 77 | constructor Create(v:TInt); overload; 78 | function Get:Int32; 79 | end; 80 | 81 | {TInteger class} 82 | constructor TInteger.Create(v:Int32); overload; 83 | begin 84 | value := v; 85 | end; 86 | 87 | function TInteger.Get:Int32; 88 | begin 89 | Result := value; 90 | end; 91 | 92 | {TLess class} 93 | constructor TLess.Create(l:TInt; r:TInt); overload; 94 | begin 95 | left := l; 96 | right := r; 97 | end; 98 | 99 | function TLess.Get:Boolean; 100 | begin 101 | Result := left.Get() < right.Get(); 102 | end; 103 | 104 | {TSub class} 105 | constructor TSub.Create(l:TInt; r:TInt); overload; 106 | begin 107 | left := l; 108 | right := r; 109 | end; 110 | 111 | function TSub.Get:Int32; 112 | begin 113 | Result := left.Get() - right.Get(); 114 | end; 115 | 116 | {TAdd class} 117 | constructor TAdd.Create(l:TInt; r:TInt); overload; 118 | begin 119 | left := l; 120 | right := r; 121 | end; 122 | 123 | function TAdd.Get:Int32; 124 | begin 125 | Result := left.Get() + right.Get(); 126 | end; 127 | 128 | {TIf class} 129 | constructor TIf.Create(t:TBool; l:TInt; r:TInt); overload; 130 | begin 131 | term := t; 132 | left := l; 133 | right := r; 134 | end; 135 | 136 | function TIf.Get:Int32; 137 | begin 138 | if term.Get() then 139 | Result := left.Get() 140 | else 141 | Result := right.Get(); 142 | end; 143 | 144 | {TFibo class} 145 | constructor TFibo.Create(v:TInt); overload; 146 | begin 147 | value := v; 148 | end; 149 | 150 | function TFibo.Get:Int32; 151 | begin 152 | Result := TIf.Create( 153 | TLess.Create(value, TInteger.Create(2)), 154 | TInteger.Create(1), 155 | TAdd.Create( 156 | TFibo.Create(TSub.Create(value, TInteger.Create(1))), 157 | TFibo.Create(TSub.Create(value, TInteger.Create(2)) 158 | ) 159 | ) 160 | ).Get(); 161 | end; 162 | 163 | var 164 | total:Int32; 165 | f:Int32; 166 | input:TInteger; 167 | cycles:Int32; 168 | i:Int32; 169 | 170 | begin 171 | total := 0; 172 | f := 0; 173 | 174 | if ParamCount <> 2 then 175 | begin 176 | WriteLn('Two args required: INPUT and CYCLES'); 177 | exit; 178 | end; 179 | 180 | input := TInteger.Create(StrToInt(ParamStr(1))); 181 | cycles := StrToInt(ParamStr(2)); 182 | 183 | for i := 1 to cycles do 184 | begin 185 | f := TFibo.Create(input).Get(); 186 | total := total + f; 187 | end; 188 | 189 | WriteLn(IntToStr(input.Get()) + '-th Fibonacci number is ' + IntToStr(f)); 190 | WriteLn('Total is ' + IntToStr(total)); 191 | end. 192 | -------------------------------------------------------------------------------- /pascal/recursion.pp: -------------------------------------------------------------------------------- 1 | (* 2 | * SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 3 | * SPDX-License-Identifier: MIT 4 | *) 5 | 6 | Program recursion; 7 | 8 | Uses sysutils; 9 | 10 | Function Fibo(n : Longint) : Longint; 11 | begin 12 | if (n < 2) then 13 | Fibo := 1 14 | else 15 | Fibo := Fibo(n - 1) + Fibo(n - 2); 16 | end; 17 | 18 | var 19 | input : Longint; 20 | total : Longint; 21 | f : Longint; 22 | i : Longint; 23 | 24 | begin 25 | input := StrToInt(ParamStr(1)); 26 | total := StrToInt(ParamStr(2)); 27 | for i := 1 to total do begin 28 | f := fibo(input); 29 | total += f; 30 | end; 31 | Write(input); 32 | Write('-th Fibonacci number is '); 33 | Write(f); 34 | WriteLn(); 35 | Write('Total is '); 36 | Write(total); 37 | WriteLn(); 38 | end. 39 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /rust/recursion.rs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | use std::env; 5 | 6 | pub fn fibonacci(input: u32) -> u32 { 7 | match input { 8 | 0 => 1, 9 | 1 => 1, 10 | n => fibonacci(n - 2) + fibonacci(n - 1) 11 | } 12 | } 13 | 14 | pub fn main() { 15 | let args: Vec = env::args().collect(); 16 | let input: u32 = args[1].parse().unwrap(); 17 | let cycles: u32 = args[2].parse().unwrap(); 18 | let mut total = 0; 19 | let mut f = 0; 20 | for _ in 0..cycles { 21 | f = fibonacci(input); 22 | total += f; 23 | } 24 | println!("{}-th Fibonacci number is {}\nTotal is {}\n", input, f, total); 25 | } 26 | -------------------------------------------------------------------------------- /rust/structs.rs: -------------------------------------------------------------------------------- 1 | // SPDX-FileCopyrightText: Copyright (c) 2022-2025 Yegor Bugayenko 2 | // SPDX-License-Identifier: MIT 3 | 4 | use std::env; 5 | 6 | pub trait Int { 7 | fn get(&self) -> i32; 8 | } 9 | 10 | pub trait Bool { 11 | fn get(&self) -> bool; 12 | } 13 | 14 | pub struct Integer { 15 | value: i32 16 | } 17 | impl Integer { 18 | pub fn new(v: i32) -> Integer { 19 | return Integer { value: v }; 20 | } 21 | } 22 | impl Int for Integer { 23 | fn get(&self) -> i32 { 24 | return self.value; 25 | } 26 | } 27 | 28 | pub struct Less<'a> { 29 | left: &'a dyn Int, 30 | right: &'a dyn Int 31 | } 32 | impl<'a> Less<'a> { 33 | pub fn new(l: &'a dyn Int, r: &'a dyn Int) -> Less<'a> { 34 | return Less { left: l, right: r }; 35 | } 36 | } 37 | impl<'a> Bool for Less<'a> { 38 | fn get(&self) -> bool { 39 | return self.left.get() < self.right.get(); 40 | } 41 | } 42 | 43 | pub struct Sub<'a> { 44 | left: &'a dyn Int, 45 | right: &'a dyn Int 46 | } 47 | impl<'a> Sub<'a> { 48 | pub fn new(l: &'a dyn Int, r: &'a dyn Int) -> Sub<'a> { 49 | return Sub { left: l, right: r }; 50 | } 51 | } 52 | impl<'a> Int for Sub<'a> { 53 | fn get(&self) -> i32 { 54 | return self.left.get() - self.right.get(); 55 | } 56 | } 57 | 58 | pub struct Add<'a> { 59 | left: &'a dyn Int, 60 | right: &'a dyn Int 61 | } 62 | impl<'a> Add<'a> { 63 | pub fn new(l: &'a dyn Int, r: &'a dyn Int) -> Add<'a> { 64 | return Add { left: l, right: r }; 65 | } 66 | } 67 | impl<'a> Int for Add<'a> { 68 | fn get(&self) -> i32 { 69 | return self.left.get() + self.right.get(); 70 | } 71 | } 72 | 73 | pub struct If<'a> { 74 | term: &'a dyn Bool, 75 | left: &'a dyn Int, 76 | right: &'a dyn Int 77 | } 78 | impl<'a> If<'a> { 79 | pub fn new(t: &'a dyn Bool, l: &'a dyn Int, r: &'a dyn Int) -> If<'a> { 80 | return If { term: t, left: l, right: r }; 81 | } 82 | } 83 | impl<'a> Int for If<'a> { 84 | fn get(&self) -> i32 { 85 | if self.term.get() { 86 | return self.left.get(); 87 | } 88 | return self.right.get(); 89 | } 90 | } 91 | 92 | pub struct Fibo<'a> { 93 | x: &'a dyn Int 94 | } 95 | impl<'a> Fibo<'a> { 96 | pub fn new(v: &'a dyn Int) -> Fibo<'a> { 97 | return Fibo { x: v }; 98 | } 99 | } 100 | impl<'a> Int for Fibo<'a> { 101 | fn get(&self) -> i32 { 102 | let two = Integer::new(2); 103 | let less = Less::new(self.x, &two); 104 | let one = Integer::new(1); 105 | let sub1 = Sub::new(self.x, &one); 106 | let prev1 = Fibo::new(&sub1); 107 | let sub2 = Sub::new(self.x, &two); 108 | let prev2 = Fibo::new(&sub2); 109 | let right = Add::new(&prev1, &prev2); 110 | let iff = If::new(&less, &one, &right); 111 | return iff.get(); 112 | } 113 | } 114 | 115 | pub fn main() { 116 | let args: Vec = env::args().collect(); 117 | let input: i32 = args[1].parse().unwrap(); 118 | let cycles: i32 = args[2].parse().unwrap(); 119 | let mut total = 0; 120 | let mut f = 0; 121 | for _ in 0..cycles { 122 | let x = Integer::new(input); 123 | let fibo = Fibo::new(&x); 124 | f = fibo.get(); 125 | total += f; 126 | } 127 | println!("{}-th Fibonacci number is {}\nTotal is {}\n", input, f, total); 128 | } 129 | --------------------------------------------------------------------------------