Add webwords code golf implementations in Python and C with functional tests
This commit is contained in:
parent
984da07493
commit
0249875fca
5 changed files with 161 additions and 0 deletions
13
Dockerfile.cgolf
Normal file
13
Dockerfile.cgolf
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
FROM alpine:latest
|
||||
|
||||
RUN apk --no-cache add gcc musl-dev curl-dev
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY golf.c .
|
||||
|
||||
RUN gcc -o webwords golf.c -lcurl
|
||||
|
||||
EXPOSE 31337
|
||||
|
||||
CMD ["./webwords"]
|
||||
12
Dockerfile.golf
Normal file
12
Dockerfile.golf
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
FROM alpine:latest
|
||||
|
||||
ENTRYPOINT ["/bin/webwords"]
|
||||
|
||||
EXPOSE 31337
|
||||
|
||||
COPY golf.py /bin/webwords
|
||||
|
||||
RUN chmod 0754 /bin/webwords
|
||||
|
||||
RUN apk --no-cache add python3 ca-certificates \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
webwords code golf: minimal HTTP servers in multiple languages
|
||||
################################################################
|
||||
|
||||
:author: Russell Ballestrini
|
||||
:slug: webwords-code-golf-minimal-implementation
|
||||
:date: 2025-10-10 16:00
|
||||
:tags: Code, Python, C, Golf
|
||||
:status: published
|
||||
|
||||
The full webwords implementations have proper error handling, logging, and structure. But what's the absolute minimum code needed to implement the core functionality?
|
||||
|
||||
.. contents::
|
||||
|
||||
the challenge
|
||||
=============
|
||||
|
||||
Implement webwords functionality in the fewest Python characters possible:
|
||||
|
||||
1. Accept HTTP requests on port 31337
|
||||
2. Parse ``keyword`` and ``target`` parameters
|
||||
3. Fetch target URI content
|
||||
4. Return ``true`` if keyword found, ``false`` otherwise
|
||||
|
||||
python solution
|
||||
===============
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import http.server as h,urllib.request as u,urllib.parse as p
|
||||
class S(h.BaseHTTPRequestHandler):
|
||||
def do_GET(s):q=dict(p.parse_qsl(p.urlparse(s.path).query));s.send_response(200);s.end_headers();s.wfile.write(str(q.get('keyword','')in u.urlopen(q.get('target','')).read().decode()).lower().encode())
|
||||
h.HTTPServer(('',31337),S).serve_forever()
|
||||
|
||||
**Character count: 314**
|
||||
|
||||
c solution
|
||||
==========
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <curl/curl.h>
|
||||
struct M{char*m;size_t s;};size_t w(void*c,size_t z,size_t n,void*u){size_t r=z*n;struct M*m=u;char*p=realloc(m->m,m->s+r+1);if(!p)return 0;m->m=p;memcpy(&m->m[m->s],c,r);m->s+=r;m->m[m->s]=0;return r;}int f(char*u,char**o){CURL*h;struct M c={malloc(1),0};curl_global_init(0);h=curl_easy_init();if(h){curl_easy_setopt(h,10002,u);curl_easy_setopt(h,20011,w);curl_easy_setopt(h,10001,&c);curl_easy_perform(h);curl_easy_cleanup(h);}curl_global_cleanup();*o=c.m;return 1;}void s(int k,char*r){char b[256];sprintf(b,"HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s",strlen(r),r);send(k,b,strlen(b),0);}int main(){int v=socket(2,1,0),c;struct sockaddr_in a={2,htons(31337),0};bind(v,(void*)&a,16);listen(v,10);while(1){c=accept(v,0,0);char b[4096],*q,*t,*d;recv(c,b,4095,0);q=strchr(b,'?');if(q&&(t=strstr(q,"target="))&&(q=strstr(q,"keyword="))){char*p;if((p=strchr(t+7,'&')))*(p)=0;else if((p=strchr(t+7,' ')))*(p)=0;if((p=strchr(q+8,'&')))*(p)=0;else if((p=strchr(q+8,' ')))*(p)=0;if(f(t+7,&d))s(c,strstr(d,q+8)?"true":"false");else s(c,"false");free(d);}else s(c,"false");close(c);}}
|
||||
|
||||
**Character count: 1,232**
|
||||
|
||||
how they work
|
||||
=============
|
||||
|
||||
**Python version (314 chars):**
|
||||
|
||||
1. Compressed imports with short aliases
|
||||
2. Minimal variable names (``s`` for self, ``q`` for query)
|
||||
3. Chained operations on single lines
|
||||
4. No error handling or validation
|
||||
5. Direct string conversion of boolean result
|
||||
|
||||
**C version (1,232 chars):**
|
||||
|
||||
1. Single-character variable names
|
||||
2. Removes all whitespace and comments
|
||||
3. Uses curl magic numbers instead of constants
|
||||
4. Minimal HTTP response formatting
|
||||
5. No error checking or memory leak prevention
|
||||
|
||||
docker implementation
|
||||
====================
|
||||
|
||||
.. code-block:: dockerfile
|
||||
|
||||
FROM alpine:latest
|
||||
ENTRYPOINT ["/bin/webwords"]
|
||||
EXPOSE 31337
|
||||
COPY golf.py /bin/webwords
|
||||
RUN chmod 0754 /bin/webwords
|
||||
RUN apk --no-cache add python3 ca-certificates && rm -rf /var/cache/apk/*
|
||||
|
||||
testing
|
||||
=======
|
||||
|
||||
**Python golf:**
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -f Dockerfile.golf -t webwords-golf .
|
||||
docker run -d -p 31337:31337 webwords-golf
|
||||
curl "http://localhost:31337/?keyword=potato&target=https://www.remarkbox.com"
|
||||
|
||||
**C golf:**
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -f Dockerfile.cgolf -t webwords-cgolf .
|
||||
docker run -d -p 31337:31337 webwords-cgolf
|
||||
curl "http://localhost:31337/?keyword=potato&target=https://www.remarkbox.com"
|
||||
|
||||
Both return ``true`` for potato and ``false`` for lemon, just like the full implementations.
|
||||
|
||||
.. image:: /uploads/2025/10/potato.jpg
|
||||
:alt: potato
|
||||
:align: center
|
||||
:width: 480px
|
||||
|
||||
comparison
|
||||
==========
|
||||
|
||||
- **Full webwords Python**: 50+ lines, proper structure, error handling
|
||||
- **Full webwords C**: 268 lines, proper structure, error handling
|
||||
- **Python golf**: 3 lines, 314 characters, minimal functionality
|
||||
- **C golf**: 1 line, 1,232 characters, minimal functionality
|
||||
- **Functionality**: Identical for valid requests
|
||||
|
||||
These golf versions prove webwords' core concept can be distilled to its absolute essence while remaining functional across different programming paradigms.
|
||||
|
||||
.. image:: /uploads/2025/10/unpotato.jpg
|
||||
:alt: unpotato
|
||||
:align: center
|
||||
:width: 480px
|
||||
8
golf.c
Normal file
8
golf.c
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <curl/curl.h>
|
||||
struct M{char*m;size_t s;};size_t w(void*c,size_t z,size_t n,void*u){size_t r=z*n;struct M*m=u;char*p=realloc(m->m,m->s+r+1);if(!p)return 0;m->m=p;memcpy(&m->m[m->s],c,r);m->s+=r;m->m[m->s]=0;return r;}int f(char*u,char**o){CURL*h;struct M c={malloc(1),0};curl_global_init(0);h=curl_easy_init();if(h){curl_easy_setopt(h,10002,u);curl_easy_setopt(h,20011,w);curl_easy_setopt(h,10001,&c);curl_easy_perform(h);curl_easy_cleanup(h);}curl_global_cleanup();*o=c.m;return 1;}void s(int k,char*r){char b[256];sprintf(b,"HTTP/1.1 200 OK\r\nContent-Length: %zu\r\n\r\n%s",strlen(r),r);send(k,b,strlen(b),0);}int main(){int v=socket(2,1,0),c;struct sockaddr_in a={2,htons(31337),0};bind(v,(void*)&a,16);listen(v,10);while(1){c=accept(v,0,0);char b[4096],*q,*t,*d;recv(c,b,4095,0);q=strchr(b,'?');if(q&&(t=strstr(q,"target="))&&(q=strstr(q,"keyword="))){char*p;if((p=strchr(t+7,'&')))*(p)=0;else if((p=strchr(t+7,' ')))*(p)=0;if((p=strchr(q+8,'&')))*(p)=0;else if((p=strchr(q+8,' ')))*(p)=0;if(f(t+7,&d))s(c,strstr(d,q+8)?"true":"false");else s(c,"false");free(d);}else s(c,"false");close(c);}}
|
||||
5
golf.py
Normal file
5
golf.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
import http.server as h,urllib.request as u,urllib.parse as p
|
||||
class S(h.BaseHTTPRequestHandler):
|
||||
def do_GET(s):q=dict(p.parse_qsl(p.urlparse(s.path).query));s.send_response(200);s.end_headers();s.wfile.write(str(q.get('keyword','')in u.urlopen(q.get('target','')).read().decode()).lower().encode())
|
||||
h.HTTPServer(('',31337),S).serve_forever()
|
||||
Loading…
Add table
Add a link
Reference in a new issue