Liczby Holiera

22

Jak dowiedzieliśmy się z The Holy Numbers , istnieje 5 świętych cyfr ( 0, 4, 6, 8, 9), a dodatnie liczby całkowite składające się wyłącznie z tych cyfr są święte. Ponadto świętość liczby jest sumą dziur w liczbie ( +2dla każdego 0lub 8, i +1inaczej).

Teraz należy wziąć pod uwagę dodatkową właściwość, aby naprawdę i dokładnie przedstawiać świętość pewnej liczby. Widzisz, liczy się nie tylko liczba dziur w cyfrze, ale także to, gdzie w liczbie występuje.

Rozważ numer 88. Według naszych starych zasad miałaby świętość 4. Ale to niesprawiedliwe! 8Po lewej robi więcej pracy niż inne 8- 10 razy więcej pracy! Powinien zostać nagrodzony za swoją pracę. Nagrodzimy go dodatkowymi punktami świętości równymi całkowitej świętości wszystkich cyfr po prawej stronie (w tym dodatkowych punktów świętości przyznanych przez tę zasadę cyfrom po prawej), minus 1.

Oto więcej przykładów, które należy wziąć pod uwagę:

Number: 8080
Digital holiness: (2 + 7 - 1) + (2 + 3 - 1) + (2 + 1 - 1) + (2 + 0 - 1)
Total holiness: 15

Number: 68904
Digital holiness: (1 + 5 - 1) + (2 + 2 - 1) + (1 + 1 - 1) + (2 + 0 - 1) + (1 + 0 - 1)
Total holiness: 10

Wszystkie cyfry są odpowiednio nagradzane za swoją pracę z dodatkową świętością i wszystko jest w porządku. Będziemy nazywać tę właściwość „zwiększoną świętością”.

We wspaniałym języku Python algorytm obliczania zwiększonej holistyczności może wyglądać mniej więcej tak:

# assumes n is a holy number
def enhanced_holarity(n):
    if n < 10:
        return 1 if n in [0, 8] else 0
    else:
        digits = list(map(int,str(n)[::-1]))
        res = []
        for i,x in enumerate(digits):
            res.append(enhanced_holarity(x))
            if i > 0:
                res[i] += sum(res[:i])
        return sum(res)

Wyzwanie

Biorąc pod uwagę liczbę całkowitą n > 0, nwypisz pierwsze Święte Liczby, posortowane według rosnącej zwiększonej holarity, używając wartości liczbowej jako rozstrzygającego. Możesz założyć, że wejście i wyjście nie będzie 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.

Dla odniesienia, oto kilka przypadków testowych (dane wejściowe, a następnie dane wyjściowe):

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

100
4, 6, 9, 44, 46, 49, 64, 66, 69, 94, 96, 99, 444, 446, 449, 464, 466, 469, 494, 496, 499, 644, 646, 649, 664, 666, 669, 694, 696, 699, 0, 8, 84, 86, 89, 844, 846, 849, 864, 866, 869, 894, 896, 899, 40, 48, 60, 68, 90, 98, 404, 406, 409, 484, 486, 489, 604, 606, 609, 684, 686, 689, 80, 88, 804, 806, 809, 884, 886, 889, 440, 448, 460, 468, 490, 498, 640, 648, 660, 668, 690, 698, 840, 848, 860, 868, 890, 898, 400, 408, 480, 488, 600, 608, 680, 688, 800, 808, 880, 888

200
4, 6, 9, 44, 46, 49, 64, 66, 69, 94, 96, 99, 444, 446, 449, 464, 466, 469, 494, 496, 499, 644, 646, 649, 664, 666, 669, 694, 696, 699, 944, 946, 949, 964, 966, 969, 994, 996, 999, 4444, 4446, 4449, 4464, 4466, 4469, 4494, 4496, 4499, 4644, 4646, 4649, 4664, 4666, 4669, 4694, 4696, 4699, 0, 8, 84, 86, 89, 844, 846, 849, 864, 866, 869, 894, 896, 899, 40, 48, 60, 68, 90, 98, 404, 406, 409, 484, 486, 489, 604, 606, 609, 684, 686, 689, 904, 906, 909, 984, 986, 989, 4044, 4046, 4049, 4064, 4066, 4069, 4094, 4096, 4099, 80, 88, 804, 806, 809, 884, 886, 889, 440, 448, 460, 468, 490, 498, 640, 648, 660, 668, 690, 698, 940, 948, 960, 968, 990, 998, 4404, 4406, 4409, 4484, 4486, 4489, 4604, 4606, 4609, 4684, 4686, 4689, 840, 848, 860, 868, 890, 898, 400, 408, 480, 488, 600, 608, 680, 688, 900, 908, 980, 988, 4004, 4006, 4009, 4084, 4086, 4089, 800, 808, 880, 888, 4440, 4448, 4460, 4468, 4490, 4498, 4640, 4648, 4660, 4668, 4690, 4698, 4040, 4048, 4060, 4068, 4090, 4098, 4400, 4408, 4480, 4488, 4600, 4608, 4680, 4688, 4000, 4008, 4080, 4088
Mego
źródło
10
Ten pomysł na dziurę jest holistyczny.
Calvin's Hobbies
Co rozumiesz przez „wynik nie będzie większy niż ...”? Jak na wyjściu nie będzie żadnej liczby większej niż 2^64 - 1? W takim przypadku prawdopodobnie warto dowiedzieć się, który sygnał wejściowy generuje takie liczby, aby ludzie mogli przetestować swoje odpowiedzi.
FryAmTheEggman
@FryAmTheEggman Nie większy niż oznacza mniejszy lub równy. Zaktualizuję post z pewnymi maksymami dla różnych rozmiarów całkowitych.
Mego
Twój kod python nie działa dla 6, daje holines 0
shrx

Odpowiedzi:

2

Python 2, 138 122 bajtów

Szuka liczb świętych do 5 N dla wejściowego N , który jest absurdalnie wolny:

e=lambda s:s and(s[0]in'08')+e(s[1:])*2or 0
lambda N:sorted([`x`for x in range(5**N)if set(`x`)<=set('04689')][:N],key=e)

Tutaj limit wynosi 5 N 2 i faktycznie można uruchomić przypadki testowe, kosztem jednego bajtu:

e=lambda s:s and(s[0]in'08')+e(s[1:])*2or 0
lambda N:sorted([`x`for x in range(5*N*N)if set(`x`)<=set('04689')][:N],key=e)

Pierwszy fragment jest ważny, jak 5 N równe 5 N 2 dla dodatnich liczb całkowitych N .

Lynn
źródło
Och, czekaj, coś mi umknęło ... Zbyt zmęczony na to.
patrz
3

Lua, 317 bajtów

Miałem pewne problemy z tym, niektóre rzeczy w Lua nie działają tak, jak mi się wydaje. Będę musiał spróbować z nimi zagrać, jeśli chcę zagrać w golfa. Możesz przetestować lua online , zastępując arg[1]je wybraną liczbą elementów :).

function f(y)h=0(y..''):reverse():gsub(".",function(c)h=c:find("[08]")and 1+h or h end)return h end
x,a=0,{}while(#a<arg[1]+0)do a[#a+1],x=(x..''):find("^[04689]*$")and x or nil,x+1 end
for i=1,#a do m=1
for j=1,#a do x=a[m]m=(f(x)~=f(a[j])and f(x)>f(a[j])or x>a[j])and j or m
end end print(a[m])table.remove(a,m)end

Bez golfa i wyjaśnienia

function f(y)                     -- function returning the enhanced holiness of a holy number
  h=0                             -- h is the cumulated holyness of processed digits
  (y..''):reverse()               -- reverse the digits in y
         :gsub(".",function(c)    -- iterate over each digits
     h=c:find("[08]")and 1+h or h -- ternary based on the digit being [08] or [469]
   end)                           
  return h                        -- return h
end

x,a=0,{}                          -- initialise a counter, and the array of holy numbers
while(#a<arg[1]+0)                -- iterate until we have n holy numbers
do
  a[#a+1]=(x..'')                 
      :find("^[04689]*$")         -- if we can't find an unholy digit
             and x or nil         -- insert x into a
  x=x+1                           -- increment x anyway
end

for i=1,#a                        -- iterate n times(current size of a)
do
  m=1                             -- m is the index of the lowest value
  for j=1,#a                      -- iterate over a
  do
    x=a[m]                        -- x is shorter to write than a[m]
    m=(f(x)~=f(a[j])              -- nested ternaries, translated in
        and f(x)>f(a[j])          -- nested if below
        or x>a[j])and j or m      
  end
  print(a[m])                     -- output a[m]
  table.remove(a,m)               -- remove it from the table a
end

Zagnieżdżone trójskładniki użyte dla nowej wartości mmogą być przetłumaczone na zagnieżdżone ifs jako:

if(f(a[m])~=f(a[j])) then         -- if a[m] and a[j] don't have the same holyness
  if(f(a[m])>f(a[j])) then m=j end-- compare by holyness
else
  if(a[m]>a[j]) then m=j end      -- else, compare by numeric value

Chciałbym również zastąpić zagnieżdżenie forza pomocą table.sort, ale z niewiadomego powodu poniższe polecenia nie działają, mimo że nie tworzy nieskończonej pętli ani nie psuje funkcji sortowania.

table.sort(a,function(i,j)
    return f(i)~=f(j)              
         and f(i)>f(j)          
         or i>j
end)
Katenkyo
źródło
1

JavaScript (ES6), 166 165 bajtów

f=n=>[...Array(n)].map((_,i)=>i.toString(5)).sort((a,b)=>e(a)-e(b),e=n=>'0b'+[...n.replace(/./g,c=>'10010'[c])].reverse().join``).map(n=>+n.replace(/./g,c=>"04689"[c]))

Edycja: Zapisano 1 bajt, zwracając tablicę ciągów.

Nie golfowany:

function base5_to_extended_holiness_binary(c) {
    return "10010"[c];
}
function extended_holiness(n) {
    var binary = n.toString(5).replace(/./g, base5_to_extended_holiness_binary);
    binary = s.split("").reverse().join("");
    return parseInt(s, 2);
}
function extended_holiness_sort(a, b) {
    return extended_holiness(a) - extended_holiness(b);
}
function base5_to_holy_number(c) {
    return "04689"[c];
}
function list_by_extended_holiness(n) {
    var array = new Array(n);
    for (var i = 0; i < n; i++)
         array[i] = i;
    array = array.sort(extended_holiness_sort);
    for (var i = 0; i < n; i++)
        array[i] = parseInt(array[i].toString(5).replace(/./g, base5_to_holy_number);
    return array;
}
Neil
źródło