การเพิ่มจำนวนมากกว่าหลายครั้ง


30

ตัวแทนกอล์ฟราตรีสวัสดิ์

ภารกิจของคุณคือในนามของ Eviltronic Arts ยักษ์ใหญ่ด้านความบันเทิงที่มีชื่อเสียง ในฐานะที่เป็นส่วนหนึ่งของแผนการชั่วช้าสำหรับการตกเป็นทาสและความบันเทิงในโลกพวกเขาจะต้องขาย SimStation V ให้มากที่สุดเท่าที่จะเป็นไปได้ ซึ่งหมายความว่าซอฟต์แวร์ต้องหยุดทำงานอย่างลึกลับหลังจากเริ่มใช้งานสองสามครั้ง

เป้าหมายของคุณคือการเขียนโปรแกรมที่นับจำนวนครั้งที่มันถูกเรียกใช้ โปรแกรมจะต้องไม่ทำอะไรอื่นแล้วเขียนจำนวนเต็มไปยัง stdout ครั้งแรกที่มันถูกเรียกใช้มันควรจะกลับมา "1" ถัดไป "2" และอื่น ๆ โปรแกรมต้องสามารถเข้าถึงหมายเลข "14" เป็นอย่างน้อย แต่ไม่มีข้อ จำกัด ด้านบน

อย่างไรก็ตามโปรแกรมของคุณจะต้องไม่เขียนไฟล์ใหม่ใด ๆ การเข้าถึงตัวเองหรือรีจิสตรีหรือแม้กระทั่งอินเทอร์เน็ตก็ไม่เป็นไร แต่ผู้ใช้ของเราบางคนสงสัยไฟล์ใหม่และจะเขียนทับมันเท่านั้น! ระบบประสาท! การเอาชนะข้อ จำกัด ของซอฟต์แวร์ที่พวกเขาซื้ออย่างถูกกฎหมาย!

โปรแกรมไม่สามารถใช้ตัวแปลที่มีเสถียรภาพหรือเชลล์ - โปรแกรมจะต้องยังคงทำงานหากทั้งตัวแปล nay shell nay คอมพิวเตอร์นั้นถูกรีสตาร์ทระหว่างการทำงาน

เนื่องจากจะต้องไม่สามารถตรวจจับได้มากที่สุดซอร์สโค้ดที่สั้นที่สุดจะเป็นผู้ชนะ

ขอให้โชคดี อุตสาหกรรมบันเทิงกำลังรอคุณอยู่


ที่เกี่ยวข้อง

คำตอบ:


21

bash script, 39 , 37 , 21 18

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

สั้นและหวานใจการส่งครั้งแรกของฉันในการตีกอล์ฟ :)


1
แทนที่echoด้วยid: D
thejh

มันผนวกเอาท์พุทที่ไม่จำเป็นไปยังไฟล์ซึ่งจะถูกเปลี่ยนเส้นทางไปยัง stderr
Rozuur

ฮะ? ไม่มีอะไรที่นี่ที่โต้ตอบกับ stderr แต่มันทำให้ไฟล์มีขนาดใหญ่ขึ้นเมื่อเวลาผ่านไป
thejh

สามารถเล่นกอล์ฟถึง 17:แทนที่;ด้วยขึ้นบรรทัดใหม่และลบบรรทัดขึ้นบรรทัดใหม่ มันจะดูดีกว่ามาก :-)
โทมัส

ขนาดเริ่มต้นของสคริปต์นั้นเกี่ยวข้องหรือไม่ พิจารณาว่าสิ่งนี้จะเพิ่มขนาดการวิ่งทุกครั้ง
ลุง

18

Python, 40 , 39 , 38 ตัวอักษร

นอกจากนี้ยังไม่มีข้อ จำกัด ด้านบนของ runtime:

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

ช่องว่างเดียวไม่จำเป็นหรือไม่
John Dvorak

1
@JanDvorak ช่องว่างเดียวเป็นสิ่งจำเป็นในโปรแกรมไม่เช่นนั้นจะมีปัญหาหลังจากการประมวลผลเพียง 10 ครั้งซึ่งไม่เป็นไปตามข้อกำหนด หลังจากการประมวลผลครั้งที่ 100 เครื่องหมายอัฒภาคจะถูกเขียนทับซึ่งทำให้เกิดข้อผิดพลาดทางไวยากรณ์
primo

มีวิธีแก้ปัญหา PHP สำหรับ 35 ตัวอักษรต้องการเอาชนะฉันไหม :)
โทมัส


5

Ruby: 31 21 ตัวอักษร

(นี่คือเขียนของAbhijit 's วิธีการแก้ปัญหาหลาม . ถ้าคุณชอบความคิดที่ฐาน 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
,?

Doh นิสัยแบบเก่าที่ดีในการทำให้มั่นใจว่าไฟล์ข้อมูลจะถูกปิด… :( ขอบคุณ @steenslag.
จัดการ

5

* sh, 17

curl -L x.co/z7Uk

การใช้บริการเว็บเป็นวิธีการที่แตกต่างจากโซลูชันที่มีอยู่ในปัจจุบัน จำกัด : หน่วยความจำของเครื่องของฉัน


JavaScript, 40

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

แทบจะไม่นับเป็นโปรแกรม แต่มันค่อนข้างนาน ไม่ทำงานใน Firefox ในไฟล์ในเครื่อง จำกัด : 2 ^ 31


Why not alert(localStorage.a=~~localStorage.a+1) 41 and technically speaking the javascript program would be without the script tags which would be only 33
David Mulder

@DavidMulder Oh, right
copy

2
Down to 33: alert((l=localStorage).a=~~l.a+1)
nitro2k01

@nitro2k01: Seems I copied the wrong stuff, cause that was the 33 I was talking about O:) 41 was the same thing including script tags~ (well, I did the decleration before the alert, cause it's just as long: a=localStorage;alert(a.b=~~a.b+1) though yours looks nicer :D
David Mulder

1
@WallyWest Nope, it's actually bitwise invert and abuses JavaScript's weird type conversion rules
copy

4

PHP 31 37 characters

Self modifying. It counts in unary. Be careful that your text editor doesn't try to be helpful and insert a newline character after the 1. It will only work (properly) in PHP < 5.3.2 because it relies on php to close open file descriptors on shutdown. Or is it acceptable to leak file descriptors?

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

Original version (36 chars), all PHP versions:

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

2
"It counts in unary"... Best Golf Hack I've seen for a long time!
lochok

I challenge you. PHP solution for 35 chars, and it's in decimal :)
Tomas

1
Wow, I see you have beaten me with your own method! Congratulations! :-) And thanks for the improvement of my method. I have included it in my answer and gave you a credit for that.
Tomas

@Tomas I owe you credit. If you hadn't challenged me, I wouldn't have looked at this answer again.
Tim Seguine

Tim, that's exactly the joy and excitement of challenging each other! :)
Tomas


2

J (58)

You need to run this as a script, it will not work from the J command line obviously.

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

In J, the tokenizer that the interpreter uses is available as the ;: function, so if x contains J code, ;:x contains the J tokens, i.e.:

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

So:

  • echo m=.1: set m to 1, and write it to the screen
  • k=.1{ARGV: store the 2nd element in ARGV (the script name) in k.
  • ...1!:2[k: write the following string to the file in k:
  • ;:1!:1[k: read k, the current script, and tokenize
  • (<":m+1)(<3)}: replace the 3rd token by the string representation of m + 1
  • ;:^:_1: run the tokenizer in reverse, producing a string
  • exit: exit the interpreter (it doesn't do that by itself even if you run a script)

2

PHP, 34 33 chars

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

Thanks to Tim for the update! My old solution:

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

The problem is that $_SESSION[A] is "" - empty string - in first iteration, but as session_start() returns 1, you can add it and kill two or three flies in one shot!

Solution with correct syntax (35 chars):

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

I will hold of judgement for a second for two reasons. "However, your program must not write any new files.": I am not sure if this isn't a problem for this solution, since opening a session creates a temporary file. Also the default session gc happens after 24 minutes. Does that really count as "over multiple sessions" then? Maybe the OP can comment.
Tim Seguine

Tim, the program doesn't write any files. I am not responsible for what the interpreter does. It's the same as HTML page is not responsible for browser creating some files in the cache, sql query is not responsible for created temporary tables on disk etc. As for the timeout, it was not specified in the rules :) Anyway, I am not sure why but on my machine the counter still holds for more than several hours!!!
Tomas

Yeah, that's why I am saying I will wait to see what the OP thinks. You definitely found a very grey area. You don't need the closing php tag btw. so your 34 char version is sufficient. I have an idea for an improvement, but I will need to test it first.
Tim Seguine

Okay, I got it down to 33 chars. I dare you to do better. ;)
Tim Seguine

@TimSeguine Aaaah, what a change in your tone! :-) Now you don't care about the rules in my post so much! :-D
Tomas

2

Haskell - 36 bytes

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

Simply adds +1 to the end of the source file, which is assumed to be named a.hs. The .hs extension is mandatory in both ghc and ghci.



1

Batch - 41

Given the example use case I probably wouldn't assume that this technique is a viable one - It renames the .bat file containing the script -

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

Save this to a file called 0.bat - and call using 0.bat 2>nul. 2>nul redirects stderr to nul which is necessary because this script will rename the file containing the script, once it does that cmd can obviously no longer see the script (before it hits EOF) and will return the error The batch file cannot be found.

Each consecutive call of the script will of course have to be 1.bat 2>nul ... 2.bat 2>nul ... 3.bat 2>nul ... etc ...


Based on this idea, you can do a variation of my php answer of counting in unary and I think it is even shorter than this.
Tim Seguine


1

Python, 49 48 characters

I realized this will only be 48 chars on Windows due to the \r\n. Otherwise it should be 49.

n=1

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

A cheap ripoff of the method by @grc


1

C, 190 Characters . Works only on 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);
}

I think its pretty simple how its working, but still if required I can add an explanation :-)
Abhijit

1

C#, 142 characters

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

You could use a shorter name like z, would get you a few chars down.
It'sNotALie.

You should also remove the whitespace.
Timtech

1
Instead of calling long API name each time, store it in a variable like: var a = Microsoft.Win32.Registry.CurrentUser; a.GetValue(); a.SetValue();
Xantix

1

Tcl, 63 or 73 bytes

  • With some web service it's 73:

    package require http
    puts [set [http::geturl http://example.com/c](data)]
    
  • modifying itself is 63:

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

1

C# - 201 239 234 chars

Works for the first 255 times, then wraps over to 0. It won't output anything on the first execution.

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

Save as Main.cs, compile with

gmcs Main.cs

Tested with gmcs 2.10.8.1 and Mono runtime 2.10.8.1-5ubuntu2


1
Actually - I did. "The program must be able to at least reach the number 14"
lochok

It works now for 255 times.
user3188175

1

Powershell, 47 Bytes

assumes script is named a.ps1

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

The script will overwrite itself replacing the 0 on the first line with 1,2,3 and so on.

could also save another 8 bytes by replaceing both instances of a.ps1 with 1 and saving the script as a file named 1 although this is a bit far out for me.

Replace second line with this if the file is not saved as 'a.ps1'.

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

0 on first line to initialize the count

Linebreak provides the easiest way to split the file in two

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

this takes the file 'a.ps1' and reads it in as an array of lines, we then iterate through it with [0..1] and set that to the variables $n which is cast as [int] and $t respectively, so that the 0 on the first line becomes $n and the 'code' on the second line becomes $t

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

This used the ,1,2 array notation, to create an array of two elements, one being the number stored in $n pre-incremented and outputted to stdout by the use of implicit brackets, the second being the second line of text from the file, and then also output it to the file named 'a.ps1'

as both input and output are arrays of strings there is minimal formatting required, and almost everything is assumed by the interpreter.


1

Zsh (no coreutils), 32 bytes

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

(Note the trailing newline) Uses the length of the script. On each invocation, the last line shown above will append : (identical to true) and a newline to the script, hence the /2.

Try it online!


0

Rust / cargo-script, 283 bytes

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

Save as w and run with 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

Don't iterate too fast or it'll get stuck.

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

Will break after 99999;


0

GNU sed, 13 + 1(n flag) = 14 bytes

$=;$eecho>>s

Run: sed -nf s s

The assumption is that the source filename is called s. A trailing newline is needed after the code, which was counted in the bytes total. Explanation:

$=           # 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'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.