Toutes les 2 ^ n fois


10

Soit nle nombre d'exécutions de votre programme. Si nest une puissance de 2, imprimez 2^xn = 2^x; sinon, affichez simplement le nombre. Exemple d'exécution:

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

etc. Il s'agit d'un concours de popularité, donc la réponse avec le plus de votes positifs l'emporte.


3
pourquoi sort-il 0lors de la première exécution?
mniip

vouliez-vous dire "où n = 2^x? Sinon, la deuxième fois que la sortie serait 2^4, la quatrième fois 2^16et ainsi de suite.
John Dvorak

@mniip les deux fautes de frappe. J'aurais probablement dû lire cela plus attentivement ...: P
Jwosty

4
Umm ... 1est une puissance de deux. 2^0=1
John Dvorak

1
Vous dites toujours x = 2^xplutôt quen = 2^x
John Dvorak

Réponses:


8

Java - Abus d'API

Il existe de nombreux ordinateurs en ligne qui peuvent compter, alors pourquoi enregistrer le compte moi-même?

Abus total de l'API Stack pour obtenir le quota et le quota restant pour voir combien de fois il a été exécuté aujourd'hui:

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

Évidemment, cela ne fonctionne qu'avec un nouveau quota quotidien pour votre adresse IP, et uniquement jusqu'au quota. Si vous souhaitez un soutien pour un plus grand nombre, afficher une [fonction de demande] pour élever quota_maxà MAX_INT.


6

Javascript

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

Les alertes successives sont les suivantes:

2^0
2^1
3
2^2
5
6
7
2^3
9
...and so on.

Merci de bien vouloir ... 'C'était le seul moyen de suivre les exécutions en JavaScript ... J'envisage d'utiliser localStorage pour un prochain jeu JS ...
WallyWest

Pour quelque chose d'aussi petit qu'un comptoir, un cookie devrait également fonctionner.
celtschk

@celtschk Excellente idée, mais je pense que faire un cookie aurait pris plus d'octets
WallyWest

6

C - écrire dans l'exécutable

Ce code C met à jour la chaîne datadans l'exécutable, il s'agit donc essentiellement d'un code auto-modifiable. Si vous l'exécutez plus de 9 999 999 fois, vous obtenez des trucs intéressants.

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

Segmentation faults après la compilation avec GCC 4.8.1-10ubuntu9: gcc test.c,./a.out 2^0 Segmentation fault (core dumped)
TimWolla

1
Sur Mac, cela fonctionne, je n'ai pas essayé Linux ou Windoze. Apparemment, Linux est plus strict avec l'accès à vous-même.
tomsmeding

6

Java

Le code suivant modifie son propre fichier de classe pour stocker le nouveau nombre d'exécutions. C'était particulièrement amusant lorsque vous n'aviez aucune idée de l'apparence du code d'octet, mais après d'innombrables heures de recherche et de test sur Google, cela fonctionne enfin! :)

Démo (en utilisant 7 comme valeur de départ à des fins de démonstration):

[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:
            }
        }
    }
}

5

dg

Ici, je vous présente un code portable! À chaque course, un #est ajouté à la fin, ce qui crée une barre de progression! Vous pouvez également déplacer le code sur une autre machine et reprendre là où vous étiez.

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

#

Après 18 fois:

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

###################

Ahh, merci de m'avoir indiqué cette langue. Il intègre ce que j'aime à la fois en Python et en Haskell.
Kaya

@Kaya, je suis content que vous l'aimiez! Si vous ne l'avez pas déjà vu, il y a une page d'accueil sur pyos.github.io/dg et un tutoriel aussi! Beaucoup de marchandises. Et n'hésitez pas à ouvrir un problème sur le référentiel si vous en avez envie. EDIT: Je voulais juste souligner que je ne suis pas le créateur de la langue.
rubik

5

Exemple de Ruby basé sur Sinatra

Cette solution basée sur serveur stocke un compteur personnel pour chaque utilisateur dans un cookie.

Essayez-le sur 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

5

perl

Voici un petit peu de perl pour le faire. Où les données doivent-elles être stockées? Pourquoi dans le fichier programme lui-même, bien sûr! =)

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

À l'origine, j'avais utilisé la poignée magique du fichier DATA comme ça, mais je pense que ce qui précède est "plus pur":

$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

Vous pouvez stocker tell DATAavant de lire, puis revenir à cet endroit.
mob

3

Frapper

Script shell auto-éditable simple.

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

2

Frapper

Je aime dfernig de » solution Bash , mais je voudrais moi aussi poster:

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

Je pense que la solution peut être considérée comme différente, car

  • le code réellement exécuté ne change pas
  • le programme calcule dinamiquement si n est une puissance de 2

La "mémoire" est la taille du script (initialement 171 octets), qui est augmentée de 1 avec l'ajout d'une nouvelle ligne à chaque exécution.
Les puissances de 2 sont reconnues en convertissant la taille du programme (moins 170, bien sûr) en binaire, puis en comptant celles-ci: s'il y en a exactement une, alors n est une puissance de 2. L'exposant est le nombre de zéros en binaire .


1

Solution Java

Uing l'API des préférences java pour stocker le montant d'exécution; et précalculé les puissances de 2 pour une table de hachage pour comparer

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

1

Javascript

J'ai choisi de ne pas utiliser la log2solution évidente mais de travailler avec des opérateurs au niveau du bit pour trouver la position du bit unique dans la représentation binaire de la puissance de 2 nombres.

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

grande stratégie, mais malheureusement, le mémoire indique qu'il doit afficher la valeur du nombre de fois qu'il a été exécuté, rendu en conséquence ... Le vôtre est juste une forboucle de 1 à 130, avec le rendu ...: /
WallyWest

@WallyWest, oui, merci de l'avoir signalé.
Michael M.

Aucune infraction prévue ...
WallyWest

1
Je n'avais pas pris votre commentaire comme une offense, c'était un vrai merci! Désolé si mes mots ne sont pas bien choisis, l'anglais n'est pas ma langue maternelle.
Michael M.

1

Rubis

D'accord, je pense que je vais essayer ça maintenant. Il recherche lui-même la définition de 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)

(testé dans Ruby 1.9.3)


1

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

Résultat:

$ ./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            !

Cela compte le nombre d'exécutions effectuées dans un répertoire particulier. L'amélioration possible serait de demander un fichier dans le répertoire / tmp et d'ajouter un sémaphore pour que plusieurs instances n'essaient pas de mettre à jour le compteur en même temps.
Glenn Randers-Pehrson

1

C

Une des façons "appropriées" de le faire (sans utiliser de fichiers, c'est-à-dire).

Vous pouvez le donner resetsur la ligne de commande pour le remettre à zéro. Vous pouvez également déplacer ou copier l'exécutable. Le déplacement de l'exécutable le réinitialise et plusieurs copies de l'exécutable sont indépendantes.

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

1

Pétillant, 423 caractères (encore un autre code auto-modifiable). Enregistrez-le sous count.spnpuis exécutez 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);

0

Voici une solution Python 3 rapide, qui utilise un fichier de données pour stocker net xentre les exécutions:

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

La sortie de l'exécuter 16 fois:

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

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

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

Cela nécessite cependant que vous définissiez une propriété de paramètres dans votre projet Visual Studio:

capture d'écran des paramètres du projet


0

C / POSIX

Ce programme utilise le nombre de liens durs vers son propre exécutable comme compteur de la fréquence à laquelle il a été appelé. Il crée les nouveaux liens durs dans le répertoire à partir duquel il a été démarré (car de cette façon, il est garanti d'être sur le même système de fichiers), ce qui nécessite donc une autorisation d'écriture. J'ai omis la gestion des erreurs.

Vous feriez mieux de vous assurer que vous n'avez pas de fichier important avec le même nom que l'un des liens durs créés dans ce répertoire, sinon il sera écrasé. Si par exemple l'exécutable est nommé counter, les liens durs seront nommés counter_1, counter_2etc.

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

Exemple d'exécution (la première ligne réinitialise le compteur, au cas où l'exécutable a déjà été exécuté):

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

0

Fortran 95

Un fichier nommé "a" (sans extension) assure le suivi de l'exécution du programme.

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.