Bilangan Holier

22

Seperti yang kita pelajari dari The Holy Numbers , ada 5 digit suci ( 0, 4, 6, 8, 9), dan bilangan bulat positif yang hanya terdiri dari digit itu adalah suci. Selain itu, kekudusan nomor adalah jumlah lubang di nomor ( +2untuk setiap 0atau 8, dan +1sebaliknya).

Sekarang, ada properti tambahan untuk dipertimbangkan, untuk benar-benar dan akurat mewakili kekudusan nomor. Anda lihat, bukan hanya jumlah lubang di digit yang penting, tetapi juga di mana jumlah itu terjadi.

Pertimbangkan angkanya 88. Dengan aturan lama kita, itu akan memiliki kekudusan 4. Tapi itu tidak adil! Yang 8di sebelah kiri melakukan lebih banyak pekerjaan daripada yang lain 8- 10 kali lipat! Itu harus dihargai untuk pekerjaannya. Kami akan menghadiahkannya dengan poin kekudusan ekstra sama dengan total kekudusan dari semua digit di sebelah kanannya (termasuk poin kekudusan ekstra yang diberikan oleh aturan ini ke digit di sebelah kanannya), minus 1.

Berikut adalah lebih banyak contoh untuk dipertimbangkan:

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

Semua digit dihargai dengan tepat untuk pekerjaan mereka dengan kesucian ekstra, dan semuanya baik-baik saja. Kami akan menyebut properti ini "holaritas yang disempurnakan".

Dalam bahasa Python yang hebat, algoritme untuk menghitung peningkatan holaritas mungkin terlihat seperti ini:

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

Tantangan

Diberikan bilangan bulat n > 0, output nBilangan Suci pertama , diurutkan dengan naik holaritas meningkat, menggunakan nilai numerik sebagai tiebreak. Anda dapat mengasumsikan bahwa input dan output tidak akan lebih besar dari integer maksimum yang dapat diwakili dalam bahasa Anda atau 2^64 - 1, mana yang kurang.

Untuk referensi, berikut adalah beberapa kasus uji (input, diikuti oleh output):

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
sumber
10
Gagasan lubang ini sangat holarious.
Calvin Hobbies
Apa yang Anda maksud dengan "output tidak akan lebih besar dari ..."? Seperti dalam output tidak akan memiliki angka lebih besar dari 2^64 - 1? Jika itu masalahnya, mungkin perlu mencari tahu input mana yang pertama kali menghasilkan angka seperti itu, sehingga orang dapat menguji jawaban mereka.
FryAmTheEggman
@FryAmTheEggman Tidak lebih dari berarti kurang dari atau sama dengan. Saya akan memperbarui posting dengan beberapa maksimum untuk berbagai ukuran integer.
Mego
Kode python Anda tidak berfungsi untuk 6, itu menghasilkan holines 0.
shrx

Jawaban:

2

Python 2, 138 122 byte

Ini mencari angka suci hingga 5 N untuk input N , yang sangat lambat:

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)

Di sini batasnya adalah 5 N 2 , dan Anda benar-benar dapat menjalankan test case, dengan biaya satu byte:

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)

Potongan pertama adalah valid, karena 5 N ≥ 5 N 2 untuk semua bilangan bulat positif N .

Lynn
sumber
Oh, tunggu, aku melewatkan sesuatu .. Terlalu lelah untuk ini.
seequ
3

Lua, 317 Bytes

Saya memiliki beberapa masalah dalam melakukan ini, beberapa hal di Lua tidak berfungsi seperti yang saya kira. Saya harus mencoba dan bermain dengan mereka jika saya ingin bermain golf ini. Anda dapat menguji lua online dengan mengganti arg[1]dengan jumlah elemen yang Anda inginkan :).

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

Tidak terseret dan penjelasan

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

Terner bersarang yang digunakan untuk nilai baru mdapat diterjemahkan dalam ifs bersarang sebagai:

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

Juga, saya akan senang mengganti sarang fordengan menggunakan table.sort, tetapi, karena suatu alasan saya tidak tahu, yang berikut ini tidak berfungsi meskipun tidak menghasilkan loop tak terbatas atau menghancurkan fungsi pengurutan.

table.sort(a,function(i,j)
    return f(i)~=f(j)              
         and f(i)>f(j)          
         or i>j
end)
Katenkyo
sumber
1

JavaScript (ES6), 166 165 byte

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

Sunting: Disimpan 1 byte dengan mengembalikan array string.

Tidak Disatukan:

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
sumber