平方数数字密度


17

我自己发明的数字的平方数字位数密度(SNDD)是连续数字中发现的平方数字计数与数字长度的比率。例如,169是一个3位数字,包含4个正方形数字-1、9、16、169-,因此正方形数字的数字密度为4/3或1.33。4位数字1444具有6个正方形-1、4、4、4、144、1444-因此比率为6/4或1.5。注意,在前面的示例中,正方形可以重复。另外,不允许441,因为无法在数字1444内连续找到它。

您的任务是编写一个程序,该程序在给定范围A-B(含)范围内搜索平方位数最高的数字。您的程序应遵守以下规范:

  • 输入A,B的范围为1到1,000,000,000(10亿)。例:sndd 50 1000
  • 结果返回SNDD最大的数字。如果是平局,则返回最小的数字。
  • 0不会以任何形式(0、00、000等)算作正方形。以0开头的正方形(如049或0049)也不算。
  • 注意,整数不必一定是平方数。

例子:

sndd 14000 15000
Output: 14441

sndd 300 500
Output: 441

奖金:SNDD最大的数字是1到1,000,000,000?您能否证明这是最大的可能性,还是更大范围的更大?

当前分数:

  1. 红宝石:142
  2. Windows PowerShell:153
  3. 斯卡拉:222
  4. 蟒蛇:245

现在已经选择了答案,这是我在JavaScript中的(unolfed)参考实现:http : //jsfiddle.net/ywc25/2/

Answers:


3

Ruby 1.9,142个字符

$><<($*[0]..$*[1]).map{|a|n=0.0;(1..s=a.size).map{|i|n+=a.chars.each_cons(i).count{|x|x[0]>?0&&(r=x.join.to_i**0.5)==r.to_i}};[-n/s,a]}.min[1]
  • (139-> 143):如果出现平局,则固定输出。

@Ventero:两个测试用例均失败。我认为您忘了省略以0 *开头的正方形
mellamokb

@mellamokb:在这里不要使它们失败:$ ruby1.9 sndd.rb 14000 15000 => 14441x[0]>?0检查从0开始的正方形
Ventero

@mellamokb:它通过了这里的测试用例。
Nabb 2011年

@Ventero:嗯..我的红宝石测试环境一定有问题。我对Ruby不熟悉。我有1.87,我认为,我复制/粘贴上面的代码为sndd.rb,然后运行ruby sndd.rb 14000 15000从Windows,我得到14000
mellamokb

@mellamokb:在Ruby 1.8中,它?0是一个Fixnum,而在Ruby 1.8中,它是一个字符串,因此我提到的比较取决于Ruby版本具有不同的含义(实际上,它应该在1.8中引发异常)。这就是为什么我在标题中明确提到1.9版的原因。
Ventero 2011年

8

回答加成:数字<1e9的最佳分数是5/3 = 1.666 ...,由144411449(也许还有其他?)生成。

但是,如果数量更多,您可以做得更好。通常,如果n的分数为x,则可以连接n的两个副本并获得相同的分数x。如果您很幸运,并且n的第一位和最后一位相同,那么您可以在级联中删除其中一位,并稍微提高分数(一位比平方数少一倍,一位比平方数少一倍) 。

n = 11449441的得分为1.625,并且第一位和最后一位相同。利用这个事实,我们得到以下分数序列:

1.625 for 11449441
1.666 for 114494411449441
1.682 for 1144944114494411449441
1.690 for 11449441144944114494411449441
1.694 for 114494411449441144944114494411449441

它给出了一个无限的数字序列,这些数字严格(尽管会有所减少)比以前的数字好,但对于前一个数字,除了前2个数字之外,所有其他数字都比最佳分数<1e9好。

但是,此顺序可能并不是最好的。它收敛为有限分数(12/7 = 1.714),并且可能还有其他分数比限制更好的数字。

编辑:更好的序列,收敛到1.75

1.600 14441
1.667 144414441
1.692 1444144414441
1.706 14441444144414441
1.714 144414441444144414441

有趣!您可能刚刚证明了这个序列实际上是无限的。
ESultanik'6

@ESultanik:并非如此,因为这里没有要求总数必须是一个完美的正方形。
mellamokb

@ESutanik:我不认为序列是相关的,因为它们要求整数必须是一个正方形-在我的序列中,唯一的正方形是小的子序列(<= 5位数字),除非偶然地有一个更大的子序列。
基思·兰德尔

您还可以生成一个无限序列,其中链接生成一个额外的正方形,即,以44结束并以1开头的东西将使每个组合产生441。一个简单的例子是序列144、144144、144144144等。– mellamokb,2011
6

@mellamokb哇,我完全想念这个数字不一定是一个完美的正方形。你是对的。
ESultanik

3

Windows PowerShell中,153 154 155 164 174

$a,$b=$args
@($a..$b|sort{-(0..($l=($s="$_").length)|%{($c=$_)..$l|%{-join$s[$c..$_]}}|?{$_[0]-48-and($x=[math]::sqrt($_))-eq[int]$x}).Count/$l},{$_})[0]

感谢Ventero减少了1个字节,我太愚蠢了,无法找到自己。

154字节版本说明:

$a,$b=$args   # get the two numbers. We expect only two arguments, so that
              # assignment will neither assign $null nor an array to $b.

@(   # @() here since we might iterate over a single number as well
    $a..$b |  # iterate over the range
        sort {   # sort
            (   # figure out all substrings of the number
                0..($l=($s="$_").length) | %{  # iterate to the length of the
                                               # string – this will run off
                                               # end, but that doesn't matter

                    ($c=$_)..$l | %{       # iterate from the current position
                                           # to the end

                        -join$s[$c..$_]    # grab a range of characters and
                                           # make them into a string again
                    }
                } | ?{                     # filter the list
                    $_[0]-48 -and          # must not begin with 0
                    ($x=[math]::sqrt($_))-eq[int]$x  # and the square root
                                                     # must be an integer
                }

            ).Count `  # we're only interested in the count of square numbers
            / $l       # divided by the length of the number
        },
        {-$_}  # tie-breaker
)[-1]  # select the last element which is the smallest number with the
       # largest SNDD

2

Python中,245 256

import sys
def t(n,l):return sum(map(lambda x:int(x**0.5+0.5)**2==x,[int(n[i:j+1])for i in range(l)for j in range(i,l)if n[i]!='0']))/float(l)
print max(map(lambda x:(x,t(str(x),len(str(x)))),range(*map(int,sys.argv[1:]))),key=lambda y:y[1])[0]
  • 256→245:由于Keith Randall的提示,清理了参数解析代码。

如果读取的是范围而stdin不是命令行参数,则长度可能要短得多。

编辑:

关于奖金,我的实验建议如下:

猜想1对于每n ∈ℕ ,在数ñ拥有最大SNDD必须完全包含数字1,4和9。

猜想2.Ñ ∈ℕ∀我ℕ&Element; Ñ:SNDD(Ñ)≥SNDD()。

证明草图。具有数字1、4和9的正方形的集合可能是有限的。∎


试试range(*map(int,sys.argv[1:]))
Keith Randall

1
如果我的答案中的1.75收敛序列产生了最高分(当然是大的话),那么猜想2是错误的,因为该序列的后续元素永远永远略胜一筹。
基思·兰德尔

@Arnt的答案推测2是错误的,因为SNDD的值可以任意增大。
mellamokb

2

斯卡拉222

object O extends App{def q(i: Int)={val x=math.sqrt(i).toInt;x*x==i}
println((args(0).toInt to args(1).toInt).maxBy(n=>{val s=n+""
s.tails.flatMap(_.inits).filter(x=>x.size>0&&x(0)!='0'&&q(x.toInt)).size.toFloat/s.size}))}

(需要2.9标量。)


1

考虑奖励问题:超出此范围的最高SNDD是无限的。

至少,如果我正确阅读了该问题,那么像100这样的正方形(10 * 10)确实可以计数。

如果考虑数字275625,则分数为5/6,因为25、625、5625、75625和275625均为正方形。

加上2个零将得出:27562500,得分为10/8。该序列的极限是5/2 = 2.5

沿着相同的线,您可以找到以所需的任意数量的较小正方形结尾的正方形。我可以证明这一点,但您可能会明白。

诚然,这不是一个很好的解决方案,但是它证明了SNDD没有上限。


“沿着相同的线,您可以找到以所需的任意多个较小的正方形结尾的正方形。我可以证明这一点,但您可能会明白。” 我希望看到这种证明得到发展。我可以看到以25结尾的最大序列,其中以25结尾的每个数字都是一个正方形,即275625。您可以在开头没有数字1-9来查找另一个正方形。您是说可以任意设置它的大小吗?如果是这样,怎么以及为什么呢?
mellamokb

是的,序列可以任意设置。证明是这样的:如果a * a = b是您的起始数字,则如果c足够大,则(a + 10 ^ c)*(a + 10 ^ c)也会以b结尾。实际上,如果取平方,则可能会有较小的数字以b结尾。例如,18275625是一个正方形(4275 * 4275)。
Arnt Veenstra

查找正方形的代码:jsfiddle.net/zVSuZ/2
mellamokb

@Arnt:这是一个(琐碎的)序列,5 ^ 2(1/2),55 ^ 2(2/4),5055 ^ 2(3/8),50005055 ^ 2(4/16)等。其中每个加法为5 * 10 ^ n,其中n是上一个条目的两倍。每个条目的分数变小,但应用加两个00的规则时的限制略微变大,因此限制为(1/2),(2/2),(3/2),(4/2)等。
mellamokb

是的,这就是可以证明SNDD可以实现任何价值的想法。
Arnt Veenstra

1

Clojure-185个字符

可能可以进一步优化,但是在这里:

(fn[A,B]((first(sort(for[r[range]n(r A(inc B))s[(str n)]l[(count s)]][(/(count(filter #(=(int%)(max 1%))(for[b(r(inc l))a(r b)](Math/sqrt(Integer/parseInt(subs s a b))))))(- l))n])))1))

用作具有两个参数的函数:

(crazy-function-as-above 14000 15000)
=> 14441

1

果冻,21字节,语言发布日期挑战

DµẆ1ị$ÐfḌƲS÷L
rµÇÐṀḢ

在线尝试!

说明

助手功能(计算其输入的数字密度):

DµẆ1ị$ÐfḌƲS÷L
Dµ              Default argument: the input's decimal representation
  Ẇ             All substrings of {the decimal representation}
      Ðf        Keep only those where
   1ị$          the first digit is truthy (i.e. not 0)
        Ḍ       Convert from decimal back to an integer
         Ʋ     Check each of those integers to see if it's square
           S    Sum (i.e. add 1 for each square, 0 for each nonsquare)
            ÷L  Divide by the length of {the decimal representation}

主程序:

rµÇÐṀḢ
rµ              Range from the first input to the second input
  ÇÐṀ           Find values that maximize the helper function
     Ḣ          Choose the first (i.e. smallest)

如果没有该程序,则该程序可能会更有趣-这样,它将返回所有最大密度数,而不是仅返回一个-但我添加了它以符合规范。

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.