9
\$\begingroup\$

Objective Requirements

  • A main 'parent' file and a 'child' file.
  • The parent file creates a new child file that contains code that must execute after creation.
  • The child file that is created must delete the existing sibling file. It wants all the attention, afterall.
  • No matter how many times the parent file is executed, a new child file must be created and executed.
  • Every time a child file is executed, it must delete it's sibling.
  • Since no two siblings are ever truly identical, each child file must also be unique.
  • No matter how many child files are created, their names and file contents MUST be unique.
  • Only the parent file may explicitly know the child names. (Parent may tell the new child it's older sibling's name.)
  • Child files may not simply be renamed.

Things to consider

  • The parent may be modified by the child (children give us all grey hairs anyways, right?), but it's methods may not change.
  • The child has to kill its sibling. It cannot force its sibling to commit suicide.
  • No human interaction may occur beyond the execution of the parent (such as manual input).

Winning Requirements

  • Only the parent file character length / byte size will be measured.
  • Fewest bytes/shortest length wins.

Inspired by this challenge.

\$\endgroup\$
3
  • \$\begingroup\$ For clarification: may the parent modify itself, or are only the children allowed to modify the parent? \$\endgroup\$
    – primo
    Apr 4, 2013 at 18:16
  • \$\begingroup\$ Hmm. I think it will be alright for the parent to modify itself however it sees fit, but the child should not be allowed to change the parent methods. Does anyone have different thoughts on this? \$\endgroup\$ Apr 4, 2013 at 18:21
  • 1
    \$\begingroup\$ I've seen that before! Glad you could do something better than I did. +1! \$\endgroup\$
    – SteeveDroz
    Apr 5, 2013 at 12:21

7 Answers 7

3
\$\begingroup\$

Perl, 4 characters

Parent file (parent.pl):

do a

Initial child file (named a):

if ($0 =~ /parent\.pl$/)
{
    $ARGV[0]=(-f 'a' ? 'a' : <a*>);
    open B,'>'.($a='a'.time);
    print B <>,'a';
    exec "perl $a";
}
else
{
    open PARENT,'>parent.pl';
    print PARENT "do <a*>";
    close PARENT;

    while (<a*>)
    {
        if ($0 !~ /\Q$_\E$/)
        {
            unlink $_;
        }   
    }
}
#

Nowhere does the question state that a child file does not exist at the beginning. Further, it might even be interpreted as requiring an initial child file (it states that the child must delete its sibling, never mentioning a special case when a sibling does not exist).

I assert that this fulfills all the requirements stated in the question.

One might object that "the child creates its own sibling"; however, this is not true. The parent is the program which is being executed when the child is created. It just gets some code stored in another file and runs that code.

This child not only kills its sibling; it also kills anyone else who is unlucky enough to have a name starting with a (consider that collateral damage). This is an artifact of my earlier attempts at the problem. Obviously, any method of killing the sibling could be implemented without changing the score.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1 for thinking inside the box ^^. naming the sibling '_' or '%' could lead to far less collateral damage in a typical system. \$\endgroup\$ Apr 12, 2013 at 7:34
2
\$\begingroup\$

Lua, 80

n=io.open(0,'a'):write' ':seek()os.execute('echo rm '..n-1 ..' >'..n..'&sh '..n)

Parent file (filename 0) appends one character to its own body on each run and treats its new length as name of next child file (so, first child file will be given name 82 and will contain rm 81).
Lua 5.2 required.
Usage: lua 0.

\$\endgroup\$
2
  • \$\begingroup\$ Does the code of the child change as well as it's name? \$\endgroup\$ Apr 5, 2013 at 2:32
  • \$\begingroup\$ @jdstankosky - Yes. My answer was updated to clarify this. \$\endgroup\$ Apr 5, 2013 at 7:41
2
\$\begingroup\$

Perl 68 bytes

utime$a+open(C,'>',$a=(stat$0)[8]),print(C"unlink~-$a"),$0;`perl $a`

Works in a similar fashion to the PHP script below, by updating its own access time to keep track of children names. As with all solutions below, the parent script may be named anything you choose.


PHP 87 bytes

It seems that since our parent is reproducing asexually, all it really needs to do is touch itself.

<?touch($f=__FILE__,1+$t=filemtime($f));fputs(fopen($t,w),"<?@unlink($t-1);");`php $t`;

PHP 110 (104) bytes

<?$f=$g=AAAAAAAA;fputs(fopen(++$f,w),"<?@unlink($g);fputs(fopen('".__FILE__."',c),'<?\$f=\$g=$f');");`php $f`;

If the parent is allowed to self-modify, a few bytes can be saved, mainly on quotation marks:

<?$f=$g=AAAAAAAA;fputs(fopen(++$f,w),"<?@unlink($g);");fputs(fopen(__FILE__,c),"<?\$f=\$g=$f");`php $f`;

Admittedly, the parent isn't very creative when naming its children. The first will be called AAAAAAAB, the second AAAAAAAC and so forth. The created child will delete its previous sibling, and modify its parent, making it somewhat 'older'.

The first child will contain the following (if the parent script is named parent.php):

<?@unlink(AAAAAAAA);fputs(fopen('parent.php',c),'<?$f=$g=AAAAAAAB');
\$\endgroup\$
7
  • \$\begingroup\$ Cut mine in more than half! hurk! /me dies. \$\endgroup\$ Apr 4, 2013 at 18:10
  • \$\begingroup\$ Correct me if I'm wrong, but can't you also start with $f=$g=0 ? The parent would grow in size, surely, but wouldn't AAAAAAAA eventually roll over as well? \$\endgroup\$ Apr 4, 2013 at 20:06
  • \$\begingroup\$ @jdstankosky If the file started with 0, after just the tenth iteration the semicolon would be overwritten, resulting in syntax error. Yes, AAAAAAAA will eventually roll over as well... after 200795254400 iterations. Executing the script one thousand times per second would take over six years to error. \$\endgroup\$
    – primo
    Apr 5, 2013 at 1:38
  • \$\begingroup\$ Solutions based on file time seem to require inserting wait 1 sec operation in parent script to be sure all file times are different. \$\endgroup\$ Apr 5, 2013 at 7:49
  • \$\begingroup\$ @EgorSkriptunoff This is why the parent script manually sets its own file time - to overcome this limitation. \$\endgroup\$
    – primo
    Apr 5, 2013 at 8:14
0
\$\begingroup\$

python 2.7 - 110 Characters

c=0
import os
i=`c+1`
o(__file__,'r+').write('c='+i)
o('c'+i,'w').write('rm c'+`c`)
os.system('sh c'+i)

The above code would throw an error that can be ignored, the first time it is run.

A slightly longer modified version (128 characters) won;t complain the first time its run

c=0
import os
i=`c+1`
o(__file__,'r+').write('c='+i)
o('c'+i,'w').write('rm c'+`c`)
os.system('sh c'+i+'>/dev/null 2>&1')
\$\endgroup\$
2
  • \$\begingroup\$ @primo: Yes, I misunderstood the problem. I corrected it, and now stands the same size as yours :-) \$\endgroup\$
    – Abhijit
    Apr 4, 2013 at 18:22
  • \$\begingroup\$ After running 10 times, this version will error. \$\endgroup\$
    – primo
    Apr 4, 2013 at 18:26
0
\$\begingroup\$

PHP 279

<?php $s="00000000.php";$c="11111111.php";$n=fopen($c,"w");fwrite($n,"<?php \$h=fopen('p.php','r');\$d=fread(\$h,328);\$h=fopen('p.php','w');fwrite(\$h,'<?php \$s=\"'.basename(__FILE__).'\";\$c=\"'.hash('crc32',microtime(true)).'.php\";'.substr(\$d,42));unlink('$s');");`php $c`;

It uses crc32 as a hash function, so it's not ENTIRELY 100% unique... I'll try to think of another solution. This one does cause a warning on the first execution, but works as expected every time there-after.

Here is a semi-ungolfed readable version (changed substr() start point so it would work ungolfed as a bit of copy+pasta):

<?php
$s="02204f88.php";
$c="4b2e0cfb.php";
$n = fopen($c, "w");
fwrite($n,"<?php
\$h=fopen('p.php','r');
\$d=fread(\$h,328);
\$h=fopen('p.php','w');
fwrite(\$h,'<?php
\$s=\"'.basename(__FILE__).'\";
\$c=\"'.hash('crc32',microtime(true)).'.php\";'.substr(\$d,43));
unlink('$s');
");
exec("php $c");
\$\endgroup\$
0
\$\begingroup\$

python2 - 154

Needs a subdirectory called c to be at the same directory. Generates sh. I took the liberty of calling the file contents unique when it contains the files random (enough?) name. Seems to work although I never close the generated file.

import os,binascii
l=os.listdir("c")
n="c/"+binascii.b2a_hex(os.urandom(15))+".py"
open(n,"w+").write("rm $1\n#"+n)
for v in l:os.system("sh "+n+" c/"+v)

If we know there is ALWAYS one child, we can shorten the script to 146 bytes:

import os,binascii
l=os.listdir("c")[0]
n="c/"+binascii.b2a_hex(os.urandom(15))+".py"
open(n,"w+").write("rm $1\n#"+n)
os.system("sh "+n+" c/"+l)
\$\endgroup\$
2
  • \$\begingroup\$ Trying to read this (I need to learn python), the child file removes everything in the /c/ directory that isn't itself? Or is the parent doing the deleting? \$\endgroup\$ Apr 4, 2013 at 16:17
  • \$\begingroup\$ @jdstankosky What, I must have been very tired. Only now I see how horribly wrong this is doing its business. I think it should be corrected now. The created files are effectively alias for rm and the parent calls the new file for each old file in c directory. \$\endgroup\$
    – shiona
    Apr 5, 2013 at 13:47
0
\$\begingroup\$

Tcl - 131 chars

set n c[expr rand()].tcl;set f [open $n w+];puts $f [string map "@ $n" {lmap f [glob -ta -di . c*] {if {$f ne {@}} {file del $f}}}]

Not sure if I understand this correctly. (Delete all siblings, or only delete last one?)
I use glob and kill all other siblings in the same directory.
Names are unique, files are unique (contains own file name).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.