[HN Gopher] Squeezing a Sokoban game into 10 lines of Haskell
___________________________________________________________________
Squeezing a Sokoban game into 10 lines of Haskell
Author : ufo
Score : 159 points
Date : 2023-02-22 23:54 UTC (1 days ago)
(HTM) web link (www.cole-k.com)
(TXT) w3m dump (www.cole-k.com)
| k2xl wrote:
| I am curious if there are languages that would be able to use the
| same techniques but beat the number of chars. Code golfers often
| use Ruby due to what the syntax allows.
|
| Also, a shameless plug, but if you are interested in a Sokoban
| like game, you might enjoy Pathology (formerly called Psychopath
| built in 2005). It is a 2d block pushing game where the goal is
| to go from Point A to Point B in shortest amount of steps.
| There's a level editor (thousands of levels) multiplayer, and
| active community (Many folks from the Sokoban online community
| play too)
|
| https://pathology.gg
| mabbo wrote:
| Having only started using ruby professionally recently, I have
| a vague idea of what you mean about "what the syntax allows".
| But I'm curious if you have specific details?
|
| Are there good references for how I can make my coworkers hate
| me?
| k2xl wrote:
| https://codegolf.stackexchange.com/questions/363/tips-for-
| go... Enjoy!
| cole-k wrote:
| At least on the Code Golf Stack Exchange, I see a lot of people
| using esolangs for golfing (two random examples: Jelly [1] and
| O5AB1E [2]). I expect that it could be a line or two shorter at
| least with a change of language. As I recall some of the
| golfing langs also have pretty sophisticated compression
| techniques for strings, although they might be optimized for
| dictionary words. Careful distinction: they are all optimizing
| for bytes used, not characters used.
|
| I don't want to neglect your shameless plug, but I struggle
| enough to find a solution to some of the puzzles I wrote (hence
| the undo), so finding the shortest path is a little daunting.
|
| [1] https://github.com/DennisMitchell/jellylanguage
|
| [2] https://github.com/Adriandmen/05AB1E
| sambalbadjak wrote:
| this post put a smile upon my face. a good example how someone
| becomes creative when limited
| kevinwang wrote:
| Amazing
| quchen wrote:
| I think another 4 chars can be removed by replacing `head` with
| `!!0`.
| cole-k wrote:
| You know I'm in too deep when the first thing I thought when
| reading this was "Oh no, not my Rick Rolll!" because now `g`
| wraps around to `}` instead of a variable.
|
| Initial readers noted that the code blocks were unreadable for
| those without dark mode extensions due to black-on-black text.
| Perhaps I should've kept them that way.
|
| Jokes aside, thank you!
| paradoja wrote:
| It'd be 2 characters no? `head x` vs `x!!0`.
| ginnungagap wrote:
| head is used twice in the program
| codetrotter wrote:
| > It stands at exactly 10 lines of 80 characters.
|
| Awesome! Sometimes people allow themselves to use unlimited
| length lines when shortening the number of lines. But this is
| good, 80 chars max per line is how it should be when talking
| about obfuscated code which has been crammed into a low number of
| lines.
| cole-k wrote:
| It would've certainly been nice to avoid playing Bin Packing,
| but alas this is just the rules of the game jam.
| BWStearns wrote:
| > "Hold on," you might stop me, "What about the other index mod 7
| that none of wasdxu map to?" Good question, just put the smallest
| variable you can get to type check there. All keys will do
| something, but we will only tell the players what 6 of them do.
|
| This made my morning.
| isoprophlex wrote:
| The title of the paragraph, "Think like a C Programmer", is
| absolutely fitting too
| noloblo wrote:
| Is there a haskell transpiler that converts well formed well
| formatted code to this obfuscation format?
| cole-k wrote:
| I don't personally know of one. It's not that I particularly
| intended this to be obfuscated, either, I just wanted it to be
| short. OK, I did rearrange it to spell out a rick roll but the
| impact to readability on that point was probably minimal. I
| guess what I'm saying is that the obfuscation is a side effect
| of the minification (side effects, in Haskell??).
|
| The best I know of are some tools people developed for the tiny
| game jam to help you minify your code, which you can find here
| https://github.com/haskell-game/tiny-games-hs#minifying.
| abecedarius wrote:
| > figure out a way to do upward movement that doesn't require
| annoying special casing. If you figure it out, don't tell me
| since it means I'll have to make more levels.
|
| Don't read this, then (from a 2048 game instead of Sokoban, but
| same principle):
| https://github.com/darius/cant/blob/master/examples/games/20...
|
| As long as I'm commenting, here are some links to other Sokobans
| I thought were fun (listed in the source code to mine). The sed
| one is nuts -- I had no idea it could do that:
| https://github.com/darius/cant/blob/master/examples/games/so...
| cole-k wrote:
| I couldn't resist and clicked your link, but thankfully it is
| early and I couldn't quite understand how to port it to the `f
| . moveRight . f` format.
|
| So really it is a shame that nothing can be done about golfing
| this further and I will be content knowing that... is what I'd
| like to say if not for the several [1] characters [2] I have at
| my disposal for a last level.
|
| Thank you for sharing though, I also was amazed by the sed one.
| And just to make it clear since sometimes these things don't
| communicate well over the internet, I'm being a little
| facetious here: if you actually want to spell it out for me I'm
| not going to be upset (but if you don't, I'm also not going to
| be upset :) ).
|
| [1] https://news.ycombinator.com/item?id=34924577
|
| [2]
| https://reddit.com/r/haskell/comments/11953ov/squeezing_a_so...
| gdprrrr wrote:
| I thought of group theory when I read this. The faf' pattern
| comes up quite a lot and is called conjugation. https://en.wi
| kipedia.org/wiki/Conjugacy_class#Conjugacy_as_g...
| mzs wrote:
| Your second link is the same as the first.
| abecedarius wrote:
| Thanks, oops, fixed.
| noloblo wrote:
| Is there a haskell compiler that does this obfuscation from well
| formatted well labeled code?
| noloblo wrote:
| Or a transpiler
| theK wrote:
| So this is a fun read and probably also lots of fun to write.
|
| One fact that does not get enough mention though is that,
| regardless of the code golfing results, Haskell programs have the
| habit of being exceptionally concise even if you don't try to
| write short code.
| cole-k wrote:
| Part of it (but certainly not all of it) is because of all the
| funny instances hanging around. I'm able to exploit the
| Semigroup b => (a -> Semigroup b) instance in a WIP version for
| example. And using (<*>) on the Applicative instance of (-> r)
| is a favorite of mine.
| chowells wrote:
| ... To be super ridiculously over-the-top pedantic... That
| Applicative instance is on ((->) r). If you could actually do
| type-level sections, that'd be (r ->). But type-level
| sections are the same as type-level lambdas, and they would
| break a lot about Haskell's type system so they don't exist.
|
| All of which is to say, great work.
| tromp wrote:
| > As I was writing up this post, I noticed that almost every
| single line began with a variable. At a first glance, "never
| gonna" wouldn't work because variables need to be unique.
|
| This is less of a challenge for IOCCC entries like my [1] where I
| wanted the variables & constants to spell out the language it
| interprets: Int L[A],m,b,*D=A,
| *c,*a=L,C,*U=L,u;s
|
| as C doesn't care about capitalization, whereas Haskell reserves
| upper case for types and constructors.
|
| [1] https://www.ioccc.org/2012/tromp/tromp.c
___________________________________________________________________
(page generated 2023-02-24 23:01 UTC)