生成乌兰数


19

给定一个整数n(where n < 10001)作为输入,编写一个程序,该程序将输出第一个n Ulam数字。Ulam编号定义如下:

  1. U 1 = 1,U 2 = 2
  2. 对于n > 2,U n是大于U n-1的最小整数,U n-1以正好一种方式是两个不同的较早项的总和。

例如,U 33(2 + 1),U 44(3 + 1)(请注意,(2 + 2)不计入条件,因为术语没有区别),而U 56,(U 5不是5因为5可以表示为2 + 3或4 + 1)。以下是前几个Ulam数字:

1, 2, 3, 4, 6, 8, 11, 13, 16, 18, 26, 28, 36, 38, 47, 48, 53, 57, 62, 69, 72, 77, 82, 87, 97, 99

这是代码高尔夫球,因此最短的入场券获胜。


输出是否必须如图所示(列表用逗号和空格分隔),还是可以输出例如数组?
丹尼斯

n我们必须处理的最小值是多少?
丹尼斯

1
@Dennis空格或逗号或两者都可以。n个最小值是1
苦艾

照原样,我在列表中有括号。可以吗?还是应该删除它们?
丹尼斯2014年

1
@Dennis括号很好。
苦艾酒

Answers:


10

CJam,47 41 37字节

li4,1${__m*{_~<\:+*}%$2/z:^$2=+}*1><`

在线尝试。

运行示例

$ cjam <(echo 'li4,1${__m*{_~<\:+*}%$2/z:^$2=+}*1><`') <<< 26
[1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99]

怎么运行的

这个基本思想如下:

  1. 从数组开始A := [ 0 U₁ U₂ ... Uₖ ]

  2. 计算S的所有和的数组,x + y例如x,y ∊ Ax < y

  3. 丢弃中的所有非唯一和S。由于每个大于2的Ulam数字都是两个较小的数字之和,也是零与它本身的和,因此将Ulam数字丢弃U₃, U₄, ... Uₖ

  4. 剩下的数组是[ U₁ U₂ Uₖ₊₁ ... ],因此下一个Ulam数字是第三小的元素。附加A到步骤1。

li                                    " Read one integer (I) from STDIN.                  ";
  4,                                  " Push the array A = [ 0 1 2 3 ].                   ";
    1${                        }*     " Do the following I times:                         ";
       __m*                           " Push the Cartesian product A × A.                 ";
           {       }%                 " For each pair (x,y) in A × A:                     ";
            _~<\:+*                   " Compute (x + y) * (x < y).                        ";
                     $2               " Sort the resulting array.                         ";
                       /              " Split it into chunks of length 2.                 ";
                        z             " Transpose the resulting two-dimensional array.    ";
                         :^           " Compute the symmetric difference of its rows.     ";
                           $          " Sort the resulting array.                         ";
                            2=        " Extract its third element.                        ";
                              +       " Push it on the array A.                           ";
                                 1>   " Discard the first element of A (0).               ";
                                   <  " Discard all but the first I elements of A.        ";
                                    ` " Push a string representation of A.                ";

输入100已经花费了几秒钟。我想计算最大输入1e5需要花费时间吗?
Martin Ender 2014年

@MartinBüttner:Java解释器快很多,但仍然很慢。所有强力算法均为O(n²)或更糟。对数组使用面向堆栈的语言从来都不是一件好事(例如,计算数组长度需要复制整个数组),因此实际执行时间可能为O(n³)。
丹尼斯

1
@MartinBüttner:WolframAlpha,所以1e4(值得庆幸的是,不是1e5)应该花费不到三周的时间。
丹尼斯2014年

6

J-46个字符

以函数n为参数。

_2}.(,]<./@-.~</~({.+_*1<#)/.~@#&,+/~)@[&0&1 2

爆炸解释:

    (                                )          NB. procedure for a list:
                                  +/~           NB.   take an addition table
              </~              #&,              NB.   select the top right half (no diag)
                 (        )/.~@                 NB.   for each unique value:
                       1<#                      NB.     if more than one present
                  {.+_*                         NB.     add infinity to it
      ]    -.~                                  NB.   remove existing Ulam numbers
       <./@                                     NB.   take the smallest
     ,                                          NB.   append to Ulam numbers
                                      @[&0      NB. repeat this procedure:
                                          &1 2  NB.   n times starting with [1, 2]
_2}.                                            NB. drop the last two numbers

+_*...
tomsmeding

6

T-SQL,301 300 288 287

我犯了一些轻微的SQL滥用。

DECLARE @N INT=100,@T INT=1DECLARE @ TABLE(I INT,U INT)INSERT @ VALUES(1,1),(2,2)#:IF @T>2INSERT @ SELECT TOP 1@T,A.U+B.U FROM @ A,@ B WHERE A.U>B.U GROUP BY A.U+B.U HAVING COUNT(*)=1AND A.U+B.U>ALL(SELECT U FROM @)ORDER BY 2SET @T+=1IF @T<=@N GOTO # SELECT U FROM @ WHERE I<=@N ORDER BY I

此处尝试在SQL Server 2008中进行尝试。

@N保存输入整数。将示例“ 100”更改为n。“ 10000”可能最终会完成,但是我没有让它完成。该条目的字符计数用于一位数字输入。输出以查询结果形式。


5

Haskell,70 67个字符

u n=take n$1:2:[x|x<-[1..],[_]<-[[y|y<-u$n-1,z<-u$n-1,y<z,y+z==x]]]

用法:

>u 6
[1,2,3,4,6,8]

5

GolfScript(41 37字节)

~.14*,3,\{1$.{2$1$-.@<*}%&,2=*|}/0-<`

在线演示

GolfScript中的笛卡尔积很长,因此采用了不同的方法。Ulam数的长期增长是,nth Ulam数约为13.5n,但是在前10000个术语中,nth Ulam数与的最大比值n小于13.3。因此,给定n我们可以过滤第一个14n数字以查找属于该序列的数字。

感谢Dennis的41-> 37。


1
这是相当快的。n = 1000用GolfScript花不到一分钟的时间;至CJam的端口将n = 1000在8秒和n = 100001h 20 m内完成。-您可以通过将方法与我的方法相结合来节省四个字节,即在数组中包含0,然后将其丢弃。这样就可以使用集合并集代替块,并消除了对变量的需要:~.14*,4,\{1$.{2$1$-.@<*}%&,2=*|}/1><`
Dennis

@ Dennis,CJam短几个字符?我假设所有操作都不会花费更长的时间,而且我很确定它具有的一字符别名14
彼得·泰勒

是的,14就是E。但是您需要从STDIN读取,在执行集合并集之前将整数转换为单例(我将提交有关此问题的错误报告),并且2$由于CJam每次迭代后都会修改堆栈,因此无法在内部循环中工作...我已经尝试了几种技巧,但最短的技巧恰好是37个字节:li4,1$E*{__{I1$-_@<*}%&,2=I*a|}fI1><`
丹尼斯

5

JavaScript ES6,100 ... 93 90个字符

在Web控制台或最新的Firefox(晚上或发行版)的Scratchpad中运行它。

编辑8打了很多球!!!并使其降至94个字符 93 90个字符(感谢@openorclose)。(我的第一个Sub 100)

这是我的版本,速度更快,但长了3个字符(107个字符) ,与上面的字符数完全相同,并且比下面的蛮力方法小得多!(感谢edc65):

u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)r.map(j=>c-=j<i/2&s[i-j])})([])||r

我将继续尝试进一步打高尔夫球。但是我们将其挤出JS:P的范围之外

当我在网页的脚本标签中运行此代码时,有一些数字:

n次
10 0.001
100 0.005
1000 2.021
10000 236.983
100000个       待定 tldr; 太久没有运行:P

这是我的第一篇论文,其灵感很大程度上来自@ rink.attendant.6在JavaScript中的回答。

u=n=>{for(l=[1,g=2],i=3;g<n;++i){z=1;for(j of l)for(k of l)z-=j<k&j+k==i;!z?l[g++]=i:0}return n>1?l:[1]}

我知道这可以打得更远。我也将发布一个非暴力的解决方案,它可能会更短。

编辑1:打更多的球,并固定为n = 1

我必须说我羡慕Haskell和J对于每种要求都非常方便的快捷方式-_-


关于Haskell,我认为函数样式和语法最重要(例如,没有可怕的巨型循环),尽管函数的数量总是很不错的:-)
引以为豪的haskeller

1
最快的一个可以肯定会打更多的高尔夫球:(104)u=n=>{for(s=[,1,1],r=[i=1,l=2];c=l<n;!c?s[r[l++]=i]=1:0,i++)for(j of r)c-=j<i/2&s[i-j];return n>1?r:[1]}甚至可能更多
edc65 2014年

1
1.我仍然几乎不了解如何避免双循环。荣誉2.高尔夫技巧:在E6中,我始终尽量避免return。100:u=n=>(s=>{for(r=[i=1,l=2];c=l<n;i+=!c?s[r[l++]=i]=1:1)for(j of r)c-=j<i/2&s[i-j]})([,1,1])|n>1?r:[1]
edc65

1
少了一个字符:u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)for(j of r)c-=j<i/2&s[i-j]})([,1])||r
openorclose 2014年

1
90个字符:u=n=>(s=>{for(r=[i=l=1];c=l<n;i+=c&&i-2?1:s[r[l++]=i]=1)r.map(j=>c-=j<i/2&s[i-j])})([])||r 除非在某处需要[,1]
openorclose 2014年

5

Perl-71字节

#!perl -p
@a=$b[2]=1;1while$b[++$a]^1||$_>map(++$b[$_+$a],@a)&&push@a,$a;$_="@a"

在线尝试!

把shebang算作一个。
使用第二个数组存储和似乎比散列要快得多。内存使用量也更少,这是我所料不到的。

用法示例:

$ echo 30 | perl ulam.pl

样本输出:

1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99 102 106 114 126

大概的运行时间:

n = 100     0.015s
n = 1000    0.062s
n = 10000   4.828s

2
为8.6秒n == 1e4。惊人!的输出n == 1虽然不正确;它应该打印一个数字。
丹尼斯

@Dennis现在已修复。
primo 2014年

4

爪哇,259

import java.util.*;class C{public static void main(String[]a){List<Integer>l=new ArrayList<>();l.add(1);l.add(2);for(int i=3,z=0;l.size()<new Long(a[0]);i++,z=0){for(int j:l){for(int k:l){if(j<k&j+k==i)z++;}}if(z==1)l.add(i);}l.forEach(System.out::println);}}

蛮力对此很有效。

import java.util.*;
class C {
    public static void main(String[] a) {
        List<Integer>l = new ArrayList<>();
        l.add(1);
        l.add(2);
        for (int i = 3, z = 0; l.size() < new Long(a[0]); i++, z = 0) {
            for (int j : l) {
                for (int k : l) {
                    if (j < k & j + k == i)
                        z++;
                }
            }
            if (z == 1)
                l.add(i);
        }
        l.forEach(System.out::println);
    }
}

1.打印结果似乎需要Java 8,这可能值得一提。2.的输出1应为单个数字。
丹尼斯

1
这可以处理10k的输入吗?
Martin Ender 2014年

我相信循环的j和k不需要大括号。
迈克尔·复活节

正如Martin所暗示的,我也希望看到该程序的定时执行N = 10K。
迈克尔·复活节

4

APL(Dyalog扩展)36 35字节

-1字节byAdám

{⍵↑{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}⍣⍵⍳2}

在线尝试!

{⍵↑{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}⍣⍵⍳2}      Monadic function taking an argument n:

{⍵,⊃∧(∊⊢⊆⍨⍧⍨∊2 3⍨)⍵~⍨,+⍀⍨⍵}   Helper function to compute the next Ulam number
                                    given  (the first few Ulam numbers)
                        +⍀⍨⍵      Make an addition table from ⍵.
                       ,          Flatten into a list.
                   ⍵~⍨            Remove all entries already in ⍵.

     (∊⊢⊆⍨2 3∊⍨⍧⍨)               Helper function taking an argument x:
                ⍧⍨                  The count of elts of x in itself                 
           2 3∊⍨                    1s where those counts are in (2 3), else 0s.*
       ⊢⊆⍨                          Partition x, removing values corresponding to 0s.
                                   Join the partitions into a single list.

    (∊⊢⊆⍨⍧⍨∊2 3⍨)                Keep all elements that occur exactly 2 or 3 times.
                                  (i.e. that occur once as a
                                  sum of distinct elements of ⍵).
                             Sort ascending.
                             Take the first value (the next Ulam #).
 ⍵,                           Append that value to ⍵.

{⍵↑{...}⍣⍵⍳2}
{  {...}⍣⍵  }                 Call the helper function n times
           2                 starting with (1 2). First n+2 Ulam numbers.
 ⍵↑                           Keep the first n elements.

xxx2a+baxbxa=12a+b{2,3}

*(在ngn / APL中,常量可以不使用而结束火车。但是ngn / APL没有计入,因此我们在某个地方需要)。)


{(2 3∊⍨⍵⍧⍵)/⍵}(∊⊢⊆⍨⍧⍨∊2 3⍨)
亚当

3

PHP 5.4 +,164

与我的答案相同的方法:

<?function u($n){for($l=[1,2],$i=3;count($l)<$n;++$i){$z=0;foreach($l as $j){foreach($l as $k){$z+=$j<$k&$j+$k==$i;}}if($z==1)$l[]=$i;}return array_slice($l,0,$n);}

3

果冻,20字节

Œc§ḟµḟœ-Q$Ṃɓ;
2RÇ⁸¡ḣ

在线尝试!

Œc§ḟµḟœ-Q$Ṃɓ;    Helper link that appends the next number to x, a list of Ulam numbers:
Œc                  All unordered pairs of x
  §                 Sum each pair
   ḟ                Filter out the numbers already present in x.
    µ               Let this list be y. Then apply the following chain:

     œ-Q$Ṃ          Find the minimum of all unique elements.
     ḟ                Take y and filter out the elements in
      œ-Q$            the multiset difference between y and its unique elements.
          Ṃ           Then find the Ṃinimum of the result.

           ɓ;    Append (ɓ reverses argument order) the result to 


2RÇ⁸¡ḣ           Main link:
2R               Start with [1,2].
  Ç⁸¡            Apply the helper link (Ç) n (⁸) times to generate n+2 Ulam #s.
     ḣ           Keep the first n values.

2

CoffeeScript,119 114

最近,我一直在练习CoffeeScript以提高高尔夫JavaScript的水平,因此,这是我编译成CoffeeScript的JavaScript答案:

u=(n)->l=[1,2];i=3;z=0;(for j in l
 for k in l
  z+=j<k&j+k==i
l.push(i) if z==1;++i;z=0)while l.length<n;l[..n-1]

我不太了解CoffeeScript中的循环和理解,因此也许可以进一步研究,但这就是我现在所拥有的。换行符被视为一个字符(Unix样式)。


2

JavaScript中,147 154 150(136)

受到@Ypnypn之前发布的蛮力Java解决方案的极大启发:

function u(n){for(l=[1,2],i=3;l.length<n;++i){z=0;l.forEach(function(j){l.forEach(function(k){z+=j<k&j+k==i})});if(z==1)l.push(i)}return l.slice(0,n)}

感谢@Dennis将原始版本减少了4到18个字节

危险版本(使用for..in循环)

我不建议运行此程序,因为使用正在循环的对象进行循环可能会导致您的机器突然起火和/或转变为愤怒的杀人机器,但是这里是:instanceof Arrayfor..in

function u(n){for(l=[1,2],i=3;l.length<n;++i){z=0;for(j in l)for(k in l)z+=l[j]<l[k]&l[j]+l[k]==i;if(z==1)l.push(i)}return l.slice(0,n)}

不打高尔夫球

function u(n) {
    var l = [1, 2],
        i = 3,
        j, k, z;

    for (; l.length < n; ++i) {
        z = 0; 
        l.forEach(function (j) {
            l.forEach(function (k) {
                if (j < k & j + k === i) {
                    z++;
                }
            });
        });
        if (z === 1) {
            l.push(i);
        }
    }

    return l.slice(0, n);
}

1的输出应为单例。
丹尼斯2014年

@丹尼斯谢谢,改正。
rink.attendant.2014年

1.如果您z=0在循环内移动,则只需一次。2. for(j in l)for(k in l)z+=l[j]<l[k]&l[j]+l[k]==i;l.forEach方法短很多。
丹尼斯2014年

2

Mathematica,107 91字节

Nest[#~Append~Min@Cases[Tally[Tr/@#~Subsets~2],{n_,1}:>n]&,{1,2},i=Input[]]~Drop~{3}~Take~i

这是规范的非常直接的实现。

  • 查找所有对。
  • 删除所有重复项。
  • 删除所有小于最后一个Ulam数字的数字。
  • 将最小值添加到列表中。

我还应用了丹尼斯(Dennis)包括sums的技巧0,但是要注意的是,这使得列表0在恢复之前的第三个元素符合人们的期望,因此我需要从列表中删除该元素。

它可以1000在几秒钟内处理输入,但是我怀疑您是否会在合理的时间内获得10k的结果。但是我认为其他任何一个在这方面都表现不佳。


2

OCaml-254个字符

该代码使用哈希表存储列表中当前元素的总和,并在每次计算新元素时对其进行更新。

open Hashtbl let h=create 7 let()=add h 3 1 let rec r n i l=if n=0then List.rev l else if mem h i&&find h i=1then(List.iter(fun x->if mem h(x+i)then replace h(x+i)2else add h(x+i)1)l;r(n-1)(i+1)(i::l))else r n(i+1)l let u n=if n=1then[1]else r(n-2)3[2;1]

用法:

在OCaml解释器中:

# u 26;;
- : int list =
[1; 2; 3; 4; 6; 8; 11; 13; 16; 18; 26; 28; 36; 38; 47; 48; 53; 57; 62; 69;
 72; 77; 82; 87; 97; 99]

不打高尔夫球

open Hashtbl
let h = create 7
let() = add h 3 1
let rec r n i l =
  if n=0 then List.rev l
  else if mem h i && find h i=1 then
    begin
      List.iter
        (fun x-> if mem h(x+i) then replace h (x+i) 2 else add h (x+i) 1)
        l;
      r (n-1) (i+1) (i::l)
    end
  else r n (i+1) l

let u n = if n=1 then [1] else r (n-2) 3 [2;1]

2

Python,137 128 126个字符。

U,i=[1,2],2
for _ in [[0]]*(input()-2):
 t=_*3*i
 for a in U:
  for b in U:t[a+b]+=a!=b
 i=t[i+1:].index(2)+i+1;U+=[i]
print U

这是我的第一场高尔夫,现在已经从250个字符左右降低了,我很高兴,但是很乐意提出改进建议!


轻微,但值得:将第5&6行for b in U:t[a+b]+=a!=b与第8&9行合并while t[i]-2:i+=1
James Waldby-jwpat7 2014年

谢谢你的建议!我也将while循环更改为索引,但是它没有保存我期望的那么多字符。
QuadmasterXLII 2014年

另外2个字符:将U初始化为[1],然后将第7行移至for
James Waldby-jwpat7

您仍然可以通过改变去掉2个字符U,i=[1,2],2U,i=[1],2,并input()-2input()-1t=_*3*it=_*3*i;U+=[i]和删除;U+=[i]在最终
詹姆斯Waldby - jwpat7

0

C#,257

使用LINQ的蛮力方法:

using System.Linq;class U{void F(int n){var u=n<2?new int[]{1}:new int[]{1,2};for(int i=3;u.Length<n;++i)if(u.SelectMany(x=>u,(a,b)=>new{A=a,B=b}).Count(x=>x.A>x.B&&x.A==i-x.B)==1)u=u.Union(new int[]{i}).ToArray();System.Console.Write(string.Join("",u));}}

脱开,带测试线束

using System.Linq;
class Ulam
{
    void F(int n)
    {
        //handle special case where n = 1 (ugh)
        var u = n < 2 ? new int[] { 1 } : new int[] { 1, 2 };
        for (int i=3; u.Length<n; ++i)
            if (u.SelectMany(x => u, (a, b) => new { A = a, B = b })
                     .Count(x => x.A > x.B && x.A == i - x.B) == 1)
                u = u.Union(new int[] { i }).ToArray();
        System.Console.Write(string.Join(" ",u));
    }
    public static void Main(string[] args)
    {
        new Ulam().F(1);
        System.Console.WriteLine();
        new Ulam().F(2);
        System.Console.WriteLine();
        new Ulam().F(3);
        System.Console.WriteLine();
        new Ulam().F(26);
        System.Console.WriteLine();
    }
}

非常慢:n = 500时46s,n = 1000时6m,n = 2000时50m。以这种指数速度,我相信处理n = 10K将需要5或6天。
理查二世

0

Pyth,27 25字节

<uaGh-sfq1lT.gksM.cG2GQS2

在这里在线尝试。

<uaGh-sfq1lT.gksM.cG2GQS2Q   Implicit: Q=eval(input())
                             Trailing Q inferred
 u                    Q      Perform the following Q times...
                       S2    ... with G initialised to [1,2]:
                 .cG2          Get all 2-element combinations of G
               sM              Sum each pair
            .gk                Group them by value
                                 The groups are sorted by the result of the sum
       f                       Filter the groups, as T, keeping those where:
          lT                     Length of T
        q1                       Equal to 1
      s                        Flatten list
     -               G         Remove elements of the above which are already in G
    h                          Take the first of the remaining elements
                                 This is the smallest, as the grouping also sorted them
  aG                           Append this to G
<                        Q   Take the first Q elements, implicit print

编辑:分组之前通过求和来打2个字节。先前版本:<uaGh-mssdfq1lT.gsk.cG2GQS2


0

C,478字节

#define R return
bs(x,v,l,h,r)unsigned x,*v,l,h,*r;{unsigned m;for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}*r=m;R 0;}
#include<stdlib.h>
unsigned*f(unsigned w){unsigned*u=0,i,k,m,y,z;if(w>1E6||w==0)R u;u=malloc(w*sizeof*u);if(!u)R u;k=0;u[k++]=1;if(w==1)R u;m=u[k++]=2;if(w==2)R u;l:for(i=0,y=0,z=k-1,++m;i<k;y+=bs(m-u[i],u,i+1,z,&z),++i)if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;if(m==0){free(u);u=0;R u;}if(y!=1)goto l;u[k++]=m;if(k< w)goto l;R u;}

现在,在Tio中,只需9秒即可找到10000个值(并在其中打印前100个值)。诀窍是在内部循环中使用的不是线性搜索,而是二进制搜索...以下这些函数具有很好的缩进性和可读性(最后对我来说):

bsCopy(x,v,l,h,r)unsigned x,*v,l,h,*r;
{unsigned m;
 for(;l<=h;){m=(l+h)/2;if(x<v[m])h=m-1;else if(x>v[m])l=m+1;else{*r=m;R 1;}}
 *r=m;R 0;// in *r if return 0 the min index that fail else the index of find x
}

unsigned*fCopy(unsigned w)
{unsigned*u=0,i,k,m,y,z;
 if(w>1E6||w==0)R u;
 u=malloc(w*sizeof*u);
 if(!u)R u;
 k=0;u[k++]=1;if(w==1)R u;
   m=u[k++]=2;if(w==2)R u;//below I suppose m-u[i] is in the range (if exist in u) (i+1)..z 
 l: for(i=0,y=0,z=k-1,++m;i<k;y+=bsCopy(m-u[i],u,i+1,z,&z),++i)
          if(y>1||u[i]+(i+1!=k?u[i+1]:0)>m)break;
   if(m==0){free(u);u=0;R u;}
          if(y!=1)goto l;
   u[k++]=m;if(k< w)goto l;
 R u;
}

看看我是否可以减少某些东西……
RosLuP

有人说我在编程中可以打高尔夫球,但还不是全部...
RosLuP


@ceilingcat“ z = k”对我来说是错误的,因为二进制搜索(bs()函数或您的B()函数)在我看来想作为参数范围(我也不知道它是否正确...),因此调用bin搜索的函数必须为z = k-1
RosLuP

0

APL(NARS),278个字符,556个字节

∇u←p w;m;y;i;k;z;r;bs
bs←{(x l h)←⍵⋄l>h:0,h⋄x<⍺[t←⌊2÷⍨l+h]:⍺∇x,l,t-1⋄x>⍺[t]:⍺∇x,(t+1),h⋄1,t}
u←⍬  ⋄→0×⍳(w>1E6)∨w≤0
u←u,1⋄→0×⍳w=1
u←u,2⋄→0×⍳w=2⋄k←m←2
i←1⋄y←0⋄m+←1⋄z←k
→7×⍳(y>1)∨i>k⋄→7×⍳m<u[i]+{i=k:0⋄u[i+1]}⋄r←u bs(m-u[i]),(i+1),z⋄y+←↑r⋄z←2⊃r⋄i+←1⋄→6
→5×⍳y≠1⋄u←u,m⋄k+←1⋄→5×⍳k<w
∇

这就是我发送的C语言在APL中的翻译。似乎我不明白何时使用∇∇代替∇...当一个参数是一个函数(而不是另一种类型)时,可能会使用∇∇。“ u bs x,a,b”应该是“ u”数组中bin搜索a..b范围内的值“ x”;它将返回1,indexWhereFind或0,indexWhereEndOfsearch。使用参数200 p函数需要+-一分钟...

  p 100
1 2 3 4 6 8 11 13 16 18 26 28 36 38 47 48 53 57 62 69 72 77 82 87 97 99 102 106 114 126 
  131 138 145 148 155 175 177 180 182 189 197 206 209 219 221 236 238 241 243 253 
  258 260 273 282 309 316 319 324 339 341 356 358 363 370 382 390 400 402 409 412 
  414 429 431 434 441 451 456 483 485 497 502 522 524 544 546 566 568 585 602 605 
  607 612 624 627 646 668 673 685 688 690 
  p¨1 2 3 4
1  1 2  1 2 3  1 2 3 4 

1
∇∇在dop中,是指运算符本身,而是指由运算符及其操作数组成的派生函数。因此,一元运算符(⍺⍺∇∇)二元运算符相同(⍺⍺∇∇⍵⍵)
阿达姆(Adám)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.