Кожні 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

ти мав на увазі "куди n = 2^x? Інакше результат буде 2^4в четвертий раз 2^16і так далі.
Джон Дворак

@mniip обидва помилки. Напевно, я мав би прочитати це уважніше ...: P
Jwosty

4
Гм ... 1це сила два. 2^0=1
Джон Дворак

1
Ви все ще говорите, x = 2^xа неn = 2^x
Джон Дворак

Відповіді:


8

Java - зловживання API

В Інтернеті є безліч комп’ютерів, на які можна порахувати, так навіщо мені зберігати підрахунок?

Повне зловживання 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

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 ... Я розглядаю можливість використання localStorage для майбутньої гри JS ...
WallyWest

Щось таке маленьке, як лічильник, також має працювати печиво.
Celtschk

@celtschk Чудова ідея, але я вважаю, що приготування файлу cookie зайняло б більше байтів
WallyWest

6

C - запис у виконуваний файл

Цей код C оновлює рядок dataу виконуваному файлі, тому по суті це код, що змінюється самостійно. Якщо ви запустили його понад 9999999 разів, ви отримаєте цікаві речі.

#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

Java

Наступний код модифікує власний файл класу для зберігання нової кількості запуску. Це було особливо весело, коли ви не мали уявлення про те, як виглядає байт-код, але після незліченних годин Googling and Testing це нарешті працює! :)

Демо (використовуючи 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

дг

Тут я представляю вам портативний код! Під час кожного прогону в #кінці додається а, роблячи панель прогресу! Також ви можете перемістити код на іншу машину та відновити місце, де ви були.

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.
Кая

@Kaya Я щасливий, що тобі це подобається! Якщо ви ще не бачили, є домашня сторінка на pyos.github.io/dg і підручник! Багато товарів. І не соромтеся відкривати випуск у сховищі, якщо вам здається, що так. EDIT: Я просто хотів зазначити, що я не творець язика.
rubik

5

Приклад Рубі на основі синатри

Це серверне рішення зберігає персональний лічильник кожного користувача у файлі 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

перл

Ось короткий замах, щоб зробити це. Де слід зберігати дані? Чому в самому програмному файлі, звичайно! =)

$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перш ніж прочитати з нього, а потім повернутися до цього місця.
моб

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

Баш

Я як dfernig «s рішення Bash , але я хотів би опублікувати моє , а також:

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. Експонент - кількість нулів у двійковій .


1

Рішення Java

Використання API налаштувань Java для зберігання запущеної суми; і заздалегідь підрахував потужності 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 чисел.

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, так, дякую, що вказали на це.
Майкл М.

Жодного правопорушення не передбачалося ...
WallyWest

1
Я не сприйняв ваш коментар як правопорушення, це була справжня подяка! Вибачте, якщо мої слова не підібрані правильно, англійська мова не є моєю рідною мовою.
Майкл М.

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

Фортран 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 та додавання семафору, щоб кілька екземплярів не намагалися оновити лічильник одночасно.
Гленн Рендерс-Персон

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, яке використовує файл даних для зберігання nта xміж прогонами:

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

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

Ця програма використовує кількість жорстких посилань на свій власний виконуваний файл як лічильник того, як часто його викликали. Він створює нові жорсткі посилання в каталозі, з якого він був запущений (оскільки таким чином гарантовано знаходитись у тій же файловій системі), тому необхідний дозвіл на запис. Я опустив обробку помилок.

Ви краще переконайтесь, що у вас немає жодного важливого файлу з таким самим іменем, як одне із створених жорстких посилань у цьому каталозі, інакше він буде перезаписаний. Якщо , наприклад , виконуваний файл називається counter, жорсткі посилання будуть названі counter_1, і counter_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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.