Kutsal Sayılar


44

Birçok fontta (özellikle Consolas fontunda ), 10 ondalık basamağın 5'inde "delik" vardır. Bu kutsal basamakları arayacağız:

46890

Böylece 5 kutsal olmayan rakam:

12357

Bu nedenle bir tamsayı, yalnızca kutsal basamaklar içeriyorsa "kutsal", aksi halde "kutsal" olarak sınıflandırılabilir. Çünkü -kutsal olmayan, hiçbir olumsuz tamsayılar kutsal olabilir.

Kutsal tamsayılar, kaç tane delik bulunduğuna göre daha fazla sınıflandırılabilir. Örneğin, aşağıdaki rakamlar 1 olan bir kutsallığa sahiptir:

469

Ve bu rakamların sayısı 2 olur:

80

Bir tamsayının genel kutsallığının, rakamlarının kutsallığının toplamı olduğunu söylüyoruz. Bu nedenle, 804 99kutsallık ve 2 kutsallık olacaktır.

Meydan okuma

İki tamsayı Verilen n > 0ve h > 0çıkış, nkimin kutsallık en az olduğu inci kutsal tamsayı h. Giriş ve çıkışların, kendi dilinizde temsil edilebilecek tam sayıdan daha büyük olmayacağını veya 2^64 - 1hangisinin daha az olacağını varsayabilirsiniz .

Burada h >= 1referans için kutsallık ile ilk 25 kutsal tam sayıların bir listesi :

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

Kutsallığı olan ilk 25 kutsal tam sayı 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

İlgili - 1 2
Mego

26
i "halt yok nasıl düşünerek otuz gibi saniye burada oturuyordum 0nihayet Consolas için wikipedia linke tıklandığında önce ikisinin bir kutsallığını var"
undergroundmonorail

Beşinci 1-Kutsal Sayı 9 veya 40 mı?
Conor O'Brien,

3
8. 8 + kutsal sayısının 8888 olması tesadüf mü? (evet, muhtemelen, ama yine de beni eğlendirdi ...)
Toby Speight

5
Aslında, bir sayıdan önce herhangi bir sayıda öncü 0'a sahip olabileceğinizden, 0'ın sonsuz kutsal olduğu durumunu ortaya çıkarabilirsiniz. Her ne kadar ∞ görünüşte kutsal olsa da. Ama garip bir şekilde, 666 daha da kutsaldır ...
Darrel Hoffman,

Yanıtlar:


6

Pyth, 32 bayt

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

açıklama

                                 - 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]

Burada dene

Formda girdi alır h \n n


12

Ruby, 109 105 95 82 bayt

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

Bu, tembel meslektaşından 13 byte kısa olan "0 ila 99999999999 ... 'dan hesapla" korkunç bir yaklaşım. Bununla birlikte, bu versiyonun evrenin sıcak ölümünden önce bitmesi pek olası değildir. Yine de 13 bayt değerinde ¯ \ _ (ツ) _ / ¯

Sen değiştirerek daha küçük değerler için test edebilirsiniz ?9*99, diyelim ki, '99999'.

Eski sürüm (95 bit, neredeyse hiç değil, neredeyse anında çalışan tembel değerlendirme ile):

->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
}

Tembel değerlendirmeyi
sevmeliyim

Neden takeyerine first?
Charles,

@ NootthatCharles , dizine alınamayan takedöndürür Lazy.
Doorknob

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]

İşte daha verimli bellek kullanan bir yaklaşım kullanan, ancak denemek istiyorsanız aynı algoritmayı kullanan bir çözüm.

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

Test durumları:

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

@Mego Cool. Statik miktarda hafıza kullanıyor gibi göründüğü için hafızanın tükenme tehlikesi yoktur. Zaten yarım saattir makinemde çalıştığından emin değildim.
Morgan Thrapp

Sadece hesaplamak için iyi bir zaman harcıyor 2**64-1; bkz stackoverflow.com/questions/34113609/...
Mego

@Mego Oh, bunu düşünmedim bile. Evet, önceden hesaplanan sabiti koda koyduğumda, biraz RAM ile çiğnemeye başlar.
Morgan Thrapp

6

PowerShell, 163 150 141 101 98 96 bayt

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

Girdiyi alır, sonra $nsıfır olana kadar döngüler . Öncelikle ilan edilmemiş olması $i=-1nedeniyle işe yarayan bir ön işleme hilesi kullanarak başlangıçta belirledik . Sonra PowerShell neden o kadar değerlendirmek olan .$i$null--$i = $null - 1$i=-1

Her döngü biz artırır $ive sonra uzun bir ifdeyim yürütür . Koşullu olan ilk bölüm , kutsal olmayan sayıları filtrelemek için operatör kullanarak içinde $ihiçbirinin bulunmadığını doğrular .12357-notmatch

Koşullu maddenin ikinci kısmı, içindeki deliklerin miktarını kontrol eder $i. Her -replacebirini 8veya 0ile değiştirmek için operatörü kullanır 11ve sonra uzunluk> = olup olmadığını karşılaştırır $h. Kutsal olmayan sayıları çıkarmaktan endişe etmemize gerek yok, çünkü bu koşullu ilk kısımda, ve tek delikli sayılar 1yine de aynı uzunlukta , bu yüzden onları değiştirmek zorunda değiliz.

Eğer bu yine de acayipse, azalırız $n(bunun anlamı girdi gereksinimlerini karşılayan başka bir sayı bulduk demektir). Böylece durum sıfır forolup olmadığını kontrol etmek için yeniden hesaplandığında $n, bu, nth olanı bulduğumuzu gösterir , bu yüzden fordöngüden çıkar, çıktı verir $ive sonlandırırız.

Düzenleme - yerine dizgenin bir dizi kullanarak kaydedilen 13 bayt $lve nasıl değiştirilmesi $nindirildiği / kontrol
denetleyerek ek 9 bayt kaydedildi - Düzenleme 2 $niçinde forkoşullu ve döngü dışında çıkış hareket
Düzenleme 3 - Bir kuyruklu kaydedildi Deliklerin nasıl hesaplanacağını kökten değiştirerek 40 bayt daha
düzenle ++. Düzenlenmiş 4 - koşullu Düzenleme 5'in ilk bölümünde ön-artmaya hareket ettirerek 3 bayt daha
kaydetti - TessellatingHeckler sayesinde 2 bayt daha kaydedildi


Temiz. İçin değiştirerek bayt başka bir çift kaydet for(--$i;$n)ve -replace"8|0"?
TessellatingHeckler

@TessellatingHeckler Evet, teşekkür ederim. Bu $i=-1beni kesinlikle bonker kullanıyordu. Hala bir yol bulmaya çalışıyorum, bu yüzden $iilk baştan başlamak zorunda değiliz , ancak şimdiye kadar denediğim şeyler daha uzundur (ve şimdi verilmişse, muhtemelen daha uzun olacaktır).
AdmBorkBork


4

Bash + GNU yardımcı programları, 67

  • @TobySpeight! Sayesinde 20 bayt kaydedildi
seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q
  • seqsadece 0yukarıdan başlayarak tam sayıları üretir
  • sed -r:
    • h giriş hattını tutma alanına kopyala
    • /12357/d kutsal olmayan numaraları sil
    • s/8|0/&&/giki kez kutsal sayıları iki kez kendisiyle değiştirin. Böylece, tek tek kutsal sayılar bir kez sayılır ve iki katına kadar kutsal sayılar iki kez sayılır.
    • /^.{$1}/!dEn az $1delik eşleşmiyorsa , silin ve bir sonraki satıra geçin.
    • x orijinal numarayı tekrar desen alanına getir
    • zımni baskı
  • sed
    • $2!dSatırdan önceki tüm satırlarda $2silin ve bir sonraki satıra geçin.
    • qsatırda olmalı $2- çık (ve örtük baskı)

Ideone.


1
9 Tıraş: sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x". Ve 4 başka: sed $2!d\;q. Ve eğer sadece 4611686018427387904'ün üst sınırından memnunsanız, buradan kaçabilirsinizseq 0 $[1<<62]
Toby Speight

1
Ooh, benim bir değer olarak seqkabul NaNediyorum: Şimdi seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q, puanlama 67.
Toby Speight

@TobySpeight vay bu şaşırtıcı!
Dijital Travma

@TobySpeight:! 'Den önce bir \ eksik, aksi takdirde:-sh: !d\: event not found
Olivier Dulac

1
` before Bir komut dosyasında @OlivierDulac ! `Gerekli değildir . Bunu doğrudan komut satırında çalıştırırken sadece bir zorunluluk olduğunu sanmıyorum.
Dijital Travma

3

MATL , 39 40 bayt

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

Inpunts n ve hbu sırada.

Çevrimiçi deneyin!

İki sayıyı takip etmeliyiz: mevcut aday numarası (kutsallığını kontrol etmek için) ve yeterince kutsal bulunan sayıların sayısını. Birincisi yığının tepesidir ve ikincisi yığındaki elemanların sayısı olarak tutulur. Program bittiğinde, sadece üst görüntülenmesi gerekir.

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, 109 107 bayt

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}

Yeni çizgiler ve girintilerle:

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
}

Kullanı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 bayt

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

Bir dizi içinde kutsal sayıları toplayan kuyruk özyinelemeli çözüm.

İlgi çekici olmayan, sayının tamamen (!) Kutsal olmasını gerektirmemek kutsallığın daha garip olmasını sağlar, ancak yine de genel olarak% 10 tasarruf sağlar:

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 Hata! iVe rparametrelerin üzerinde bir noktada yer değiştirdim ve değişikliği doğru şekilde düzenleyemedim.
Neil

1

JavaScript ES6, 191 bayt

Tabii, bu en etkili yol değil. Ama beni biliyorsun, jeneratörleri severim <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)))

Biraz ungolfed:

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 bayt

(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;}

Bu, Func <int, int, int> türünde bir Lambda İfadesidir. Bu kod, minimum boyut için azaltılmıştır (performans göstermiyor).

Aşağıda, yöntem bildirgesindeki güzelleştirilmiş kod (daha fazla performans ile):

    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;
    }

Selam Bobson, yanlış anladığım için üzgünüm ama kodumda belirttiğiniz hataları tespit etmiyor musunuz? Gerekli olan nth elemanını döndürür ve eğer girdiyse n = 1 ve h <= 2 olduğunu varsayarsak, yalnızca o ve sıfır ise sıfır değerini alır. . Ama beni yanlış anladım ve İngilizce kaybettim: D teşekkürler
Paulo César B. Sincos

Hayır, tamamen haklısın. Referans listeleri tarafından yanıltıldım ve sadece ilk haneyi istediği gerçeğini kaçırdım . Sürdürmek!
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")

Daha az golf oynadı

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
}  

Ölçek

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 bayt

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

Ungolfed:

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 Bayt

Her iki girişi de komut satırı argümanıyla alır (ilk argüman n, sonra h'dir)

Düzenleme: 14 bayt'ı tıraş etmeme yardım eden @DavisDude sayesinde bana tüm kutsal sayıları n'ye kadar basmak zorunda olmadığımı hatırlattı.

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])

Ungolfed ve açıklamalar

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

Yaparak bazı karakterleri print(a[arg[1]])
çıkarabilirsiniz

@DavisDude Aptaldım, bunu yazarken, kadar olan sayısız sayının listesini yazdırmak zorunda kaldım n. Aslında, print(a[#a])daha fazla bayt tasarrufu sağlar. Yorumunuz için teşekkürler!
Katenkyo

Sen yaz Bazı nedenlerden dolayı bana gelmedi.
DavisDude

Bunun x=0a={}yerine bir karakter yazabilirsiniz x,a=0,{}.
Çatlak Rahibe

1
@KennyLau Aslında, yapamazsınız çünkü 0aonaltılık bir sayı olarak yorumlanırdı, ama a={}x=0whileproblemsiz bir şekilde yapabilirim :)
Katenkyo

0

Oracle SQL 11.2, 229 bayt

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;

Un-golfed

: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 bayt

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)

Kutsallık durumu açık kolarak kontrol edilir

  • sum(map(s.count,`k`))>=hBurada, her bir karakter için sayıları toplayarak delik sayısını sayar s="0046889", nerede 0ve 8iki kez görünür.
  • set(str(k))<=set(s)), sayıların hepsinin kutsal olduğunu kontrol eder. struzun süreler için son eki önlemek için geri tepme yerine kullanılır L.

Bunlar, Python 2 sayısının kümelerden daha küçük olduğu gerçeğini kullanarak tek bir eşitlik halinde zincirlenir.

Fonksiyon, sayıları saymak için tekrar tekrar tanımlanır kve nher vuruşta çarpmadığı sürece sayısız vuruş yapar 0. Daha sonra kbunu tetikleyen şeyi geri getirebilir , ancak 1her defasında ekleyerek sayımı tekrar tekrar tutmak daha kısadır , ancak bir off-one için bir baz sayısının -1düzeltilmesi gerekir.


0

Haskell, 94 bayt

crakamın vkutsallığı, sayının kutsallığı n!h, gerisini yapar.

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

Not: Bunun karaktersiz tek cevap olduğunu düşünüyorum 4,6,8.


0

hızlı

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}}
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.