Số tăng dần, qua nhiều phiên


30

Đại lý Golf buổi tối,

Nhiệm vụ của bạn là thay mặt cho người khổng lồ giải trí khét tiếng Eviltronic Arts. Là một phần trong kế hoạch bất chính của họ về nô lệ và giải trí thế giới, họ phải bán càng nhiều bản sao của SimStation V càng tốt. Điều này có nghĩa là phần mềm phải ngừng hoạt động một cách bí ẩn, sau khi khởi động nó một vài lần.

Mục tiêu của bạn là viết một chương trình đếm số lần nó đã được chạy. Chương trình không phải làm gì khác sau đó ghi số nguyên vào thiết bị xuất chuẩn. Lần đầu tiên được chạy, nó sẽ trả về "1". "2" tiếp theo và cứ thế. Chương trình ít nhất phải có thể đạt đến số "14", nhưng không có giới hạn trên bắt buộc.

Tuy nhiên, chương trình của bạn không được ghi bất kỳ tập tin mới. Truy cập chính nó, hoặc đăng ký, hoặc thậm chí internet là hoàn toàn OK. Nhưng một số người dùng của chúng tôi nghi ngờ về các tệp mới và sẽ chỉ ghi đè lên chúng! Dây thần kinh! Đánh bại những hạn chế trên phần mềm họ mua một cách hợp pháp!

Chương trình không thể giả sử trình thông dịch hoặc trình bao ổn định - chương trình vẫn phải hoạt động nếu toàn bộ trình thông dịch hiện tại máy tính này được khởi động lại giữa lúc chạy.

Vì nó phải càng không bị phát hiện càng tốt, mã nguồn ngắn nhất sẽ giành chiến thắng.

Chúc các đại lý may mắn. Ngành công nghiệp giải trí đang trông cậy vào bạn.


Câu trả lời:


21

kịch bản bash, 39 , 37 , 21 18

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

Ngắn gọn và ngọt ngào, bài nộp đầu tiên của tôi trong môn đánh gôn :)


1
Thay thế echobằng id: D
thejh

nó nối thêm đầu ra không cần thiết vào tập tin, nó sẽ được chuyển hướng đến stderr
Rozuur

Huh? Không có gì ở đây tương tác với stderr. Nhưng đúng, nó làm cho tập tin phát triển lớn hơn theo thời gian.
thejh

có thể được đánh gôn đến 17: Thay thế ;bằng dòng mới và loại bỏ dòng mới. Nó thậm chí sẽ trông đẹp hơn rất nhiều :-)
Tomas

Là chỉ kích thước bắt đầu của kịch bản có liên quan? Xem xét rằng điều này sẽ tăng kích thước mỗi lần chạy.
khai mạc

18

Con trăn, 40 , 39 , 38 ký tự

Ngoài ra, không có giới hạn trên như vậy trong thời gian chạy:

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

Như bạn có thể thấy, kích thước của chương trình tăng dần nhưng không có hạn chế nào như vậy trong vấn đề ban đầu. Tôi tin rằng, quy mô của chương trình đã gửi là tất cả những gì quan trọng


Tôi không nghĩ rằng bạn cần phải đặt a+, anên làm việc tốt.
beary605

@ beary605: Cảm ơn vì Tiền boa
Abhijit

10

PHP 48 byte

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

Một cách tiếp cận tự sửa đổi đơn giản. Sau khi chạy 99 lần, nó sẽ gặp sự cố một cách ngoạn mục.

$ 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

không phải là khoảng trắng duy nhất không cần thiết?
John Dvorak

1
@JanDvorak Khoảng trắng duy nhất là cần thiết trong chương trình, nếu không, nó sẽ bị sập chỉ sau 10 lần thực thi, không đáp ứng các đặc điểm kỹ thuật. Sau lần thực hiện thứ 100, dấu chấm phẩy bị ghi đè, gây ra lỗi cú pháp.
Primo

giải pháp PHP cho 35 ký tự , muốn đánh bại tôi không? :)
Tomas


5

Ruby: 31 21 ký tự

(Đây là một ghi đè của Abhijit 's giải pháp Python . Nếu bạn thích ý tưởng cơ bản, upvote câu trả lời của mình, như tôi đã làm.)

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

Chạy mẫu:

bash-4.2$ ruby increment.rb 
1

bash-4.2$ ruby increment.rb 
2

bash-4.2$ ruby increment.rb 
3

1
Sử dụng <<bạn có thể lưu một số ký tự: `open ($ 0 ,? A) <<" + 1 "; p 1 \`
steenslag

Doh. Thói quen cũ tốt để đảm bảo các tập tin dữ liệu được đóng lại ... :( Cảm ơn bạn, @steenslag.
manatwork

5

* sh, 17

curl -L x.co/z7Uk

Sử dụng một dịch vụ web, một cách tiếp cận khác với các giải pháp hiện có khác cho đến nay. Giới hạn: Bộ nhớ của máy tôi.


JavaScript, 40

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

Hầu như không được coi là một chương trình, nhưng dù sao nó cũng khá dài. Không hoạt động trong Firefox trong một tệp cục bộ. Giới hạn: 2 ^ 31.


Tại sao không phải là alert(localStorage.a=~~localStorage.a+1)41 và về mặt kỹ thuật, chương trình javascript sẽ không có các thẻ script chỉ có 33
David Mulder

@DavidMulder Ồ, phải
sao chép

2
Xuống tới 33:alert((l=localStorage).a=~~l.a+1)
nitro2k01

@ nitro2k01: Có vẻ như tôi đã sao chép sai nội dung, vì đó là 33 tôi đã nói về O :) 41 là điều tương tự bao gồm các thẻ script ~ (tốt, tôi đã giải mã trước cảnh báo, vì nó cũng dài như a=localStorage;alert(a.b=~~a.b+1)vậy : mặc dù là của bạn trông đẹp hơn: D
David Mulder

1
@WallyWest Không, nó thực sự đảo ngược và lạm dụng các quy tắc chuyển đổi loại kỳ lạ của JavaScript
sao chép

4

PHP 31 37 ký tự

Tự sửa đổi. Nó được tính trong unary. Hãy cẩn thận rằng trình soạn thảo văn bản của bạn không cố gắng hữu ích và chèn một ký tự dòng mới sau 1. Nó sẽ chỉ hoạt động (đúng) trong PHP <5.3.2 vì nó dựa vào php để đóng mô tả tệp mở khi tắt máy. Hoặc có thể chấp nhận để rò rỉ mô tả tập tin?

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

Phiên bản gốc (36 ký tự), tất cả các phiên bản PHP:

<?file_put_contents(__FILE__,1,8)?>1

2
"Nó được tính bằng unary" ... Hack Golf tốt nhất tôi đã thấy trong một thời gian dài!
lochok

Tôi thách thức bạn Giải pháp PHP cho 35 ký tự , và đó là số thập phân :)
Tomas

1
Wow, tôi thấy bạn đã đánh bại tôi bằng phương pháp của riêng bạn! Xin chúc mừng! :-) Và cảm ơn vì sự cải tiến của phương pháp của tôi. Tôi đã đưa nó vào câu trả lời của mình và cho bạn một khoản tín dụng cho điều đó.
Tomas

@Tomas tôi nợ bạn tín dụng. Nếu bạn không thách thức tôi, tôi sẽ không nhìn vào câu trả lời này nữa.
Tim Seguine

Tim, đó chính xác là niềm vui và sự phấn khích khi thử thách lẫn nhau! :)
Tomas

2

Con trăn, 50

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

Nó sử dụng cách tiếp cận tương tự như câu trả lời của primo và sự cố tương tự trên đường chạy thứ 100.


2

J (58)

Bạn cần chạy nó như một kịch bản, nó sẽ không hoạt động từ dòng lệnh J rõ ràng.

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

Trong J, mã thông báo mà trình thông dịch sử dụng có sẵn dưới dạng ;:hàm, vì vậy nếu xchứa mã J, ;:xcó chứa mã thông báo J, nghĩa là:

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

Vì thế:

  • echo m=.1: đặt mthành 1 và viết nó lên màn hình
  • k=.1{ARGV: lưu trữ phần tử thứ 2 trong ARGV(tên tập lệnh) trong k.
  • ... 1!:2[k: ghi chuỗi sau vào tệp trong k:
  • ;:1!:1[k: đọc k, tập lệnh hiện tại và mã thông báo
  • (<":m+1)(<3)}: thay thế mã thông báo thứ 3 bằng cách biểu diễn chuỗi m + 1
  • ;:^:_1: chạy mã thông báo ngược lại, tạo ra một chuỗi
  • exit: thoát trình thông dịch (nó không tự làm điều đó ngay cả khi bạn chạy tập lệnh)

2

PHP, 34 33 ký tự

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

Cảm ơn Tim đã cập nhật! Giải pháp cũ của tôi:

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

Vấn đề là $_SESSION[A]""- chuỗi rỗng - trong lần lặp đầu tiên, nhưng khi session_start()trở về 1, bạn có thể thêm nó và giết hai hoặc ba con ruồi trong một shot!

Giải pháp với cú pháp đúng (35 ký tự):

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

Tôi sẽ giữ phán quyết trong một giây vì hai lý do. "Tuy nhiên, chương trình của bạn không được ghi bất kỳ tệp mới nào.": Tôi không chắc liệu đây có phải là vấn đề đối với giải pháp này hay không, vì việc mở một phiên tạo ra một tệp tạm thời. Ngoài ra phiên gc mặc định xảy ra sau 24 phút. Điều đó thực sự được tính là "qua nhiều phiên"? Có lẽ OP có thể bình luận.
Tim Seguine

Tim, chương trình không ghi bất kỳ tập tin. Tôi không chịu trách nhiệm cho những gì người phiên dịch làm. Nó giống như trang HTML không chịu trách nhiệm cho trình duyệt tạo một số tệp trong bộ đệm, truy vấn sql không chịu trách nhiệm tạo các bảng tạm thời trên đĩa, v.v ... Về phần thời gian chờ, nó không được chỉ định trong quy tắc :) Dù sao, tôi không chắc chắn tại sao nhưng trên máy của tôi, quầy vẫn giữ trong hơn vài giờ !!!
Tomas

Vâng, đó là lý do tại sao tôi nói rằng tôi sẽ chờ xem OP nghĩ gì. Bạn chắc chắn tìm thấy một khu vực rất xám. Bạn không cần thẻ btw đóng btw. Vì vậy, phiên bản 34 char của bạn là đủ. Tôi có một ý tưởng cho một cải tiến, nhưng tôi sẽ cần phải thử nghiệm nó trước.
Tim Seguine

Được rồi, tôi đã giảm xuống còn 33 ký tự. Tôi dám làm bạn tốt hơn. ;)
Tim Seguine

@TimSeguine Aaaah, thật là một sự thay đổi trong giọng điệu của bạn! :-) Bây giờ bạn không quan tâm đến các quy tắc trong bài viết của tôi rất nhiều! :-D
Tomas

2

Haskell - 36 byte

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

Đơn giản chỉ cần thêm +1vào cuối tệp nguồn, được giả sử là được đặt tên a.hs. Việc .hsmở rộng là bắt buộc trong cả ghc và ghci.



1

Mẻ - 41

Với trường hợp sử dụng ví dụ, có lẽ tôi sẽ không cho rằng kỹ thuật này là khả thi - Nó đổi tên tệp .bat chứa tập lệnh -

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

Lưu tệp này vào một tệp được gọi 0.bat- và gọi bằng cách sử dụng 0.bat 2>nul. 2>nulchuyển hướng stderr sang nul là cần thiết bởi vì tập lệnh này sẽ đổi tên tập tin chứa tập lệnh, một khi cmd đó rõ ràng không thể thấy tập lệnh nữa (trước khi nó chạm EOF) và sẽ trả về lỗiThe batch file cannot be found.

Tất cả các cuộc gọi liên tiếp của kịch bản tất nhiên sẽ phải 1.bat 2>nul ... 2.bat 2>nul ... 3.bat 2>nul ... etc ...


Dựa trên ý tưởng này, bạn có thể thực hiện một biến thể của câu trả lời php của tôi về việc đếm đơn nhất và tôi nghĩ nó thậm chí còn ngắn hơn thế này.
Tim Seguine

1

tập lệnh mIRC, 28/22 byte

Nếu đặt trong tab "bí danh", "bí danh" có thể được bỏ qua tạo ra 22 byte.

alias x inc %i | echo -ag %i

1

Con trăn, 49 48 ký tự

Tôi nhận ra rằng đây sẽ chỉ là 48 ký tự trên Windows do \r\n. Nếu không thì phải là 49.

n=1

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

Một ripoff giá rẻ của phương thức bởi @grc


1

C, 190 ký tự. Chỉ hoạt động trên 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);
}

Tôi nghĩ nó khá đơn giản làm thế nào nó hoạt động, nhưng nếu cần tôi có thể thêm một lời giải thích :-)
Abhijit

1

C #, 142 ký tự

int v=(Microsoft.Win32.Registry.CurrentUser.GetValue("c") as int?)??0+1;Console.Write(v);Microsoft.Win32.Registry.CurrentUser.SetValue("c",v);

Bạn có thể sử dụng một tên ngắn hơn như z, sẽ giúp bạn có một vài ký tự.
Đó là NÓI.

Bạn cũng nên loại bỏ khoảng trắng.
Timtech

1
Thay vì gọi tên API dài mỗi lần, hãy lưu trữ nó trong một biến như: var a = Microsoft.Win32.Registry.C hiệnUser; a.GetValue (); a.SetValue ();
Xantix

1

Tcl, 63 hoặc 73 byte

  • Với một số dịch vụ web, 73:

    package require http
    puts [set [http::geturl http://example.com/c](data)]
    
  • Sửa đổi chính nó là 63:

    proc a a {puts [string le $a]};puts -nonewline [open $argv0 a] a; a a
    

1

C # - 201 239 234 ký tự

Hoạt động trong 255 lần đầu tiên, sau đó kết thúc thành 0. Nó sẽ không tạo ra bất cứ điều gì trong lần thực hiện đầu tiên.

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

Lưu dưới dạng Main.cs, biên dịch với

gmcs Main.cs

Đã thử nghiệm với gmcs 2.10.8.1 và Mono runtime 2.10.8.1-5ubfox2


1
Thật ra - tôi đã làm. "Chương trình phải có khả năng ít nhất đạt được số 14"
lochok

Nó hoạt động bây giờ cho 255 lần.
dùng3188175

1

Powershell, 47 byte

giả sử kịch bản được đặt tên a.ps1

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

Các kịch bản sẽ ghi đè lên bản thân thay thế 0trên dòng đầu tiên với 1, 2, 3và vân vân.

cũng có thể lưu thêm 8 byte bằng cách thay thế cả hai trường hợp a.ps1bằng 1và lưu tập lệnh dưới dạng tệp có tên 1mặc dù điều này hơi xa đối với tôi.

Thay thế dòng thứ hai bằng dòng này nếu tệp không được lưu dưới dạng 'a.ps1'.

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

0 trên dòng đầu tiên để khởi tạo số đếm

Linebreak cung cấp cách dễ nhất để chia tệp thành hai

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

cái này lấy tệp 'a.ps1' và đọc nó dưới dạng một mảng các dòng, sau đó chúng tôi lặp lại nó với nó [0..1]và đặt nó vào các biến $nđược tạo thành [int]$ttương ứng, sao cho dòng 0trên dòng đầu tiên trở thành $nvà mã ' 'trên dòng thứ hai trở thành$t

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

Điều này đã sử dụng ,1,2ký hiệu mảng, để tạo ra một mảng gồm hai phần tử, một phần tử được lưu trữ trong $nphần tăng trước và xuất ra thành stdout bằng cách sử dụng dấu ngoặc ẩn, phần thứ hai là dòng văn bản thứ hai từ tệp, sau đó cũng xuất ra nó vào tệp có tên 'a.ps1'

vì cả đầu vào và đầu ra là các chuỗi của chuỗi, cần có định dạng tối thiểu và hầu hết mọi thứ đều do trình thông dịch đảm nhận.


1

Zsh (không có coreutils), 32 byte

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

(Lưu ý dòng mới theo dõi) Sử dụng độ dài của tập lệnh. Trên mỗi lời gọi, dòng cuối cùng được hiển thị ở trên sẽ nối thêm :(giống hệt true) và một dòng mới vào tập lệnh, do đó /2.

Hãy thử trực tuyến!


0

Rust / Freight-script, 283 byte

Lót:

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

Lưu dưới dạng wvà chạy với 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

Đừng lặp lại quá nhanh nếu không nó sẽ bị kẹt .

Một phần vô dụng:

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

Sẽ nghỉ sau 99999;


0

GNU sed, 13 + 1 (cờ n) = 14 byte

$=;$eecho>>s

Chạy: sed -nf ss

Giả định là tên tệp nguồn được gọi s. Một dòng mới theo sau là cần thiết sau mã, được tính trong tổng số byte. Giải trình:

$=           # 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'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.