10
\$\begingroup\$

Let n be the number of times your program has been executed. If n is a power of 2, then print 2^x where n = 2^x; otherwise, simply output the number. Example run:

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

and so on. This is a popularity contest, so the answer with the most upvotes wins..

\$\endgroup\$
  • 3
    \$\begingroup\$ why does it output 0 in the first run? \$\endgroup\$ – mniip Mar 4 '14 at 5:19
  • \$\begingroup\$ did you mean "where n = 2^x? Otherwise the second time the output would be 2^4, the fourth time 2^16 and so on. \$\endgroup\$ – John Dvorak Mar 4 '14 at 5:23
  • \$\begingroup\$ @mniip both typos. I probably should've read that more carefully... :P \$\endgroup\$ – Jwosty Mar 4 '14 at 5:27
  • 4
    \$\begingroup\$ Umm... 1 is a power of two. 2^0=1 \$\endgroup\$ – John Dvorak Mar 4 '14 at 5:32
  • 1
    \$\begingroup\$ You still say x = 2^x rather than n = 2^x \$\endgroup\$ – John Dvorak Mar 4 '14 at 5:36

20 Answers 20

8
\$\begingroup\$

Java - API Abuse

There are plenty of computers online that can count, so why store the count myself?

Full-on abuse of the Stack API to get quota and remaining quota to see how many times it's been run today:

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

Obviously this only works with a fresh daily quota for your IP, and only up to the quota. If you want support for higher numbers, post a [feature-request] to raise quota_max to MAX_INT.

\$\endgroup\$
6
\$\begingroup\$

JavaScript

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

Successive alerts are as follows:

2^0
2^1
3
2^2
5
6
7
2^3
9
...and so on.
\$\endgroup\$
  • \$\begingroup\$ Thank you kindly... 'Twas the only way to keep track of executions in JavaScript... I'm considering using localStorage for an upcoming JS game... \$\endgroup\$ – WallyWest Mar 4 '14 at 22:27
  • \$\begingroup\$ For something as small as a counter, a cookie should work as well. \$\endgroup\$ – celtschk Mar 6 '14 at 22:23
  • \$\begingroup\$ @celtschk Great idea, but I believe making a cookie would have taken more bytes \$\endgroup\$ – WallyWest Dec 4 '14 at 22:47
6
\$\begingroup\$

C – writing to the executable

This C code updates the string data in the executable, so essentially this is self-modifying code. If you run it over 9,999,999 times, you get interesting stuff.

#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;
}
\$\endgroup\$
  • \$\begingroup\$ It Segmentation faults after compiling it with GCC 4.8.1-10ubuntu9: gcc test.c, ./a.out 2^0 Segmentation fault (core dumped) \$\endgroup\$ – TimWolla Mar 4 '14 at 16:40
  • 1
    \$\begingroup\$ On Mac it works, haven't tried Linux or Windoze. Apparently Linux is more strict with accessing yourself. \$\endgroup\$ – tomsmeding Mar 4 '14 at 20:32
6
\$\begingroup\$

Java

The following code modifies it's own class file to store the new run count. This was especially fun when you had no idea how the byte code looks, but after countless hours of Googling and Testing it finally works! :)

Demo (using 7 as starting value for demo purposes):

[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

Code:

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:
            }
        }
    }
}
\$\endgroup\$
5
\$\begingroup\$

dg

Here I present you a portable code! At every run a # is added at the end, making a progress bar! Also, you can move the code to another machine and resume from where you were.

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

#

After 18 times:

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

###################
\$\endgroup\$
  • \$\begingroup\$ Ahh, thanks for pointing this language out to me. It incorporates what I love about both Python and Haskell. \$\endgroup\$ – Kaya Mar 4 '14 at 17:35
  • \$\begingroup\$ @Kaya I'm happy you like it! In case you haven't already seen, there's a homepage at pyos.github.io/dg and a tutorial as well! Lots of goods. And don't hesitate to open an issue on the repository if you feel like so. EDIT: I just wanted to point out that I am not the creator of the lang. \$\endgroup\$ – rubik Mar 4 '14 at 18:14
5
\$\begingroup\$

Sinatra-based Ruby Example

This server-based solution stores a personal counter for each user in a cookie.

Try it at 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
\$\endgroup\$
5
\$\begingroup\$

perl

Here's a short bit of perl to do it. Where should the data be stored? Why in the program file itself, of course! =)

$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 }

Originally I had used the magic DATA file handle like so, but I feel the above is "purer":

$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
\$\endgroup\$
  • \$\begingroup\$ You can store tell DATA before you read from it, then seek back to that spot. \$\endgroup\$ – mob Mar 10 '14 at 21:23
3
\$\begingroup\$

Bash

Simple self-editing shell script.

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
\$\endgroup\$
2
\$\begingroup\$

Bash

I like dfernig's Bash solution, but I would like to post mine as well:

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

I think the solution can be considered different, because

  • the code actually executed doesn't change
  • the program dinamically calculates if n is a power of 2

The "memory" is the script size (initially 171 bytes), which is increased by 1 with the append of a newline at each execution.
Powers of 2 are recognized by converting the program size (minus 170, of course) to binary, and then counting the ones: if there is exactly one one, then n is a power of 2. The exponent is the number of zeros in binary.

\$\endgroup\$
1
\$\begingroup\$

Java solution

Uing the java preferences API to store the run amount; and precalculated the powers of 2 for a hashmap to compare

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));
    }
}
\$\endgroup\$
1
\$\begingroup\$

Javascript

I chose to not use the obvious log2 solution but work with bitwise operators to find the single bit position in the binary representation of power of 2 numbers.

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);
}
\$\endgroup\$
  • \$\begingroup\$ great strategy, but unfortunately, the brief states that it needs to display the value of the number of times it has been executed, rendered accordingly... Yours is just a for loop from 1 to 130, with the rendering... :/ \$\endgroup\$ – WallyWest Mar 4 '14 at 12:04
  • \$\begingroup\$ @WallyWest, yeah, thanks for pointing this out. \$\endgroup\$ – Michael M. Mar 4 '14 at 12:21
  • \$\begingroup\$ No offence intended... \$\endgroup\$ – WallyWest Mar 4 '14 at 12:36
  • 1
    \$\begingroup\$ I had not taken your comment as an offense, that was a real thanks ! Sorry if my words are not well chosen, english is not my mother tongue. \$\endgroup\$ – Michael M. Mar 4 '14 at 13:29
1
\$\begingroup\$

Ruby

Alright, I think I'll try this now. It searches itself for the definition of 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)

(tested in Ruby 1.9.3)

\$\endgroup\$
1
\$\begingroup\$

Fortran 77

Code:

      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

Result:

$ ./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            !
\$\endgroup\$
  • \$\begingroup\$ This counts the number of runs done within a particular directory. Possible improvement would be to request a file in the /tmp directory, and to add a semaphore so multiple instances don't try to update the counter at the same time. \$\endgroup\$ – Glenn Randers-Pehrson Mar 4 '14 at 22:29
1
\$\begingroup\$

C

One of the "proper" ways to do it (without using files, that is).

You can give it reset on the command line to set it back to zero. You can also move or copy the executable around. Moving the executable resets it, and multiple copies of the executable are independent.

#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;
}
\$\endgroup\$
1
\$\begingroup\$

Sparkling, 423 characters (yet another self-modifying code). Save it as count.spn then run 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);
\$\endgroup\$
0
\$\begingroup\$

Here's a quick Python 3 solution, which uses a data file to store n and x between runs:

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

The output of running it 16 times:

2^0
2^1
3
2^2
5
6
7
2^3
9
10
11
12
13
14
15
2^4
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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

This does, though, require that you define a settings property in your Visual Studio project:

project settings screen shot

\$\endgroup\$
0
\$\begingroup\$

C/POSIX

This program uses the number of hard links to its own executable as counter of how often it was called. It creates the new hard links in the directory it was started from (because that way it's guaranteed to be on the same file system), which therefore needs write permission. I've omitted error handling.

You better make sure that you have no important file with the same name as one of the created hard links on that directory, or it will be overwritten. If e.g. the executable is named counter, the hard links will be named counter_1, counter_2 etc.

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

Example run (the first line resets the counter, in case the executable has already been run):

$ 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~
\$\endgroup\$
0
\$\begingroup\$

Fortran 95

A file named "a" (without extension) keeps track of the run of the 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
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.