Увеличение числа на несколько сеансов

30

Добрый вечер, агенты по гольфу,

Ваша миссия от имени известного гиганта индустрии развлечений Eviltronic Arts. В рамках своего гнусного плана порабощения и развлечений в мире они должны продать как можно больше копий SimStation V. Это означает, что программное обеспечение должно загадочным образом перестать работать, после его запуска несколько раз.

Ваша цель - написать программу, которая будет подсчитывать, сколько раз она была запущена. Программа не должна делать ничего другого, кроме как записать целое число в стандартный вывод. При первом запуске он должен вернуть «1». Следующая «2» и так далее. Программа должна быть в состоянии, по крайней мере, достигнуть числа «14», но нет обязательного верхнего предела.

Однако ваша программа не должна писать никаких новых файлов. Доступ к самому себе, или реестру, или даже интернету абсолютно нормален. Но некоторые наши пользователи с подозрением относятся к новым файлам и просто перезаписывают их! Нерв! Победив ограничения на программное обеспечение, которое они законно приобрели!

Программа не может предполагать стабильный интерпретатор или оболочку - программа все равно должна работать, если весь компьютер интерпретатора или оболочки перезапускается между выполнением.

Поскольку он должен быть как можно более детектируемым, победит самый короткий исходный код.

Удачи, агенты. Индустрия развлечений рассчитывает на вас.

lochok
источник

Ответы:

21

bash script, 39 , 37 , 21 18

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

Коротко и сладко, моя первая подача в коде гольф :)

Rozuur
источник
1
Заменить echoна id: D
thejh
он добавляет ненужный вывод в файл, который будет перенаправлен на stderr
Rozuur
А? Здесь нет ничего, что взаимодействует с stderr. Но верно, это увеличивает размер файла с течением времени.
thejh
можно сыграть в гольф до 17: замените символ; новой строки и удалите завершающий символ новой строки. Это даже будет выглядеть намного лучше :-)
Томас
Относится ли только начальный размер скрипта? Учитывая, что это будет увеличиваться в размерах при каждом запуске.
unclemeat
18

Python, 40 , 39 , 38 символов

Также нет такого верхнего предела времени выполнения:

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

Как видите, размер программы постепенно увеличивается, но в исходной задаче такого ограничения не было. Я считаю, что размер представленной программы - это все, что имеет значение

Abhijit
источник
Я не думаю, что нужно ставить a+, aдолжно работать нормально.
beary605
@ beary605: Спасибо за совет
Абхиджит
10

PHP 48 байт

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

Простой самоизменяющийся подход. После прогона 99 раз он эффектно рухнет.

$ 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
Примо
источник
не является ли единственный пробел ненужным?
Джон Дворжак
1
@JanDvorak В программе необходим один пробел, в противном случае он завершится сбоем после всего 10 выполнений, что не соответствует спецификации. После сотого выполнения точка с запятой перезаписывается, что приводит к синтаксической ошибке.
Примо
Получил PHP решение на 35 символов , хочешь побить меня? :)
Томас
7

bash script, 37

n=1;echo $n;sed -ie s/$n/$((n+1))/ $0
Джефф Риди
источник
5

Рубин: 31 21 символов

(Это переписывание Abhijit «s решения Python . Если вы как базовая идея, upvote своего ответа, как я.)

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

Образец прогона:

bash-4.2$ ruby increment.rb 
1

bash-4.2$ ruby increment.rb 
2

bash-4.2$ ruby increment.rb 
3
manatwork
источник
1
Используя <<вы можете сохранить некоторые символы: `open ($ 0
,? A
Doh. Старая добрая привычка гарантировать, что файлы данных будут закрыты… :( Спасибо, @steenslag.
manatwork
5

* ш, 17

curl -L x.co/z7Uk

Использование веб-сервиса, другой подход, чем другие существующие решения до сих пор. Лимит: память о моей машине.


JavaScript, 40

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

Едва ли считается программой, но в любом случае она довольно длинная. Не работает в Firefox в локальном файле. Лимит: 2 ^ 31.

копия
источник
Почему бы не alert(localStorage.a=~~localStorage.a+1)41, и технически говоря, программа javascript была бы без тегов сценария, которых было бы только 33
Дэвид Малдер
@DavidMulder О, верно
скопируйте
2
До 33:alert((l=localStorage).a=~~l.a+1)
nitro2k01
@ nitro2k01: Кажется, я скопировал неправильный материал, потому что это был 33, о котором я говорил O :) 41 - это то же самое, что и теги сценария ~ (ну, я сделал декларацию перед предупреждением, потому что он такой же длинный, a=localStorage;alert(a.b=~~a.b+1)хотя ваш выглядит лучше: D
Дэвид Малдер
1
@WallyWest Нет, он на самом деле побитовый инвертирует и использует странные правила преобразования типов в JavaScript
скопируйте
4

PHP 31 37 символов

Самостоятельная модификация. Это считается в одинарном. Будьте осторожны, чтобы ваш текстовый редактор не пытался быть полезным и вставлял символ новой строки после 1. Он будет работать (правильно) только в PHP <5.3.2, потому что он полагается на php для закрытия дескрипторов открытых файлов при завершении работы. Или это допустимо для утечки файловых дескрипторов?

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

Оригинальная версия (36 символов), все версии PHP:

<?file_put_contents(__FILE__,1,8)?>1
Тим Сегин
источник
2
"Это считается одинарным" ... Лучший гольф-хак, который я видел давно!
lochok
Я бросаю вам вызов. PHP решение для 35 символов , и это в десятичном виде :)
Томас
1
Ух ты, я вижу, ты избил меня своим собственным методом! Поздравляем! :-) И спасибо за улучшение моего метода. Я включил это в свой ответ и дал вам кредит на это.
Томас
@ Томас, я в долгу перед тобой. Если бы ты не бросил мне вызов, я бы не стал снова смотреть на этот ответ.
Тим Сегин
Тим, это как раз радость и волнение соперничества друг с другом! :)
Томас
2

Питон, 50

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

Он использует тот же подход, что и в ответе primo, и аналогичным образом дает сбой при 100-м прогоне.

GRC
источник
2

J (58)

Вам нужно запустить это как скрипт, он не будет работать из командной строки J, очевидно.

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

В J токенайзер, который использует интерпретатор, доступен как ;:функция, поэтому, если он xсодержит код J, он ;:xсодержит токены J, то есть:

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

Так:

  • echo m=.1: установите mв 1 и запишите это на экран
  • k=.1{ARGV: сохранить второй элемент в ARGV(имя скрипта) в k.
  • ... 1!:2[k: записать в файл следующую строку k:
  • ;:1!:1[k: чтение k, текущий скрипт и токенизация
  • (<":m+1)(<3)}: заменить третий токен строковым представлением m + 1
  • ;:^:_1: запустить токенизатор в обратном порядке, создав строку
  • exit: выйти из интерпретатора (он не делает это сам по себе, даже если вы запускаете скрипт)
Мэринус
источник
2

PHP, 34 33 символа

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

Спасибо Тиму за обновление! Мое старое решение:

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

Проблема заключается в том, что $_SESSION[A]это ""- пустая строка - в первой итерации, но session_start()возвращает 1, вы можете добавить его и убить двух или трех мух в одном кадре!

Решение с правильным синтаксисом (35 символов):

<?=session_start()+$_SESSION[A]++?>
Tomas
источник
Я буду судить секунду по двум причинам. «Однако ваша программа не должна записывать какие-либо новые файлы.»: Я не уверен, не является ли это проблемой для этого решения, так как открытие сеанса создает временный файл. Также сессия gc по умолчанию происходит через 24 минуты. Значит ли это на самом деле как «за несколько сеансов» тогда? Может быть, ОП может прокомментировать.
Тим Сегин
Тим, программа не пишет никаких файлов. Я не несу ответственности за то, что делает переводчик. Это так же, как HTML-страница не отвечает за создание браузером некоторых файлов в кеше, SQL-запрос не отвечает за созданные временные таблицы на диске и т. Д. Что касается времени ожидания, оно не было указано в правилах :) В любом случае, я не конечно, почему, но на моей машине счетчик все еще держится более нескольких часов !!!
Томас
Да, именно поэтому я говорю, что буду ждать, чтобы увидеть, что думает ОП. Вы определенно нашли очень серую область. Вам не нужен закрывающий тег php между прочим. так что вашей 34-символьной версии достаточно. У меня есть идея для улучшения, но сначала мне нужно ее протестировать.
Тим Сегин
Хорошо, я получил это до 33 символов. Смею вас сделать лучше. ;)
Тим Сегин
@TimSeguine Ааааа, какое изменение в вашем тоне! :-) Теперь вас не волнуют правила в моем посте! :-D
Томас
2

Haskell - 36 байт

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

Просто добавляет +1в конец исходный файл, который предполагается именовать a.hs. .hsРасширение является обязательным и в GHC и GHCI.

судейская шапочка
источник
1

Партия - 41

Учитывая пример использования, я, вероятно, не предположил бы, что этот метод является жизнеспособным - он переименовывает файл .bat, содержащий скрипт -

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

Сохраните это в файл с именем 0.bat - и вызовите с помощью 0.bat 2>nul. 2>nulперенаправляет stderr на nul, что необходимо, потому что этот скрипт переименует файл, содержащий скрипт, как только он это сделает, cmd, очевидно, больше не сможет видеть скрипт (до того, как он достигнет EOF) и вернет ошибкуThe batch file cannot be found.

Каждый последующий вызов сценария, конечно, должен быть 1.bat 2>nul ... 2.bat 2>nul ... 3.bat 2>nul ... etc ...

unclemeat
источник
Основываясь на этой идее, вы можете сделать вариант моего ответа php о подсчете в унарном, и я думаю, что он даже короче этого.
Тим Сегин
1

скрипт mIRC, 28/22 байта

Если поместить на вкладку «псевдонимы», «псевдоним» может быть опущен и составляет 22 байта.

alias x inc %i | echo -ag %i
FIQ
источник
1

Python, 49 48 символов

Я понял, что это будет только 48 символов на Windows из-за \r\n. В противном случае это должно быть 49.

n=1

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

Дешевый грабеж метода от @grc

jamylak
источник
1

C 190 символов. Работает только на 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
источник
Я думаю, это довольно просто, как это работает, но все же, если потребуется, я могу добавить объяснение :-)
Abhijit
1

C #, 142 символа

int v=(Microsoft.Win32.Registry.CurrentUser.GetValue("c") as int?)??0+1;Console.Write(v);Microsoft.Win32.Registry.CurrentUser.SetValue("c",v);
ZafarYousafi
источник
Вы можете использовать более короткое имя, например, z, вы получите несколько символов вниз.
Это не так.
Вы также должны удалить пробелы.
Timtech
1
Вместо того, чтобы каждый раз вызывать длинное имя API, сохраните его в переменной типа: var a = Microsoft.Win32.Registry.CurrentUser; a.GetValue (); a.setValue ();
Xantix
1

Tcl, 63 или 73 байта

  • С некоторым веб-сервисом это 73:

    package require http
    puts [set [http::geturl http://example.com/c](data)]
    
  • Модификация сама по себе составляет 63:

    proc a a {puts [string le $a]};puts -nonewline [open $argv0 a] a; a a
    
Йоханнес Кун
источник
1

C # - 201 239 234 символа

Работает первые 255 раз, затем обнуляется до 0. При первом выполнении ничего не выдается.

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

Сохранить как Main.cs, скомпилировать с

gmcs Main.cs

Протестировано с gmcs 2.10.8.1 и Mono runtime 2.10.8.1-5ubuntu2

user3188175
источник
1
На самом деле - я сделал. «Программа должна быть в состоянии хотя бы достичь номера 14»
Лочок
Работает сейчас 255 раз.
user3188175
1

Powershell, 47 байт

предполагает, что сценарий назван a.ps1

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

Скрипт перезапишет себя, заменив 0первую строку на1 , 2,3 и так далее.

также можно сохранить еще 8 байтов, заменив оба экземпляра a.ps1 с 1и сохранения сценария в виде файла с именем1 , хотя это немного далеко для меня.

Замените вторую строку этим, если файл не сохранен как «a.ps1».

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

0 на первой строке инициализировать счет

Linebreak обеспечивает самый простой способ разбить файл на две части

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

он берет файл «a.ps1» и считывает его как массив строк, затем мы перебираем его с [0..1]и устанавливаем его в переменные, $nкоторые преобразуются как [int]и $tсоответственно, так что 0первая строка становится $nи код на второй строке становится$t

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

При этом использовалась ,1,2запись массива для создания массива из двух элементов, один из которых является числом, хранящимся в$n предварительно увеличенном виде и выводимое на стандартный вывод с использованием неявных скобок, второе - вторая строка текста из файла, а затем также выводится это в файл с именем «a.ps1»

поскольку и вход, и выход являются массивами строк, требуется минимальное форматирование, и интерпретатор принимает почти все.

colsw
источник
1

Zsh (без coreutils), 32 байта

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

(Обратите внимание на завершающий перевод строки) Использует длину скрипта. На каждом вызове, последняя линия , показанная выше будет добавлять :(идентичный true) и перевод строки в сценарий, отсюда /2.

Попробуйте онлайн!

GammaFunction
источник
0

Rust / cargo-script, 283 байта

Один лайнер:

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

Сохранить как wи запустить с 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

Не повторяйте слишком быстро, иначе он застрянет .

Частично негольфированный:

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

Сломается после 99999;

Vi.
источник
0

GNU sed, 13 + 1 (флаг n) = 14 байт

$=;$eecho>>s

Выполнить: sed -nf ss

Предполагается, что имя файла источника называется s. После кода необходим завершающий символ новой строки, который был подсчитан в общем количестве байтов. Объяснение:

$=           # 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
источник