Суммы цифр от 1 до 7


21

Вызов

Учитывая положительное целое число N, которое 28 или выше, выходной список номеров суммирующих в Nкоторый использует каждую цифру 1через 7ровно один раз. Вы можете дать как программу или функцию.

Цифры могут появляться сами по себе или объединяться, если вы используете каждую из них один раз без повторов. Например, [12, 34, 56, 7]действительно, как [1, 27, 6, 4, 35]и [1234, 567], но не [123, 34567]или [3, 2, 1476]. Порядок перечисления номеров не имеет значения.

Если Nне может быть сделано с 1-7, вернуть или ничего не выводить.

Дополнительная информация

  • Это кодовый гольф, поэтому самый короткий код в байтах к четвергу 15 октября выигрывает.

  • Задайте любые вопросы в комментариях.

  • Все, что я не указываю в вызове, остается за вами.

  • Стандартные лазейки запрещены.

Примеры

Это может устранить любую путаницу:

вход

28

Выход

[1, 2, 3, 4, 5, 6, 7]

вход

100

Выход

[56, 7, 4, 31, 2]

вход

1234567

Выход

[1234567]

вход

29

Выход

Ничего, 29 недействительно.

вход

1891

Выход

[1234, 657]

вход

370

Выход

[15, 342, 7, 6]

Я сделаю больше, если нужно.

Вот пастбище всех возможных чисел, созданных с этими семью числами, любезно предоставлено FryAmTheEggman.


Для чего нужен выход 29?
Geobits

4
Если вы хотите, чтобы вывод был ничем, не ставьте его (N/A)в качестве вывода.
mbomb007

1
@LukStorms [1234566, 1]не является допустимым выводом, потому что 6 повторяется. Вы не можете повторять числа в выводе.
The_Basset_Hound

2
Может быть »... список чисел, составленных из десятичных цифр от 1 до 7, сумма которых равна N«, является более четкой формулировкой, чем та, которая в настоящее время обсуждается.
Паŭло Эберманн

3
Для чуть менее грубого решения: это равносильно назначению коэффициента степени 10 для каждого из них, 1, ..,, 7чтобы было как минимум столько же 1, сколько 10s, как минимум столько же 10, сколько 100s и так далее.
xnor

Ответы:


9

Pyth, 18 14 байтов

hfqSjkTjkS7./Q

Спасибо @isaacg за игру в 2 байта и прокладку еще 2.

Код будет аварийно завершен, если он не произведет вывод, что не приведет к выводу.

Это будет работать для небольших входных данных, если вы достаточно терпеливы, и для больших, если достаточно времени и памяти.

Для того, чтобы убедиться в том , что код работает , как задумано, вы можете заменить 7с 3для сумм цифр 1 по 3 . Нажмите здесь для теста.

Пример работает

$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 28
(1, 2, 3, 4, 5, 6, 7)

real    4m34.634s
user    4m34.751s
sys     0m0.101s
$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 29 2>/dev/null

real    9m5.819s
user    9m6.069s
sys     0m0.093s

Как это устроено

           ./Q    Compute all integer partitions of the input.
 f                Filter the integer partitions:
    jkT             Join the integers with empty separator.
   S                Sort the characters of the resulting string.
      jkS7          Join [1, ..., 7] with empty separator.
  q                 Check both results for equality.
                  Keep the partition of `q' returned True.
h                 Retrieve the first element of the filtered list.
                  For a non-empty list, this retrieves the solution.
                  For the empty list, it causes an error and produces no output.

2
Отлично сработано! Довольно инновационный подход. `` `MS7`` короче чем r\1\8. И тоже @ .. 0самое h.
Исаак

@isaacg Спасибо! Я не уверен, как я пропустил h, но я понятия не имел, что вы могли бы использовать Sтаким образом. (Ссылка на символ в онлайн-интерпретаторе не упоминает об этом.) jkS7Кажется, еще короче, так как мне больше не нужно s.
Деннис

5

Python 3, 109

def f(n,s=set('1234567'),l='0,'):[f(n,s-{x},l+x+c)for c in(',','')for x in s]or n-sum(eval(l))or~print(l[2:])

Функция, которая принимает число и выводит кортеж подобным образом 123,4567,. Да, это допустимый кортеж.

Идея заключается в том , чтобы создать все возможные строки , как , 43,126,7,5,которые имеют цифры 1через 7разделенные запятыми, без двух запятых подряд. Оцените это выражение как кортеж, и его сумма равна n, выведите его и завершите с ошибкой.

Чтобы построить все такие строки, мы отслеживаем набор sсимволов для использования и пытаемся добавлять каждый из них либо через запятую, что делает цифру в конце записи, либо без нее, и в этом случае будущие цифры будут объединяться с ней.

Короткое замыкание используется , чтобы проверить, sпусто , потому что список-комп пуст, и что n==sum(eval(l)), в этом случае мы печатаем lи завершаться с ошибкой, взяв ~из Noneвозвращаемых печатей (благодаря Sp3000 для этого.).

Я считаю, что в Python 3.5 два символа могут быть сохранены путем записи s={*'1234567'}(спасибо Sp3000).

Есть некоторые маленькие неприятности, которые съедают символы. Один из них заключается в том, что в случае, когда он lвыглядит 1234567без запятых, он разбирается как один номер, и вызов sumвызывает ошибку. Это происходит с помощью взлома, начиная lс элемента 0и удаляя его при печати. Это стоит 6 символов.

Перебор cзапятой и пустой строки раздражающе многословен for c in(',',''), поскольку Python 3 не позволяет обнажать этот кортеж. Я хотел бы, чтобы был какой-то символ, ?который игнорируется в цифрах, чтобы сделать его ',?'на 4 символа меньше, но, похоже, такого символа нет.


Старый метод:

Питон 2, 117

def f(n,s={1,2,3,4,5,6,7},l=[],p=0):
 if{n,p}|s=={0}:print l;1/0
 if p:f(n-p,s,l+[p])
 for x in s:f(n,s-{x},l,p*10+x)

Определяет функцию, которая принимает число и печатает список.

Идея состоит в том, чтобы использовать рекурсию, чтобы попробовать каждую ветку. Трек переменных

  • Оставшаяся сумма nнужна
  • Набор цифр, sоставшихся для использования
  • Список lномеров, сделанных до сих пор
  • Текущий частично сформированный номер p

Когда n==0и sпусто, распечатайте lи завершите по ошибке.

Если текущее частично сформированное число pне равно нулю, попробуйте добавить его в список и удалить из оставшейся суммы.

Для каждой цифры, которую xмы можем использовать s, попробуйте добавить ее pи удалить из s.


4

Пиф, 23

#iRThfqQsiR10Ts./M.pS7q

Наивная грубая сила, слишком медленная онлайн, занимает около минуты на моем компьютере. Использует общий шаблон «цикл навсегда до исключения» пит-гольфов, где доступ к результирующему отфильтрованному списку комбинаций приводит к ошибке для невозможных чисел, например 29.

Выходы, такие как список питонов, например

1891
[1234, 657]
100
[1, 2, 34, 56, 7]
370
[12, 345, 6, 7]

Вот паста всех 10136 номеров, которые можно сделать таким образом.


Могу ли я использовать ссылку для вставки в качестве примера?
The_Basset_Hound

@The_Basset_Hound Конечно, давай.
FryAmTheEggman

3

Python 2,7, 178 172 169 байт

n=input()
for i in range(8**7):
 for j in len(set('%o0'%i))/8*range(128):
    s=''
    for c in'%o'%i:s+='+'[:j%2*len(s)]+c;j/=2
    if eval(s)==n:print map(int,s.split('+'));1/0

Обратите внимание, что последние три строки должны иметь отступы от вкладок, но я не могу понять, как это сделать в этом редакторе.

Изменить: Сглаживание одного слоя вложенности с помощью Sp3000


К сожалению, SE удаляет вкладки, так что просто сказать, как это должно быть с отступом, хорошо :)
Sp3000

Ах, ладно, я все еще обдумываю этот сайт.
xsot

3

JavaScript (ES6), 165 196

Редактировать немного укоротил. Может быть короче eval, но мне нравится, что это быстро

Грубая сила, позорно длиннее, чем в пробковой версии, но быстрее. Попробуйте запустить приведенный ниже фрагмент в браузере, совместимом с EcmaScript 6.

f=z=>{for(r=i=1e6;r&&++i<8e6;)for(m=/(.).*\1|[089]/.test(w=i+'')?0:64;r&&m--;t.split`+`.map(v=>r-=v,r=z))for(t=w[j=0],l=1;d=w[++j];l+=l)t+=l&m?'+'+d:d;return r?'':t}

function test() { O.innerHTML=f(+I.value) }

test()

// Less golfed

f=z=>{
  for(r=i=1e6; r&&++i<8e6;)
    for(m=/(.).*\1|[089]/.test(w=i+'')?0:64; r&&m--; t.split`+`.map(v=>r-=v,r=z))
      for(t=w[j=0],l=1;d=w[++j];l+=l)
        t+=l&m?'+'+d:d;
  return r?'':t
}
<input id=I value=28><button onclick=test()>-></button><span id=O></span>


Не стыдно быть дольше из-за языка, мне очень нравятся твои ответы JS, +1
FryAmTheEggman

1

Python 2, 270 268 байт

from itertools import*;P=permutations
x,d,f=range(1,8),[],input()
r=sum([[int(''.join(str(n)for n in i))for i in list(P(x,j))]for j in x],[])
z=1
while z:
 t=sum([[list(j)for j in P(r,z)]for i in x],[])
 v=filter(lambda i:sum(i)==f,t)
 if v:print v[0];break
 else:z+=1

Все еще работаю над игрой в гольф.

Это повторяется, пока не будет найдено совпадение.


import asредко требуется - вы можете сделатьfrom itertools import*;P=permutations
Sp3000

Его использование короче, map(str,i)чем понимание списка, и вы можете создать список r напрямую, а не путем выравнивания вложенного списка:, r=[int(''.join(map(str,i)))for j in x for i in P(x,j)]и аналогичное для t.
Рут Франклин

Вы можете использовать `n`вместо str(n), так nкак никогда не будет выше максимального целого числа.
mbomb007

1

Haskell (145 байт)

main=getLine>>=print.head.f[1..7].read
f[]0=[[]]
f b s=[n:j|(n,g)<-m b,j<-f g$s-n]
m b=[(d+10*z,g)|d<-b,(z,g)<-(0,filter(/=d)b):m(filter(/=d)b)]

Использует рекурсию.

Ungolfed (337 байт):

delete d = filter (/= d)
main = getLine >>= print . (`form` [1..7]) . read

form s [] | s == 0    = [[]]
form s ds | s <= 0    = []
form s ds | otherwise = [n:ns | (n, ds') <- makeNumbers ds, ns <- form (s-n) ds']

makeNumbers [] = []
makeNumbers ds  = [(d + 10 * n',ds') | d <- ds, (n',ds') <- (0,delete d ds):makeNumbers (delete d ds)]

0

Scala, 195 байт

Это не самый эффективный и потребовалось более 15 минут, чтобы получить результат за 29, но это работает

def g(s: Seq[Int]): Iterator[Seq[Int]]=s.combinations(2).map(c=>g(c.mkString.toInt +: s.filterNot(c.contains))).flatten ++ Seq(s)
def f(i: Int)=(1 to 7).permutations.map(g).flatten.find(_.sum==i)

Вот некоторые выводы

scala> f(100)
res2: Option[Seq[Int]] = Some(Vector(46, 35, 12, 7))

scala> f(1891)
res3: Option[Seq[Int]] = Some(Vector(567, 1324))

scala> f(370)
res4: Option[Seq[Int]] = Some(Vector(345, 12, 6, 7))

scala> f(29)
res5: Option[Seq[Int]] = None

0

Рубин, 105 байт

Грубая сила! Проверяет каждое подмножество длин от 0 до 7 целых чисел от 1 до 7654321 и определяет, соответствует ли любое из них нашим критериям. Вы, вероятно, не хотите ждать, пока это не прекратится.

->n{8.times{|i|[*1..7654321].permutation(i){|x|return x if
x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}

Чтобы запустить и проверить алгоритм, вы можете сузить область поиска, заменив 7654321на наибольшее число, которое вы знаете, будет в ответе. Например, 56 для n = 100 или 1234 для n = 1891. Вот пробный запуск последнего:

$ ruby -e "p ->n{8.times{|i|[*1..1234].permutation(i){|x|return x if x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}[gets.to_i]" <<< 1891
[657, 1234]

От 0 до 7 целых чисел? Вы должны использовать exaclty 7 целых чисел: 1,2,3,4,5,6,7
edc65

@ edc65 Вы имеете в виду ровно 7 цифр . Результатом является набор целых чисел, а размер набора зависит от входных данных.
Даниеро

Я не говорю на Ruby, я предполагаю, что программа работает, но я не получаю объяснения. Если ваши целые числа меньше 1234567, как вы получите 7654321?
edc65

@ edc65 Вы правы, мне придется изменить это число. Я тоже постараюсь объяснить это лучше.
Даниеро
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.