Збільшення чисел за кілька сеансів


30

Добрі вечірні гольф-агенти,

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

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

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

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

Оскільки це повинно бути якомога невиразніше, виграє найкоротший вихідний код.

Агенти удачі Індустрія розваг розраховує на вас.


Відповіді:


21

bash script, 39 , 37 , 21 18

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

Короткий і милий, моє перше подання в коді гольфу :)


1
Замініть echoна id: D
thejh

він додає зайвий вихід до файлу, який буде переспрямовано на stderr
Rozuur

Так? Тут немає нічого, що взаємодіє з stderr. Але правильно, це змушує файл зростати з часом.
thejh

можна пограти в гольф до 17: Замініть нову; лінію та видаліть нижню лінію. Це навіть буде виглядати набагато приємніше :-)
Томаш

Чи відповідний лише початковий розмір сценарію? Враховуючи, що це збільшуватиметься в розмірі з кожним циклом.
нечисте м'ясо

18

Пітон, 40 , 39 , 38 символів

Також немає такої верхньої межі часу виконання:

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

Як бачите, розмір програми поступово збільшується, але такого обмеження в початковій проблемі не було. Я вважаю, що розмір поданої програми - це все, що має значення


Я не думаю, що потрібно ставити 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 виконання, що не відповідає специфікації. Після 100-го виконання крапка з комою переписується, що викликає синтаксичну помилку.
прима

Отримали рішення на PHP на 35 символів , хотіли бити мене? :)
Томаш


5

Ruby: 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

1
Використовуючи <<ви можете зберегти кілька символів: `open ($ 0,? A) <<" + 1 "; p 1 \`
steenslag

До. Стара добра звичка забезпечувати закриття файлів даних… :( Дякую, @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 Nope, це насправді побітове інвертування та зловживає дивними правилами перетворення типу 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
Вау, я бачу, ти побив мене своїм методом! Вітаємо! :-) І дякую за вдосконалення мого методу. Я включив це у свою відповідь і віддячив вам за це.
Томаш

@Tomas я зобов'язаний вам кредитом. Якби ти не кинув мені виклик, я б не переглядав цю відповідь ще раз.
Тім Сегуїн

Тіме, саме ця радість і хвилювання кидають виклик один одному! :)
Томаш

2

Пітона, 50

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

Він використовує той самий підхід, що і відповідь примо, і аналогічно руйнується на 100-му пробігу.


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: збережіть 2-й елемент у ARGV(ім'я сценарію) в k.
  • ... 1!:2[k: напишіть наступний рядок у файл у k:
  • ;:1!:1[k: прочитати k, поточний сценарій та токенізувати
  • (<":m+1)(<3)}: замініть 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]++?>

Я буду приймати рішення на секунду з двох причин. "Однак ваша програма не повинна записувати жодних нових файлів.": Я не впевнений, чи це не проблема для цього рішення, оскільки відкриття сеансу створює тимчасовий файл. Також сеанс gc за замовчуванням відбувається через 24 хвилини. Чи справді це тоді вважається "над кількома сесіями"? Можливо, ОП може прокоментувати.
Тім Сегуїн

Тим, програма не записує жодних файлів. Я не несу відповідальності за те, що робить перекладач. Це те саме, що HTML-сторінка не відповідає за створення браузера деяких файлів у кеші, sql-запит не несе відповідальності за створені тимчасові таблиці на диску тощо. Що стосується тайм-ауту, він не був вказаний у правилах :) Так чи інакше, я не впевнений, чому, але на моїй машині лічильник все ще тримається більше декількох годин !!!
Томаш

Так, саме тому я кажу, що я зачекаю, щоб побачити, що думає ОП. Ви точно знайшли дуже сіру зону. Вам не потрібен закриваючий тег php btw. тож ваша версія 34 знаків достатня. У мене є ідея для вдосконалення, але мені потрібно спочатку її перевірити.
Тім Сегуїн

Гаразд, я знизив це до 33 символів. Я зважусь на те, щоб ти зробила краще. ;)
Тім Сегейн

@TimSeguine Aaaah, яка зміна твого тону! :-) Тепер ти так не хвилюєшся правилами в моєму пості! :-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 ...


Виходячи з цієї ідеї, ви можете зробити варіацію моєї відповіді на php підрахунку в одинаковій формі, і я думаю, вона ще коротша за цю.
Тім Сегуїн

1

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

Якщо розмістити вкладку "псевдоніми", "псевдонім" можна пропустити, склавши 22 байти.

alias x inc %i | echo -ag %i

1

Пітон, 49 48 символів

Я зрозумів, що це буде лише 48 знаків у Windows через \r\n. Інакше має бути 49.

n=1

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

Недорогий рипофф методу від @grc


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

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

Ви можете використовувати скорочене ім’я, наприклад z, аби зменшити кілька символів.
ЦеNotALie.

Також слід видалити пробіл.
Тімтех

1
Замість того, щоб викликати довге ім'я API щоразу, зберігайте його у змінній, наприклад: var a = Microsoft.Win32.Registry.CurrentUser; a.GetValue (); a.SetValue ();
Ксантікс

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 час виконання 2.10.8.1-5ubuntu2


1
Власне - я і зробив. "Програма повинна мати можливість принаймні досягти числа 14"
lochok

Він працює зараз 255 разів.
користувач3188175

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попередньо збільшеному і виведене в stdout за допомогою неявних дужок, другий - другий рядок тексту з файлу, а потім також вихід його у файл з назвою 'a.ps1'

оскільки вхід і вихід є масивами рядків, потрібне мінімальне форматування, і майже все бере на себе перекладач.


1

Zsh (без Coreutils), 32 байти

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

(Зверніть увагу на тривалість нового рядка) Використовується довжина сценарію. У кожному виклику останній рядок, показаний вище, буде доданий :(ідентичний true) та новий рядок до сценарію, отже /2.

Спробуйте в Інтернеті!


0

Іржа / вантаж-сценарій, 283 байти

Oneliner:

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 р .;


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'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.