Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Hangman in 3 lines of Python (danverbraganza.com)
58 points by nvader on Feb 7, 2016 | hide | past | favorite | 25 comments

I like the conclusion to this fun little exercise:

"""To write out all the code and make minor refactorings took around 30 minutes. It took me way longer than that to write this blog post detailing exactly how it works. If I wanted to draw a moral from an exercise I entered into purely for amusement, I would have to repeat the oft-quoted wisdom that code that is readable and understandable is going to save you much more time in the long run."""

I think characters are a better count of brevity. Consider the archetypical shell is 80 chars wide, so there exists a direct translation to 'real' lines of code.

See my 52 char fizz buzz in js: https://github.com/codeocelot/fizzbuzz_oneliner/

So, https://gist.github.com/danverbraganza/8447acc70ad08c92d4fd has an uglified version of the same code, shortening identifiers, removing extraneous whitespace, and (!) replacing bool(x) with not x to save 2 characters.

That's a good first stab at it, but it can definitely be smaller, esp. if you're willing to add more lines (which I'm not). Happy hacking!

Isn't the rest of the problem of fizzbuzz to then map your oneliner over the range 1 to 100, and print each result on a new line?

For the lulz, I turned your code into one line with lambdas: https://gist.github.com/betaveros/1e76b3ca53001c8edcef

It takes quite a few more characters, but it was fun.

Okay, I have an even better challenge for you guys.

Instead of minimizing it to least amount of lines/chars, you have to maximize the clarity of the code such that the rest of us laymen can understand it.


I tried to explain in my article how the code works. If I did my job well, you should be able to write the clear version yourself!

Okay I just read the full article - you've done your job really, really well! I look forward to reading more from you.

I like it! Looks like you replaced while with a recursion, and you had to import sys to get rid of a print statement. Bravo :)

A line is 80 characters. You can write arbitrarily long python programs without the newline character.

Here is the Python 2/3 compatible version:

  license, chosen_word, guesses, scaffold, man, guesses_left = 'https://opensource.org/licenses/MIT', ''.join(filter(str.isalpha, __import__('random').choice(open('/usr/share/dict/words').readlines()).upper())), set(), '|======\n|   |\n| {3} {0} {5}\n|  {2}{1}{4}\n|  {6} {7}\n|  {8} {9}\n|', list('OT-\\-//\\||'), 10
  while not all(letter in guesses for letter in chosen_word) and guesses_left: _, guesses_left = list(map(guesses.add, filter(str.isalpha, (__builtins__.raw_input if 'raw_input' in dir(__builtins__) else __builtins__.input)('%s(%s guesses left)\n%s\n%s:' % (','.join(sorted(guesses)), guesses_left, scaffold.format(*(man[:10-guesses_left] + [' '] * guesses_left)), ' '.join(letter if letter in guesses else '_' for letter in chosen_word))).upper()))), max((10 - len(guesses - set(chosen_word))), 0)
  print('You', ['lose!\n' + scaffold.format(*man), 'win!'][bool(guesses_left)], '\nWord was', chosen_word)

Fun, thanks! I'm going to try and best it in the J programming language. I am betting it will be 1 or 2, 80 character lines maximum. I'll post when done.

I while ago I wrote a simple Hangman in K, a cousin of J. 6 fairly simple SLoC, and there's still some room for golfing it:

    d: ("aardvark";"apple";"peanut";"etc");     / dictionary
    w: d[*1?#d];                                / pick a word
    c: {|/w=/:x};                               / correctly guessed
    b: {{$[x 0;x 1;"_"]}'+(c[x];w)};            / word with blanks
    p: {`0:" > ";*0:`};                         / prompt for a letter
    {~&/c[x]}{`0:b[x]; x,p[]}/"__"; `0:w,"\n";

Nice. And I am sure in K that you can put all of those lines in one big line, making it a one line solution vs. his 3 line solution. This is why I think the suggestion above about character count is more relevant in this type of 'golfing'. This will give me a start on my J program. However, he does some reaching out for words to the word list found in a local word list. I plan on doing the same, and possibly an internet connection more word lists.

EDIT: Realized words from usr/.. word list, not internet.

Sure, I could certainly compress it into a oneliner. I'm mainly focused on trying to make something simple with few moving parts. To that end I did a little more tinkering. Most pleasantly I was able to remove the conditional:

    w: *1?("aardvark";"apple";"peanut";"etc")  / pick a word
    c: {|/w=/:x}                               / correctly guessed
    b: {("_",'w)@'c x}                         / word with blanks
    p: {`0:" > ";*0:`}                         / prompt for a letter
    {~&/c x}{`0:b x; x,p[]}/"__"; `0:w,"\n";

I guessed a word I never heard of, "Phytolaccaceae"! Learnt a new word today. It's a group of flowering plants.

Thanks for doing this write up.

The functional style of the code reminded me of Haskell.

This is kinda cool.

My favorite Apple II periodical "Nibble Magazine" had a regular feature called One & Two Liners, neat little type-in BASIC programs. I learned a lot about programming by trying to decode the techniques. Thanks for sharing.

I am sure Electron magazine (or whatever the UK publication for the Acorn Electron was called) had a "ten liners" section. To be honest I never learned much from it, as I was too young to have a proper grasp of programming, but you could get some neat stuff happening by typing those ten lines.

> and is present on all UNIX and UNIX-like systems.

Except for Arch Linux, apparently. It requires the words package, which then links to the file corresponding to your locale.

Please stop writing programs and then abusing punctuation to get the "line count" smaller. That doesn't enlighten anyone.

Ctrl-C to win. ;)

This is a great example of "lines of code" being prioritized over the actual program itself. I suppose it's neat that he abused style to shrink a program to three lines, but it's not really meaningful.

I do think the program itself is pretty neat and never would have thought of using the word list for hangman.

Meh, many JavaScript apps are one line of code.

In this context, I don't really think this should be down-voted. It sums up why LoC-minimisation (unless, perhaps, we say give a strict character limit per line, 80 say) is fairly meaningless.

That said, I think this is a neat, small, working, fun implementation of Hangman, and using the system dictionary is a great idea.

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