Hacker Newsnew | past | comments | ask | show | jobs | submit | susam's commentslogin

A minimal implementation in about 30 lines of Python inspired by this: https://github.com/susam/mvs

See also a recent discussion about it here: https://news.ycombinator.com/item?id=46257607


With Perl, once you install cpanminus:

      cpanm -n local::lib

      cpanm -n Hailo

      ~/perl5/bin/hailo -E Scored -t corpus.txt -b brain.brn
      
      ~/perl5/bin/hailo -E Scored -b brain.brn

+1 Whenever I create a favicon.png, I always run it through ImageOptim and I consistently get an optimised PNG that is about 30% to 40% smaller than the original.

Slightly off-topic but related.

See also: The Ultimate Oldschool PC Font Pack from VileR at <https://int10h.org/oldschool-pc-fonts/fontlist/>.

I came across this website when I was looking for IBM PC OEM fonts for a little HTML + Canvas-based invaders-like game I was developing a few years ago. It is impressive how much effort VileR has poured into recovering each OEM font and their countless variants, from a wide range of ROMs. The site not only archives them all with incredible attention to detail, but also offers live previews, aspect ratio correction and other thoughtful features that make exploring it a joy. I've spent numerous hours there comparing different OEM fonts and hunting down the best ones to use in my own work!


I've been using the Px437 Verite 9x6 font from this pack as my main terminal font for years now, and couldn't be happier with it. VileR's font pack is great for both retro use cases, like displaying ANSI art, and for modern ones.

Quicklisp is great and I recommend using it along with a brief introduction in both my Common Lisp setup guides for Vim and Emacs:

https://susam.net/lisp-in-vim.html

https://github.com/susam/emacs4cl

However, for my personal projects, I usually just download the package versions I need from GitHub with curl within a simple while loop:

https://github.com/susam/susam.net/blob/0.4.0/Makefile#L83-L...

https://github.com/susam/susam.net/blob/0.4.0/meta/cldeps/fo...

Then I point ASDF to the download directory with CL_SOURCE_REGISTRY and load it in my Lisp program using good old ASDF:LOAD-SYSTEM:

https://github.com/susam/susam.net/blob/0.4.0/etc/form.servi...

https://github.com/susam/susam.net/blob/0.4.0/form.lisp#L5

The last four links I have shared above all get automated by a simple QL:QUICKLOAD call if we're using Quicklisp, and that's one of the reasons Quicklisp has become almost a de facto standard in the community.


I'd suggest you submodule in dependencies rather than curl. Supply chain attacks and version incompatibilities both happen and suck

> I'd suggest you submodule in dependencies rather than curl. Supply chain attacks and version incompatibilities both happen and suck

What kind of supply chain attack or version incompatibility would affect

  curl -sSL https://github.com/edicl/hunchentoot/archive/v1.3.1.tar.gz | tar -xz
but not

  git submodule add https://github.com/edicl/hunchentoot.git && cd hunchentoot/ && git checkout v1.3.1

?

Submodules are pinned by commit hash. It prevents an attacker from replacing a release.

That is very handy to know.

You can achieve roughly the same by writing down the SHA256 hash the first time you download and then comparing when you download the next time.

But, yeah, while I do not like submodules, for vendoring stuff it seems a reasonable approach. There's also https://github.com/fosskers/vend if you lean that way.


Indeed! It's said that no talk should be longer than a microcentury.

https://www.ams.org/notices/199701/comm-rota.pdf

https://susam.net/microcentury.html


Nice one! I would've said half a microcentury would be the perfect limit for most school lectures, but for an engaging talk a full microcentury would be acceptable :-)

A few years ago, I wrote an esoteric, minimalistic turtle graphics language called CFRS[]: <https://susam.net/cfrs.html>.

This was an exercise in making a turtle graphics language that is as minimal as possible. It is closer to Brainfsck than JavaScript and it is not Turing complete, by design.

To see some demos, go to <https://susam.github.io/cfrs/demo.html>.


Interesting project. I guess you know Forth as well? :)

Yes, I do! <https://github.com/susam/may4>

I have a Forth-inspired, esoteric, stack-based, postfix, colouring language too: <https://susam.net/fxyt.html>

Demos: <https://susam.github.io/fxyt/demo.html>


computer goes [[[[BRRRRRRRRRR]]]]

A shorter solution is possible with an ordered list (<ol>) if we're willing to ignore the untidy output:

  li:nth-child(3n), li:nth-child(5n) { list-style: none }
  li:nth-child(3n)::before { content: "Fizz" }
  li:nth-child(5n)::after { content: "Buzz" }
Example: https://susam.net/code/web/css-fizz-buzz-ol.html

  $ curl -sS https://susam.net/code/web/css-fizz-buzz-ol.html | sed -n '/none/,/after/p' |  tr -d '[:space:]' 
  li:nth-child(3n),li:nth-child(5n){list-style:none}li:nth-child(3n)::before{content:"Fizz"}li:nth-child(5n)::after{content:"Buzz"}
  $ curl -sS https://susam.net/code/web/css-fizz-buzz-ol.html | sed -n '/none/,/after/p' |  tr -d '[:space:]' | wc -c
  129
But I don't quite like how misaligned the numbers and the words look in this version. Correcting that would call for extra code that would cancel out the characters saved.


    list-style-position: inside;


Yes! However, like I mentioned in my previous comment, corrections like this cancel out the number of bytes saved with the <ol>-based solution.

I mean, the solution in the original post is 152 characters long.

The <ol> based solution is 129 characters long. Shorter but uglier.

If we add your correction, we get neater output, which is nice, but it comes at the cost of 30 additional characters in the minified code thereby making the solution 159 characters long.

  li { list-style-position: inside }
  li:nth-child(3n), li:nth-child(5n) { list-style: none }
  li:nth-child(3n)::before { content: "Fizz" }
  li:nth-child(5n)::after { content: "Buzz" }


I learnt this subject from the book Galois Theory, 5th ed. by Ian Stewart. Quoting from page 177:

Theorem 15.10. The polynomial t⁵ - 6t + 3 over ℚ is not soluble by radicals.

As you can see, this theorem occurs in Chapter 15. So it takes fourteen chapters before we reach here. It takes a fair amount of groundwork to reach the point where the insolubility of a specific quintic feels natural rather than mysterious.

To achieve this result, the book takes us through a fascinating journey involving field extensions, field homomorphisms, impossibility proofs for ruler and compass constructions, the Galois correspondence, etc. For me, the impossibility proofs were the most interesting sections of the book. Before reading the book, I had no idea how one could even formalise questions about what is achievable with a ruler and compass, let alone prove impossibility. Chapter 7 explains this beautifully and the algebraic framework that makes those proofs possible is very elegant.

By the time we reach the section about the insoluble quintic, two key results have been established:

Corollary 14.8. The symmetric group S_n is not soluble for n ≥ 5.

Theorem 15.8. Let f be a polynomial over a subfield K of ℂ. If f is soluble by radicals, then the Galois group of f over K is soluble.

The final step is then quite neat. We show that the Galois group of f = t⁵ - 6t + 3 over ℚ is S₅. Corollary 14.8 tells us S₅ is not soluble. By the contrapositive of Theorem 15.8, f is not soluble by radicals.

Obviously whatever I've written here compresses a huge volume of work into a short comment, so it cannot capture how fascinating this subject is and how all the pieces fit together. But I'll say that the book is absolutely wonderful and I would highly recommend it to anyone interested in the subject. The table of contents is available here if you want to take a look: https://books.google.co.uk/books?id=OjZ9EAAAQBAJ&pg=PT4

Two small warnings: The book contains a fair number of errors which can be confusing at times, though there are plenty of errata and clarifications available online. And unless you already have sufficient background in field homomorphisms and field extensions, it can take several months of your life before you reach the proof of the insoluble quintic.


The OP proof is the Abel-Ruffini theorem which requires far less abstract algebra.

That is precisely how I began writing this post. I thought I'd demonstrate how to apply the discrete Fourier transform (DFT) but to do so for each of the 15 coefficients turned out to be a lot of tedious work. That's when I began noticing shortcuts for calculating each coefficient c_k based on the divisibility properties of k. One shortcut led to another and this post is the end result. It turns out it was far less tedious (and more interesting as well) to use the shortcuts than to perform a full-blown DFT calculation for each coefficient.

Of course, we could calculate the DFT using a tool, and from there work out the coefficients for the cosine terms. For example, we could get the coefficients for the exponential form like this:

https://www.wolframalpha.com/input?i=Fourier%5B%7B3%2C+0%2C+...

And then convert them to the coefficients for the cosine form like this:

https://www.wolframalpha.com/input?i=%7B11%2F15%2C+2*0%2C+2*...

That's certainly one way to avoid the tedious work but I decided to use the shortcuts as the basis for my post because I found this approach more interesting. The straightforward DFT method is perfectly valid as well and it would make an interesting post by itself.


Update: I went ahead and added the method of obtaining the coefficients using DFT anyway. Like I mentioned above, this approach is quite tedious by hand, so I only work out the first few coefficients explicitly. In practice, these are almost always computed using numerical software. But for some people it may still be interesting to see a direct calculation rather than relying on shortcuts.

Here is the direct link to the new section on DFT: https://susam.net/fizz-buzz-with-cosines.html#dft


This is a joy.


> There are several mentions of "closed-form expression" without precisely defining what that means, only "finite combinations of basic operations".

There is no universal definition of 'closed-form expression'. But there are some basic operations and functions that are broadly accepted, and they are spelled out directly after the 'finite combinations' phrase you quoted from the post. Quoting the remainder of that sentence here:

'[...] finite combinations of basic operations such as addition, subtraction, multiplication, division, integer exponents and roots with integer index as well as functions such as exponentials, logarithms and trigonometric functions.'



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: