Incrémentation de nombres, sur plusieurs sessions

30

Bons agents de golf du soir,

Votre mission est au nom du géant du divertissement notoire Eviltronic Arts. Dans le cadre de leur plan néfaste d'esclavage et de divertissement mondial, ils doivent vendre autant d'exemplaires de SimStation V que possible. Cela signifie que le logiciel doit mystérieusement cesser de fonctionner, après l'avoir démarré plusieurs fois.

Votre objectif est d'écrire un programme qui compte le nombre d'exécutions. Le programme ne doit rien faire d'autre puis écrire l'entier dans stdout. La première fois qu'il est exécuté, il doit retourner "1". Le prochain "2" et ainsi de suite. Le programme doit pouvoir atteindre au moins le chiffre "14", mais il n'y a pas de limite supérieure requise.

Cependant, votre programme ne doit pas écrire de nouveaux fichiers. L'accès à lui-même, au registre ou même à Internet est absolument OK. Mais certains de nos utilisateurs se méfient des nouveaux fichiers et les écraseront simplement! Le nerf! Vaincre les limitations des logiciels qu'ils ont légitimement achetés!

Le programme ne peut pas supposer un interpréteur ou un shell stable - le programme doit toujours fonctionner si l'intégralité de l'interpréteur nay shell nay ordinateur est redémarré entre l'exécution.

Comme il doit être aussi indétectable que possible, le code source le plus court gagnera.

Agents de bonne chance. L'industrie du divertissement compte sur vous.

lochok
la source

Réponses:

21

script bash, 39 , 37 , 21 18

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

Bref et doux, ma première soumission en code golf :)

Rozuur
la source
1
Remplacer echopar id: D
thejh
il ajoute une sortie inutile au fichier, qui sera redirigé vers stderr
Rozuur
Hein? Il n'y a rien ici qui interagit avec stderr. Mais bon, cela agrandit le fichier au fil du temps.
thejh
peut être joué à 17: remplacez le ;par un retour à la ligne et supprimez le retour à la ligne de fin. Il sera encore plus beau :-)
Tomas
Seule la taille de départ du script est-elle pertinente? Considérant que cela augmentera de taille à chaque exécution.
unclemeat
18

Python, 40 , 39 , 38 caractères

De plus, il n'y a pas de limite supérieure de ce type lors de l'exécution:

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

Comme vous pouvez le voir, la taille du programme augmente progressivement, mais il n'y avait pas une telle restriction dans le problème d'origine. Je crois que la taille du programme soumis est tout ce qui compte

Abhijit
la source
Je ne pense pas que vous ayez besoin de mettre a+, adevrait fonctionner correctement.
beary605
@ beary605: Merci pour le conseil
Abhijit
10

PHP 48 octets

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

Une approche simple d'auto-modification. Après avoir couru 99 fois, il plantera de façon spectaculaire.

$ 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
la source
le seul espace blanc n'est-il pas inutile?
John Dvorak
1
@JanDvorak Le seul espace blanc est nécessaire dans le programme, sinon il planterait après seulement 10 exécutions, ce qui ne correspond pas aux spécifications. Après la 100e exécution, le point-virgule est remplacé, ce qui provoque l'erreur de syntaxe.
primo
Vous avez une solution PHP pour 35 caractères , vous voulez me battre? :)
Tomas
7

script bash, 37

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

Ruby: 31 21 caractères

(Ceci est une réécriture de la solution Python d' Abhijit . Si vous aimez l'idée de base, votez sa réponse, comme je l'ai fait.)

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

Exemple d'exécution:

bash-4.2$ ruby increment.rb 
1

bash-4.2$ ruby increment.rb 
2

bash-4.2$ ruby increment.rb 
3
homme au travail
la source
1
En utilisant, <<vous pouvez enregistrer quelques caractères: `open ($ 0
,? A
Doh. La bonne vieille habitude de s'assurer que les fichiers de données soient fermés… :( Merci, @steenslag.
manatwork
5

* sh, 17

curl -L x.co/z7Uk

L'utilisation d'un service Web, une approche différente de celle des autres solutions existantes jusqu'à présent. Limite: la mémoire de ma machine.


JavaScript, 40

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

Ne compte guère comme un programme, mais c'est quand même assez long. Ne fonctionne pas dans Firefox dans un fichier local. Limite: 2 ^ 31.

copie
la source
Pourquoi pas alert(localStorage.a=~~localStorage.a+1)41 et techniquement parlant, le programme javascript serait sans les balises de script qui ne seraient que 33
David Mulder
@DavidMulder Oh, à droite
copie
2
alert((l=localStorage).a=~~l.a+1)
Jusqu'à
@ nitro2k01: On dirait que j'ai copié les mauvaises choses, parce que c'était le 33 dont je parlais O :) 41 était la même chose, y compris les balises de script ~ (eh bien, j'ai fait le filtrage avant l'alerte, car c'est aussi long: a=localStorage;alert(a.b=~~a.b+1)bien que le vôtre semble plus joli: D
David Mulder
1
@WallyWest Nope, il s'agit en fait d'un inverseur au niveau du bit et abuse des règles de conversion de type bizarre de JavaScript
copiez le
4

PHP 31 37 caractères

Auto-modifiant. Cela compte à l'unaire. Faites attention que votre éditeur de texte n'essaye pas d'être utile et insérez un caractère de nouvelle ligne après le 1. Il ne fonctionnera (correctement) qu'en PHP <5.3.2 car il s'appuie sur php pour fermer les descripteurs de fichiers ouverts à l'arrêt. Ou est-il acceptable de divulguer des descripteurs de fichiers?

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

Version originale (36 caractères), toutes les versions PHP:

<?file_put_contents(__FILE__,1,8)?>1
Tim Seguine
la source
2
"Ça compte à l'unaire" ... Meilleur Golf Hack que j'ai vu depuis longtemps!
lochok
Je te met au défi. Solution PHP pour 35 caractères , et c'est en décimal :)
Tomas
1
Wow, je vois que tu m'as battu avec ta propre méthode! Toutes nos félicitations! :-) Et merci pour l'amélioration de ma méthode. Je l'ai inclus dans ma réponse et je vous en remercie.
Tomas
@Tomas, je vous dois le crédit. Si vous ne m'aviez pas défié, je n'aurais pas revu cette réponse.
Tim Seguine
Tim, c'est exactement la joie et l'excitation de se défier! :)
Tomas
2

Python, 50

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

Il utilise la même approche que la réponse de primo et se bloque de la même manière au 100e passage.

grc
la source
2

J (58)

Vous devez l'exécuter en tant que script, cela ne fonctionnera évidemment pas à partir de la ligne de commande J.

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

En J, le tokenizer utilisé par l'interpréteur est disponible en tant que ;:fonction, donc s'il xcontient du code J, il ;:xcontient les jetons J, c'est-à-dire:

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

Alors:

  • echo m=.1: mis mà 1, et écrivez-le à l'écran
  • k=.1{ARGV: stocke le 2ème élément dans ARGV(le nom du script) dans k.
  • ... 1!:2[k: écrivez la chaîne suivante dans le fichier en k:
  • ;:1!:1[k: lire k, le script actuel et tokenize
  • (<":m+1)(<3)}: remplace le 3ème jeton par la représentation sous forme de chaîne de m + 1
  • ;:^:_1: exécuter le tokenizer en sens inverse, produisant une chaîne
  • exit: quitte l'interpréteur (il ne le fait pas tout seul même si vous exécutez un script)
marinus
la source
2

PHP, 34 33 caractères

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

Merci à Tim pour la mise à jour! Mon ancienne solution:

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

Le problème est que $_SESSION[A]est ""- chaîne vide - dans la première itération, mais session_start()renvoie 1, vous pouvez l' ajouter et de tuer deux ou trois mouches d'un seul coup!

Solution avec une syntaxe correcte (35 caractères):

<?=session_start()+$_SESSION[A]++?>
Tomas
la source
Je tiendrai du jugement une seconde pour deux raisons. "Cependant, votre programme ne doit pas écrire de nouveaux fichiers.": Je ne sais pas si ce n'est pas un problème pour cette solution, car l'ouverture d'une session crée un fichier temporaire. De plus, la session par défaut gc se produit après 24 minutes. Est-ce que cela compte vraiment comme "plusieurs sessions"? Peut-être que le PO peut commenter.
Tim Seguine
Tim, le programme n'écrit aucun fichier. Je ne suis pas responsable de ce que fait l'interprète. C'est la même chose que la page HTML n'est pas responsable de la création par le navigateur de certains fichiers dans le cache, la requête sql n'est pas responsable de la création de tables temporaires sur le disque, etc. Quant au délai d'attente, il n'était pas spécifié dans les règles :) mais pourquoi sur ma machine le compteur tient encore plus de plusieurs heures !!!
Tomas
Oui, c'est pourquoi je dis que j'attendrai de voir ce que pense l'OP. Vous avez certainement trouvé une zone très grise. Vous n'avez pas besoin de la balise php de fermeture btw. donc votre version 34 caractères est suffisante. J'ai une idée d'amélioration, mais je devrai d'abord la tester.
Tim Seguine
D'accord, je suis descendu à 33 caractères. Je vous mets au défi de faire mieux. ;)
Tim Seguine
@TimSeguine Aaaah, quel changement de ton! :-) Maintenant, vous ne vous souciez plus tellement des règles de mon article! :-D
Tomas
2

Haskell - 36 octets

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

Ajoute simplement +1à la fin du fichier source, qui est supposé être nommé a.hs. L' .hsextension est obligatoire dans ghc et ghci.

BlackCap
la source
1

TI-Basic, 9 caractères

:X+1->X:X
Timtech
la source
1

Lot - 41

Étant donné l'exemple d'utilisation, je ne supposerais probablement pas que cette technique est viable - elle renomme le fichier .bat contenant le script -

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

Enregistrez-le dans un fichier appelé 0.bat- et appelez en utilisant 0.bat 2>nul. 2>nulredirige stderr vers nul ce qui est nécessaire car ce script renommera le fichier contenant le script, une fois qu'il le fera, cmd ne pourra évidemment plus voir le script (avant qu'il ne frappe EOF) et renverra l'erreurThe batch file cannot be found.

Chaque appel consécutif du script devra bien entendu être 1.bat 2>nul ... 2.bat 2>nul ... 3.bat 2>nul ... etc ...

dégrader
la source
Sur la base de cette idée, vous pouvez faire une variation de ma réponse php de compter en unaire et je pense que c'est encore plus court que cela.
Tim Seguine
1

Script mIRC, 28/22 octets

S'il est placé dans l'onglet "alias", "alias" peut être omis, ce qui fait 22 octets.

alias x inc %i | echo -ag %i
FIQ
la source
1

Python, 49 48 caractères

J'ai réalisé que ce ne sera que 48 caractères sur Windows en raison de la \r\n. Sinon, il devrait être de 49.

n=1

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

Une arnaque bon marché de la méthode par @grc

jamylak
la source
1

C, 190 caractères. Fonctionne uniquement sur 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
la source
Je pense que son fonctionnement est assez simple, mais si nécessaire, je peux ajouter une explication :-)
Abhijit
1

C #, 142 caractères

int v=(Microsoft.Win32.Registry.CurrentUser.GetValue("c") as int?)??0+1;Console.Write(v);Microsoft.Win32.Registry.CurrentUser.SetValue("c",v);
ZafarYousafi
la source
Vous pouvez utiliser un nom plus court comme z, vous obtiendrez quelques caractères.
It'sNotALie.
Vous devez également supprimer l'espace blanc.
Timtech
1
Au lieu d'appeler un nom d'API long à chaque fois, stockez-le dans une variable comme: var a = Microsoft.Win32.Registry.CurrentUser; a.GetValue (); a.SetValue ();
Xantix
1

Tcl, 63 ou 73 octets

  • Avec certains services Web, c'est 73:

    package require http
    puts [set [http::geturl http://example.com/c](data)]
    
  • se modifier est 63:

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

C # - 201 239 234 caractères

Fonctionne pour les 255 premières fois, puis passe à 0. Il ne produira rien lors de la première exécution.

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);}}}

Enregistrer sous Main.cs, compiler avec

gmcs Main.cs

Testé avec gmcs 2.10.8.1 et Mono runtime 2.10.8.1-5ubuntu2

user3188175
la source
1
En fait - je l'ai fait. "Le programme doit pouvoir atteindre au moins le nombre 14"
lochok
Cela fonctionne maintenant 255 fois.
user3188175
1

Powershell, 47 octets

suppose que le script est nommé a.ps1

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

Le script s'écrase en remplaçant le 0sur la première ligne avec 1, 2, 3et ainsi de suite.

pourrait également économiser 8 octets supplémentaires en remplaçant les deux instances de a.ps1with 1et en enregistrant le script sous forme de fichier nommé 1bien que ce soit un peu loin pour moi.

Remplacez la deuxième ligne par ceci si le fichier n'est pas enregistré en tant que «a.ps1».

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

0 en première ligne pour initialiser le décompte

Le saut de ligne offre le moyen le plus simple de diviser le fichier en deux

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

cela prend le fichier 'a.ps1' et le lit comme un tableau de lignes, nous le parcourons ensuite avec [0..1]et le définissons sur les variables $nqui sont converties en [int]et $trespectivement, de sorte que 0la première ligne devienne $net le 'code 'sur la deuxième ligne devient$t

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

Cela a utilisé la ,1,2notation de tableau, pour créer un tableau de deux éléments, l'un étant le nombre stocké dans$n pré-incrémenté et sorti vers stdout par l'utilisation de crochets implicites, le second étant la deuxième ligne de texte du fichier, puis également la sortie dans le fichier nommé 'a.ps1'

comme l'entrée et la sortie sont des tableaux de chaînes, la mise en forme est minimale et presque tout est assumé par l'interpréteur.

colsw
la source
1

Zsh (pas de coreutils), 32 octets

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

(Notez la nouvelle ligne de fin) Utilise la longueur du script. A chaque appel, la dernière ligne ci-dessus s'ajoutera :(identique à true) et une nouvelle ligne au script, d'où le /2.

Essayez-le en ligne!

GammaFunction
la source
0

Rust / cargo-script, 283 octets

Bon mot:

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);}

Enregistrez sous wet exécutez avec 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

Ne répétez pas trop vite ou ça va rester coincé .

Partiellement non golfé:

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);
}

Se cassera après 99999;

Vi.
la source
0

GNU sed, 13 + 1 (drapeau n) = 14 octets

$=;$eecho>>s

Courir: sed -nf ss

L'hypothèse est que le nom du fichier source est appelé s. Une nouvelle ligne de fin est nécessaire après le code, qui a été compté dans le total d'octets. Explication:

$=           # 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
la source