Teraz wszyscy wiemy, że większość języków ma bardzo proste sposoby na „samodzielną modyfikację” kodu. Co jednak, jeśli faktycznie zmodyfikujesz kod i edytujesz jego części ... na dysku?
Twoim celem jest utworzenie kodu, który wypisze liczbę, a następnie edytuje własny plik, zastępując go numerem kolejnym w sekwencji Fibonacciego:
$ ./program
1
$ ./program
1
$ ./program
2
$ ./program
3
$ ./program
5
[etc...]
Zasady
- Nie możesz przechowywać numerów poza kodem. Bez komentarzy, bez informowania skryptu o wyjściu, bez EOF itp.
- Jeśli kod działa z dowolną nazwą pliku, odejmij 2 od ilości bajtów i wpisz
$BYTESNOW ($ORIGINALBYTES - 2)
tytuł. (Zakłada się, że nazwy plików mieszczą się w zakresie dowolnej ścieżki alfanumerycznej). - Twój kod musi zapisywać dane wyjściowe do pliku we własnym zakresie, bez żadnej pomocy zewnętrznego potoku.
- Twój kod może zaczynać się od zera lub zera. To nie ma znaczenia
perl6 program
), Czy też musi on zawierać linię shebang, aby można ją było wywołać jako./program
?program
i czy możemy założyć, że znajduje się ona w bieżącym katalogu roboczym?"a"
zamiastarg[0]
. To nie wydaje się tego warte.Odpowiedzi:
Bash,
5247 (49-2) bytesEDITS:
Golfed
Test
źródło
-?
from the regex. And since you're there, you could also remove the first capturing group :)Python 2,
118111 bytes ( 113 - 2 )It works with any valid filename. There is not much to explain here, the code itself is very verbose.
Thanks to FlipTack for reminding me,
close()
is not mandatory.źródło
f=open(...)
instead of thewith
statement?Batch, 81 bytes
Note: the trailing newline is significant. Requires the script to be invoked using its full name including extension. Output starts at 0.
Since Batch can't realistically edit a file, I just add extra lines to the end of the file, so eventually it will know which the next number to print is. The
>>%0
placement saves a byte because I can't precede it with a digit.źródło
C, 142 bytes (144 - 2)
It's pretty straight forward. First it reads then saves the two chars at position 0x1A in the header. I probably could've looked deeper to find a safer spot to save the data but it works for me on my machine running OSX, compiled with GCC 4.2ish and I doubt it's very portable. Also, since it's based off chars it overflows after the 13th iteration.
It gives the output:
źródło
Node.js,
152137 bytes (139 - 2)Separated with newlines for clarity, not part of byte count.
Explanation:
Usage:
źródło
Python 3.6,
9691 (93-2) byteshardcoding the filename would save 5 bytes (88 bytes):
Saved some bytes thanks to @Artyer
źródło
a,b=0,1
f=open('f','r+');next(f);f.write(f'a,b={b,a+b}\n{next(f)}{f.seek(0)}');print(b)#
bash + Unix utilities, 43 bytes (45-2)
The first time this is run, it uses dc to compute the 1st Fibonacci number via the Binet formula. Each call to sed modifies the program by changing the string passed to dc; this change tells dc to add an additional 1 to the exponent in the formula, which causes it to compute the next number in the Fibonacci sequence each time.
Test
To illustrate how it works, at this point, after the 55 is printed, the program has been modified to read:
so running it again yields
and the program now reads:
źródło
SmileBASIC 3, 99 bytes (101 -2)
-2 byte bonus because it works with any filename.
This one does work, and it somehow ended up being the same size as my broken one!
źródło
PRGEDIT
commands to replace the first line (and add a linebreak afterA=0B=1
) And you also don't needA=0
the first time.R, 145 bytes (147 - 2)
(Has a trailing newline). It works with any valid filename.
źródło
Perl 6,
6762 bytes (64 - 2)źródło
Stacked, noncompeting, 65 (67 - 2) bytes
Some issues regarding file IO were fixed in the most recent series of commits. Thus, noncompeting.
Here's a link to the github.
Example execution
(I omitted the actual path for clarity.)
Explanation
How this works is by taking a pair of numbers to begin the sequence (
2:>
in this case is the integer range[0, 2)
, which is(0 1)
), then performing the Fibonacci transformation on them, like so:On each run, this transformation is executed on the top of stack. Then, the stack is pushed to the stack, duplicated, and its first member obtained (
stack:0#
). This item is then outputted, and is the desired Fibonacci number.repr
then takes the representation of the stack and appends a newline. Then, the program is pushed to the stack, and split on newlines. Then, we take the last member (the last line), and append this to the aforementioned string. Finally, we pushd0
(the file itself; thinkd
ollar sign0
==$0
.) and write to it.źródło
Ruby, 68 bytes (70-2)
źródło
Clojure,
209204195 bytes-5 bytes by switching to parse the numbers as a long instead of an integer, and removing a couple missed spaces.
-9 bytes by removing the space between the second number and
(let...)
(most expensive space ever!).See the pregolfed code comments for a description.
Tested again, and it no longer throws unmatched bracket errors. It works up to 7540113804746346429, at which point it throws an integer overflow exception.
Also note, this assumes the source code is located at "./src/s.clj".
źródło