From 5c89b0aafe277e5fa0b4eacc8d1ef97f626ada2c Mon Sep 17 00:00:00 2001 From: fonsp Date: Mon, 1 Jul 2024 09:31:14 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20JuliaPlu?= =?UTF-8?q?to/static-export-template@01173cd13ce89a4a11ae2cf5908a4cbada8d1?= =?UTF-8?q?4f0=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- My cool notebook.html | 20 ++ My cool notebook.jl | 267 ++++++++++++++++++ My cool notebook.plutostate | Bin 0 -> 39611 bytes README.md | 124 ++++++++ index.html | 23 ++ pluto_export.json | 1 + ...lEs4imA3z_G4vjfMQ67vAnEYMBFfBdg.plutostate | Bin 0 -> 39611 bytes 7 files changed, 435 insertions(+) create mode 100644 My cool notebook.html create mode 100644 My cool notebook.jl create mode 100644 My cool notebook.plutostate create mode 100644 README.md create mode 100644 index.html create mode 100644 pluto_export.json create mode 100644 pluto_state_cache/0_19_43er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg.plutostate diff --git a/My cool notebook.html b/My cool notebook.html new file mode 100644 index 0000000..3bf3614 --- /dev/null +++ b/My cool notebook.html @@ -0,0 +1,20 @@ + + + + + + + + + + +
\ No newline at end of file diff --git a/My cool notebook.jl b/My cool notebook.jl new file mode 100644 index 0000000..77cb21b --- /dev/null +++ b/My cool notebook.jl @@ -0,0 +1,267 @@ +### A Pluto.jl notebook ### +# v0.12.18 + +using Markdown +using InteractiveUtils + +# ╔═║ 5b2ee40e-a2b8-11ea-0fef-c35fe6918860 +md""" +# The tower of Hanoi + +The tower of hanoi is a famous puzzle. + +![setup of the tower of a hanoi](https://upload.wikimedia.org/wikipedia/commons/0/07/Tower_of_Hanoi.jpeg) + +The game consists of three rods with disks stacked on top of them. The puzzle will start with all disks in a stack on one of the rods (like in the picture). The goal is to move all the discs to a single stack on different rod. + +To move the disks, you have to follow the following rules: + +* You can move only one disk at a time. +* For each move, you have to take the upper disk from one of the stacks, and place it on top of another stack or empty rod. +* You cannot place a larger disk on top of a smaller disk. + +This notebook will define a Julia implementation of the puzzle. It's up to you to write an algorithm that solves it. +""" + +# ╔═║ 95fbd0d2-a2b9-11ea-0682-fdf783251797 +md""" +## Setting up the game pieces + +What does a Julia implementation look like? We're not really interested in writing code that will manipulate physical disks. Our final goal is a function that will give us a _recipe_ to solve the tower of hanoi, which is just a list of moves to make. Because of that, we can use a lot of abstraction in our implementation, and keep the data structures as simple as possible. + +To start, we have to define some representation of the disks and the stacks. The disks have one important property, which is that they are ordered. We can use integers to represent them. +""" + +# ╔═║ 620d6834-a2ba-11ea-150a-2132bb54e4b3 +num_disks = 8 + +# ╔═║ 35ada214-a32c-11ea-0da3-d5d494b28467 +md"""(Side note: the number of disks is arbitrary. When testing your function, you may want to set it to 1 or 2 to start.)""" + +# ╔═║ 7243cc8e-a2ba-11ea-3f29-99356f0cdcf4 +all_disks = 1:num_disks + +# ╔═║ 7e1ba2ac-a2ba-11ea-0134-2f61ed75be18 +md""" +A single stack can be represented as an array with all the disks in it. We will list them from top to bottom. +""" + +# ╔═║ 43781a52-a339-11ea-3803-e56e2d08aa83 +first_stack = collect(all_disks) + +# ╔═║ b648ab70-a2ba-11ea-2dcc-55b630e44325 +md""" +Now we have to make three of those. +""" + +# ╔═║ 32f26f80-a2bb-11ea-0f2a-3fc631ada63d +starting_stacks = [first_stack, [], []] + +# ╔═║ e347f1de-a2bb-11ea-06e7-87cca6f2a240 +md""" +## Defining the rules + +Now that we have our "game board", we can implement the rules. + +To start, we make two functions for states. A state of the game is just an array of stacks. + +We will define a function that checks if a state is okay according to the rules. To be legal, all the stacks should be in the correct order, so no larger disks on top of smaller disks. + +Another good thing to check: no disks should have appeared or disappeared since we started! +""" + +# ╔═║ 512fa6d2-a2bd-11ea-3dbe-b935b536967b +function islegal(stacks) + order_correct = all(issorted, stacks) + + # check if we use the same disk set that we started with + + disks_in_state = sort([disk for stack in stacks for disk in stack]) + disks_complete = disks_in_state == all_disks + + order_correct && disks_complete +end + +# ╔═║ c56a5858-a2bd-11ea-1d96-77eaf5e74925 +md""" +Another function for states: check if we are done! We can assume that we already checked if the state was legal. So we know that all the disks are there and they are ordered correctly. To check if we are finished, we just need to check if the last stack contains all the disks. +""" + +# ╔═║ d5cc41e8-a2bd-11ea-39c7-b7df8de6ae3e +function iscomplete(stacks) + last(stacks) == all_disks +end + +# ╔═║ 53374f0e-a2c0-11ea-0c91-97474780721e +md""" +Now the only rules left to implement are the rules for moving disks. + +We could implement this as another check on states, but it's easier to just write a legal `move` function. Your solution will specify moves for the `move` function, so this will be the only way that the stacks are actually manipulated. That way, we are sure that nothing fishy is happening. + +We will make our `move` function so that its input consists of a state of the game, and instructions for what to do. Its output will be the new state of the game. + +So what should those instructions look like? It may seem intuitive to give a _disk_ that should be moved, but that's more than we need. After all, we are only allowed to take the top disk from one stack, and move it to the top of another. So we only have to say which _stacks_ we are moving between. + +(Note that the `move` function is okay with moving a larger disk on top of a smaller disk. We already implemented that restriction in `islegal`.) +""" + +# ╔═║ e915394e-a2c0-11ea-0cd9-1df6fd3c7adf +function move(stacks, source::Int, target::Int) + # check if the from stack if not empty + if isempty(stacks[source]) + error("Error: attempted to move disk from empty stack") + end + + new_stacks = deepcopy(stacks) + + disk = popfirst!(new_stacks[source]) # take disk + pushfirst!(new_stacks[target], disk) # put on new stack + + return new_stacks +end + +# ╔═║ 87b2d164-a2c4-11ea-3095-916628943879 +md""" +## Solving the problem + +We have implemented the game pieces and the rules, so you can start working on your solution. + +To do this, you can fill in the `solve(stacks)` function. This function should give a solution for the given `stacks`, by moving all the disks from stack 1 to stack 3. + +As output, `solve` should give a recipe, that tells us what to do. This recipe should be an array of moves. Each moves is a `(source, target)` tuple, specifying from which stack to which stack you should move. + +For example, it might look like this: +""" + +# ╔═║ 29b410cc-a329-11ea-202a-795b31ce5ad5 +function wrong_solution(stacks)::Array{Tuple{Int,Int}} + return [(1, 2), (2, 3), (2, 1), (1, 3)] +end + +# ╔═║ ea24e778-a32e-11ea-3f11-dbe9d36b1011 +md""" +Now you can work on building an actual solution. Some tips: +* `solve(stacks)` can keep track of the board if you want, but it doesn't have to. +* The section below will actually run your moves, which is very useful for checking them. +* If you want, you can change `num_disks` to 1 or 2. That can be a good starting point. +""" + +# ╔═║ 010dbdbc-a2c5-11ea-34c3-837eae17416f +function solve(stacks)::Array{Tuple{Int,Int}} + + # what to do? + + return [] +end + +# ╔═║ 3eb3c4c0-a2c5-11ea-0bcc-c9b52094f660 +md""" +## Checking solutions + +This is where we can check a solution. We start with a function that takes our recipe and runs it. +""" + +# ╔═║ 4709db36-a327-11ea-13a3-bbfb18da84ce +function run_solution(solver::Function, start = starting_stacks) + moves = solver(deepcopy(start)) # apply the solver + + all_states = Array{Any,1}(undef, length(moves) + 1) + all_states[1] = starting_stacks + + for (i, m) in enumerate(moves) + try + all_states[i + 1] = move(all_states[i], m[1], m[2]) + catch + all_states[i + 1] = missing + end + end + + return all_states +end + +# ╔═║ 372824b4-a330-11ea-2f26-7b9a1ad018f1 +md""" +You can use this function to see what your solution does. + +If `run_solution` tries to make an impossible move, it will give `missing` from that point onwards. Look at what happens in the `wrong_solution` version and compare it to the moves in `wrong_solution`. +""" + +# ╔═║ d2227b40-a329-11ea-105c-b585d5fcf970 +run_solution(wrong_solution) + +# ╔═║ 9173b174-a327-11ea-3a69-9f7525f2e7b4 +run_solution(solve) + +# ╔═║ bb5088ec-a330-11ea-2c41-6b8b92724b3b +md""" +Now that we have way to run a recipe, we can check if its output is correct. We will check if all the intermediate states are legal and the final state is the finished puzzle. +""" + +# ╔═║ 10fb1c56-a2c5-11ea-2a06-0d8c36bfa138 +function check_solution(solver::Function, start = starting_stacks) + try + # run the solution + all_states = run_solution(solver, start) + + # check if each state is legal + all_legal = all(islegal, all_states) + + # check if the final state is is the completed puzzle + complete = (iscomplete ∘ last)(all_states) + + all_legal && complete + catch + # return false if we encountered an error + return false + end +end + +# ╔═║ 8ea7f944-a329-11ea-22cc-4dbd11ec0610 +check_solution(solve) + +# ╔═║ e54add0a-a330-11ea-2eeb-1d42f552ba38 +if check_solution(solve) + if num_disks >= 8 + md""" + Congratulations, your solution works! + """ + else + md""" + Your solution works for $(num_disks) disks. Change `num_disks` to see if it works for 8 or more. + """ + end +else + md""" + The `solve` function doesn't work yet. Keep working on it! + """ +end + +# ╔═║ Cell order: +# β•Ÿβ”€5b2ee40e-a2b8-11ea-0fef-c35fe6918860 +# β•Ÿβ”€95fbd0d2-a2b9-11ea-0682-fdf783251797 +# ╠═620d6834-a2ba-11ea-150a-2132bb54e4b3 +# β•Ÿβ”€35ada214-a32c-11ea-0da3-d5d494b28467 +# ╠═7243cc8e-a2ba-11ea-3f29-99356f0cdcf4 +# β•Ÿβ”€7e1ba2ac-a2ba-11ea-0134-2f61ed75be18 +# ╠═43781a52-a339-11ea-3803-e56e2d08aa83 +# β•Ÿβ”€b648ab70-a2ba-11ea-2dcc-55b630e44325 +# ╠═32f26f80-a2bb-11ea-0f2a-3fc631ada63d +# β•Ÿβ”€e347f1de-a2bb-11ea-06e7-87cca6f2a240 +# ╠═512fa6d2-a2bd-11ea-3dbe-b935b536967b +# β•Ÿβ”€c56a5858-a2bd-11ea-1d96-77eaf5e74925 +# ╠═d5cc41e8-a2bd-11ea-39c7-b7df8de6ae3e +# β•Ÿβ”€53374f0e-a2c0-11ea-0c91-97474780721e +# ╠═e915394e-a2c0-11ea-0cd9-1df6fd3c7adf +# β•Ÿβ”€87b2d164-a2c4-11ea-3095-916628943879 +# ╠═29b410cc-a329-11ea-202a-795b31ce5ad5 +# β•Ÿβ”€ea24e778-a32e-11ea-3f11-dbe9d36b1011 +# ╠═010dbdbc-a2c5-11ea-34c3-837eae17416f +# β•Ÿβ”€3eb3c4c0-a2c5-11ea-0bcc-c9b52094f660 +# ╠═4709db36-a327-11ea-13a3-bbfb18da84ce +# β•Ÿβ”€372824b4-a330-11ea-2f26-7b9a1ad018f1 +# ╠═d2227b40-a329-11ea-105c-b585d5fcf970 +# ╠═9173b174-a327-11ea-3a69-9f7525f2e7b4 +# β•Ÿβ”€bb5088ec-a330-11ea-2c41-6b8b92724b3b +# ╠═10fb1c56-a2c5-11ea-2a06-0d8c36bfa138 +# ╠═8ea7f944-a329-11ea-22cc-4dbd11ec0610 +# β•Ÿβ”€e54add0a-a330-11ea-2eeb-1d42f552ba38 diff --git a/My cool notebook.plutostate b/My cool notebook.plutostate new file mode 100644 index 0000000000000000000000000000000000000000..999d778cb9c39d6df58b7cba35dcd8926aeb356f GIT binary patch literal 39611 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 literal 0 HcmV?d00001 diff --git a/README.md b/README.md new file mode 100644 index 0000000..7448027 --- /dev/null +++ b/README.md @@ -0,0 +1,124 @@ +# static-export-template + +This is a demo repository containing two [Pluto](https://github.com/fonsp/Pluto.jl) notebooks that are **automatically converted to HTML** by a github action, and published to github pages! 🌝 + +See the github pages deployment of this repository: +https://juliapluto.github.io/static-export-template/ + +# How to use the template + +### πŸ‘‰ Step 1 + +Create a GitHub account, and click on ["Use this template"](https://github.com/JuliaPluto/static-export-template/generate). Choose a new name! + +screenshot of clicking the Use-this-template button + +You now have your own repository (take a look at the URL), containing a copy of the template files, including the file you are currently reading (`README.md`)! + +### πŸ‘‰ Step 2 + +Click on **Add files** (or **+**), and then **Upload files**. In the next page, upload your `.jl` notebook files. + +screenshot of clicking the Upload-files button + +Your notebooks will run on github every time that you update the files in this repository. To check the progress, go to the ["Actions" page](./actions) of your repository, you will find the _workflow_ for the last commit. + +screenshot of the actions page, showing a currently running workflow + +Wait for the Action to finish running your notebook. + +### πŸ‘‰ Step 3 + +Go to the ["Settings" page](./settings) of your repository, and go to [the "Pages" section](./settings/pages). For the "Source", choose `gh-pages`. Wait a minute for everything to initialize, and the URL to your web page will be shown! + +screenshot of the Pages settings, displaying the URL after the web page is ready + +Don't worry if it doesn't work immediately! It can take a while for the web page to be ready, even after your settings page says it's done. (Github pages says 20 minutes, but it can take even longer.) + +## Update notebook files + +To update an existing notebook file, simply repeat Step 2 above! (You can also use **Add files** `>` **Upload files** to _update_ upload a file that already exists on the repository.) + +Are you working on this website and planning to make many changes? Then it might be nice to use [GitHub Desktop](https://github.com/apps/desktop), a program on your computer that lets you synchronise your local files with github.com more easily, without having to upload to the website each time. If you are familiar with using the terminal, then you can also use the `git` command to publish changes. + +# Alternative setup: add web pages to an existing repository + +If you already have a github repository with some pluto notebooks in it, you may want to add a web view like the one for this repository. In that case, the steps are slightly different. In this case, I assume that you are familiar with adding files to a repository. If not, follow the steps above. + +### πŸ‘‰ Step 1 + +From this repository, download [ExportPluto.yaml](./.github/workflows/ExportPluto.yaml). + +Save the file in your own repository, in the same location: make a folder `.github` in the main directory, within that a folder `workflows`, and add the file there, with the name `ExportPluto.yaml`. Commit the new file to your repository. + +*Note: The yaml file states that github should use the github notebooks in the `main` branch or `master` branch of your repository. If you changed the name of your default branch, or you want to use a different branch, change `main` in [line 5](https://github.com/JuliaPluto/static-export-template/blob/main/.github/workflows/ExportPluto.yaml#L5) in the yaml file to the name of your favourite branch.* + +Your notebooks will run on github every time that you update the files in this repository. To check the progress, click on ["Actions"](./actions), you will find the _workflow_ for the last commit. + +Schermafbeelding 2021-01-06 om 00 45 25 + +### πŸ‘‰ Step 2 + +Go to the ["Settings" page](./settings) of your repository, and go to [the "Pages" section](./settings/pages). For the "Source", choose `gh-pages`. Wait a minute for everything to initialize, and the URL to your web page will be shown! + +Schermafbeelding 2021-01-06 om 00 43 00 + +Don't worry if it doesn't work immediately! It can take a while for the web page to be ready, even after your settings page says it's done. (Github pages says 20 minutes, but it can take even longer.) + + +# πŸ’‘Tips + +### Julia Packages + +Because Pluto has a [built-in package manager](https://github.com/fonsp/Pluto.jl/wiki/%F0%9F%8E%81-Package-management), packages will automatically work on the website! + +### Default files + +This files `README.md` and `My cool notebook.jl` are example files, and you can safely edit or delete them! After you have set up your repository, you can remove these setup instructions from the `README.md` file, and write a description of your project. + +### Not working? + +If your website is not automatically updating, then go to the **"Actions"** page of your repository, and take a look at the latest logs. If they show a ❌ symbol, then something went wrong. Click on it, and carefully read the error message. If you get stuck, be sure to ask for help: open an issue at https://github.com/JuliaPluto/static-export-template/issues/new and send us a link to your repository. + +### Homepage + +If you go to the (GitHub Pages) URL of repository, you will see a small index of the notebooks in this repository. You can customize this page, two options are: + +- Create your own `index.html` or `index.md` file, it will be used as the homepage. +- Rename one of your notebooks to `index.jl`, and it will be the default notebook! + +# License + +This *template* repository is [Unlicensed](https://unlicense.org), which means that you can do anything you want with it! When you use this template, you are also free to remove this license message. + +
+View license text +(This license applies to the template https://github.com/JuliaPluto/static-export-template, not necessarily to the user of the template.) + +``` +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to +``` +
diff --git a/index.html b/index.html new file mode 100644 index 0000000..b889d02 --- /dev/null +++ b/index.html @@ -0,0 +1,23 @@ + + + + + + + + + + + + +

Notebooks

+ + + + diff --git a/pluto_export.json b/pluto_export.json new file mode 100644 index 0000000..de9a2bc --- /dev/null +++ b/pluto_export.json @@ -0,0 +1 @@ +{"notebooks":{"My cool notebook.jl":{"id":"My cool notebook.jl","hash":"er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg","html_path":"My cool notebook.html","statefile_path":"My cool notebook.plutostate","notebookfile_path":"My cool notebook.jl","current_hash":"er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg","desired_hash":"er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg","frontmatter":{"title":"My cool notebook"}}},"pluto_version":"0.19.43","julia_version":"1.10.4","format_version":"1","title":null,"description":null,"collections":null,"binder_url":"https://mybinder.org/v2/gh/fonsp/pluto-on-binder/v0.19.43","slider_server_url":null} \ No newline at end of file diff --git a/pluto_state_cache/0_19_43er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg.plutostate b/pluto_state_cache/0_19_43er_4xRqJjwBRlEs4imA3z_G4vjfMQ67vAnEYMBFfBdg.plutostate new file mode 100644 index 0000000000000000000000000000000000000000..999d778cb9c39d6df58b7cba35dcd8926aeb356f GIT binary patch literal 39611 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 literal 0 HcmV?d00001