Święte Liczby


44

W wielu czcionkach (szczególnie w czcionce Consolas ) 5 z 10 cyfr dziesiętnych ma w nich „dziury”. Nazwiemy te święte cyfry:

46890

5 bezbożnych cyfr to:

12357

Liczba całkowita może być zatem sklasyfikowana jako „święta”, jeśli zawiera tylko święte cyfry, a w przeciwnym razie „bezbożna”. Ponieważ -jest bezbożny, żadne ujemne liczby całkowite nie mogą być święte.

Święte liczby całkowite mogą być dalej klasyfikowane na podstawie liczby otworów. Na przykład następujące cyfry mają świętość 1:

469

I te cyfry mają świętość 2:

80

Mówimy, że ogólna świętość liczby całkowitej jest sumą świętości jej cyfr. Dlatego 80miałby świętość 4 i 99miałby świętość 2.

Wyzwanie

Biorąc pod uwagę dwie liczby całkowite n > 0i h > 0, wyjście nth święty całkowitą którego świętość jest przynajmniej h. Możesz założyć, że dane wejściowe i wyjściowe nie będą większe niż maksymalna reprezentowalna liczba całkowita w twoim języku lub 2^64 - 1, zależnie od tego, która wartość jest mniejsza.

Oto lista pierwszych 25 świętych liczb całkowitych ze świętością h >= 1, w celach informacyjnych:

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

Pierwszych 25 świętych liczb całkowitych ze świętością h >= 2to:

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

Powiązane - 1 2
Mego

26
Siedziałem tutaj jak trzydzieści sekund myślenia „jak do cholery nie 0ma świętości dwojga”, zanim w końcu kliknięciu na link Wikipedii Consolas
undergroundmonorail

Czy piąty 1-Święty numer 9 czy 40?
Conor O'Brien

3
Czy to przypadek, że ósma ósma cyfra 8 + to 8888? (tak, prawdopodobnie tak jest, ale i tak mnie to bawiło ...)
Toby Speight

5
W rzeczywistości, ponieważ możesz mieć dowolną liczbę wiodących zer przed liczbą, można by uznać, że 0 jest nieskończenie święte. Chociaż ∞ jest najwyraźniej tak samo święty. Ale, co dziwne, 666 jest jeszcze bardziej święte ...
Darrel Hoffman

Odpowiedzi:


6

Pyth, 32 bajty

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

Wyjaśnienie

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

Wypróbuj tutaj

Pobiera dane wejściowe w formularzu h \n n


12

Rubin, 109 105 95 82 bajtów

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

Jest to okropne podejście „oblicz od 0 do 99999999999 ...”, które jest o 13 bajtów krótsze niż jego leniwy odpowiednik. Jednak ta wersja prawdopodobnie nie zakończy się przed śmiercią wszechświata przed upałem. W każdym razie wart 13 bajtów ¯ \ _ (ツ) _ / ¯

Można przetestować go dla mniejszych wartości przez zmianę ?9*99do, powiedzmy '99999'.

Oto stara wersja (95 bajtów, z leniwą oceną, która działa prawie natychmiast, a nie prawie nigdy):

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

Uwielbiam leniwe oceny :)
Emigna

Dlaczego nie takezamiast first?
Nie to, że Charles

takeZwraca @NotthatCharles Lazy, do którego nie można zaindeksować.
Klamka

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]

Oto rozwiązanie, które wykorzystuje bardziej wydajne podejście do pamięci, ale w przeciwnym razie używa tego samego algorytmu, jeśli chcesz go przetestować.

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

Przypadki testowe:

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

@Mego Cool. Wygląda na to, że wykorzystuje statyczną ilość pamięci, więc nie grozi jej wyczerpanie. Po prostu nie byłem pewien, ponieważ działa na moim komputerze już od pół godziny.
Morgan Thrapp,

Obliczenie zajmuje sporo czasu 2**64-1; patrz stackoverflow.com/questions/34113609/…
Mego

@Mego Och, nawet o tym nie myślałem. Tak, kiedy wstawiam wstępnie obliczoną stałą do kodu, zaczyna przeżuwać trochę pamięci RAM.
Morgan Thrapp,

6

PowerShell, 163 150 141 101 98 96 bajtów

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

Pobiera dane wejściowe, a następnie zapętla, aż do $nzera. Początkowo ustawiamy $i=-1za pomocą sztuczki wstępnego przetwarzania, która działa, ponieważ $inie została wcześniej zadeklarowana $null. Następnie my --, co powoduje, że PowerShell ocenia to jako $i = $null - 1, co jest $i=-1.

Każdą pętlę zwiększamy, $ia następnie wykonujemy długą ifinstrukcję. Pierwsza część weryfikacji warunkowych, $iktóra nie zawiera żadnej z 12357nich, za pomocą -notmatchoperatora w celu odfiltrowania bezbożnych liczb.

Druga część warunkowa sprawdza liczbę otworów w $i. Wykorzystuje się -replaceoperatora w celu zastąpienia każdego 8lub 0z 11, a następnie porównuje czy długość wynosi> = $h. Nie musimy się martwić o usunięcie bezbożnych liczb, ponieważ jest to pierwsza część warunku, a liczby z jednym otworem mają i tak taką samą długość 1, więc nie musimy ich również zastępować.

Jeśli nadal jest to prawdą, zmniejszamy się $n(ponieważ oznacza to, że znaleźliśmy inną liczbę, która spełnia wymagania wejściowe). Zatem, kiedy forwarunek zostanie ponownie obliczony, aby sprawdzić, czy $nwynosi zero, oznacza to, że znaleźliśmy n-ty , więc wychodzimy z forpętli, wysyłamy dane $ii kończymy .

Edit - 13 bajtów zapisany przy użyciu tablicę zamiast sznurka do $li zmieniając sposób $njest zmniejszana / sprawdzone
Edit 2 - zapisane dodatkowe 9 bajtów, sprawdzając $nw forwarunkowy i przesuwając wyjście na zewnątrz pętli
Edycja 3 - zapisane fest 40 dodatkowych bajtów, radykalnie zmieniając sposób, w jaki obliczamy dziury
Edytuj 4 - zapisałeś dodatkowe 3 bajty, przesuwając tak, ++aby był wstępnym przyrostem w pierwszej części warunkowej
edycji 5 - zapisałeś kolejne 2 bajty dzięki TessellatingHeckler


Schludny. Zapisać kolejną parę bajtów, zmieniając na for(--$i;$n)i -replace"8|0"?
TessellatingHeckler

@TessellatingHeckler Tak, dziękuję. To $i=-1doprowadzało mnie do szału. Nadal próbuję znaleźć sposób, aby nie trzeba było inicjalizować $i, ale rzeczy, które próbowałem do tej pory były dłuższe (a biorąc pod uwagę to, prawdopodobnie będą jeszcze dłuższe).
AdmBorkBork,


4

Narzędzia Bash + GNU, 67

  • 20 bajtów zapisanych dzięki @TobySpeight!
seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q
  • seqpo prostu generuje liczby całkowite, zaczynając od 0góry
  • sed -r:
    • h skopiuj wiersz wejściowy do miejsca wstrzymania
    • /12357/d usuń bezbożne liczby
    • s/8|0/&&/gzamień podwójnie święte cyfry dwukrotnie na siebie. W ten sposób pojedyncze święte cyfry są liczone raz, a podwójnie święte cyfry są liczone dwa razy.
    • /^.{$1}/!dJeśli nie pasują co najmniej $1dołki, usuń i przejdź do następnego wiersza
    • x przywróć oryginalny numer do obszaru wzorów
    • druk niejawny
  • sed
    • $2!dw dowolnych wierszach przed wierszem $2usuń i przejdź do następnego wiersza
    • qmusi znajdować się w linii $2- zakończ (i niejawny wydruk)

Ideone.


1
Golić 9: sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x". I kolejna 4: sed $2!d\;q. A jeśli jesteś zadowolony z górnej granicy wynoszącej zaledwie 4611686018427387904, możesz uciecseq 0 $[1<<62]
Toby Speight

1
Ooh, mój seqprzyjmuje NaNjako wartość: teraz mam seq 0 NaN|sed -r "h;/[12357]/d;s/8|0/&&/g;/^.{$1}/!d;x"|sed $2!d\;q, zdobywając 67.
Toby Speight

@TobySpeight wow thats amazing!
Cyfrowa trauma

@TobySpeight: brakuje \ przed !, w przeciwnym razie:-sh: !d\: event not found
Olivier Dulac

1
@OlivierDulac ` before ! `Nie jest potrzebny w skrypcie . Jest to potrzebne tylko podczas uruchamiania tego bezpośrednio z wiersza poleceń, co nie uważam za wymóg.
Cyfrowa trauma

3

MATL , 39 40 bajtów

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

Inpunts są ni hw tej kolejności.

Wypróbuj online!

Musimy śledzić dwie liczby: aktualny numer kandydata (aby sprawdzić jego świętość) i liczbę znalezionych liczb, które są wystarczająco święte. Pierwszy to górna część stosu, a drugi jest przechowywany jako liczba elementów na stosie. Po zakończeniu programu wyświetlana jest tylko górna część.

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 bajtów

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}

Dzięki nowym wierszom i wcięciom:

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
}

Stosowanie:

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

3

JavaScript (ES6), 110 bajtów

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

Ogonowe rozwiązanie rekurencyjne, które gromadzi święte liczby w tablicy.

Z braku zainteresowania, nie wymaganie, aby liczba była całkowicie (!) Święta, sprawia, że ​​świętość liczy się bardziej niezręcznie, ale wciąż oszczędza 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 Ups, zamieniłem parametry ii rw jednym momencie i nie edytowałem poprawnie zmiany.
Neil

1

JavaScript ES6, 191 bajtów

Jasne, to nie jest najbardziej efektywny sposób. Ale znasz mnie, uwielbiam generatory <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)))

Nieznacznie nie golfista:

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 bajtów

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

To jest wyrażenie Lambda typu Func <int, int, int>. Ten kod jest minimalizowany dla rozmiaru minimalnego (nie wykonanie).

Poniżej upiększony kod w deklaracji metody (z większą wydajnością):

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

Cześć Bobson, przepraszam, jeśli źle zrozumiałem, ale nie wykrywam błędów, które wskazałeś w moim kodzie? Zwraca n-ty wymagany element, a tylko on i zero, jeśli jest poprawny, przy założeniu, że dane wejściowe to n = 1 i h <= 2. Jeśli rozumiem wyzwanie, musi zwrócić tylko ten jeden element, a nie wszystko do niego . Ale źle mnie zrozumiałem i zgubiłem po angielsku: D dzięki
Paulo César B. Sincos

Nie, masz całkowitą rację. Wprowadzono mnie w błąd przez listy referencyjne i brakowało mi faktu, że prosiłem tylko o n-tą cyfrę. Kontynuować!
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")

Mniej golfa

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
}  

Test

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 bajtów

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

Nie golfowany:

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 bajtów

Pobiera oba dane wejściowe za pomocą argumentu wiersza polecenia (pierwszy argument to n, a następnie h)

Edycja: Dzięki @DavisDude, który pomógł mi zgolić 14 bajtów i przypomniał mi, że nie muszę drukować wszystkich świętych liczb do n, ale tylko n-ty.

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

Bez golfa i wyjaśnienia

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

Możesz zdjąć kilka znaków, wykonującprint(a[arg[1]])
DavisDude

@ DavisDude Byłem głupi, kiedy to napisałem, myślałem, że muszę wydrukować całą listę przeklętych liczb aż do n. W rzeczywistości print(a[#a])oszczędza jeszcze więcej bajtów. Dziękuję za komentarz !
Katenkyo

Piszesz Z jakiegoś powodu nawet nie przyszło mi to do głowy.
DavisDude

Możesz zdjąć jeden znak, pisząc x=0a={}zamiast x,a=0,{}.
Leaky Nun

1
@KennyLau W rzeczywistości nie możesz, ponieważ 0abyłby interpretowany jako liczba szesnastkowa, ale mogę zrobić to a={}x=0whilebez problemu :)
Katenkyo

0

Oracle SQL 11.2, 229 bajtów

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;

Bez golfa

: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 bajtów

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)

Włączony stan świętości kjest sprawdzany przez

  • sum(map(s.count,`k`))>=h, która zlicza liczbę dołków, sumując liczbę dla każdej postaci w s="0046889", gdzie 0i 8pojawia się dwukrotnie.
  • set(str(k))<=set(s)), która sprawdza, czy wszystkie liczby są święte. strsłuży raczej niż backticksowi, aby uniknąć sufiksu Lprzez długi czas.

Są one połączone w jedną równość za pomocą faktu, że liczby w Pythonie 2 są mniejsze niż zbiory.

Funkcja jest definiowana rekurencyjnie w celu zliczania liczb k, zmniejszając licznik za nkażdym razem świętą liczbę trafień, chyba że trafi 0. Może wtedy zwrócić wartość, kktóra to wywołała, ale krótsze jest utrzymywanie liczby rekurencyjnie przez dodawanie za 1każdym razem, chociaż oddzielne wymaga podstawowej liczby -1poprawek.


0

Haskell, 94 bajty

cjest świętością cyfry, vświętością liczby, n!hresztą zajmuje się.

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

Uwaga: Myślę, że to jedyna odpowiedź bez postaci 4,6,8.


0

Szybki

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}}
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.