Setiap 2 kali

10

Biarkan nmenjadi berapa kali program Anda telah dieksekusi. Jika nkekuatan 2, maka cetak di 2^xmana n = 2^x; jika tidak, cukup tampilkan angkanya. Contoh dijalankan:

[1st time] 2^0
[2nd time] 2^1
[3rd time] 3
[4th time] 2^2
[5th time] 5

dan seterusnya. Ini adalah kontes popularitas, jadi jawabannya dengan kemenangan terbanyak menang ..

Jwosty
sumber
3
mengapa output 0di jalankan pertama?
mniip
maksud Anda "di mana n = 2^x? Kalau tidak, yang kedua adalah output 2^4, yang keempat 2^16dan seterusnya.
John Dvorak
@mniip kedua kesalahan ketik. Saya mungkin harus membaca itu lebih hati-hati ...: P
Jwosty
4
Umm ... 1adalah kekuatan dua. 2^0=1
John Dvorak
1
Anda masih mengatakan x = 2^xdaripadan = 2^x
John Dvorak

Jawaban:

8

Java - Penyalahgunaan API

Ada banyak komputer daring yang dapat dihitung, jadi mengapa menyimpan sendiri hitungannya?

Penyalahgunaan penuh atas Stack API untuk mendapatkan kuota dan sisa kuota untuk melihat berapa kali telah dijalankan hari ini:

public static void main(String[] args) throws Exception {
    URLConnection c = new URL("http://api.stackexchange.com/2.2/info?site=stackoverflow").openConnection();
    c.setRequestProperty("Accept-Encoding", "gzip");
    GZIPInputStream gz = new GZIPInputStream(c.getInputStream());
    BufferedReader r = new BufferedReader(new InputStreamReader(gz));
    String reply = r.readLine();
    r.close();

    reply = reply.substring(reply.indexOf("quota_max"), reply.length()-1);
    String[] t = reply.split("[:,]");
    int runs = Integer.parseInt(t[1]) - Integer.parseInt(t[3]);        
    if((runs & (runs -1)) == 0){
        int exp = 0;
        while(runs % 2 == 0){
            runs = runs >> 1;
            exp++;
        }
        System.out.println("2^" + exp);
    } else {
        System.out.println("" + runs);
    }
}

Jelas ini hanya berfungsi dengan kuota harian baru untuk IP Anda, dan hanya sampai kuota. Jika Anda ingin dukungan untuk nomor yang lebih tinggi, kirim [permintaan fitur] untuk naik quota_maxke MAX_INT.

Geobit
sumber
6

JavaScript

alert((n=Math.log((l=localStorage).m=~~l.m+1)/Math.log(2))==(n|0)?"2^"+n:l.m)

Peringatan berturut-turut adalah sebagai berikut:

2^0
2^1
3
2^2
5
6
7
2^3
9
...and so on.
WallyWest
sumber
Terima kasih ... "Ini satu-satunya cara untuk melacak eksekusi dalam JavaScript ... Saya sedang mempertimbangkan untuk menggunakan localStorage untuk game JS yang akan datang ...
WallyWest
Untuk sesuatu yang sekecil counter, cookie juga bisa digunakan.
celtschk
@celtschk Ide bagus, tapi saya percaya membuat cookie akan membutuhkan lebih banyak byte
WallyWest
6

C - menulis ke executable

Kode C ini memperbarui string datadalam executable, jadi pada dasarnya ini adalah kode modifikasi diri. Jika Anda menjalankannya lebih dari 9.999.999 kali, Anda mendapatkan hal-hal menarik.

#include <stdio.h>
#include <stdlib.h>

int main(int argc,char **argv){
    //               'abcdefghijklmnopqrstuvwxyz1' << that's 27 characters inside the quotes
    const char *data="Da best marker in da world 1\0\0\0\0\0\0";
    FILE *f;
    int i,n,m;
    char c;
    long int pos;
    m=n=strtol(data+27,NULL,10);
    i=0;
    while(1){
        if(n==0){
            printf("This code should never have been reached... Unless you've messed with my executable.\n");
            return 1;
        }
        if(n==1){
            printf("2^%d\n",i);
            break;
        }
        if(n&1){
            printf("%d\n",m);
            break;
        }
        i++;
        n>>=1;
    }
    f=fopen(argv[0],"r+b");
    i=0;
    c=fgetc(f);
    while(!feof(f)){
        if(data[i]==c){
            i++;
            if(i==27)break;
        } else i=0;
        c=fgetc(f);
    }
    if(i!=27)return 1;
    n=0;
    pos=ftell(f);
    c=fgetc(f);
    while(c!='\0'){
        n=10*n+c-'0';
        c=fgetc(f);
    }
    n++; //The big increment!
    fseek(f,pos,SEEK_SET);
    fprintf(f,"%d",n);
    fflush(f);
    fclose(f);
    return 0;
}
tommeding
sumber
Ini Segmentasi kesalahan setelah kompilasi dengan GCC 4.8.1-10ubuntu9: gcc test.c,./a.out 2^0 Segmentation fault (core dumped)
TimWolla
1
Di Mac berfungsi, belum mencoba Linux atau Windoze. Tampaknya Linux lebih ketat dalam mengakses diri Anda.
tommeding
6

Jawa

Kode berikut memodifikasi file kelasnya sendiri untuk menyimpan jumlah proses yang baru. Ini sangat menyenangkan ketika Anda tidak tahu bagaimana tampilan kode byte, tetapi setelah berjam-jam Googling dan Pengujian akhirnya bekerja! :)

Demo (menggunakan 7 sebagai nilai awal untuk tujuan demo):

[timwolla@/data/workspace/java]javac Runs.java 
[timwolla@/data/workspace/java]java Runs 
7
[timwolla@/data/workspace/java]java Runs 
2^3
[timwolla@/data/workspace/java]java Runs 
9
[timwolla@/data/workspace/java]java Runs 
10

Kode:

import java.io.*;
import java.util.*;

class Runs {

    public static void main(String[] args) throws Exception {
        // RUN-- makes the string easy to find in the byte code
        String runString = "RUN--1";

        // extract the number
        int runs = Integer.parseInt(runString.substring(5));

        // output the number properly
        int power = 0;
        boolean outputted = false;
        while (Math.pow(2, power) <= runs) {
            if (Math.pow(2, power) == runs) {
                outputted = true;
                System.out.println("2^"+power);
            }
            power++;
        }
        if (!outputted) System.out.println(runs);

        // increase run count
        runs++;

        // build new string
        String newRunString = runString.substring(0, 5) + runs;

        // get folder of class file
        String folder = Runs.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        // append class file name
        String me = folder + "/Runs.class";

        // and open it up
        RandomAccessFile in = new RandomAccessFile(me, "rw");

        int read;
        int state = 0;
        while ((read = in.read()) != -1) {
            char c = (char) read;

            // state machine to find the RUN--
            switch (state) {
                case 0:
                    // 2 bytes before: upper byte of the two byte length
                    if (c == ((runString.length() >> 8) & 0xFF)) state++;
                break;
                case 1:
                    // 1 byte before: lower byte of the two byte length
                    if (c == (runString.length() & 0xFF)) state++;
                    else state = 0;
                break;
                case 2:
                    if (c == 'R') state++;
                    else state = 0;
                break;
                case 3:
                    if (c == 'U') state++;
                    else state = 0;
                break;
                case 4:
                    if (c == 'N') state++;
                    else state = 0;
                break;
                case 5:
                case 6:
                    if (c == '-') state++;
                    else state = 0;
                break;
                case 7:
                    // we found run, now: Modify byte code

                    // back to the bytes that determine the length
                    in.seek(in.getFilePointer() - 8);

                    // expand the file if neccessary
                    int lengthChange = (newRunString.length() - runString.length());
                    in.setLength(in.length() + lengthChange);

                    // write new length
                    in.writeByte(((newRunString.length() >> 8) & 0xFF));
                    in.writeByte((newRunString.length() & 0xFF));

                    // length changed, shift all the following bytes by one
                    if (lengthChange > 0) {
                        long target = in.getFilePointer();
                        in.seek(in.length() - 1 - lengthChange);
                        while (in.getFilePointer() > target) {
                            in.write(in.read());
                            in.seek(in.getFilePointer() - 3);
                        }
                        in.seek(target);
                    }

                    // write new string
                    in.writeBytes(newRunString);

                    return;
                case 8:
            }
        }
    }
}
TimWolla
sumber
5

dg

Di sini saya berikan Anda kode portabel! Setiap kali dijalankan, #ditambahkan di akhir, membuat bilah kemajuan! Anda juga dapat memindahkan kode ke komputer lain dan melanjutkan dari tempat Anda sebelumnya.

import '/math'

with fd = open __file__ 'r' =>
  code = fd.read!
  times = code.count('#') - 2
with fd = open __file__ 'w' =>
  fd.write $ code.rstrip! + '#'
exp = math.log2 times
if exp.is_integer! => print $ '2^{}'.format $ int exp
   otherwise => print times

#

Setelah 18 kali:

import '/math'

with fd = open __file__ 'r' =>
  code = fd.read!
  times = code.count('#') - 2
with fd = open __file__ 'w' =>
  fd.write $ code.rstrip! + '#'
exp = math.log2 times
if exp.is_integer! => print $ '2^{}'.format $ int exp
   otherwise => print times

###################
rubik
sumber
Ahh, terima kasih sudah menunjukkan bahasa ini padaku. Ini menggabungkan apa yang saya sukai tentang Python dan Haskell.
Kaya
@Kaya aku senang kamu menyukainya! Jika Anda belum melihat, ada beranda di pyos.github.io/dg dan tutorial juga! Banyak barang. Dan jangan ragu untuk membuka masalah di repositori jika Anda mau. EDIT: Saya hanya ingin menunjukkan bahwa saya bukan pencipta lang.
rubik
5

Contoh Ruby Berbasis Sinatra

Solusi berbasis server ini menyimpan penghitung pribadi untuk setiap pengguna dalam cookie.

Cobalah di http://every-2-to-the-n-times.herokuapp.com/

require 'sinatra'
require 'sinatra/cookies'

# https://github.com/sinatra/sinatra-contrib/issues/113
set :cookie_options, :domain => nil

get '/' do
   x = cookies[:x].to_i || 1
   cookies[:x] = x + 1

   # power of 2 test from http://grosser.it/2010/03/06/check-if-a-numer-is-a-power-of-2-in-ruby/
   return (x & (x - 1) == 0) ? "2^#{Math.log2(x).to_i}" : x.to_s
end
Steve Wilhelm
sumber
5

perl

Berikut sedikit perl untuk melakukannya. Di mana seharusnya data disimpan? Kenapa di file program itu sendiri, tentu saja! =)

$b = sprintf '%b', $x=x();
print $b=~/^10*$/ ? "2^".(length($b)-1) : $x, "\n";
open F, "+<", $0;
seek F, -3-length $x, 2;
print F $x+1, " }\n";
sub x { 1 }

Awalnya saya telah menggunakan pegangan file DATA ajaib seperti itu, tetapi saya merasa di atas "lebih murni":

$b = sprintf '%b', $x = <DATA>;
print $b =~ /^10*$/ ? "2^".(length($b)-1)."\n" : $x;
open F, "+<", $0;
seek F, -length $x, 2;
print F $x+1, "\n";
__DATA__
1
skibrianski
sumber
Anda dapat menyimpan tell DATAsebelum Anda membacanya, lalu mencari kembali ke tempat itu.
mob
3

Pesta

Script shell mengedit diri yang sederhana.

n=1;e=0;p=1
sed -i s/"n=$n"/"n=`expr $n + 1`"/g $0
if [[ $n -eq $p ]];then
    echo 2^$e
    sed -i s/"p=$p"/"p=`expr $p \* 2`"/g $0
    sed -i s/"e=$e"/"e=`expr $e + 1`"/g $0
else
    echo $n
fi
dfernig
sumber
2

Pesta

Aku seperti dfernig 's solusi Bash , tapi saya ingin posting saya juga:

n=$(expr `cat $0|wc -c` - 170)
if [ $(echo "obase=2;$n"|bc|grep -o 1|wc -l) == 1 ]
then echo -n "2^"; echo "obase=2;$n"|bc|grep -o 0|wc -l;
else echo $n; fi
echo "" >> $0

Saya pikir solusinya dapat dianggap berbeda, karena

  • kode yang benar-benar dieksekusi tidak berubah
  • program secara dinamis menghitung jika n adalah kekuatan 2

"Memori" adalah ukuran skrip (awalnya 171 byte), yang meningkat sebesar 1 dengan menambahkan baris baru pada setiap eksekusi.
Powers of 2 dikenali dengan mengubah ukuran program (minus 170, tentu saja) menjadi biner, dan kemudian menghitung yang: jika ada tepat satu, maka n adalah kekuatan 2. Eksponen adalah jumlah nol dalam biner .

scristalli
sumber
1

Solusi Java

Gunakan API preferensi java untuk menyimpan jumlah proses; dan menghitung ulang kekuatan 2 untuk dibandingkan dengan peta hash

import java.util.HashMap;
import java.util.prefs.Preferences;
class Pow
{
    public static void main(String[]a)
    {
        int rt = Integer.valueOf(Preferences.userRoot().get("Pow.run", "1"));
        HashMap<String,Integer> powof2 = new HashMap<>();
        //pregenerating the powers of 2;
        for (int i = 0; i < 46340; i++)//highest power of 2 before int overflow
        {
            powof2.put(((int)Math.pow(2, i))+"",i);
        }
        if(powof2.containsKey(rt+""))
        {System.out.println("2^"+powof2.get(rt+""));}
        else
        {
            System.out.println(rt);
        }
        rt++;
        Preferences.userRoot().put("Pow.run", ""+(rt));
    }
}
masterX244
sumber
1

Javascript

Saya memilih untuk tidak menggunakan log2solusi yang jelas tetapi bekerja dengan operator bitwise untuk menemukan posisi bit tunggal dalam representasi biner kekuatan 2 angka.

Number.prototype.singleBitPosition = function() {
  var r=1, k;
  if (this==0) return -1;
  while(this==(k=this>>r<<r)) r++; //set r last bits to zero and compare
  return k?-1:r; //if k is zero, there is one single bit to 1 in number representation ie power of 2
};

var n;
if (n === undefined) n=0;
n++;

var e = n.singleBitPosition();
if (e > 0) {
  console.log('2^'+(e-1));
} else {
  console.log(n);
}
Michael M.
sumber
strategi yang hebat, tetapi sayangnya, pernyataan singkat yang dibutuhkan untuk menampilkan nilai berapa kali telah dieksekusi, diberikan sesuai ... Anda hanya satu forloop dari 1 hingga 130, dengan rendering ...: /
WallyWest
@WallyWest, ya, terima kasih telah menunjukkan ini.
Michael M.
Tidak ada pelanggaran yang dimaksudkan ...
WallyWest
1
Saya tidak menganggap komentar Anda sebagai pelanggaran, itu benar-benar ucapan terima kasih! Maaf jika kata-kata saya tidak dipilih dengan baik, bahasa Inggris bukan bahasa ibu saya.
Michael M.
1

Rubi

Baiklah, saya pikir saya akan mencoba ini sekarang. Ia mencari sendiri definisi n.

def p2 n
  n == 1 ? 0 : p2(n >> 1) + 1
end
n = 1
if (n != 0) & (n & (n - 1) == 0) || n == 1
  puts("2^" + (p2(n).to_s))
else
  puts n
end

contents = File.read(__FILE__)
newContents = contents.gsub(/(?<=n \= )[0-9]+/) {|n| (n.to_i + 1).to_s}
File.write(__FILE__, newContents)

(diuji dalam Ruby 1.9.3)

Jwosty
sumber
1

Fortran 77

Kode:

      program twok
      rewind 1
      read(1,'(I20,I3)',end=10,err=30)n,k
      go to 20
10    n=-1
      k=0
20    n=n+1
      if (n .eq. 2**k) then
        if (k.le.9) then
          write(*,'(A3,i1)')' 2^',k
        else
          write(*,'(A3,i2)')' 2^',k
        endif
        k=k+1
      else
        write(*,*)n
      endif
      if (n .lt. 0) then
         n=-1
         k=0
      endif
      rewind 1
      write(1,'(I20,I3)')n,k
30    continue
      end

Hasil:

$ ./a.out       !       $ ./a.out
 2^0            !        2^1
$ ./a.out       !
 2^1            !       $ while true
$ ./a.out       !       > do
 3              !       > ./a.out | grep "2^"
$ ./a.out       !       > done
 2^2            !        2^2
$ ./a.out       !        2^3
 5              !        2^4
$ ./a.out       !        2^5
 6              !        ...
...             !        2^12
$ ./a.out       !        2^13
 2147483647     !       ^C # (after about 5 minutes)
$ ./a.out       !       $ ./a.out
 2^31           !        14718
$ ./a.out       !       $ ./a.out
 0              !        14719
$ ./a.out       !       $
 2^0            !
Glenn Randers-Pehrson
sumber
Ini menghitung jumlah proses yang dilakukan dalam direktori tertentu. Kemungkinan perbaikan adalah dengan meminta file di direktori / tmp, dan menambahkan semaphore sehingga beberapa instance tidak mencoba memperbarui konter pada saat yang sama.
Glenn Randers-Pehrson
1

C

Salah satu cara "tepat" untuk melakukannya (tanpa menggunakan file, yaitu).

Anda dapat memberikannya resetdi baris perintah untuk mengaturnya kembali ke nol. Anda juga dapat memindahkan atau menyalin file yang dapat dieksekusi. Memindahkan yang dapat dieksekusi akan menyetel ulang, dan banyak salinan yang dapat dieksekusi independen.

#include <stdio.h>
#include <sys/msg.h>
#include <sys/shm.h>

int main(int argc, char **argv) {
   // get a shared memory segment associated with our program
   long key = ftok(argv[0], 1);
   long id = shmget(key, sizeof(long), 0666 | IPC_CREAT);
   long *num = (long*) shmat(id, NULL, 0);

   // reset parameter
   if (argc == 2 && !strcmp(argv[1], "reset")) {
      *num = 0;
   }

   if (*num & *num-1) {
      // not a power of two
      printf("%li\n", *num);
   } else {
      // power of two
      int exp = 0;
      int n=*num;
      while (n >>= 1) exp++;
      printf("2^%d\n", exp);
   }

   ++*num;

   // detach from shared memory
   shmdt(num);
   return 0;
}
marinus
sumber
1

Sparkling, 423 karakter (kode modifikasi lain). Simpan count.spnsaat dijalankan spn count.spn:

var n =
19
;

var l = log2(n);
if l == floor(l) {
    printf("2 ^ %d\n", floor(l));
} else {
    printf("%.0f\n", n);
}

var f = fopen("count.spn", "rb");
var g = fopen("count.spn.2", "wb");
var line = fgetline(f);
fprintf(g, "%s", line);
fprintf(g, "%d\n", n + 1);
fgetline(f);

while (line = fgetline(f)) != nil {
    fprintf(g, "%s", line);
}

fclose(f);
fclose(g);
H2CO3
sumber
0

Berikut solusi Python 3 cepat, yang menggunakan file data untuk menyimpan ndan di xantara berjalan:

try:
    with open("count.txt") as f:
        n, x = map(int, f.readline().split())
except FileNotFoundError:
    n = x = 0

n += 1
if n == 2**x:
    print("2^{}".format(x))
    x += 1
else:
    print(n)

with open("count.txt", "w") as f:
    f.write("{} {}".format(n, x))

Output menjalankannya 16 kali:

2^0
2^1
3
2^2
5
6
7
2^3
9
10
11
12
13
14
15
2^4
Blckknght
sumber
0

Python 2

import inspect
import math

file_name = inspect.getfile(inspect.currentframe())

n = int(open(file_name).readlines()[-1].strip())

l = math.log(n, 2)
if int(l) == l:
    print '2^%d' % (l)
else:
    print n

with open(file_name, 'a') as f:
    f.write('%d\n' % (n + 1))

1
Jayanth Koushik
sumber
0

C #

static void Main()
{
  ulong cnt         = ++Properties.Settings.Default.NumberOfExecutions ;
  int?  log2        = Log2( cnt ) ;
  Console.WriteLine( log2.HasValue ? "2^{0}" : "{1}" , log2 , cnt ) ;
  Properties.Settings.Default.Save() ;
  return ;
}

static int? Log2( ulong m )
{
  int? n = null ;
  if ( m > 0 )
  {
    n = 0 ;

    // find the first set bit
    ulong mask = 0x0000000000000001ul ;
    while ( mask != 0 && 0ul == (m&mask) )
    {
      mask <<= 1 ;
      ++n ;
    } ;

    // if the mask is identical to m,
    // we've got a power of 2: return n, otherwise null
    n = mask == m ? n : null ;

  }
  return n ;
}

Ini, bagaimanapun, mengharuskan Anda menentukan properti pengaturan dalam proyek Visual Studio Anda:

tangkapan layar pengaturan proyek

Nicholas Carey
sumber
0

C / POSIX

Program ini menggunakan jumlah tautan keras yang dapat dieksekusi sebagai penghitung dari seberapa sering dipanggil. Itu menciptakan tautan keras baru di direktori tempat ia dimulai (karena dengan cara itu dijamin berada pada sistem file yang sama), yang karenanya memerlukan izin menulis. Saya telah menghilangkan penanganan kesalahan.

Anda lebih baik memastikan bahwa Anda tidak memiliki file penting dengan nama yang sama dengan salah satu tautan keras yang dibuat pada direktori itu, atau itu akan ditimpa. Jika misalnya executable dinamai counter, tautan keras akan dinamai counter_1, counter_2dll.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char* argv[])
{
  /* get persistent counter */
  struct stat selfstat;
  stat(argv[0], &selfstat);
  int counter = selfstat.st_nlink;

  /* determine digits of counter */
  int countercopy = counter;
  int digits = 1;
  while (countercopy /= 10)
    ++digits;

  /* increment persistent counter */
  char* newname = malloc(strlen(argv[0]) + digits + 2);
  sprintf(newname, "%s_%d", argv[0], counter);
  link(argv[0], newname);

  /* output the counter */
  if (counter & (counter-1)) // this is zero iff counter is a power of two
    printf("%d\n", counter);
  else
  {
    /* determine which power of 2 it is */
    int power = 0;
    while (counter/=2)
      ++power;
    printf("2^%d\n", power);
  }
  return 0;
}

Contoh run (baris pertama me-reset counter, jika eksekusi sudah dijalankan):

$ rm counter_*
$ ./counter
2^0
$ ./counter
2^1
$ ./counter
3
$ ./counter
2^2
$ ./counter
5
$ ./counter
6
$ ./counter
7
$ ./counter
2^3
$ ./counter
9
$ ls counter*
counter    counter_2  counter_4  counter_6  counter_8  counter.c
counter_1  counter_3  counter_5  counter_7  counter_9  counter.c~
celtschk
sumber
0

Fortran 95

File bernama "a" (tanpa ekstensi) melacak jalannya program.

logical::l
inquire(file="a",exist=l)
open(unit=11,file="a")
if (l) then
  read(11,*)n
  close(unit=11,status="delete")
  open(unit=11,file="a")
  n=n+1
  write(11,*)n
  do i=1,n
    if (2**i==n) then
      write(*,"(A2,I1)")"2^",i
      goto 1        
    endif
  enddo
  print*,n
  else
    print*,"2^0"
    write(11,*)1
endif
1 end
gilbertohasnofb
sumber