Inkrementieren von Zahlen über mehrere Sitzungen

30

Guten Abend Golf Agents,

Ihre Mission ist im Auftrag des berüchtigten Unterhaltungsgiganten Eviltronic Arts. Im Rahmen ihres schändlichen Plans zur Versklavung und Unterhaltung der Welt müssen sie so viele Exemplare wie möglich von SimStation V verkaufen. Dies bedeutet, dass die Software nach ein paar Starts auf mysteriöse Weise nicht mehr funktioniert.

Ihr Ziel ist es, ein Programm zu schreiben, das zählt, wie oft es ausgeführt wurde. Das Programm darf nichts anderes tun, als die Ganzzahl in stdout zu schreiben. Bei der ersten Ausführung sollte "1" zurückgegeben werden. Die nächste "2" und so weiter. Das Programm muss mindestens die Zahl "14" erreichen können, es ist jedoch keine Obergrenze erforderlich.

Ihr Programm darf jedoch keine neuen Dateien schreiben. Der Zugriff auf sich selbst, die Registrierung oder sogar das Internet ist absolut in Ordnung. Einige unserer Benutzer sind jedoch misstrauisch gegenüber neuen Dateien und werden diese lediglich überschreiben! Der Nerv! Die Einschränkungen der Software, die sie zu Recht gekauft haben, aufheben!

Das Programm kann keinen stabilen Interpreter oder keine stabile Shell annehmen - das Programm muss weiterhin funktionieren, wenn der gesamte Interpreter bzw. die Shell bzw. der Computer zwischen dem Ausführen neu gestartet wird.

Da es so unauffindbar wie möglich sein muss, gewinnt der kürzeste Quellcode.

Viel Glück Agenten. Die Unterhaltungsindustrie zählt auf Sie.

Lochok
quelle

Antworten:

21

Bash-Skript, 39 , 37 , 21 18

wc -l<$0;echo>>$0

Kurz und gut, meine erste Einsendung in Code Golf :)

Rozuur
quelle
1
Ersetzen echodurch id: D
thejh
Es hängt unnötige Ausgaben an die Datei an, die
Uhr
Huh? Hier gibt es nichts, was mit stderr interagiert. Aber richtig, es vergrößert die Datei mit der Zeit.
thejh
kann bis 17 golfen werden: Ersetze die ;mit newline und entferne die nachlaufende newline. Es wird noch viel schöner aussehen :-)
Tomas
Ist nur die Anfangsgröße des Skripts relevant? In Anbetracht dessen, dass dies mit jedem Lauf größer wird.
Unclemeat
18

Python, 40 , 39 , 38 Zeichen

Es gibt auch keine solche Obergrenze für die Laufzeit:

open(__file__,'a').write("+1");print 1

Wie Sie sehen, nimmt die Größe des Programms allmählich zu, das ursprüngliche Problem unterlag jedoch keiner solchen Einschränkung. Ich glaube, die Größe des eingereichten Programms ist alles, was zählt

Abhijit
quelle
Ich denke nicht, dass Sie setzen müssen a+, asollte gut funktionieren.
beary605
@ beary605: Danke für den Tipp
Abhijit
10

PHP 48 Bytes

<?=$n=1 ;fputs(fopen(__FILE__,c),'<?=$n='.++$n);

Ein einfacher selbstmodifizierender Ansatz. Nach 99 Läufen stürzt es spektakulär ab.

$ php increment.php
1
$ php increment.php
2
$ php increment.php
3

$ php increment.php
97
$ php increment.php
98
$ php increment.php
99
$ php increment.php
PHP Parse error:  syntax error, unexpected T_STRING, expecting ',' or ';' in increment.php on line 1
primo
quelle
Ist das einzelne Leerzeichen nicht unnötig?
John Dvorak
1
@JanDvorak Das einzelne Leerzeichen ist im Programm erforderlich, sonst würde es nach nur 10 Ausführungen abstürzen, was der Spezifikation nicht entspricht. Nach der 100. Ausführung wird das Semikolon überschrieben, was den Syntaxfehler verursacht.
Primo
Haben Sie eine PHP-Lösung für 35 Zeichen , wollen Sie mich schlagen? :)
Tomas
7

Bash-Skript, 37

n=1;echo $n;sed -ie s/$n/$((n+1))/ $0
Geoff Reedy
quelle
5

Ruby: 31 21 Zeichen

(Dies ist ein Umschreiben von Abhijit ‚s Python - Lösung . Wenn Sie wie die Grundidee, upvote seine Antwort, wie ich es tat.)

open($0,?a)<<"+1";p 1

Probelauf:

bash-4.2$ ruby increment.rb 
1

bash-4.2$ ruby increment.rb 
2

bash-4.2$ ruby increment.rb 
3
Mann bei der Arbeit
quelle
1
Mit können <<Sie einige Zeichen speichern: `open ($ 0
,?
Doh. Die gute alte Angewohnheit, sicherzustellen, dass die Datendateien geschlossen werden ... :( Vielen Dank, @steenslag.
manatwork
5

* sh, 17

curl -L x.co/z7Uk

Verwenden Sie einen Webservice, einen anderen Ansatz als die anderen bisherigen Lösungen. Limit: Der Speicher meiner Maschine.


JavaScript, 40

alert(localStorage.a=~~localStorage.a+1)

Gilt kaum als Programm, ist aber trotzdem ziemlich lang. Funktioniert nicht in Firefox in einer lokalen Datei. Limit: 2 ^ 31.

Kopieren
quelle
Warum nicht alert(localStorage.a=~~localStorage.a+1)41 und technisch gesehen wäre das Javascript-Programm ohne die Script-Tags, die nur 33 wären
David Mulder
@ DavidMulder Oh, richtig
kopiere den
2
Bis 33:alert((l=localStorage).a=~~l.a+1)
nitro2k01
nitro2k01 @: Scheint ich die falsche Sachen kopiert, dazu führen , dass die 33 war ich sprach O :) 41 wurde das gleiche einschließlich Script - Tags ~ (na ja, ich habe die Angabe vor dem Alarm, weil es nur so lange ist: a=localStorage;alert(a.b=~~a.b+1)wenn Ihr sieht schöner aus: D
David Mulder
1
@WallyWest Nein, es ist tatsächlich bitweise invertiert und missbraucht die seltsamen JavaScript-Konvertierungsregeln
kopiere den
4

PHP 31 37 Zeichen

Selbstmodifizierend. Es zählt unär. Achten Sie darauf, dass Ihr Texteditor nicht versucht, hilfreich zu sein, und fügen Sie nach dem 1. ein Zeilenumbruchzeichen ein. Es funktioniert nur (ordnungsgemäß) in PHP <5.3.2, da es beim Herunterfahren auf PHP angewiesen ist, offene Dateideskriptoren zu schließen. Oder ist es akzeptabel, Dateideskriptoren zu verlieren?

<?fputs(fopen(__FILE__,a),1)?>1

Originalversion (36 Zeichen), alle PHP-Versionen:

<?file_put_contents(__FILE__,1,8)?>1
Tim Seguine
quelle
2
"Es zählt eins" ... Bester Golf-Hack, den ich seit langem gesehen habe!
Lochok
Ich fordere dich heraus. PHP-Lösung für 35 Zeichen , und es ist in Dezimalzahl :)
Tomas
1
Wow, ich sehe, du hast mich mit deiner eigenen Methode geschlagen! Herzliche Glückwünsche! :-) Und danke für die Verbesserung meiner Methode. Ich habe es in meine Antwort aufgenommen und dir dafür eine Anerkennung gegeben.
Tomas
@Tomas Ich schulde dir etwas. Wenn Sie mich nicht herausgefordert hätten, hätte ich mir diese Antwort nicht noch einmal angesehen.
Tim Seguine
Tim, genau das ist die Freude und Aufregung, sich gegenseitig herauszufordern! :)
Tomas
2

Python, 50

n=1;
print n
open(__file__,'r+').write("n="+`n+1`)

Es verwendet den gleichen Ansatz wie die Antwort von primo und stürzt in ähnlicher Weise beim 100. Durchgang ab.

grc
quelle
2

J (58)

Sie müssen dies als Skript ausführen, es funktioniert offensichtlich nicht über die J-Befehlszeile.

echo m=.1
exit(;:^:_1(<":m+1)(<3)};:1!:1[k)1!:2[k=.1{ARGV

In J steht der Tokenizer, den der Interpreter verwendet, als ;:Funktion zur Verfügung. Wenn er also xJ-Code ;:xenthält , enthält er die J-Token, dh:

    ;: 'echo 1 2 3+4 5 6'
+----+-----+-+-----+
|echo|1 2 3|+|4 5 6|
+----+-----+-+-----+

So:

  • echo m=.1: mauf 1 setzen und auf den Bildschirm schreiben
  • k=.1{ARGV: Speichern Sie das 2. Element in ARGV(den Skriptnamen) in k.
  • ... 1!:2[k: schreibe folgenden String in die Datei in k:
  • ;:1!:1[k: kdas aktuelle Skript lesen und tokenisieren
  • (<":m+1)(<3)}: Ersetzen Sie das 3. Token durch die Zeichenfolgendarstellung von m + 1
  • ;:^:_1: Führen Sie den Tokenizer in umgekehrter Reihenfolge aus und erstellen Sie eine Zeichenfolge
  • exit: verlasse den Interpreter (das macht er nicht von alleine, auch wenn du ein Skript ausführst)
Marinus
quelle
2

PHP, 34 33 Zeichen

<?=$_SESSION[A]+=session_start();

Danke an Tim für das Update! Meine alte Lösung:

<?=session_start()+$_SESSION[A]++;

Das Problem ist, dass $_SESSION[A]es sich ""bei der ersten Iteration um eine leere Zeichenfolge handelt. Wenn Sie jedoch session_start()1 zurückgeben, können Sie diese hinzufügen und zwei oder drei Fliegen auf einmal töten!

Lösung mit korrekter Syntax (35 Zeichen):

<?=session_start()+$_SESSION[A]++?>
Tomas
quelle
Ich werde aus zwei Gründen für eine Sekunde über ein Urteil entscheiden. "Ihr Programm darf jedoch keine neuen Dateien schreiben.": Ich bin nicht sicher, ob dies für diese Lösung kein Problem darstellt, da beim Öffnen einer Sitzung eine temporäre Datei erstellt wird. Auch die Standardsitzung gc findet nach 24 Minuten statt. Zählt das dann wirklich als "über mehrere Sitzungen"? Vielleicht kann das OP einen Kommentar abgeben.
Tim Seguine
Tim, das Programm schreibt keine Dateien. Ich bin nicht verantwortlich für das, was der Dolmetscher tut. Es ist dasselbe, als ob die HTML-Seite nicht für den Browser verantwortlich ist, der einige Dateien im Cache erstellt. Die SQL-Abfrage ist nicht für die Erstellung temporärer Tabellen auf der Festplatte verantwortlich. Das Timeout wurde in den Regeln nicht angegeben Klar warum aber auf meiner Maschine hält der Zähler noch länger als mehrere Stunden !!!
Tomas
Ja, deshalb sage ich, ich werde abwarten, was das OP denkt. Sie haben definitiv eine sehr graue Fläche gefunden. Das schließende PHP-Tag brauchen Sie übrigens nicht. Ihre 34-Zeichen-Version ist also ausreichend. Ich habe eine Idee für eine Verbesserung, aber ich muss sie zuerst testen.
Tim Seguine
Okay, ich habe es auf 33 Zeichen reduziert. Ich wage dich, es besser zu machen. ;)
Tim Seguine
@TimSeguine Aaaah, was für eine Veränderung in deinem Ton! :-) Jetzt interessieren dich die Regeln in meinem Beitrag nicht so sehr! :-D
Tomas
2

Haskell - 36 Bytes

main=do appendFile"a.hs""+1";print$1

Fügt einfach +1das Ende der Quelldatei hinzu , von der angenommen wird, dass sie benannt ist a.hs. Die .hsErweiterung ist in ghc und ghci obligatorisch.

BlackCap
quelle
1

TI-Basic, 9 Zeichen

:X+1->X:X
Timtech
quelle
1

Charge - 41

In Anbetracht des Anwendungsbeispiels würde ich wahrscheinlich nicht annehmen, dass diese Technik praktikabel ist. Sie benennt die .bat-Datei um, die das Skript enthält.

@set/aa=%~n0+1
@echo %a%&@ren %0 %a%.bat

Speichern Sie dies in einer Datei namens 0.bat - und rufen Sie mit 0.bat 2>nul. 2>nulleitet stderr nach nul um, was notwendig ist, da dieses Skript die Datei mit dem Skript umbenennt, wenn dies der Fall ist, kann cmd das Skript offensichtlich nicht mehr sehen (bevor es auf EOF trifft) und gibt den Fehler zurückThe batch file cannot be found.

Jeder nachfolgende Aufruf des Skripts muss natürlich sein 1.bat 2>nul ... 2.bat 2>nul ... 3.bat 2>nul ... etc ...

unclemeat
quelle
Basierend auf dieser Idee können Sie eine Variation meiner PHP-Antwort von unary zählen und ich denke, es ist noch kürzer als diese.
Tim Seguine
1

mIRC-Skript, 28/22 Bytes

In der Registerkarte "Aliase" kann "Alias" weggelassen werden, wodurch 22 Bytes entstehen.

alias x inc %i | echo -ag %i
FIQ
quelle
1

Python, 49 48 Zeichen

Ich erkannte, dass dies unter Windows nur 48 Zeichen sein wird \r\n. Ansonsten sollte es 49 sein.

n=1

print n;print>>open(__file__,'r+'),"n=",n+1

Eine billige Abzocke der Methode von @grc

jamylak
quelle
1

C, 190 Zeichen. Funktioniert nur unter Win NT

#include <stdio.h>
int main(int c,char *v[]){
char f[100];sprintf(f,"%s:s",v[0]);
if (FILE *fp=fopen(f,"r"))fscanf(fp,"%d",&c);
FILE *fp=fopen(f,"w");printf("%d",c-1);fprintf(fp,"%d",++c);
}
Abhijit
quelle
Ich denke, es ist ziemlich einfach, wie es funktioniert, aber trotzdem kann ich bei Bedarf eine Erklärung hinzufügen :-)
Abhijit
1

C #, 142 Zeichen

int v=(Microsoft.Win32.Registry.CurrentUser.GetValue("c") as int?)??0+1;Console.Write(v);Microsoft.Win32.Registry.CurrentUser.SetValue("c",v);
ZafarYousafi
quelle
Sie könnten einen kürzeren Namen wie z verwenden, um ein paar Zeichen zu sparen.
istNotALie.
Sie sollten auch das Leerzeichen entfernen.
Timtech
1
Anstatt jedes Mal einen langen API-Namen aufzurufen, speichern Sie ihn in einer Variablen wie: var a = Microsoft.Win32.Registry.CurrentUser; a.GetValue (); a.SetValue ();
Xantix
1

Tcl, 63 oder 73 Bytes

  • Mit einigen Webservices sind es 73:

    package require http
    puts [set [http::geturl http://example.com/c](data)]
    
  • Änderung selbst ist 63:

    proc a a {puts [string le $a]};puts -nonewline [open $argv0 a] a; a a
    
Johannes Kuhn
quelle
1

C # - 201 239 234 Zeichen

Funktioniert die ersten 255 Male und geht dann auf 0 über. Bei der ersten Ausführung wird nichts ausgegeben.

namespace System.IO{class s{static void Main (string[]a){char f='|';if(f!='|'){Console.Write (255);}string p=Reflection.Assembly.GetCallingAssembly().Location;byte[]d=File.ReadAllBytes(p);d[769]++;d[780]++;File.WriteAllBytes(p,d);}}}

Speichern als Main.cs, kompilieren mit

gmcs Main.cs

Getestet mit gmcs 2.10.8.1 und Mono Runtime 2.10.8.1-5ubuntu2

user3188175
quelle
1
Eigentlich - ich habe. "Das Programm muss in der Lage sein, mindestens die Nummer 14 zu erreichen"
lochok
Es funktioniert jetzt 255 mal.
user3188175
1

Powershell, 47 Bytes

geht davon aus, dass das Skript benannt ist a.ps1

0
[int]$n,$t=(gc a.ps1)[0..1];,(++$n),$t>a.ps1

Das Skript überschreibt sich das Ersetzen 0in der ersten Zeile mit 1, 2, 3und so weiter.

Sie könnten auch weitere 8 Byte speichern, indem Sie beide Instanzen von a.ps1mit ersetzen 1und das Skript als Datei namens speichern1 obwohl dies für mich ein wenig zu weit geht.

Ersetzen Sie die zweite Zeile durch diese, wenn die Datei nicht als 'a.ps1' gespeichert ist.

[int]$n,$t=(gc($s=$MyInvocation.MyCommand.Name))[0..1];,(++$n),$t>$s

0 in der ersten Zeile, um die Zählung zu initialisieren

Zeilenumbruch bietet die einfachste Möglichkeit, die Datei in zwei Teile zu teilen

[int]$n,$t=(gc a.ps1)[0..1]

dies nimmt die Datei 'a.ps1' und liest sie als Array von Zeilen ein, wir durchlaufen sie dann mit [0..1]und setzen sie auf die Variablen, $ndie als [int]und $tentsprechend umgewandelt werden, so dass die 0in der ersten Zeile wird $nund der 'Code 'In der zweiten Zeile wird$t

,(++$n),$t>a.ps1

Hierbei wurde die ,1,2Array-Notation verwendet, um ein Array aus zwei Elementen zu erstellen, wobei eines die Zahl ist, die $nvorab inkrementiert gespeichert und mit Hilfe impliziter Klammern auf stdout ausgegeben wird. Das zweite ist die zweite Textzeile aus der Datei und wird dann ebenfalls ausgegeben es in die Datei mit dem Namen "a.ps1"

Da sowohl Eingabe als auch Ausgabe Arrays von Strings sind, ist nur eine minimale Formatierung erforderlich und fast alles wird vom Interpreter übernommen.

colsw
quelle
1

Zsh (keine Coreutils), 32 Bytes

a=`<$0`
<<<$[$#a/2-15]
>>$0<<<:

(Beachten Sie den abschließenden Zeilenumbruch.) Verwendet die Länge des Skripts. Bei jedem Aufruf wird die letzte oben gezeigte Zeile :(identisch mit true) und eine neue Zeile an das Skript angehängt, daher die /2.

Probieren Sie es online!

GammaFunktion
quelle
0

Rust / Cargo-Skript, 283 Bytes

Einzeiler:

use std::fs::File;use std::io::Write;fn main(){let c=     0; let mut v = vec![];::std::io::Read::read_to_end(&mut File::open("w").unwrap(),&mut v);let mut q=&mut File::create("w").unwrap();q.write(&v[..53]);q.write(format!("{:6}",c+1).as_bytes());q.write(&v[59..]);println!("{}",c);}

Speichern unter wund ausführen mit cargo-script:

$ cargo-script script w
   Compiling w v0.1.0 (file:///home/vi/.cargo/script-cache/file-w-b4d6541706fabb11)
    (warnings skipped...)
    Finished release [optimized] target(s) in 1.47 secs
0
$ cargo-script script w
    (compilation output skipped)
1
$ cargo-script script w
...
2
$ cargo-script script w 2> /dev/null
3
$ cargo-script script w 2> /dev/null
4
$ cargo-script script w 2> /dev/null
5
$ cargo-script script w 2> /dev/null
6
$ cargo-script script w 2> /dev/null
7
$ cargo-script script w 2> /dev/null
8
$ cargo-script script w 2> /dev/null
9
$ cargo-script script w 2> /dev/null
10
$ cargo-script script w 2> /dev/null
11

Iteriere nicht zu schnell, sonst bleibt es hängen .

Teilweise ungolfed:

use std::fs::File;use std::io::Write;fn main(){let c=     0;
    let mut v = vec![];
    ::std::io::Read::read_to_end(&mut File::open("w").unwrap(),&mut v);
    let mut q = &mut File::create("w").unwrap();
    q.write(&v[..53]);
    q.write(format!("{:6}",c+1).as_bytes());
    q.write(&v[59..]);
    println!("{}", c);
}

Wird nach 99999 brechen;

Vi.
quelle
0

GNU sed, 13 + 1 (n Flag) = 14 Bytes

$=;$eecho>>s

Run: sed -nf ss

Die Annahme ist, dass der Quellendateiname aufgerufen wird s. Nach dem Code, der in der Gesamtsumme der Bytes gezählt wurde, wird eine nachgestellte Zeile benötigt. Erläuterung:

$=           # print the number of lines of the input file
$eecho>>s    # a shell echo call that appends an empty line to the source file 's'
Seshoumara
quelle