圣数字


44

在许多字体(特别是Consolas字体)中,十个十进制数字中有五个在其中带有“孔”。我们将这些神圣数字称为:

46890

因此,这5位邪恶的数字是:

12357

如果一个整数仅包含圣数字,则可以将其分类为“圣”,否则为“不圣”。因为-是不圣洁的,所以没有负整数可以是圣洁的。

可以根据它们具有多少个孔来进一步分类圣整数。例如,以下数字的整洁度为1:

469

这些数字的圣洁度为2:

80

我们说整数的整体圣洁度是其数字圣洁度的总和。因此,80将具有4的圣洁度,并且99将具有2的圣洁度。

挑战

给定两个整数n > 0h > 0,输出n圣洁度至少为的圣整数h。您可以假定输入和输出将不大于您的语言中可表示的最大整数或2^64 - 1,以较小者为准。

以下是具有holiness的前25个圣整数的列表h >= 1,以供参考:

0, 4, 6, 8, 9, 40, 44, 46, 48, 49, 60, 64, 66, 68, 69, 80, 84, 86, 88, 89, 90, 94, 96, 98, 99

具有圣洁性的前25个圣整数h >= 2是:

0, 8, 40, 44, 46, 48, 49, 60, 64, 66, 68, 69, 80, 84, 86, 88, 89, 90, 94, 96, 98, 99, 400, 404, 406

相关-1 2
Mego

26
我坐在这里就像30秒思考“到底如何确实0有两个圣洁”之前我终于点击维基百科的链接上索拉
undergroundmonorail

第五个圣洁数字是9还是40?
Conor O'Brien

3
第八位8+圣号是8888只是巧合吗?(是的,可能是,但是无论如何我都感到很开心...)
Toby Speight

5
实际上,由于您可以在数字前面加上任意多个前导0,所以可以使0无限地为圣。尽管∞显然同样神圣。但奇怪的是,666甚至更高……
Darrel Hoffman

Answers:


6

Pyth,32个字节

e.fg*g.{`46890J`Z++lJ/J`8/J`0QE0

说明

                                 - autoassign Q = eval(input())
 .f                           E0 -  first eval(input()) terms of func V starting Z=0

     g.{`46890J`Z                -    Are all the digits in Z in "46890"?
               `Z                -      str(Z)
              J                  -     autoassign J = ^
     g                           -    is_subset(V,^)
      .{`46890                   -     set("46890")

    *                            -   ^*V (Only return non-zero if only contains holy numbers)

                 ++lJ/J`8/J`0    -    Get the holiness of the number
                   lJ            -      len(J)
                  +              -     ^+V
                     /J`8        -      J.count("8") 
                 +               -    ^+V
                         /J`0    -     J.count("0")
   g                         Q   -  ^>=Q (Is the holiness great enough)
e                                - ^[-1]

在这里尝试

以表格形式输入 h \n n


12

红宝石,109 105 95 82个字节

->n,h{(?0..?9*99).select{|x|x.count('469')+2*x.count('80')>=h&&/[12357]/!~x}[n-1]}

这是一种可怕的“从0到99999999999 ...计算”的方法,它的延迟时间恰好比其惰性方法短13个字节。但是,这个版本不太可能在宇宙热死之前完成。仍然值得13个字节\ _(ツ)_ /¯

您可以通过更改?9*99为来测试较小的值'99999'

这是旧版本(95字节,具有延迟评估,几乎立即运行,而不是几乎从未运行):

->n,h{(?0..?9*99).lazy.select{|x|x.count('469')+2*x.count('80')>=h&&/[12357]/!~x}.first(n)[-1]}
->n,h{
(?0..?9*99)  # range '0' (string) to '9' repeated 99 times, way more than 2**64
.lazy        # make the range lazy, so we can call `select' on it
.select{|x|  # choose only elements such that...
 x.count('469')+2*x.count('80')  # naive holiness calculation
 >=h         # is at least h
 &&/[12357]/!~x                  # naive "is holy" calculation
}
.first(n)    # take the first n elements that satisfy the condition
[-1]         # choose the last one from this array
}

要爱懒惰的评价:)
艾米娜(Emigna)

为什么不take代替first呢?
并不是查尔斯(Charles)

@NotthatCharles take返回Lazy,无法将其编入索引。
门把手

6

Python 3、103

lambda n,h,l='4698080':[y for y in range(2**64-1)if(sum(l.count(x)-(x not in l)for x in str(y))>=h)][n]

这是一个使用内存效率更高的方法的解决方案,但如果要测试,则使用相同的算法。

l='4689080'
def f(n,h):
 c=i=0
 while i<n:
  if sum(l.count(x)-(x not in l)for x in str(c))>=h:u=c;i+=1
  c+=1
 return u

测试用例:

assert f(3, 1) == 6
assert f(4, 2) == 44

@Mego酷。它似乎使用了静态的内存量,因此没有内存用完的危险。我只是不确定,因为它已经在我的机器上运行了半个小时。
Morgan Thrapp '16

实际上,要计算就需要花费相当多的时间2**64-1。看到stackoverflow.com/questions/34113609/...
美高

@Mego哦,我什至都没有想到。是的,当我将预计算的常量放入代码中时,它开始通过一点RAM进行咀嚼。
Morgan Thrapp '16

6

PowerShell中,163 150 141 101 98 96个字节

param($n,$h)for(--$i;$n){if(++$i-notmatch"[12357]"-and($i-replace"8|0",11).Length-ge$h){$n--}}$i

接受输入,然后循环直到$n为零。我们最初$i=-1使用预处理技巧进行设置,该技巧之所以有效$i,是因为以前尚未声明它为$null。然后我们执行--它,这使PowerShell将其评估$i = $null - 1$i=-1

每个循环我们递增$i,然后执行一个冗长的if语句。条件运算的第一部分通过使用运算符来过滤掉其中的有害数字,以验证其中$i没有任何内容。12357-notmatch

条件的第二部分检查中的孔的数量$i。它使用-replace运算符将8或替换011,然后比较长度是否为> = $h。我们不必担心会剔除邪恶的数字,因为这是有条件的第一部分,并且单孔数字的长度始终相同1,因此也不需要替换它们。

如果这仍然是真实的,那么我们将递减$n(因为这意味着我们找到了另一个满足输入要求的数字)。因此,当for重新计算条件以检查是否$n为零时,这意味着我们找到了第n个,因此退出for循环,输出$i并终止。

编辑-保存的13个字节通过使用阵列的代替字符串$l和改变如何$n被递减/检查
编辑2 -通过检查保存额外的9个字节$nfor条件和移动所述环的外侧的输出
编辑3 -保存高达通过从根本上改变我们计算孔
的方式,再增加++40个字节。编辑4 –通过在条件编辑5 的第一部分上将其作为预增量来节省额外的3个字节
–感谢TessellatingHeckler,节省了2个字节


整齐。通过更改为for(--$i;$n)和保存另外两个字节-replace"8|0"
TessellatingHeckler

@TessellatingHeckler是的,谢谢。那$i=-1绝对让我疯狂。我仍在尝试一种方法,因此我们不必$i首先进行初始化,但是到目前为止我尝试过的事情都更长(现在,这样做可能会更长)。
AdmBorkBork '16


4

Bash + GNU实用程序,67

  • @TobySpeight节省了20个字节!
seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q
  • seq简单地生成从0向上开始的整数
  • sed -r
    • h 将输入行复制到保留空间
    • /12357/d 删除邪恶的数字
    • s/8|0/&&/g用自己两次替换双倍的神圣数字。因此,单个圣数字被计数一次,而双圣数字被计数两次。
    • /^.{$1}/!d如果至少不匹配$1孔,则删除并继续下一行
    • x 将原始编号带回图案空间
    • 隐式打印
  • sed
    • $2!d在line之前的任何行上$2,删除并继续到下一行
    • q必须在线$2-退出(和隐式打印)

伊迪恩


1
刮胡子9 :sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"。还有另外4个:sed $2!d\;q。如果您对4611686018427387904的上限感到满意,就可以摆脱seq 0 $[1<<62]
Toby Speight

1
哦,我seq接受NaN的值:我现在有seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q,得分67
托比·斯佩特

@TobySpeight哇,真是太神奇了!
Digital Trauma

@TobySpeight:在!之前缺少\,否则:-sh: !d\: event not found
Olivier Dulac

1
脚本中` before 不需要@OlivierDulac !` 。仅在直接在命令行上运行时才需要它,我认为这不是必需的。
Digital Trauma

3

MATL,39 40字节

x~q`QtV4688900V!=stA*s2G<?T}N1G=?F1$}tT

Inpunts是nh的顺序。

在线尝试!

我们需要跟踪两个数字:当前的候选数字(以检查其完整性)和足够多的神圣数字。前者是堆栈的顶部,而后者则保留为堆栈中元素的数量。程序完成时,仅需要显示顶部。

x~q          % implicitly take two inputs. Delete one and transform the other into -1
`            % do...while loop
  Q          %   add 1 to current candidate number
  tV         %   duplicate and convert to string
  4688900V!  %   column char array of '4', '6' etc. Note '8' and '0' are repeated 
  =          %   compare all combinations. Gives 2D array
  s          %   sum of each column: holiness of each digit of candidate number
  tA*        %   are all digits holy? Multiply by that
  s          %   sum of holiness of all digits, provided they are all holy
  2G<        %   is that less than second input (h)?
  ?          %   if so: current candidate not valid. We'll try the next
    T        %     push true to be used as loop condition: next iteration
  }          %   else: current candidate valid
    N1G=     %     does stack size equal first input (n)?
    ?        %     if so: we're done
      F1$    %       push false to exit loop. Spec 1 input, to display only top
    }        %     else: make a copy of this number
      tT     %       duplicate number. Push true to continue with next iteration
             %     implicit end if 
             %   implicit end if 
             % implicit end do...while. If top of stack is truthy: next iteration
             % implicit display

3

R,109107字节

f=function(n,h){m=-1;while(n){m=m+1;if(!grepl("[12357]",m))if(nchar(gsub("([08])","\\1\\1",m))>=h)n=n-1};m}

带有新行和缩进:

f=function(n,h){
    m=-1
    while(n){
        m=m+1
        if(!grepl("[12357]",m))
            if(nchar(gsub("([08])","\\1\\1",m))>=h)
                n=n-1
    }
    m
}

用法:

> f(4,3)
[1] 68
> f(4,2)
[1] 44
> f(6,2)
[1] 48
> f(10,2)
[1] 66

3

JavaScript(ES6),110个字节

f=(n,h,r=[],i=0)=>r.length<n?f(n,h,/[12357]/.test(i)|[...''+i].reduce((t,c)=>t+1+!(c%8),0)<h?r:[...r,i],i+1):r

尾递归解决方案,可在数组中累积圣数字。

出于兴趣,不要求数字是完整的(!),会使圣洁计数更加笨拙,但总体上还是节省了10%:

f=(n,h,r=[],i=0)=>r.length<n?f(n,h,[...''+i].reduce((t,c)=>+"2000101021"[c]+t,0)<h?r:[...r,i],i+1):r

@ edc65糟糕,我一次交换了ir参数,但无法正确编辑更改。
尼尔

1

JavaScript ES6,191个字节

当然,这不是最有效的方法。但是你知道我,我爱发电机<3

H=(x,o=x+"")=>(F=/^[46890]+$/).test(o)&&[...o].map(y=>d+=(F.test(y)+/8|0/.test(y)),d=0)&&d;(n,h)=>(a=(function*(h){q=0;while(1){if(H(q)>=h)yield q;q++}})(h),eval("a.next().value;".repeat(n)))

稍微松了一下:

H = (x, o = x + "") => (F = /^[46890]+$/).test(o) && [...o].map(y => d += (F.test(y) + /8|0/.test(y)), d = 0) && d;
Q = (n, h) => (a = (function*(h) {
    q = 0;
    while (1) {
        if (H(q) >= h) yield q;
        q++
    }
})(h), eval("a.next().value;".repeat(n)))

1

C#6,168字节

(n,h)=>{for(int i=0;i<=int.MaxValue;i++){string d=$"{i}";if(d.Any(y=>"12357".Contains(y)))continue;n-=d.Sum(y=>y=='0'||y=='8'?2:1)>=h?1:0;if(n==0)return i;}return -1;}

这是Func <int,int,int>类型的Lambda表达式。此代码针对最小大小进行了优化(不具有性能)。

下面是方法声明中的美化代码(具有更高的性能):

    int GetHolyNumber(int n, int h)
    {
        for (int i = 0; i <= int.MaxValue; i++)
        {
            string d = $"{i}";
            char[] cs = "12357".ToArray();
            if (d.Any(y => cs.Contains(y))) continue;

            n -= d.Sum(y => y == '0' || y == '8' ? 2 : 1) >= h ? 1 : 0;

            if (n == 0)
                return i;
        }
        return -1;
    }

嗨,鲍勃森,很抱歉,如果我误解了,但是没有检测到您在我的代码中指出的错误?它返回所需的第n个元素,仅返回他,如果返回有效,则返回零(假定输入为n = 1且h <= 2)。如果我理解挑战,则必须仅返回该一个元素,而不返回全部归他所有。但我误会了我,英语迷失了:D谢谢
PauloCésarB. Sincos

不,您完全正确。我被名单,供参考误导了,错过了一个事实,即它只是要求第n个数字。继续!
Bobson

1

JavaScript(ES6),87

(n,h)=>eval("for(i=0;[...i+''].map(d=>r-=~!(d%8),r=0),/[12357]/.test(i)|r<h||--n;)++i")

少打高尔夫球

f=(n,h)=>{
  for (i=0;
    // this is the loop condition
    /[12357]/.test(i) // go on if not holy
    ||([...i+''].map(d=>r-=~!(d%8),r=0),r<h) // go on if not holy enough
    ||--n; // ok, found one! go on if we need to find more
  )
    ++i; // loop body - using eval this is the returned value
  return i; // not using eval, an explicit return is needed
}  

测试

f=(n,h)=>eval("for(i=0;[...i+''].map(d=>r-=~!(d%8),r=0),/[12357]/.test(i)|r<h||--n;)++i")

function test() {
  var a,b
  [a,b]=I.value.match(/\d+/g)
  R.textContent = f(a,b)
}

test()
N, H: <input id=I value="25 2" oninput="test()"> >>
<span id=R></span>


1

Lua,169个字节

function a(n,h)H=0N=0I=-1while N<n do I=I+'1'H=0 if not I:find('[12357]') then _,b=I:gsub('[469]',1)_,c=I:gsub('[08]',1)H=b+2*c end N=H>=h and N+1 or N end print(I) end

取消高尔夫:

function a(n,h) -- nth term, holiness
    H=0N=0I=-1 -- Really ugly, but hey, it works. Set up 3 vars
    while N<n do -- While nth term is lower than desired term
        I=''..I+1 -- Convert number to string (can't coerce since it will become a float)
        if not I:find('[12357]') then -- If the number doesn't have those numbers
            _,b=I:gsub('[469]',1) -- _ is the new string, b is the number of changes
            _,c=I:gsub('[08]',1) -- Same as above. Use 1 to replace to save chars
            H=b+2*c -- Increase holiness appropriately
        end
        N=H>=h and N+1 or N -- If current holiness >= desired holiness, increment N
    end 
    print(I) -- Once the loop ends, print the current term
end

1

Lua中,155个 141个 140字节

通过命令行参数获取两个输入(第一个参数为n,然后为h)

编辑:感谢@DavisDude,他帮助我节省了14个字节,并提醒我不必打印所有的圣数字,最多可以打印n个,而只需打印第n个。

a={}x=0while(#a<arg[1])do b,c=(x..""):gsub("[08]","")e,d=b:gsub("[469]","")a[#a+1],x=c*2+d>=arg[2]and #e<1 and x or nil,x+1 end print(a[#a])

脱节和解释

x,a=0,{}                      -- initialise a counter, and the array which 
                              -- contains the holy numbers found
while(#a<arg[1])              -- iterate while we found less holy numbers than n
do
  b,c=(x..""):gsub("[08]","") -- replace [08] by "", b=the new string
                              -- c=the number of subsitution
  e,d=b:gsub("[469]","")      -- same thing for [469]
  a[#a+1]=c*2+d>=arg[2]       -- insert the number into a if:nb[08]*2+nb[469]>h
             and #e<1         -- and e is empty (no unholy numbers)
             and x or nil
      x=x+1                   -- increment x
end
print(a[#a])                  -- print the last element of a

您可以通过这样做来去除一些字符print(a[arg[1]])
DavisDude

@DavisDude我很傻,当我写这篇文章的时候,尽管我不得不打印出直到的整个邪恶数字列表n。实际上,print(a[#a])可以节省更多的字节。感谢您的评论!
Katenkyo '16

你写。由于某种原因,我什至没有想到。
戴维斯·德德

您可以通过写x=0a={}而不是来删除一个字符x,a=0,{}
Leaky Nun

1
@KennyLau实际上,您不能,因为0a会被解释为十六进制数,但是我可以a={}x=0while毫无问题地进行操作:)
Katenkyo

0

Oracle SQL 11.2,229字节

WITH v(c,p,i,j,n)AS(SELECT 0,-1,0,0,0 FROM DUAL UNION ALL SELECT c+1,c,REGEXP_COUNT(c||'','[4,6,9]'),REGEXP_COUNT(c,'[8,0]'),n+DECODE(LENGTH(p),i+j,DECODE(SIGN(i+j*2-:h),-1,0,1),0)FROM v WHERE p<c AND n<:n)SELECT MAX(p)-1 FROM v;

未打高尔夫球

:h -> required min holy value
:n -> nth number 

curv   -> current number
precv  -> previous number
prech1 -> number of holy 1 letters in previous number 
prech2 -> number of holy 2 letters in previous number
n      -> how many numbers with at least the required holy value 

WITH v(curv,precv,prech1,prech2,n)AS 
(
  SELECT 0 curv, -1 precv, 0 prech1, 0 prech2, 0 n FROM DUAL     -- Start with 0
  UNION ALL
  SELECT curv+1,   -- Next number
         curv,     -- Current Number 
         REGEXP_COUNT(curv||'','[4,6,9]'),  -- number of holy 1 letters
         REGEXP_COUNT(curv,'[8,0]'),        -- number of holy 2 letters
         n+DECODE(LENGTH(precv),prech1+prech2,DECODE(SIGN(prech1+prech2*2-:h),-1,0,1),0) -- Is the previous number holy enough ?
  FROM   v 
  WHERE  precv<curv   -- Needed to trick oracle cycle detection 
         AND n<:n     -- Until clause
)
SELECT MAX(precv)-1 FROM v 

0

Python 2,96字节

f=lambda n,h,k=0,s="0046889":-0**n or-~f(n-(sum(map(s.count,`k`))>=h<set(str(k))<=set(s)),h,k+1)

圣洁条件k

  • sum(map(s.count,`k`))>=h,它通过对s="0046889"0和中的每个字符的计数相加来计算孔的数量8
  • set(str(k))<=set(s)),检查数字是否全部为圣。str而不是反引号用于避免长时间使用后缀L

使用Python 2事实,即数字小于集合,将它们链接成一个单一的等式。

该函数递归地定义为递增计数kn每次击中神圣次数时都会减少计数器,除非它击中了0。然后k,它可以返回触发该事件的,但是通过1每次相加来递归地保持计数的时间要短一些,尽管“ 1:1”需要一个基本计数-1来修复。


0

Haskell,94个字节

c是数字的圣洁,数字v的圣洁,n!h剩下的就做。

c=([2,0,0,0,1,0,1,0,2,1]!!)
v n|n>9=c(mod n 10)+v(div n 10)|1<2=c n
n!h=[i|i<-[0..],v i<=h]!!n

注意:我认为这是没有字符的唯一答案4,6,8


0

迅速

func f(n: Int, h: Int) {
    var m = 0
    let a = [1,2,3,5,7]
    for j in 0..<Int.max {
        var c = 0
        for i in (j.description.characters.map{(String($0) as NSString).integerValue}) {
            c += (a.contains(i)) ? 0 : (i == 8 || i == 0) ? 2 :1
        }
        if c >= h { m += 1; if m >= n {print(j); break}}
    }
}
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.