Die heiligeren Zahlen

22

Wie wir aus den heiligen Zahlen erfahren haben , gibt es 5 heilige Ziffern ( 0, 4, 6, 8, 9), und positive ganze Zahlen, die nur aus diesen Ziffern bestehen, sind heilig. Außerdem ist die Heiligkeit einer Zahl die Summe der Löcher in der Zahl ( +2für jedes 0oder 8und +1sonstiges).

Nun gibt es eine zusätzliche Eigenschaft, die berücksichtigt werden muss, um die Heiligkeit einer Zahl wirklich und genau darzustellen. Sie sehen, es kommt nicht nur auf die Anzahl der Löcher in der Ziffer an, sondern auch darauf, wo sie vorkommt.

Betrachten Sie die Nummer 88. Nach unseren alten Regeln hätte es eine Heiligkeit von 4. Das ist aber kaum fair! Die 8linke macht mehr Arbeit als die andere 8- zehnmal so viel ! Es sollte für seine Arbeit belohnt werden. Wir werden es mit zusätzlichen Heiligkeitspunkten belohnen, die der Gesamtheiligkeit aller Ziffern zu seiner Rechten entsprechen (einschließlich der zusätzlichen Heiligkeitspunkte, die diese Regel den Ziffern zu seiner Rechten gewährt), minus 1.

Hier sind weitere Beispiele zu berücksichtigen:

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

Alle Ziffern werden für ihre Arbeit angemessen mit zusätzlicher Heiligkeit belohnt, und alles ist in Ordnung. Wir werden diese Eigenschaft "verstärkte Ganzheitlichkeit" nennen.

In der großartigen Sprache Python könnte ein Algorithmus zur Berechnung der erweiterten Holarität ungefähr so ​​aussehen:

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

Die Herausforderung

Bei einer gegebenen Ganzzahl n > 0werden die ersten nheiligen Zahlen ausgegeben , sortiert nach aufsteigender verstärkter Holarität, wobei der numerische Wert als Tiebreaker verwendet wird. Sie können davon ausgehen, dass die Eingabe und Ausgabe nicht größer ist als die maximal darstellbare Ganzzahl in Ihrer Sprache oder 2^64 - 1, je nachdem, welcher Wert kleiner ist.

Als Referenz sind hier einige Testfälle (Eingabe, gefolgt von Ausgabe):

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
quelle
10
Diese ganze Idee ist heilig.
Calvins Hobbys
Was meinst du mit "Ausgabe wird nicht größer als ..."? Wie in der Ausgabe wird keine Nummer größer als 2^64 - 1? In diesem Fall lohnt es sich wahrscheinlich herauszufinden, welche Eingabe zuerst solche Zahlen generiert, damit die Benutzer ihre Antworten testen können.
FryAmTheEggman
@FryAmTheEggman Nicht größer als bedeutet kleiner oder gleich. Ich werde den Beitrag mit einigen Maximalwerten für verschiedene Ganzzahlgrößen aktualisieren.
Mego
Ihr Python-Code funktioniert nicht für 6, er erzeugt ein holines von 0.
shrx

Antworten:

2

Python 2, 138 122 Bytes

Dies sucht nach heiligen Zahlen bis zu 5 N für eine Eingabe N , was lächerlich langsam ist:

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)

Hier beträgt die Grenze 5 N 2 , und Sie können die Testfälle tatsächlich auf Kosten eines einzelnen Bytes ausführen:

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)

Der erste Schnipsel gültig ist , als 5 N ≥ 5 N 2 für alle positiven ganzen Zahlen N .

Lynn
quelle
Oh, warte, ich habe etwas verpasst. Zu müde dafür.
Siehe auch
3

Lua, 317 Bytes

Ich hatte einige Probleme damit, einige Dinge in Lua funktionieren nicht so, wie ich denke. Ich werde versuchen müssen, mit ihnen zu spielen, wenn ich das runter spielen will. Sie können lua online testen, indem Sie arg[1]durch die Anzahl der gewünschten Elemente ersetzen :).

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

Ungolfed und Erklärungen

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

Die geschachtelten Ternaries, die für den neuen Wert von mverwendet werden, können in geschachtelten ifs wie folgt übersetzt werden:

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

Außerdem hätte ich es geliebt, das Verschachtelte fordurch die Verwendung von zu ersetzen table.sort, aber aus einem mir nicht bekannten Grund funktioniert das Folgende nicht, obwohl keine Endlosschleife erzeugt oder die Sortierfunktion zerstört wurde.

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

JavaScript (ES6), 166 165 Bytes

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

Bearbeiten: 1 Byte durch Rückgabe eines String-Arrays gespeichert.

Ungolfed:

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
quelle