매 2 ^ n 회


10

n프로그램이 실행 된 횟수를 보자 . n2의 거듭 제곱 인 경우 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

당신은 "어디서 n = 2^x? 그렇지 않으면? 그렇지 않으면 두 번째 출력 2^4, 네 번째 시간 2^16등이 될 것입니다.
John Dvorak

@mniip 두 오타. 아마 더 자세히 읽어 보셨을 것입니다 ... : P
Jwosty

4
음 ... 12의 거듭 제곱입니다. 2^0=1
John Dvorak

1
당신은 여전히 말할 x = 2^x보다는n = 2^x
존 드보락

답변:


8

자바-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에 대한 신선한 매일 할당량와 함께 작동, 오직 최대 할당량. 더 높은 숫자에 대한 지원을 원하는 경우에, 인상하는 [기능 요청] 게시물 quota_max에를 MAX_INT.


6

자바 스크립트

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

@celtschk 위대한 아이디어,하지만 난하고 믿는다는 쿠키가 더 바이트를 촬영 한 것
WallyWest

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

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

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

아,이 언어를 알려 주셔서 감사합니다. 파이썬과 하스켈 모두에 대해 내가 좋아하는 것을 통합합니다.
Kaya

@ 카야 당신이 좋아서 기뻐요! 아직 보지 못했다면 pyos.github.io/dg 의 홈페이지 와 튜토리얼도 있습니다! 많은 상품. 필요하다면 리포지토리에 대한 문제를 주저하지 마십시오. 편집 : 나는 내가 언어의 창조자가 아니라는 것을 지적하고 싶었다.
rubik

5

시나트라 기반 루비 예제

이 서버 기반 솔루션은 쿠키에 각 사용자의 개인 카운터를 저장합니다.

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

여기에 약간의 펄이 있습니다. 데이터를 어디에 저장해야합니까? 물론 프로그램 파일 자체에 왜! =)

$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

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

세게 때리다

같은 I dfernig배쉬 솔루션을 하지만, 나뿐만 아니라 내를 게시하고 싶습니다 :

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)를 이진수로 변환 한 다음 그 수를 세어 인식합니다. 정확히 하나가 있으면 n 은 2의 거듭 제곱입니다. 지수는 이진수의 0의 수입니다. .


1

자바 솔루션

실행 량을 저장하기 위해 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

자바 스크립트

나는 명백한 log2해결책을 사용하지 않고 비트 연산자를 사용하여 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);
}

좋은 전략 그러나 불행하게도, 짧은 상태는 자신의 소유는 단지이다 .. 따라서 렌더링이 실행 된 횟수의 값을 표시하는 데 필요한 for렌더링하여, 1 내지 130 루프 ... /
WallyWest

@WallyWest, 이것을 지적 해 주셔서 감사합니다.
Michael M.

의도 된 범죄 없음 ...
WallyWest

1
나는 당신의 의견을 공격으로 받아들이지 않았습니다. 정말 감사했습니다! 내 말이 제대로 선택되지 않으면 영어가 모국어가 아닙니다.
Michael 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)

(루비 1.9.3에서 테스트)


1

포트란 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

1

파일을 사용하지 않고 "적절한"방법 중 하나입니다.

당신은 그것을 줄 수있는 reset0으로 다시 설정하려면 명령 줄에서. 실행 파일을 이동하거나 복사 할 수도 있습니다. 실행 파일을 이동하면 재설정되고 실행 파일의 여러 복사본이 독립적입니다.

#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

다음은 데이터 파일을 사용하여 실행 을 저장 n하고 x실행 하는 빠른 Python 3 솔루션입니다 .

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

파이썬 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

씨#

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

이 프로그램은 얼마나 자주 호출되는지에 대한 카운터로 자체 실행 파일에 대한 하드 링크 수를 사용합니다. 시작 디렉토리에 새로운 하드 링크를 생성하므로 (동일한 파일 시스템에 있도록 보장되므로) 쓰기 권한이 필요합니다. 오류 처리를 생략했습니다.

해당 디렉토리에 작성된 하드 링크 중 하나와 이름이 같은 중요한 파일이 없는지 확인하십시오. 그렇지 않으면 파일을 겹쳐 씁니다. 예를 들어 실행 파일의 이름 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

포트란 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.