[HN Gopher] A tiny self-remaking C program
       ___________________________________________________________________
        
       A tiny self-remaking C program
        
       Author : goranmoomin
       Score  : 102 points
       Date   : 2024-09-05 20:40 UTC (4 days ago)
        
 (HTM) web link (www.humprog.org)
 (TXT) w3m dump (www.humprog.org)
        
       | LorenDB wrote:
       | In D, this is a fully-supported used case. The DMD compiler
       | provides an executable called rdmd that can be used as the
       | shebang executable at the top of any D file, and the shebang
       | itself is also codified as valid D syntax.
        
         | Y_Y wrote:
         | Walter, is that you?
        
           | LorenDB wrote:
           | Nope, that would be
           | https://news.ycombinator.com/user?id=WalterBright
        
       | rwmj wrote:
       | This is completely off topic for the actual article, but I had a
       | bit of fun a while back working out how to make self-executing C
       | and OCaml scripts/programs.
       | 
       | It's an interesting exercise working out what is both a comment
       | in the target language but is also an executable shell script.
       | For C it's reasonably straightforward but for OCaml it's quite
       | subtle:
       | 
       | https://libguestfs.org/nbdkit-cc-plugin.3.html#C-plugin-as-a...
       | https://libguestfs.org/nbdkit-cc-plugin.3.html#Using-this-pl...
        
       | d99kris wrote:
       | I do something similar (but less portable and more verbose) in
       | C++ sometimes when I want to prototype something. My boilerplate
       | is something like this:                 #if 0       TMP=$(mktemp
       | -d);       c++ -std=c++11 -o ${TMP}/a.out ${0} && ${TMP}/a.out
       | ${@:1}; RV=${?};       rm -rf ${TMP};       exit ${RV};
       | #endif                #include <iostream>                int
       | main()       {         std::cout << "Hello, world!\n";       }
       | 
       | (the trailing semi-colons in the script part is to make my editor
       | indent the C++ code properly)
        
         | stefanos82 wrote:
         | HA! I was about to share my way, but you seem to have done more
         | or less what I have in C instead!
         | 
         | I was having fun with old Golang C code before they started
         | bootstrapping in Go and have found they were using interpunct
         | to separate function names, so I decided to play around with
         | shellscript-like C code to goof around:
         | #if 0             set -e; [ "$0" -nt "$0.bin" ] &&
         | gcc -O2 -Wall -Wextra -Wpedantic -std=c11 "$0" -o "$0.bin" -s
         | exec "$0.bin" "$@"             #endif                  #include
         | <stdio.h>                  void runtime*sysAlloc(void);
         | int main(void)             {                 unsigned age = 44;
         | printf("I am %u years old.\n", age);
         | runtime*sysAlloc();                 return 0;             }
         | void runtime*sysAlloc(void) {                 printf("Hello
         | from C code, %d!\n", 90);             }
        
           | hawski wrote:
           | That's exactly how I keep my quick test C or C++ programs. I
           | like how one can keep all the compilation options in the same
           | file this way.
        
         | seeknotfind wrote:
         | I love the opening #if 0. So many tricks from multilingual
         | quines, maybe they can actually be useful :)
        
         | ktm5j wrote:
         | I absolutely love this, super clever!
        
       | hippich wrote:
       | Somewhat adjacent- I recently discovered
       | https://github.com/rofl0r/rcb2 - it can take it quite far without
       | using make file. And similarly to OP - it allows to keep relevant
       | build info right in the source code. (Rcb2 is great at prototype
       | stage, but obviously at some point makefiles are worth spending
       | time on)
        
       | slippy wrote:
       | Didn't this exist conceptually anyway as the C shell (csh) where
       | the scripting language was "closer to" C?
       | 
       | https://en.wikipedia.org/wiki/C_shell
       | 
       | It seems like you are on your way to making the C++ shell.
        
         | 082349872349872 wrote:
         | Although the substantial functionality overlap between shells
         | and programming languages has caused many to attempt to combine
         | them, someone a while back (Yossi Kreinin?) had a reason that's
         | probably not what we want: a shell should be optimised for
         | quickly doing specific things, and programming languages should
         | be optimised for concisely doing general things. In particular,
         | this suggests that bare words in shells should default to being
         | literals, and variable substitution will take extra characters,
         | while bare words in programming languages should default to
         | being variables, and literal values will take extra characters.
        
       | trollied wrote:
       | You might all enjoy The International Obfuscated C Code Contest
       | https://www.ioccc.org/
       | 
       | https://www.ioccc.org/years.html
        
         | hoseja wrote:
         | Is the linked example a quine or something else? It's a quine,
         | right?
        
           | mananaysiempre wrote:
           | TFA? No, it's a C / Bourne shell polyglot where the shell
           | part compiles and runs the C part. I've also used this
           | technique when I needed to post self-contained examples (e.g.
           | to mailing lists), but I don't know if people actually
           | appreciated it.
        
         | lifthrasiir wrote:
         | IOCCC is almost irrelevant here, but one particular winning
         | entry _is_ relevant: 2000 /tomx [1]. Nowadays IOCCC is hosted
         | in GitHub Pages and it is hard to look at the verbatim source,
         | so the following is the entire source code:
         | #include <stdio.h>         #define  true                  true
         | /*:all                  CC=cc         PROG=tomx
         | false :             make -f $0 $1             exit 0
         | all: $(PROG)                  %:%.c             $(CC) $< -o $@
         | clean:             rm $(PROG)                  .PHONY: /* true
         | clean */             int main() {return!printf("Hello,
         | world\n");}
         | 
         | (All indentations here are actually tabs.)
         | 
         | [1] https://www.ioccc.org/2000/tomx.c
        
       | actionfromafar wrote:
       | "TCC can also be used to make C scripts, i.e. pieces of C source
       | that you run as a Perl or Python script. Compilation is so fast
       | that your script will be as fast as if it was an executable."
       | 
       | https://bellard.org/tcc/tcc-doc.html
        
         | fuhsnn wrote:
         | https://github.com/vnmakarov/mir is also great for this, the
         | c2m binary is an optimizing C11 JIT runner, even accept "*.c"
         | as input.
        
       | necovek wrote:
       | The way I see it, this is something a true built-from-source
       | system could do with their packaging system to enable no-effort
       | code changes for any system utility and true trust in you running
       | what you have source for (other than backdoored hardware).
       | 
       | Debian is pretty far off from this vision (if we also want
       | performant execution), but I wonder how do the Gentoo, ArchLinux
       | and Nix fare in this regard? Is this something that could be
       | viably built with their current packaging formats?
        
         | antoinealb wrote:
         | In arch at least it is reasonnably easy to download the source
         | for a package, modify it locally, build it and install it. Not
         | sure if that's what you are asking for?
        
           | Brian_K_White wrote:
           | I think no matter how easy a seperate source package is, it's
           | still a seperate thing, and not the same (not as good) as the
           | source being a built in part of the package.
           | 
           | freebsd/gentoo ports comes close where if you pretend that
           | pkg doesn't exist, or at least imagine a world where it's
           | only used for the absolute minimum necessary bootstrap, then
           | ports is probably the closest.
           | 
           | The source is still actually a seperate thing even then so I
           | think even ports with no pkg usage is still not really there.
           | 
           | Imagine the package itself being the source, the one and only
           | form of the package is the source. If it builds an
           | executable, that executable is actually just an automatically
           | generated throw-away artifact that you don't care about and
           | don't save or distribute. Maybe most normal users don't even
           | know where the compiled bin really lives, buried in some /var
           | tree or something, or maybe even in a kind of kernel level
           | db. All the user ever overtly interacts with is actually the
           | self-building source package. When you want to copy it or
           | delete it etc, that's the only thing you touch and everything
           | else is just automatically managed cache.
           | 
           | Then it's not merely easy to get the source and modify it,
           | it's simply THE package in the first place. If you can even
           | run a thing, then you automatically and indellibly also have
           | the full source to that thing. That would be pretty huge I
           | think.
           | 
           | It would probably result in slow installs and updates like
           | gentoo or freebsd ports, but only if we only imagine
           | switching to this today as the only variable changed, out of
           | context, without also imagining the last 40 years of tooling
           | and os development optimizing pain points to make whatever we
           | do most go faster, if we had decided to package apps this way
           | all along.
        
             | Brian_K_White wrote:
             | BTW I don't mean to imply that it's a good idea
             | necessarily, just that it is an interesting idea.
        
       | codethief wrote:
       | > the right conceptual basis for build systems: "build is the
       | first stage of execution"
       | 
       | I have long been thinking the same. And also: "Running tests is
       | the first stage of deploying in production" etc.
       | 
       | In other words: There is often a whole dependency graph between
       | various stages (install toolchain, install 3rd-party
       | dependencies, do code generation, compile, link/bundle, test,
       | run, ...) and each of those stages should ideally be a pure
       | function mapping inputs to outputs. In my experience, we often
       | don't do a good job making this graph explicit, nor do we usually
       | implement build steps as pure functions or think of build systems
       | as another piece of software which needs to be subject to the
       | same quality criteria that we apply to any other line of code we
       | write. As a result, developer experience ends up suffering.
       | 
       | Large JavaScript projects are particularly bad in this regard.
       | Dependencies, auto-generated code and build output live right
       | alongside source code, essentially making them global state from
       | the point of view of the build system. The package.json contains
       | dozens of "run" commands which more often than not are an arcane
       | mix of bash scripts invoking JS code. Even worse, those commands
       | typically need to be run in juuust the right order because they
       | all operate on the same global state. There is no notion of one
       | command depending on another. No effort put into isolating build
       | tasks from each other and making them pure. No caching of
       | intermediate results. Pipelines take ages even though they
       | wouldn't have to. Developers get confused because a coworker
       | introduced a new npm command yesterday which now needs be to run
       | before anything else. Ugghhh.
        
         | haberman wrote:
         | "Build is the first stage of execution" resonates with me too.
         | 
         | It follows that build systems should be written in terms of
         | real, encapsulated APIs that separate interface from
         | implementation.
         | 
         | Make-like build systems are like programming in assembly
         | language: there is no structure that isolates one build step
         | from another. Make offers no way of creating a "local variable"
         | -- an intermediate file that is hidden from any other build
         | step. The filesystem is like memory: as long as you can figure
         | out the filename (address) somehow, you can read and write
         | whatever you want.
         | 
         | Even if you can declare that one build step depends on another,
         | there's usually nothing that prevents a step from reading (or
         | even writing!) files from other build steps that it did not
         | declare a dependency on.
         | 
         | What you want is a build system that lets you define real APIs,
         | with truly private state. For example, cc_library() in Bazel
         | (cxx_library() in Buck2) lets you define a C++ library in terms
         | of the srcs/hdrs/etc, but you don't know how it will be
         | implemented. Other rules and targets can consume the outputs of
         | cc_library(), but _only_ the files that are publicly exposed in
         | the returned providers.
         | 
         | This model brings true encapsulation to build systems, which
         | makes it much more feasible to change implementation details
         | without breaking users.
        
           | necovek wrote:
           | It's basically impossible to program with no side effects in
           | any general purpose language, and providing a build system
           | language likely requires side-effect rich APIs too (to write
           | files, call external tools, etc).
           | 
           | Which is to say that you can perfectly well implement a
           | "clean" build setup with make, and provide an "interface" for
           | parts of the system to tie into. Files and directories are as
           | good an input/output interface as any other, and you can do
           | some simple safeguards with permissions on directories and
           | files.
           | 
           | To create a local, intermediate file with make, you create a
           | file in TMPDIR (eg with mktemp or tempfile) and remove it at
           | the end, setting the permissions the way you want for any
           | nested steps not to be able to access it.
        
         | kaba0 wrote:
         | I think one build tool that has the fundamental abstraction
         | well thought out is mill (written in Scala). Every task is just
         | an ordinary function written in plain Scala, outputting
         | something. Other functions can use this output by simply
         | calling that function. In many cases the output will be simply
         | a target directory, that is cached when none of the
         | dependencies have changed.
        
           | codethief wrote:
           | Too bad that mill is JVM-specific. :\
        
       | seanw265 wrote:
       | Based on the title, I was expecting this to be about quines [1].
       | 
       | If you aren't familiar, quines are programs which produce their
       | own source as their only output. They're quite interesting and
       | worth a dive if you haven't explored them before.
       | 
       | My personal favorites are the radiation-hardened variety, which
       | still produce the original pre-modified source even when any
       | single character is removed before the program is run.
       | 
       | [1]: https://en.wikipedia.org/wiki/Quine_(computing)
        
         | f1shy wrote:
         | You can chain 128 quines: https://github.com/mame/quine-relay
        
           | cmdlineluser wrote:
           | Their "keep ruby weird" quine is my favourite:
           | https://www.youtube.com/watch?v=IgF75PjxHHA                 %
           | q!.!;eval$s=%q{eval(%w{$s=("%q!.!;eval$s=%q{#$s}"+'.gsub(/#{2
           | 7.chr<<92<<91}[0-9]+m/,"")').lines;C=->x,y{Complex(x,y)};P=->
           | r,a{Complex.polar(r,a*Math::PI)};S=->((a,b),(c           ,d))
           | {[a-c,b-d]};D=->((a,b),(c,d)){(a*c.conj).real+b*d};R=->((a,b)
           | ,(c,d)){e,f=a.rect;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g]};a
           | =[];b=[];6.times{|i|a<<[P[1,i/3.0],1];b<<[P           [2,(i+0
           | .5)/3.0],0]};F=[a];6.times{|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],
           | b[i],b[j]]<<[b[i],[0,-2],b[j]]};J=->k,v{k=[k/500.0,0].min+2.5
           | ;(v/(k+0.5)+C[k,k/2])*48};r=0;T=->p{x,y=           p.rect;z
           | =O[y/2];x>=0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r};L=->p,q{s=(
           | p+q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q]};N=->((a,b)){s=(a.abs
           | 2+b*b)**0.5;[a/s,b/s]};E=->p,r,a{10           0.times  {|  i|
           | m=-P[r,1.5+i*a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J[0
           | ,p+m]];T[J[0,C[-c,d           ]]])}};A=27.chr;$><<"%q#{33.
           | chr+A}[H#{A}[2J";g="NZDD           CLYJXMX  ;Y  K(OQ'PP  YZA5
           | YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(ZTT[[X'X&Y%Y'ZZWW['Z&
           | $$[%(''  '(&[$(%($(  CRGZHZI)DIOZ;IVPZ(SP)[X*  DRZCGJJT<<
           | +XI,%%:S=[E==RE&LEXX-'.           RMY:(>>U(HU  /U[/[R   KOO0Y
           | $1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6H@ZISS
           | MS-XL  .LLVL?RR8O[O K9B,$%Y[3Y0X";41.upto(91 ){|c|g=g[2..
           | -1].gsub(c.chr){g[0,2]           }};G=g.spli  t(?();  Z=[C[7,
           | 10],C[13,76]];U=(0..48).map{[0]*169};O=[];srand(0);q=20;m=40;
           | x=0; Threa   d.new  {open("/dev/dsp","w"){  |f|50   0.dow
           | nto(0){|k|e=[];300.tim           es{|i|e<<((  x=(x+  k**1.9/9
           | e4+0.001)%8)>4?138:118)};f<<e.pack("C*")}}};I=(0..48).map{[0]
           | *169  };9.t  imes{ |y|76.times{|x|"1ea8yyjb v4x7d  zlzqj
           | sxd8dz4uqjfpb66bq7tu6l           wql6vdbds6f  6h60  xz2iglxie
           | 44ax1nygtie5t8xpgk2oq00uzj0ucoq2gqc70y9fplfzez0d682syamnhicpw
           | flot4  o9s".to_i(  36)[x+y*76]>0&&I[24+y][4  +x]=1}};-5
           | 00.upto(518){|k|k==1&&s           leep(1);k=   =q&
           | &(n=rand(11);q+=m;m-=2
           | ;spawn("espeak","-s",(60+m*2).to_s,"-ven+#{n<7?"m    #{n+
           | 1}":"f#{n-6}"}",["keep",k<    320|
           | |k>360?"ruby":"Austin","           weird"]*32  .c
           | hr));a=[-k,0].max**1.9/  1e4;v
           | ,z=d=N[[P[1,a/3],Math.sin(Math::PI*a)]];u=N[z==0 ?
           | [0,-1]:z>0?[v,z-1/z]:[-v,1/z-z]]      ;
           | n=R[d,u];O.replace(U.map{           |l|l+       [  ]});F.m
           | ap{    |f|a,  b,c=f;D
           | [R[S[b,a],S[c,a]],d]>0&&f.size.times{|i|a,b=f[  i],
           | f[i-1];L[J[k,C[D[n,a],D[u,a]]],J[k,C[D [n,
           | b],D[u,b]]]]}};k>0&&(b=M           ath.  sin(    [k,210]  .m
           | i  n*  Math  :   :PI
           | /15)/36;a=P[1,b*2];y=(30-[k,30].min)/10.0-2.8; E[C[
           | -1.2,y]*a.conj,(2-k/10%2)*0.06,-1];E[C [-1.
           | 2,y]*a.conj,0.45,-1];E[C           [-1.  2,y    +1.1]*a,  2.
           | 7  5,  b-0.   3];
           | E[C[-0.6,y+0.5]*a,1.85,b-0.25]);k>=90&&k<210&&2 .tim
           | es{|i|G[(k-90)*2+i].scan(/./){|c|Z[i]+ =[C[
           | 1,0],C[0,2],C[-1,0],C[0,           -2]][c     .  ord%4]}  ;i
           | =  k/  10%   7*8+92  ;U[Z[0].
           | imag/2][Z[0].real,2]=U[Z[1].imag/2][Z [1].
           | real,2]=[i,i];r=8;L[J[k,C[-1.2,-2.8]  *a.c
           | onj],Z[0]];L[J[k,C[1.2,-           2.8]*a],   Z[  1]];r=0}
           | ;      j=        0;k==400&&15.times{|y|65.times{|x|"7gtz
           | whx13 bfmrr9tsr8y0d007qlmygnh47axi9g9v609t cxjuv
           | la0k6y1r96drdisqmfpao411           n6e661l3  zykt   bqk
           | p4i33eecq7i2u  tfm
           | 2n0bhrviijbr51nwcuhm5ufx3t79a9whf01e3a8kzzepid45ro83 n9r07k
           | xxeht1pycrqo72".to_i(36)[x+y*65]>0 &&U[21
           | +y][14+x]=88}};s=O.map{|           l|i=0;j+  =1;l.m
           | ap{|n|(i+=1)>2&  &i<8
           | 3&&k>260&&k<420&&((k-j/6)%80>60||k>320&&k<400&&I[j- 1][i]>0
           | )&&n=88;a=("%c^_@****"%32)[n%8]; n>7?"%c
           | [%dm%s%c[0m"%[27,30+n/8,           a,27]:a}
           | *""};$><<A+"[H"+(0..47).ma  p{|i
           | |k+i>517?$s[i].chomp.gsub(32.chr){27.chr+"[44m"+$&+ 27.chr+"
           | [0m"}:s[i]}*10.chr;sleep(0.0  2)};puts
           | }*'');%q{%q.;eval$s=%qev           al(%w$s=
           | ("%q.;eval$s=%q$s"+'.gsub(/  27.
           | chr<<92<<91[0-9]+m/,"")').lines;C=->x,yComplex(x,y)  ;P=->r,a
           | Complex.polar(r,a*Math::PI  );S=->((
           | a,b),(c,d))[a-c,b-d];D=-           >((a,b),  (c,d)
           | )(a*c.conj).  re  al+b*d;R=->((a,b),(c   ,d))e,f=a.
           | rect;g,h=c.rect;[ C[f*d-b*h   ,b*g-e*d],e*h-f*g];a=[
           | ];b=[];6. times|i|a<<[P[1,i/3.0],1]           ;b<<[P[2,(i+0.5
           | )/3.0],   0];F=   [a    ];6   .t       imes|j|   F<<[a[i=
           | j-1],b[i],a[j]]<<[  a[j],b
           | [i],b[  j]]<<[b[i],[0,-2],b[j]];J           =->k,vk=[k/500.
           | 0,0].min+   2.5   ;(v/(k+0.   5)   +C[k,   k/2]   )*48;r
           | =0;T=->px,y=p.rect;z =O[   y /2];x>=0&&  y>=0  &&z&&z[x]& &
           | z[x ]|=(y%2>1?2:1)|r;L=->p,qs=           (p+q)/2;(p-q).a
           | bs<1?(T[s]   ;q   ):L[L[p,s   ],   q];N=-   >((a   ,b))
           | s=(a.abs2+b*b)**0.5;[a    /s, b/s];E=-  >p,r,a10  0.times|
           | i|m    =-P[r,1.5+i*a*0.02];c,d=(p+           m).rect;(c.abs-
           | d>2||d<-1)   &&   (T[J[0,p+   m]   ];T[J[   0,C[-   c,
           | d]]]);A=27.chr;$><<"%q   33.ch r+A[HA  [2J";g="NZDD  CLYJXM
           | X;YK(   OQ'PPYZA5YTZ7M(VOBBSYVXQQ[           SUZV(U:G[NVZ[ZS
           | &V[(YUU(ZT   T[   [X'X&Y%Y'   ZZ   WW[    'Z&$$[%(
           | '''(&[$(%($(CRGZHZI)D  IOZ;IVP  Z(SP  )[X*DRZCGJJT<<+X  I,%%
           | :S=[E==  RE&LEXX-'.RMY:(>>U(HU/U[           /[RKOO0Y$1F?LZ%
           | &M@(2NGU3   41R   U?+6S2(NV   YV          AFVR(8FFR
           | YRN4W'NHI@>(EUM6H@Z   ISSMS-XL. LLV  L?RR8O[OK9B,$%Y[3Y0X
           | ";4 1.upto(91   )|c|g=g[2..-1].gsub(c
           | .chr)g[0,2];G=g            .split   (?();Z=[C   [7   ,10],C
           | [13,76]]   ;U=(0..48).map[0]   *169;O=[];s r
           | and(0);q=20;m=40;x=0;Thr  e ad.newopen(   "/dev/dsp","w")|f|5
           | 00.downto(0)|k|   e=[];3   00.time   s|i|e<<(   (x   =(x+k**
           | 1.9/9e   4+0.001)%8)>4?13  8:118);f<<e.pa
           | ck("C*");I=(0..48).map[0]*16  9;9.times|y|76
           | .times|x|"1ea8yyj           bv4x7dzlzqjsxd8   dz4uqjf
           | pb66bq   7tu6lwql   6v   dbds6f6   h60xz   2iglxie44ax1nygti
           | e5t8xpgk2oq00uzj0           ucoq2gqc70y9fpl   fzez0d68
           | 2syam   nhicpwfl   ot   4o9s".t   o_i(   36)[x+y*76]>0&&I[24+
           | y][4+x]=1;-50 0.upto(518)|k|k==1&&sleep(1) ;k==q&&(n=ran
           | d(11);q+=m;m-=2;spa           wn("espeak","-s   ",(60+m*2
           | ).to   _s,"-ve   n+n   <7?"mn   +1":
           | "fn-6"",["keep",k<320||  k>360?"ruby"
           | :"Austin","weird"]*32.chr) );a=[-k,0].m
           | ax**1.9/1e4;v,z=d=N[[           P[1,a/3],Math.   sin(Math::P
           | I*a)   ]];u=   N[z=   =0?     [0,-
           | 1]:z>0?[v,z-1/z]:[-v,1/z-z  ]];n=R[d,u]
           | ;O.replace(U.map|l|l+[]) ;F.map|f|a,  b,c=f;D[R[S[b,a],S[c,a]
           | ],d]>0&&f.size   .times|i|a,   b=f[i]       ,f[i-1]
           | ;L[J[k,   C[D[n,a],D[u,a]]],J[k,C[D[n,  b],D[u,b]]
           | ]];k>0&&(b=Math.sin([k ,210].min*  Math::PI/15)/36;a=P[1,b*2
           | ];y=(30-[k,30]   .min)/10.0-2.8;E[C[-1.2,y]*a.conj,(2-k/10%2)
           | *0.06,-1];E[C[-1.2,y]*a.conj,0.45,-1]  ;E[C[-1.2
           | ,y+1.1]*a,2.75,b-0.3 ];E[C[-0.  6,y+0.5]*a,1.85,b-0.25]);k>
           | =90&&k<210&&2.times|i|G[(k-90)*2+i].scan(/.
           | /)|c|Z[i]+=[C[1,  0],C[0,2],C[-1,0],C[0,-2]][c.ord%4];
           | i=k/10%7 *8+92;U[Z[0].imag/ 2][Z[0].
           | real,2]=U[Z[1].imag/2][Z[1].r           eal,2]=[i,i];r=8;L[J[
           | k,C[-1.2,-2.8]*a.conj],Z[0]];L[J[k,C[1.2,-
           | 2.8]*a],Z[1]];r=0;j=0;k==400&&15.time  s|y|65.
           | times|x|"7gtzwhx 13bfmrr  9tsr8y0d007qlmygnh47axi9g9v609t
           | cxjuvla0k6y1r  96drdisqmf  pao4        11n6  e661  l
           | 3zyktb  qkp4i33eecq7i2utfm2n0bhrviijbr51nwcuhm  5ufx3t
           | 79a9whf01e3a8k zzepid  45ro83n9r07kxxeht1pycrqo72".to_i(
           | 36)[x+y*65]>0  &&U[  21+y]  [1  4+x]=8  8;s=  O.ma  p|l|i=
           | 0;j+=  1;l.map|n|(i+=1)>2&&i<83&&k>260&&k<420&  &((k-
           | j/6)%80>60|| k>320  &&k<400&&I[j-1][i]>0)&&n=88;a=("%c^
           | _@****"%32)[n  %8];  n>7?"  %c         [%dm%  s%c[  0m"%[27,
           | 30+n/8,a,27]:a*"";$><<A+"[H"+(0..47).map  |i|k +i>517?$s[
           | i].c  homp.gsub(32.chr)27.chr+"[44m"+$&+27.
           | chr+"[0m":s[i]  *10  .chr;  sl  eep(0.02  );  puts  *'');%
           | q%q.;e  val$   s=%qeval(%w$s=("%q.;eval$s=%q$s"+'.  gsu
           | b(/27.ch r<<  92<<91[0-9]+m/,"")').lines;C=->x,yCompl
           | ex(x,y);P=->r,aC   om      plex         .pola  r(r  ,a*Ma
           | th::PI);  S=-   >((a,b),(c,d))[a-c,b-d];D=->((a,b),(c  ,d
           | ))(a*c .c  onj).real+b*d;R=->((a,b),(c,d))e,f=a.rect
           | ;g,h=c.rect;[C[f*d-b*h,b*g-e*d],e*h-f*g];a=[]  ;b=  [];6.t
           | imes|i  |a<<[P[1,i/3.0],1];b<<[P[2,(i+0.5)/3.0],0];F=[  a
           | ];6. t  imes|j|F<<[a[i=j-1],b[i],a[j]]<<[a[j],b[i],
           | b[j]]<<[b[i],[0,-2],b[j]];J=->k,vk=[k/500.0,0].min+2.5;(v/(
           | k+0.5)+C[k,k/2])*48;r=0;T=->px,y=p.rect;z=O[y/2];   x>
           | =0&&y>=0&&z&&z[x]&&z[x]|=(y%2>1?2:1)|r;L=->p,           qs=(p
           | +q)/2;(p-q).abs<1?(T[s];q):L[L[p,s],q];N=->((a,b))s=(a.abs2+b
           | *b)**0.5;[a/s,b/s];E=->p,r,a100.times|i|m=-P[r,1.5+i
           | *a*0.02];c,d=(p+m).rect;(c.abs-d>2||d<-1)&&(T[J           [0,
           | p+m]];T[J[0,C[-c,d]]]);A=27.chr;$><<"%q33.chr+A[HA[2J";g="NZD
           | DCLYJXMX;YK(OQ'PPYZA5YTZ7M(VOBBSYVXQQ[SUZV(U:G[NVZ[ZS&V[(YUU(
           | ZTT[[X'X&Y%Y'ZZWW['Z&$$[%('''(&[$(%($(CRGZHZ           I)DIOZ
           | ;IVPZ(SP)[X*DRZCGJJT<<+XI,%%:S=[E==RE&LEXX-'.RMY:(>>U(HU/U[/[
           | RKOO0Y$1F?LZ%&M@(2NGU341RU?+6S2(NVYVAFVR(8FFRYRN4W'NHI@>(EUM6
           | H@Z}}.gsub(/#{27.chr<<92<<91}[0-9]+m/,"")
        
             | mjcohen wrote:
             | Looks ok to me - can't see anything wrong.
        
               | dorianmariefr wrote:
               | rubocop says no offenses :D
        
         | rkagerer wrote:
         | Wikipedia's specific radiation-hardened example looks like
         | goobly-gook to me, could you explain it in principle? Also does
         | it only compensate for removed characters, or also for "bit
         | flips" i.e. a changed character?
        
       | o11c wrote:
       | Sometimes it's useful to do something like:
       | /*usr/bin/env echo 'Hello World!' #*/
       | 
       | Even if, for some reason, there are multiple `usr` folders, the
       | use of `env` means it will eventually call the executable.
       | 
       | As for getting rid of the shebang - swapping the ! with a / means
       | that the line and character counts don't change so you get
       | meaningful error messages.
        
         | dorianmariefr wrote:
         | what kind of sorcery is this :D
        
       | dorianmariefr wrote:
       | "$0".bin: -c: line 0: unexpected EOF while looking for matching
       | `''         "$0".bin: -c: line 1: syntax error: unexpected end of
       | file
        
       ___________________________________________________________________
       (page generated 2024-09-09 23:01 UTC)