2 ^ n回ごと


10

してみましょうnあなたのプログラムが実行された回数とします。nが2の累乗の場合、2^xどこに出力するかn = 2^x。それ以外の場合は、単に数値を出力します。実行例:

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

等々。これは人気コンテストなので、賛成票が最も多い回答が勝ちます。


3
なぜ0最初の実行で出力するのですか?
mniip 2014年

「どこでn = 2^x?それ以外の場合、出力は2回2^4目、4回目2^16など」
John Dvorak

@mniip両方のタイプミス。おそらくもっと注意深く読むべきだったでしょう...:P
Jwosty

4
うーん... 12の累乗です。2^0=1
John Dvorak

1
あなたはまだとx = 2^xいうよりn = 2^x
John Dvorak

回答:


8

Java-APIの悪用

オンラインでカウントできるコンピュータはたくさんあるので、なぜ自分でカウントを保存するのでしょうか。

Stack APIを全面的に悪用して割り当てと残りの割り当てを取得し、今日何回実行されたかを確認します。

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

明らかに、これはIPの新しい1日の割り当てでのみ機能し、割り当てまでしか機能ません。より大きな数のサポートが必要な場合は、[feature-request]を投稿してにレイズ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)

連続するアラートは次のとおりです。

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

ありがとうございました...「JavaScriptで実行を追跡する唯一の方法でした...今後のJSゲームにlocalStorageを使用することを検討しています...
WallyWest

カウンターと同じくらい小さいものについては、クッキーも同様に機能するはずです。
celtschk 2014年

@celtschk素晴らしいアイデアですが、Cookieを作成するとバイト数が
増えると思い

6

C –実行可能ファイルへの書き込み

このCコードdataは実行可能ファイルの文字列を更新するため、基本的にこれは自己変更コードです。9,999,999回以上実行すると、興味深い結果が得られます。

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

GCC 4.8.1-10ubuntu9でコンパイルした後のセグメンテーションエラー:gcc test.c./a.out 2^0 Segmentation fault (core dumped)
TimWolla

1
Macでは動作しますが、LinuxやWindozeは試していません。どうやらLinuxは自分自身にアクセスする方がより厳しいです。
tomsmeding 2014年

6

ジャワ

次のコードは、独自のクラスファイルを変更して、新しい実行カウントを保存します。これは、バイトコードがどのように見えるかわからないときに特に楽しかったですが、グーグルとテストの数え切れないほどの時間の後で、ようやく動作しました!:)

デモ(デモ目的の開始値として7を使用):

[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

コード:

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

ここに私はあなたにポータブルコードを提示します!実行ごとに#最後にa が追加され、進行状況バーが作成されます。また、コードを別のマシンに移動して、元の場所から再開することもできます。

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

#

18回後:

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

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

ああ、この言語を私に指摘してくれてありがとう。PythonとHaskellの両方について私が気に入っている点が組み込まれています。
カヤマール

@カヤ君が気に入って嬉しいです!まだご覧になっていない方のために、pyos.github.io / dgにホームページとチュートリアルがあります。商品がたくさん。必要に応じて、リポジトリで問題を開くことをためらわないでください。編集:私は私が言語の作成者ではないことを指摘したかっただけです。
ルービック2014年

5

SinatraベースのRubyの例

このサーバーベースのソリューションは、各ユーザーの個人用カウンターをCookieに保存します。

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

これを行うための短いPerlを以下に示します。データはどこに保存する必要がありますか?もちろん、プログラムファイル自体にあるのはなぜですか。=)

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

もともとは魔法のDATAファイルハンドルをこのように使用していましたが、上記は「より純粋」であると感じています。

$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

tell DATA読み取る前に保存して、その場所に戻ることができます。
mob 2014年

3

バッシュ

単純な自己編集シェルスクリプト。

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

バッシュ

私はdfernigBashソリューションが好きですが、私のものも投稿したいと思います。

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

ソリューションは異なると考えることができると思います、なぜなら

  • 実際に実行されるコードは変更されません
  • プログラムは、nが2の累乗であるかどうかを動的に計算します

「メモリ」はスクリプトサイズ(最初は171バイト)で、実行ごとに改行が追加されて1ずつ増加します。2のべき乗は、
プログラムサイズ(もちろんマイナス170)をバイナリに変換し、1を数えることで認識されます。1がちょうど1の場合、nは2のべき乗です。指数はバイナリのゼロの数です。 。


1

Javaソリューション

実行量を格納するためにJavaプリファレンスAPIを使用します。ハッシュマップを比較するために2のべき乗を事前に計算しました

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

私は明白なlog2解決策を使用しないことを選択しましたが、ビットごとの演算子を使用して、2の累乗の2進数表現の単一ビット位置を見つけました。

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

偉大な戦略が、残念ながら、簡単な状態、それはそれに応じてレンダリングされた、実行された回数の値を表示する必要があることを...ユアーズだけでfor1から130までのループ、レンダリングと...:/
ウォリーウエスト

@WallyWest、そう、これを指摘してくれてありがとう。
マイケルM.

違反は意図されていません...
WallyWest

1
私はあなたのコメントを攻撃とは思っていませんでした、本当に感謝しました!私の言葉がうまく選択されていない場合は申し訳ありませんが、英語は私の母国語ではありません。
マイケルM.

1

ルビー

よし、これからやってみようと思う。自分自身での定義を検索します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)

(Ruby 1.9.3でテスト済み)


1

Fortran 77

コード:

      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

結果:

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

これは、特定のディレクトリ内で実行された実行の数をカウントします。考えられる改善は、/ tmpディレクトリ内のファイルを要求し、セマフォを追加して、複数のインスタンスが同時にカウンタを更新しようとしないようにすることです。
Glenn Randers-Pehrson 2014年

1

C

それを行う「適切な」方法の1つ(つまり、ファイルを使用せずに)。

あなたはそれを与えることができreset、それをゼロに戻って設定するには、コマンドラインで。実行可能ファイルを移動またはコピーすることもできます。実行可能ファイルを移動するとリセットされ、実行可能ファイルの複数のコピーは独立しています。

#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

きらめく、423文字(さらに別の自己修正コード)。保存してcount.spn実行します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

ここストアにデータファイルを使用して迅速なPythonの3溶液、だnx実行の間には:

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

16回実行した場合の出力:

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

ただし、Visual Studioプロジェクトで設定プロパティを定義する必要があります。

プロジェクト設定のスクリーンショット


0

C / POSIX

このプログラムは、それが呼び出された頻度のカウンターとして、自身の実行可能ファイルへのハードリンクの数を使用します。起動元のディレクトリに新しいハードリンクを作成します(その方法で同じファイルシステム上にあることが保証されているため)。そのため、書き込みアクセス許可が必要です。エラー処理を省略しました。

そのディレクトリに作成されたハードリンクの1つと同じ名前の重要なファイルがないことを確認してください。そうしないと、上書きされます。例えば実行可能ファイルが指定されている場合counter、ハードリンクは名前が付けられますcounter_1counter_2など

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

実行例(実行ファイルが既に実行されている場合、最初の行はカウンターをリセットします):

$ 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

"a"(拡張子なし)という名前のファイルは、プログラムの実行を追跡します。

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.