
A 220b spreadsheet app in HTML/JS - akras14
http://xem.github.io/sheet/
======
xem
Hello World,

I'm xem, author of this mini app, but standing on the shoulders of giants:

it's inspired by [http://aem1k.com/sheet/](http://aem1k.com/sheet/)

which was inspired by
[http://jsfiddle.net/ondras/hYfN3/](http://jsfiddle.net/ondras/hYfN3/)

Cheers to all the JS codegolf team who teached me this noble art and continue
to learn new tricks everyday with me!

You can find a list of all our mini apps here:
[https://gist.github.com/xem/206db44adbdd09bac424](https://gist.github.com/xem/206db44adbdd09bac424)

~~~
xem
NB: as mentioned in the "AMA" page, the whole team also helped a lot to reduce
the size of this app after I got into the game, it's not just golfed by me.

Cheers

------
zestyping
Initially, I wa puzzled by how the grid could be showing placeholders (the
grey "A1", "A2", etc.) when there's no placeholder attribute defined in the
source code. Then I discovered that the code running in the demo is not
actually the showcased 220-byte source code at all. The code is still
impressively small, but you should fix this — it's misleading as is.

~~~
aidos
I think that's probably just because it's been revised and the placeholders
were added after.

To be fair, it only adds an extra 18 chars, taking it up to 238-byte in size.

EDIT Here it is once you add the extra property:

    
    
        (o=b=>{for(j in a)for(i in a)y=a[i]+-~j,b?document.write([["<p>"][i]]+"<input onfocus=value=[o[id]] onblur=o[id]=value;o() id="+y+" placeholder="+y+">"):eval(y+(".value"+o[y]).replace(/[A-Z]\d/g," +$&.value"))})(a="ABCD")

~~~
jahnu
I'm more concerned with the use of the symbol `b` to denote bytes instead of
`B` :)

~~~
abainbridge
Yeah. A 220 bit spreadsheet would be impressive. Particularly the achievement
of the source length not being a whole number of bytes.

~~~
dheera
If you include start and stop bits it works out.

------
tombh
There's a nice comment from the author in an AMA about how this project
contained one of his best coding moments:
[https://github.com/xem/ama/issues/14#issuecomment-123275496](https://github.com/xem/ama/issues/14#issuecomment-123275496)

~~~
xem
Thanks for mentioning/enjoying it :)

------
warent
Judging by some of the comments one can regularly find on HN about the size of
apps, this may be considered a pinnacle internet technology to be standardized
mainstream

Tongue in cheek aside, very creative code. Thank you for sharing

~~~
debacle
There's intrinsic value in doing more with less, especially when it comes to
the malleability of code.

------
odensc
If we're using ES2015, why not save a byte?

    
    
      <script>(o=b=>{for(j in a)for(i in a)y=a[i]+-~j,b?document.write([["<p>"][i]]+`<input onfocus=value=[o[id]] onblur=o[id]=value;o() id=${y}>`):eval(y+(".value"+o[y]).replace(/[A-Z]\d/g," +$&.value"))})(a="ABCD")</script>

~~~
xem
of course! Thanks, I'm adding this enhancement on github!

~~~
corruptio
Here's another char off:

    
    
        (o=b=>{for(j in a)for(i in a)y=a[i]+j,b?document.write(`<${i*j?'input':'p'} onfocus=value=[o[id]] onblur=o[id]=value;o() id=${y}>`):eval(y+(".value"+o[y]).replace(/[A-Z]\d/g," +$&.value"))})(a="_ABCD")

~~~
xem
awesome! (oh noes, it gets rid of the +-~j trick! :D)

~~~
corruptio
[https://github.com/xem/sheet/pull/7](https://github.com/xem/sheet/pull/7) :D

------
murftown
If, like me, you're trying to figure out how this works, I've expanded it here
to make it more readable:

[https://pastebin.com/1c72BYK1](https://pastebin.com/1c72BYK1)

~~~
xem
Hey, thanks! Would you like me to write a commented version of that code? A
lot of black magic is still hidden in every line :)

~~~
sandGorgon
That would be awesome!

~~~
xem
Okay :) We're still removing a few bytes but when it's done I'll make a
commented version.

~~~
xem
Hey, the new version and its updated code are live!
[http://xem.github.io/sheet/](http://xem.github.io/sheet/)

------
HumanDrivenDev
Awesome Job. Looks like it was an iterative effort

[https://github.com/xem/ama/issues/14](https://github.com/xem/ama/issues/14)

------
darth_mastah
I hate to say that, but I just seem to have broken it. Here's how: I put 0.1
in A1, 0.2 in A2 and =A1+A2 in B1. Now B1 displays "=A1+A2" instead of the
result.

~~~
nkoren
Looks like any decimal place breaks it. Whole numbers only. But hey, whaddaya
want for 220 bytes?!?

~~~
Narishma
Weirdly enough, it works if the first number is an integer even if the second
isn't.

------
MosheZada
=1;alert("Hi")

~~~
blauditore
You don't need that, just `=alert('Hi')` is enough.

~~~
quickthrower2
=alert(A1) is more "useful" though.

The cool thing is you could code some extra features or an entire SPA inside
the spreadsheet. Better than XL.

------
speps
Fits in a tweet!

~~~
kreetx
.. and hence can be deploy on Twitter :)

------
spectaclepiece
Yesterday I was blown away by both tetris and snake golfed out to this degree
and now this. I feel like this is the modern reincarnation of obfuscated c.

Can somebody explain to me how: "a[i]+-~j" is the same as "a[i]+(j+1)" ?

~~~
Arnavion
>Can somebody explain to me how: "a[i]+-~j" is the same as "a[i]+(j+1)" ?

-(~j) = Twos complement of the ones complement of j

Twos complement = ones complement + 1

So twos complement of (ones complement of j) = ones complement of (ones
complement of j) + 1 = j + 1

~~~
hjalle
Am I missing something or isn't the "+" unnecessary? i.e. a[i]+-~j = a[i]-~j

~~~
xem
Sure, i explained it here earlier today:
[https://github.com/xem/sheet/issues/4](https://github.com/xem/sheet/issues/4)

------
52-6F-62
I was wondering and wondering why it wasn't working for me. Colons break the
script. I tried to write "TOTAL:" in a cell and none of the equations would
resolve. I wanted in on the fun and I didn't get it until I relented and
checked the console. :P

Pretty fun, though

------
leni536
Reminds me of an IOCCC entry.

[http://www0.us.ioccc.org/years.html#2000_jarijyrki](http://www0.us.ioccc.org/years.html#2000_jarijyrki)

------
thinbeige
Super impressive and I love code-golfing but the title is slighlty misleading
since the HTML part of the app, the cells, seem not to be included in the
220b. Still great.

~~~
xem
I think I see what you're meaning, but this code actually generates all the
cells (<input onfocus=... onblur=... id=...>). You can execute it in a JS
console and it'll work fine.

------
repler
And you didn't need a dozen node.js modules!! Amazing!!

------
aaln
This is awesome, are you planning to add more features like complex functions
that are minimally sized?

~~~
xem
Well, it's a 3 years old app, and we like it in this "minimal" form. We've
made a lot of other mini apps, tools and games though, you can find the link
on top of xem.github.io/sheet

------
fabxl
The bad part of eval: insert `;alert("test")` in a used cell by a formula.

------
amelius
Didn't know minimizers were _this_ good today ;)

Well done!

~~~
aldanor
Human minimizers are the best.

------
zichy
Reminds me of the HTML-only MTG life counter I made:

[http://zichy.de/public/counter.html](http://zichy.de/public/counter.html)
(437b)

------
icantrank
aint nobody wana write caps tho

------
sparaker
I learned the neat trick of -~

Thanks!

------
tcper
Great app!

------
ubersoldat2k7
Doesn't work with decimals.

~~~
HumanDrivenDev
You're right. I'm re-installing Excel and giving this a negative review on the
app store!

~~~
adtac
Please. It won't even pass Apple's strict standards. Everyone knows your app
has to be 50MB in size.

------
projectant
I'm concerned about the lack of type annotations. What about XSS prevention?
Maintainability? An API? How are people supposed to use this code in future
projects? Your variable names don't conform to Code Complete. This code smells
funny. Haven't you read clean code? And I don't think it's general enough.
What if people want to add columns, but preserve formulas? What made you think
you shouldn't use React for this? At least Vue, come on.

 _ah, if only we could all code just what we needed, instead of over-
engineering solutions to problems we wished we had_

~~~
smt88
XSS prevention, maintainability, code reuse, good variable names, good-
smelling code, readability, and using popular libraries are not "over-
engineering". They are 95% of what makes someone a good employee instead of a
shitty one.

With modern languages and tooling, you can have the benefits of most of these
things at little-to-no additional cost. If any of these require something
complicated and "over-engineered", I'd instead describe it as "bad
engineering".

~~~
geocar
No.

Rule one is making code that works correctly and quickly, in a short about of
time. This is 100% of the job.

If you think that "maintainability" and "readability" and "popular" libraries,
and "code reuse" and "good variable names" and code that "smells good" to you,
help someone do that, then great: That's an argument we can have just by
pointing to anyone who gets rule one without those things.

However.

There's another kind of person - and there's a lot of them - who thinks those
things are important _by themselves_ , and that putting those things ahead of
what I think are rule one is _ever_ acceptable.

The number of times I've heard some "experienced" programmer say with all
earnestness that we should ask for another 1/4 million dollars of tin so that
he can use his "clean" (but slow) algorithm makes _me_ wary of anyone who uses
those words you just used in seriousness.

 _That 's_ the person the parent comment is mocking.

~~~
projectant
> There's another kind of person - and there's a lot of them - who thinks
> those things are important by _themselves_ , and that putting those things
> ahead of what I think are rule one is ever acceptable.

I think you totally understood my humor. Thanks!

I saw a good blog in 2011 about how it is a waste of time to overbuild things
since mostly you are only ever going to use that code for the specific purpose
you are writing it, and you'll likely never need to generalize and you'll
probably chuck it out anyway and start from scratch.

Obviously there are a bunch of caveats to that and it's not always true that's
the case but I think it's a very useful counterpoint to the profession's
current best-practice obsession. If you keep it in mind, alongside all the
best practices, and you make a choice about approach in any given situation
based on appropriateness, rather than just robotically applying best practices
or giving into that common Engineer's temptation to overbuild, this
counterpoint can help you build quickly just what's needed, which is
effective, exactly like you said.

~~~
geocar
No problem. And I agree almost completely:

I _don 't_ think those caveats are _obvious_ to a junior (or otherwise
inexperienced) developer. Maybe some of them are obvious, but I don't think
anyone runs into these enough daily that programming by dogma actually helps.

And yet I _do_ see value if there are rules! Why should we think about having
"good variable names" or not if _most of the time_ "good variable names" don't
cause much harm, and most of the time not having them does?

It's just that I don't think this is a real problem; I don't believe anyone
actually makes _that_ choice.

I think if something doesn't have "good variable names" (as an example), then
it's possible someone was programming who couldn't think of good ones (to
which the rule wouldn't help anyway), and it's possible that these _are_ good
variable names, and that it's our opinion that is wrong (perhaps because we
don't yet understand what we're looking at). NB) I'm not saying both are
equally likely.

To put it another way, how can one recommend programming by brute force, "as
long as you've got "readability" and "popular" libraries, and "code reuse" and
"good variable names" and so on... What can we possibly add to that list that
will be even a _good_ substitute for a few decades of experience successfully
delivering software?

------
patanja
wow. thats what I was looking for

------
datpuz
Why

~~~
KGIII
If it is like many other such projects, just to say they did it.

Why climb Everest? Why play a video game on the hardest setting? Why learn to
write Hello World in the top 100 programming languages?

I can't say I wrote a spreadsheet in 220b. They can.

Maybe the question is, "Why not?" It is _Hacker_ News, after all.

------
mbertschler
Yet our browsers blow the page up to 100 or 1000 times that.

~~~
lifthrasiir
Probably you should first consider that our browsers contain a fully capable
programming system which this golfed program abuses as an expression
evaluator. :-) By comparison, this C program [1] (hints are at [2]) is a
stripped down spreadsheet program for X, and it only has an RPN evaluator
(probably to make a room for graphing features?).

[1]
[http://www.ioccc.org/2000/jarijyrki.c](http://www.ioccc.org/2000/jarijyrki.c)

[2]
[http://www.ioccc.org/2000/jarijyrki.hint](http://www.ioccc.org/2000/jarijyrki.hint)

~~~
vidarh
Hilariously Chrome offers to pass the c code through Google Translate (with
predictably useless results)

~~~
dannyw
Language detection works on language trigrams, and are trained on human
language. I bet punctuation is stripped during preprocessing. So it's not
surprising that code will have false positives.

~~~
vidarh
Not surprising, but still funny when applied to obfuscated code.

