Somme des chiffres 1 à 7


21

Défi

Étant donné un nombre entier positif Nqui est 28 ou plus, la production d' une liste de numéros de sommation pour Nque les utilisations de chaque chiffre 1par 7exactement une fois. Vous pouvez donner comme programme ou fonction.

Les chiffres peuvent apparaître seuls ou concaténés, à condition que vous les utilisiez une fois sans répétition. Par exemple, [12, 34, 56, 7]est valide, tel quel [1, 27, 6, 4, 35]et [1234, 567], mais pas [123, 34567]ou [3, 2, 1476]. L'ordre dans lequel les numéros sont répertoriés n'a pas d'importance.

Si Ncela ne peut pas être fait avec 1-7, ne retournez ou n'émettez rien.

Les autres informations

  • C'est le code golf, donc le code le plus court en octets avant le jeudi 15 octobre l'emporte.

  • Posez des questions dans les commentaires.

  • Tout ce que je ne précise pas dans le défi vous appartient.

  • Les failles standard ne sont pas autorisées.

Exemples

Ceux-ci peuvent dissiper toute confusion:

Contribution

28

Production

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

Contribution

100

Production

[56, 7, 4, 31, 2]

Contribution

1234567

Production

[1234567]

Contribution

29

Production

Rien, 29 n'est pas valide.

Contribution

1891

Production

[1234, 657]

Contribution

370

Production

[15, 342, 7, 6]

Je ferai plus si nécessaire.

Voici une boîte à pâte de tous les nombres possibles créés avec ces sept nombres, gracieuseté de FryAmTheEggman.


À quoi sert la sortie 29?
Geobits

4
Si vous voulez que la sortie ne soit rien, ne la mettez pas (N/A)comme sortie.
mbomb007

1
@LukStorms [1234566, 1]n'est pas une sortie valide, car 6 est répété. Vous ne pouvez pas répéter des nombres dans la sortie.
The_Basset_Hound

2
Peut-être »... une liste de nombres constitués des chiffres décimaux 1 à 7 qui résument jusqu'à N« est une formulation plus claire que celle actuellement en question.
Paŭlo Ebermann,

3
Pour une solution de force brute légèrement inférieure: cela équivaut à attribuer un coefficient de puissance de 10 à chacun de 1, ..,, 7sorte qu'il y ait au moins autant de 1'que 10', au moins autant 10de que 100', et ainsi de suite.
xnor

Réponses:


9

Pyth, 18 14 octets

hfqSjkTjkS7./Q

Merci à @isaacg pour avoir joué au golf sur 2 octets et ouvert la voie à 2 autres.

Le code se bloque s'il ne doit produire aucune sortie, ce qui ne produit aucune sortie.

Cela fonctionnera pour les entrées de petite taille si vous êtes assez patient et pour les plus grandes si vous disposez de suffisamment de temps et de mémoire.

Pour vérifier que le code fonctionne comme prévu, vous pouvez remplacer le 7par un 3pour les sommes des chiffres 1 à 3 . Cliquez ici pour une suite de tests.

Exemple d'exécutions

$ 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

Comment ça marche

           ./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
Bien joué! Une approche assez innovante. `` MS7`` est plus court que r\1\8. Est également @ .. 0le même que h.
isaacg

@isaacg Merci! Je ne sais pas comment j'ai raté h, mais je ne savais pas que vous pouviez utiliser de Scette façon. (La référence char dans l'interprète en ligne ne le mentionne pas.) jkS7Semble être encore plus courte, car je n'en ai plus besoin s.
Dennis

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

Une fonction qui prend un nombre et génère un tuple similaire 123,4567,. Oui, c'est un tuple valide.

L'idée est de générer toutes les chaînes possibles comme 43,126,7,5,ayant les chiffres 1par 7séparés par des virgules, sans deux virgules consécutives. Évaluez cette expression comme un tuple, et sa somme est égale n, imprimez-la et terminez avec une erreur.

Pour construire toutes ces chaînes, nous ssuivons l'ensemble des caractères à utiliser et essayons de les ajouter chacun avec une virgule, ce qui fait que le chiffre termine l'entrée, ou sans, auquel cas les prochains chiffres seront concaténés dessus.

Le court-circuitage est utilisé pour vérifier qu'il sest vide car la liste-comp est vide, et que n==sum(eval(l)), dans ce cas, nous imprimons let terminons avec une erreur en prenant ~le Noneretourné par impression (merci à Sp3000 pour cela.).

Je crois qu'en Python 3.5, deux caractères peuvent être enregistrés en écrivant s={*'1234567'}(merci Sp3000).

Il y a quelques petits ennuis qui dévorent les caractères. La première est que dans le cas qui lressemble 1234567à sans virgule, il est analysé comme un seul numéro et l'appel sumdonne une erreur. Ceci est géré avec le hack de commencer lpar l'élément 0et de le supprimer lors de l'impression. Cela coûte 6 caractères.

Itérer csur la virgule et la chaîne vide est ennuyeux for c in(',',''), car Python 3 ne permet pas à ce tuple d'être nu. J'aimerais qu'il y ait des caractères ?qui sont ignorés en nombre pour faire ',?'4 caractères de moins, mais il ne semble pas y avoir un tel caractère.


Ancienne méthode:

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

Définit une fonction qui prend un nombre et imprime une liste.

L'idée est d'utiliser la récursivité pour essayer chaque branche. La piste des variables est

  • La somme restante nnécessaire
  • L'ensemble de chiffres srestant à utiliser
  • La liste ldes numéros réalisés jusqu'à présent
  • Le nombre partiellement formé actuel p

Lorsque n==0et sest vide, imprimez let terminez par erreur.

Si le nombre partiellement formé actuel pest différent de zéro, essayez de l'ajouter à la liste et de le supprimer de la somme restante.

Pour chaque chiffre que xnous pouvons utiliser à partir de s, essayez de l'ajouter à pet de le supprimer de s.


4

Pyth, 23

#iRThfqQsiR10Ts./M.pS7q

La force brute naïve, trop lente en ligne, prend environ une minute sur mon ordinateur. Utilise le modèle commun "boucle pour toujours jusqu'à exception" des golfs pyth où l'accès à la liste filtrée résultante des combinaisons provoque une erreur pour les nombres impossibles, comme 29.

Sorties comme une liste pythonique, par exemple

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

Voici une pâte de tous les numéros 10136 qui peuvent être faits de cette façon.


Puis-je utiliser le lien pastebin pour des exemples?
The_Basset_Hound

@The_Basset_Hound Bien sûr, allez-y.
FryAmTheEggman

3

Python 2.7, 178 172 169 169 octets

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

Notez que les trois dernières lignes sont censées être en retrait avec des onglets mais je ne peux pas comprendre comment le faire dans cet éditeur.

Edit: aplati une couche d'imbrication à l'aide de Sp3000


SE supprime les onglets malheureusement, donc juste dire comment il est censé être mis en retrait est très bien :)
Sp3000

Ah d'accord, toujours en train de trouver mon chemin sur ce site.
xsot

3

JavaScript (ES6), 165 196

Modifier raccourci un peu. Pourrait être plus court à utiliser eval, mais j'aime être rapide

Force brute, honteusement plus longue que la version Pith, mais plus rapide. Testez l'exécution de l'extrait ci-dessous dans un navigateur compatible 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>


Pas dommage d'être plus long à cause de la langue, j'apprécie vraiment vos réponses JS, +1
FryAmTheEggman

1

Python 2, 270 268 octets

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

Je travaille toujours sur le golf.

Cela boucle jusqu'à ce qu'une correspondance soit trouvée.


import asest rarement nécessaire - vous pouvez le fairefrom itertools import*;P=permutations
Sp3000

Il est plus court à utiliser map(str,i)que la compréhension de liste, et vous pouvez construire la liste r directement plutôt qu'en aplatissant une liste imbriquée:, r=[int(''.join(map(str,i)))for j in x for i in P(x,j)]et une chose similaire pour t.
Ruth Franklin

Vous pouvez utiliser à la `n`place de str(n), car nne sera jamais supérieur à l'entier maximum.
mbomb007

1

Haskell (145 octets)

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

Utilise la récursivité.

Non golfé (337 octets):

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 octets

Ce n'est pas le plus efficace et il a fallu plus de 15 minutes pour obtenir la sortie pour 29, mais cela fonctionne

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)

Voici une sortie

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

Rubis, 105 octets

Force brute! Vérifie chaque sous-ensemble de longueurs comprises entre 0 et 7 des entiers compris entre 1 et 7654321 et voit si l'un d'entre eux correspond à nos critères. Vous ne voulez probablement pas attendre que cela se termine.

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

Pour exécuter et vérifier l'algorithme, vous pouvez réduire l'espace de recherche en le remplaçant 7654321par le plus grand nombre dont vous savez qu'il figurera dans la réponse. Par exemple, 56 pour n = 100 ou 1234 pour n = 1891. Voici un essai de ce dernier:

$ 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 entiers? Vous devez utiliser exaclty 7 entiers: 1,2,3,4,5,6,7
edc65

@ edc65 Vous voulez dire exactement 7 chiffres . Le résultat est un ensemble d'entiers, et la taille de l'ensemble dépend de l'entrée.
daniero

Je ne parle pas Ruby, je suppose que le programme fonctionne, mais je n'ai pas d'explication. Si vos nombres entiers sont inférieurs à 1234567, comment obtenez-vous 7654321?
edc65

@ edc65 Vous avez raison, je vais devoir changer ce nombre. Je vais aussi essayer de mieux l'expliquer.
daniero
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.