Add tags

Add tags to the following comment

これ、キミならどう書く 2.0 - ROUND 2 -と同じ問題ですね。違うのは、LL Ringの時の「どう書く」では、1の時も1と数えるので、1違うだけで。

その時にいろいろ書いて出来た最速の奴を。j詳しくは404 Blog Not Found:h(4294967295) = 2610744987 where g = 1051 をご覧下さい。

途中経過表示をやめれば、もっと速くなるでしょう。

Dan the Number Cruncher

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
Core 2 Duo 2.33GHzで

% time ./a.out 1000000
h(1000000) = 837799 where g(837799) = 525
0.264u 0.006s 0:00.27 96.2%     0+0k 0+0io 0pf+0w
*/

#include <stdio.h>
#include <stdlib.h>

#ifndef CACHE_SIZE
#define CACHE_SIZE 64*1024*1024 /* large enough */
#endif

#define MAX_U16        65535
typedef unsigned short U16;
typedef long long      I64;

U16 *cache;
int cachesize;
#define lookup(n)  ((n) < cachesize ? cache[(n)] : 0)
#define store(n,g) if ((n) < cachesize && g <= MAX_U16) cache[(n)] = (g)

I64 g(I64 n){
    I64 result = lookup(n);
    if (result) return result;
    I64 i = n;
    I64 l;
    result = 1;
    while (i > 1){
        i = i & 1 ? i*3+1 : i >> 1;
        l = lookup(i);
        if (l){
            result += l;
            break;
        }else{
            result++;
        }
    }
    if (i < 1)       fprintf(stderr, "overflow! g(%qd) = %qd\n", n, i);
    store(n, result);
    return result;
}

I64 *h(I64 n){
    I64 i, nmax = 0, gmax = 0, gnext = 0;
    static I64 result[2];
    for (i = n; i > 1 ; i--){
        gnext = g(i);
#ifdef VERBOSE
        fprintf(stderr, "g(%qd) = %qd\r", i, gnext);
#endif
        if (gnext > gmax){
            nmax = i; gmax = gnext;
        }
        if (i & 0xffff) continue;
       printf("nmax = %qd, gmax = %qd, n = %qd\r", nmax, gmax, i);
       fflush(stdout);
    }
    result[0] = nmax; result[1] = gmax;
    return result;
}

#define min(x,y) ((x) < (y) ? (x) : (y))

void init_cache(I64 n){
    cachesize = min(n, CACHE_SIZE);
    cache     = (U16 *)calloc(cachesize, sizeof(U16));
    if (cache == NULL) exit(-1);
}

int main(int argc, char **argv){
    I64 n = 0xffffffff; /* look @ this! */
    if (argc > 1){
        n = atoll(argv[1]);
    }
    init_cache(n);
    I64 *hg = h(n);
    printf("h(%qd) = %qd where g(%qd) = %qd\n", n, hg[0], hg[0], hg[1]);
    return 0;
}

Add tags

The input will be splited to tags with space.

Index

Feed

Other

Link

Pathtraq

loading...