Святые числа


22

Как мы узнали из Святого Числа , есть 5 святых цифр ( 0, 4, 6, 8, 9), и положительные целые числа, состоящие исключительно из этих цифр, являются святыми. Кроме того, святость числа - это сумма дыр в числе ( +2для каждого 0или 8, и +1иначе).

Теперь необходимо принять во внимание еще одно свойство, чтобы действительно и точно представлять святость числа. Видите ли, важно не только количество дырок в цифре, но и то, где в числе это происходит.

Рассмотрим число 88. По нашим старым правилам это будет иметь святость 4. Но это вряд ли справедливо! 8Слева делает больше работы , чем другой 8- в 10 раз больше работы! Должен быть вознагражден за свою работу. Мы вознаградим его дополнительными баллами святости, равными общей святости всех цифр справа от нее (включая дополнительные баллы святости, предоставленные этим правилом цифрам справа), минус 1.

Вот еще примеры, чтобы принять во внимание:

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

Все цифры соответственно вознаграждены за свою работу с дополнительной святостью, и все хорошо. Мы будем называть это свойство "повышенной целостностью".

В великолепном языке Python алгоритм для вычисления повышенной целостности может выглядеть примерно так:

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

Соревнование

Получив целое число n > 0, выведите первые nсвятые числа, отсортированные по возрастанию расширенной целостности, используя числовое значение в качестве прерывателя связей. Вы можете предположить, что ввод и вывод будут не больше максимально представимого целого числа в вашем языке или в 2^64 - 1зависимости от того, что меньше.

Для справки, вот несколько тестов (ввод, затем вывод):

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

10
Эта дырочная идея очень сложна.
Увлечения Кэлвина

Что вы подразумеваете под "выходной будет не больше, чем ..."? Как на выходе не будет иметь никакого числа больше 2^64 - 1? Если это так, то, вероятно, стоит выяснить, какой вход сначала генерирует такие числа, чтобы люди могли проверить свои ответы.
FryAmTheEggman

@FryAmTheEggman Не больше, чем означает, меньше или равно. Я обновлю пост с некоторыми максимумами для различных целочисленных размеров.
Мего

Ваш код Python не работает для 6, он производит голин 0.
shrx

Ответы:


2

Python 2, 138 122 байта

Это ищет святые числа до 5 N для входа N , который смехотворно медленен:

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)

Здесь ограничение составляет 5 N 2 , и вы можете запустить тестовые случаи за счет одного байта:

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)

Первый фрагмент действителен, как 5 N ≥ 5 Н 2 для всех положительных целых чисел N .


Ой, подождите, я что-то упустил .. Слишком устал для этого.
Seequ

3

Луа, 317 байт

У меня были некоторые проблемы с этим, некоторые вещи в Lua не работают так, как я думаю. Мне придется попробовать поиграть с ними, если я хочу сыграть в эту игру. Вы можете проверить lua онлайн , заменив arg[1]на количество элементов, которое вы хотите :).

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

Неуправляемый и объяснения

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

Вложенные троичные, используемые для нового значения, mмогут быть переведены во вложенные ifs как:

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

Кроме того, я бы хотел заменить вложенное forс помощью table.sort, но по неизвестной мне причине следующее не работает, несмотря на то, что не создает бесконечный цикл или не выполняет функцию сортировки.

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

1

JavaScript (ES6), 166 165 байт

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

Редактировать: 1 байт сохранен, возвращая массив строк.

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;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.