mousetail / Byte-Heist

Yet Another Golfing Site
https://byte-heist.com
GNU General Public License v3.0
8 stars 6 forks source link

Always count newlines as single bytes #34

Open MichalMarsalek opened 2 days ago

MichalMarsalek commented 2 days ago

When I submit using a browser newlines cost 2 bytes. I'm submitting my solutions through Postman with \n as newlines to avoid that but it would be cool to make that work in the browser.

Andriamanitra commented 5 hours ago

I think the problem here is that web browsers "normalize" line endings to "\r\n" when form data is URL encoded. As far as I can tell the only fix would be to do the HTTP POST request using JS. We can't really replace the newlines on server side because for some challenges the exact representation could be critical.

Injecting a script like the one below would get the byte count right, but it also prevents the page from reloading when submitting. I think that's actually a good thing – full reload is not really necessary, and it's really annoying to have the browser ask if you want to re-submit when refreshing the page after making a submission – but we would then need to handle updating the page on the client side. I'm not sure how we want to handle that, we could just handle it ourselves in plain JS, or use a front-end framework, or we could use something like HTMX to do partial updates. @mousetail thoughts?

let form = document.getElementsByTagName("form")[0]
form.addEventListener('submit', e => {
  e.preventDefault();
  const formData = new FormData(form);
  const data = Object.fromEntries(formData.entries());
  fetch(form.action, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data)
  })
})
mousetail commented 3 hours ago

Being able to submit without reloading the page is definitely desirable, I do want to make sure everything mostly works even with JS disabled though.

Updating the test cases seems to be the most difficult part since there are a lot of different variants and they might have their own interactions (I want to collapse non-failed test cases by default).

Never used HTMX but seems interesting.

MichalMarsalek commented 3 hours ago

We can't really replace the newlines on server side because for some challenges the exact representation could be critical.

Right, but can we not just update the serverside code that counts the bytes so that \r\n counts as a single byte? In the future there will be custom scoring functions but the default could be doing that.

Andriamanitra commented 2 hours ago

We can't really replace the newlines on server side because for some challenges the exact representation could be critical.

Right, but can we not just update the serverside code that counts the bytes so that \r\n counts as a single byte? In the future there will be custom scoring functions but the default could be doing that.

That's a good short term solution until the frontend is fleshed out enough to handle it properly. I first thought it could be abused by encoding information in the carriage returns, but I now realize it's just one "free" bit per newline which should never be an issue.

PR incoming soon..

MichalMarsalek commented 2 hours ago

Yes, you effectively have 257 states per byte instead of 256, which should be acceptable. You'd need solution longer than 1423 bytes to save a single byte and that's assuming a decoder which costs 0 bytes.