Considérez un tableau A
de longueur n
. Le tableau ne contient que des entiers positifs. Par exemple A = (1,1,2,2)
. Définissons f(A)
comme l'ensemble des sommes de tous les sous-réseaux contigus non vides de A
. Dans ce cas f(A) = {1,2,3,4,5,6}
. Les étapes de production f(A)
sont les suivantes:
Les sous-réseaux de A
sont (1), (1), (2), (2), (1,1), (1,2), (2,2), (1,1,2), (1,2,2), (1,1,2,2)
. Leurs sommes respectives sont 1,1,2,2,2,3,4,4,5,6
. L'ensemble que vous obtenez de cette liste est donc {1,2,3,4,5,6}
.
Tâche
Étant donné un ensemble de sommes S
données dans un ordre trié ne contenant que des entiers positifs et une longueur de tableau n
, votre tâche consiste à générer au moins un tableau X
tel que f(X) = S
.
Par exemple, si S = {1,2,3,5,6}
et n = 3
alors une sortie valide est X = (1,2,3)
.
S'il n'y a pas un tel tableau, X
votre code devrait afficher n'importe quelle valeur constante.
Exemples
Entrée n=4, S = (1, 3, 4, 5, 6, 8, 9, 10, 13)
:, sortie possible:X = (3, 5, 1, 4)
Entrée n=6, S = (2, 3, 4, 5, 7, 8, 9, 10, 12, 14, 17, 22)
:, sortie possible:X = (5, 3, 2, 2, 5, 5)
Entrée n=6, S = (2, 4, 6, 8, 10, 12, 16)
:, sortie possible:X = (4, 2, 2, 2, 2, 4)
Entrée n=6, S = (1, 2, 3, 4, 6, 7, 8, 10, 14)
:, sortie possible:X = (4, 2, 1, 1, 2, 4)
Entrée: n=10, S = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25)
, sortie possible: X = (1, 1, 3, 1, 2, 1, 2, 5, 4, 5)
.
Entrée: n=15, S = (1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31)
, sortie possible: X = (1, 2, 1, 3, 3, 1, 3, 3, 1, 3, 3, 1, 2, 1, 3)
.
Format d'entrée et de sortie
Votre code peut prendre en entrée et donner une sortie dans n'importe quel format de lecture facilement humain que vous trouvez commode. Cependant, veuillez montrer le résultat du test sur les exemples de la question.
Durée
Vous devez être en mesure d'exécuter le code jusqu'à la fin pour tous les exemples de la question. Il devrait en principe être correct n
jusqu'à 15
mais vous n'avez pas besoin de prouver qu'il serait assez rapide pour toutes les entrées.
Réponses:
Coque , 20 octets
Essayez-le en ligne!
Renvoie une solution ou une liste vide si elle n'existe pas. Le dernier cas de test (
n=15
) se termine en 3,8 secondes sur TIO.Explication
Le programme comprend deux parties. Dans la première partie (
¡
et à droite de celle-ci), nous construisons une liste infinie dont lek
th élément est une liste contenant toutes lesk
listes de longueur dont les sommes de tranche sont dedansS
. Nous le faisons de manière inductive, en commençant par les tranches de 1 élément deS
, et à chaque étape en ajoutant chaque élément deS
à chaque liste, et en conservant ceux dont les sommes de préfixe sont dedansS
. Dans la deuxième partie (!
et à gauche), nous prenons len
e élément de la liste, qui contient lesn
listes de longueurs . Parmi ceux-ci, nous sélectionnons le premier dont les sommes de tranche contiennent réellement chaque élément deS
.Dans le code, remplaçons d'abord
o
etȯ
(qui composent deux et trois fonctions en une) par des parenthèses pour plus de clarté.Certaines parties nécessitent des explications supplémentaires. Dans ce programme, les exposants
⁰¹
font tous deux référence au premier argumentS
. Cependant, siα
est une fonction, alorsα¹
signifie "appliquerα
àS
", tandis que⁰α
signifie "se connecterS
au deuxième argument deα
". La fonction¦
vérifie si son premier argument contient tous les éléments du second (comptage des multiplicités), doncS
devrait être son deuxième argument.Dans la première partie, la fonction qui
¡
utilise peut être interprétée commeS(f~Λ€∫)(×:)¹
. Le combinateurS
se comporte commeSαβγ -> (αγ)(βγ)
, ce qui signifie que nous pouvons le simplifier(f~Λ€∫¹)(×:¹)
. La deuxième partie,×:¹
est "mix withS
by prepending", et son résultat est transmis à la première partie. La première partief~Λ€∫¹
, fonctionne comme ça. La fonctionf
filtre une liste par une condition, qui dans ce cas est~Λ€∫¹
. Il reçoit une liste de listesL
, donc nous l'avons~Λ€∫¹L
. Le combinateur~
se comporte comme~αβγδε -> α(βδ)(γε)
: le premier argument est passé àβ
, le second àγ
et les résultats sont combinés avecα
. Cela signifie que nous avonsΛ(€¹)(∫L)
. La dernière partie∫L
est juste les sommes cumulées deL
,€¹
est une fonction qui vérifie l'appartenanceS
,Λ
prend une condition (ici€¹
) et une liste (ici∫L
), et vérifie que tous les éléments la satisfont. En termes simples, nous filtrons les résultats du mixage en fonction de leur somme cumuléeS
.la source
Rubis , 135 octets
Essayez-le en ligne!
Utilisez une recherche en premier. n = 10 fonctionne sur TIO, n = 15 prend plus d'une minute, mais fonctionne sur ma machine.
Rubis , 147 octets
Essayez-le en ligne!
Version optimisée, fonctionne sur TIO pour n = 15 (~ 20 sec)
En fait, c'est le début d'une approche sans force brute. J'espère que quelqu'un y travaillera et trouvera une solution complète.
Premières idées:
Ce qui nous amène à la prochaine optimisation:
Rubis , 175 octets
Essayez-le en ligne!
~ 8,5 secondes sur TIO. Pas mal...
... et ainsi de suite (à mettre en œuvre)
la source
Haskell,
117111 octets6 octets économisés grâce à @nimi!
Essayez-le en ligne!
f
r
i
n
s
Quand
n
est zéro (joué aun<1
), la liste doit être prête, nous vérifions donc si toutes les valeurs ont été vues. Sinon, nous retournons une liste vide pour indiquer aucune solution, sinon nous retournons une liste singleton contenant une liste vide, à laquelle les éléments choisis seront ajoutés. Ce cas aurait également pu être traité avec les équations supplémentairesSi
n
n'est pas nul, on retourneC'est la liste des (1) listes d'où provient le premier élément (2)
s
et le reste (5) de l'appel récursif, à la condition (4) que toutes les nouvelles sommes soient dedanss
. Les nouvelles sommes sont calculées en (3) - note quit
est tirée d'une liste singleton, un hack de golf laid pour ce que serait Haskell idiomatiquelet t=y:map(y+)i
. L'appel récursif (5) obtient comme nouveaur
mis l'ancien sans les éléments qui apparaissent parmi les nouvelles sommest
.La fonction principale
&
appelle la fonction d'aide en disant que nous devons encore voir toutes les valeurs (r=s
) et qu'il n'y a pas encore de sommes (i=[]
).Pour sept octets supplémentaires, nous pouvons restreindre le calcul pour ne donner que le premier résultat (le cas échéant), qui est beaucoup plus rapide et gère tous les cas de test en moins de 2 secondes.
Essayez-le en ligne! (il s'agit du premier résultat uniquement une variation de l'ancienne version)
la source
map
, j'ai seulement essayé<$>
mais cela avait besoin de parens supplémentaires ... @Anush Je n'ai aucune idée d'une solution de temps polynomialNettoyer , 177 octets
Essayez-le en ligne!
Prend environ 40 secondes sur ma machine pour le
n=15
cas de test, mais il expire sur TIO.Nettoyer , 297 octets
Essayez-le en ligne!
Celui-ci comprend quelques optimisations faites par GB ainsi que certaines des miennes. Je pense que certains d'entre eux peuvent être rendus plus génériques, alors j'ajouterai une explication une fois cela fait.
Cela prend environ 10 secondes sur ma machine, 40 secondes sur TIO.
la source
@mention
vous demain quand ils seront finis , vous n'avez malheureusement pas le temps aujourd'hui.Python 3 , 177 octets
Essayez-le en ligne!
(quelques nouvelles lignes / espaces ajoutés pour éviter aux lecteurs d'avoir à faire défiler le code)
Un port direct de ma réponse Jelly (avec quelques modifications, voir la section "note" ci-dessous)
Résultat de l'exécution locale:
J'ai entendu que
itertools
c'était verbeux, mais ma meilleurecombinations
implémentation est encore plus verbeuse:Remarque .
a[p//n:p%n+1]
prend environ 2 fois plus de temps, mais économise quelques octets.combinations
retour d'un itérateur, c'est plus convivial pour la mémoire.la source
Gelée , 35 octets
Essayez-le en ligne!
Exécuter localement: (n = 15 prend plus de 1 Go de RAM)
(en fait, j'ai exécuté la version codée UTF8, qui prend plus de 35 octets, mais le résultat est quand même le même)
Cette solution utilise un court-circuit pour réduire le temps d'exécution.
Sans court-circuit, ce code prend environ( | S| -2n - 2) ×( n36+ n2Journaln2) opérations, qui évalue à ( 26-deux15 - 2) ×( 1536+ 152Journal152) ≈5,79× 109 , mais en raison de l'inefficacité de Python et Jelly, il faut une éternité pour terminer. Grâce au court-circuit, il peut se terminer beaucoup plus tôt.
Explication
Nous notons que les sommes de tous les préfixes non vides sont présentes dans l'entrée et qu'elles augmentent strictement. Nous pouvons également supposer que le plus grand et le deuxième plus grand élément sont une somme de préfixes.
Par conséquent, nous pouvons envisager toutes les façons de choisirn - 2 éléments distincts du premier | S| -2 éléments (il y a ( | S| -2n - 2) ces listes), calculer les différences consécutives pour récupérer les éléments; puis vérifiez si elle est valide naïvement (obtenez toutn2 sous-réseaux, calculer la somme, unifier. La longueur totale des sous-réseaux est d'environn36 )
Non testé (mais devrait avoir des performances identiques)
Gelée , 32 octets
Essayez-le en ligne!
Version plus inefficace (sans court-circuit):
Gelée , 27 octets
Essayez-le en ligne!
Pour le test n = 15, cela prend jusqu'à 2 Go de RAM et ne se termine pas après environ 37 minutes.
note :
Ẇ§
peut être remplacé parÄÐƤẎ
. Cela peut être plus efficace.la source
APL (NARS), caractères 758, octets 1516
La fonction G dans G x (à l'aide de la fonction H) trouverait toutes les permutations de x. La fonction d dans xdy trouve si le tableau y génère à la suite du tableau d'exercices x renvoyant une valeur booléenne. La fonction F dans x F y retournerait le tableau r de longueur x, tel que ydr est vrai (= 1) Un peu long comme implémentation, mais c'est celle-ci qui calcule tous les cas en test moins de temps ... Le dernier cas pour n = 15 il tourne 20 secondes seulement ... je dois dire que cela ne trouve pas beaucoup de solutions, retourne une seule solution (enfin il semble que oui) en moins de temps (test non exploré pour différentes entrées ...) 16 + 39 + 42 + 8 + 11 + 11 + 18 + 24 + 24 + 54 + 11 + 12 + 7 + 45 + 79 + 69 + 12 + 38 + 26 + 72 + 79 + 27 + 15 + 6 + 13 (758)
la source