L'idée ici est de produire un motif presque répétitif. C'est-à-dire que la séquence en cours de construction change au dernier moment pour éviter la répétition de certaines sous-séquences. Les conséquences de type AA et ABA sont à éviter (où B n'est pas plus long que A).
Exemples:
Je vais commencer et énumérer tous les petits exemples pour rendre ma description plus claire. Commençons par 0.
Valable: 0 Invalide: 00 (motif AA) Valable: 01 Non valide: 010 (modèle ABA) Non valide: 011 (modèle AA) Valable: 012 Valable: 0120 Non valide: 0121 (modèle ABA) Non valide: 0122 (motif AA) Non valide: 01200 (modèle AA) Non valide: 01201 (modèle ABA; 01-2-01) Non valide: 01202 (modèle ABA) Valable: 01203
Maintenant, je crois fermement qu'un a 4
n'est jamais nécessaire, même si je n'ai pas de preuve, car j'ai facilement trouvé des séquences de centaines de caractères qui n'utilisent que 0123
. (Cela est probablement étroitement lié à la façon dont seuls trois caractères sont nécessaires pour avoir des chaînes infinies sans motifs AA. Il y a une page Wikipedia à ce sujet.)
Entrée sortie
L'entrée est un entier unique, positif et non nul n
. Vous pouvez supposer cela n <= 1000
.
La sortie est une n
séquence de caractères sans sous-séquence qui correspond à un motif interdit (AA ou ABA).
Exemples d'entrées et de sorties
>>> 1 0 >>> 2 01 >>> 3 012 >>> 4 0120 >>> 5 01203 >>> 50 01203102130123103201302103120132102301203102132012
Règles
- Seuls les personnages
0123
sont autorisés. - B n'est plus que A. Cela permet d' éviter la situation dans laquelle
012345
doit être suivie6
parce0123451
a ceci:1-2345-1
. En d'autres termes, la séquence serait triviale et sans intérêt. n
peut être entré par n'importe quelle méthode souhaitée, à l' exception du codage en dur.- La sortie peut être une liste ou une chaîne, selon ce qui est le plus facile.
- Pas de force brute ; le temps d'exécution doit être de l'ordre de quelques minutes, au plus une heure sur une machine très lente, pour
n=1000
. (Ceci est destiné à disqualifier les solutions qui ne font que boucler à travers toutes lesn
permutations de longueur{0,1,2,3}
, de sorte que les trucs et astuces similaires sont interdits.) - Les failles standard sont interdites, comme d'habitude.
- La notation est en octets. Il s'agit de code-golf , donc l'entrée la plus courte gagne (probablement - voir bonus).
- Bonus: choisissez le chiffre le plus bas autorisé à chaque étape. Si
1
et3
sont des choix possibles pour le chiffre suivant de la séquence, choisissez1
. Soustrayez 5 octets de votre score. Cependant, prenez note de la note ci-dessous.
Remarque!
Des impasses sont possibles. Votre programme ou fonction doit les éviter. Voici un exemple:
Souche: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302302 Souche: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302302 Souche: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203123021032012310213012031023013203123020 Souche: 012031021301231032013021031201321023012031021320123021031201302310320123021320310230120321023120130210312301320310213012032102301320312302103201231021301203102301320312302302
Chacune de ces séquences ne peut plus être étendue (sans utiliser a 4
). Mais notez également qu'il existe une différence cruciale entre les deux premiers et les deux derniers. Je vais remplacer la sous-séquence initiale partagée par un X
pour rendre cela plus clair.
Souche: X2130120 Souche: X2130123 Souche: X320 Souche: X321301203102130
Les deux derniers chiffres de X
sont 10
, donc les seuls choix possibles pour le chiffre suivant sont 2
et 3
. Le choix 2
conduit à une situation où la séquence doit se terminer. L'algorithme gourmand ne fonctionnera pas ici. (Pas sans retour en arrière, de toute façon.)
la source
n
? Si quelqu'un donne un algorithme heuristique semi-gourmand, comment vérifierez-vous qu'il ne rencontre pas de problèmes sur une très grande longueur? Le problème général est intéressant, et je n'ai pas pu trouver quoi que ce soit sur l'évitement de modèle où nous limitons la longueur d'une partie du modèle. Si quelqu'un peut produire une recette générale, je m'attends à ce que ce soit la meilleure approche.n
, mais étant donné que les souches que mon programme trouve ont tendance à s'allonger de 10 chiffres en moyenne à chaque fois, je suis très sûr qu'une séquence infinie existe. Je ne sais pas comment un algorithme semi-gourmand pourrait être testé pour des séquences arbitrairement grandes. Je pourrais limiter l' exigence àn
= 1000 et ne pas m'inquiéter de plusn
.AA
c'est vraiment taperABA
oùB
est vide. Cela pourrait peut-être aider à rationaliser certaines solutions.Réponses:
Rétine , 86 octets - 5 = 81
Où
<empty>
représente une ligne de fin vide. Vous pouvez exécuter le code ci-dessus à partir d'un seul fichier avec l'-s
indicateur.L'entrée doit être donnée en unaire , par exemple
111111
. Je ne l'ai pas encore testé pour une sortie de l'ordre de milliers - deux des expressions régulières peuvent devenir un peu lentes après un certain temps - mais il peut facilement en gérer quelques centaines en quelques secondes.Explication
Il s'agit d'une simple solution de retour en arrière.
0
.3
.Ce retour en arrière est implémenté par une boucle de substitutions d'expression régulière qui s'interrompt une fois que la chaîne reste inchangée à travers une itération.
Cela ajoute un
_
à l'entrée, qui est utilisé pour séparer l'entrée unaire de la séquence que nous construisons.Il s'agit de la première substitution dans la boucle (indiquée par le début
(
). Le regex correspond si a) il y a un caractère de mot (c'est-à-dire un chiffre) à la fin de la chaîne (ce qui signifie que la chaîne est valide - nous verrons ci-dessous que les séquences invalides sont marquées d'un caractère de fin#
) et b) il y a au moins autant de caractères dans la séquence que dans l'entrée (ceci est vérifié à l'aide des groupes d'équilibrage ). Si tel est le cas, nous supprimons l'entrée et ajoutons a!
. Cela!
sert à faire échouer tous les regex dans la boucle, de sorte qu'elle se termine.S'il y a un mot à la fin (c'est-à-dire que la séquence est valide et que la boucle n'a pas été terminée par l'étape précédente), ajoutez a
0
.Si (à la place) la séquence avait été marquée comme invalide et terminée
3
, nous la supprimons3
(mais laissons la séquence comme invalide, car il n'y a pas de suite possible pour le préfixe actuel ... donc le caractère suivant doit également être inversé).Si la séquence est marquée comme invalide et tout chiffre autre que celui
3
à la fin, nous incrémentons le chiffre et retirons le marqueur.La dernière substitution dans la boucle (comme indiqué par le
)
). Il vérifie si la chaîne se termine parABA
(oùB
n'est pas plus longue queA
mais potentiellement vide). Les longueurs relatives deA
etB
sont à nouveau vérifiées à l'aide de groupes d'équilibrage, et la répétition deA
est vérifiée avec une simple référence arrière.Si cette expression régulière correspond, nous marquons la séquence non valide en ajoutant
#
.Une fois la boucle terminée, tout ce que nous devons faire est de supprimer le
!
et nous nous retrouvons avec la sortie souhaitée.la source
Python 2, 175 - 5 = 170 octets
Il s'agit de l'algorithme gourmand avec retour en arrière. Je souhaite que ce soit plus court. J'espère que c'est correct (voir ci-dessous).
Il construit la chaîne un chiffre à la fois. Étant donné une chaîne de
d
chiffres qu'il a déjà trouvée, il essaie d'ajouter un0
comme(d+1)
st chiffre. Si cela ne fonctionne pas, il essaie un1
, puis un2
, puis un3
. Si aucun de ces éléments ne fonctionne, il revient aud
troisième chiffre et l'incrémente (s'il est inférieur à3
) ou le supprime (s'il est égal à3
, auquel cas il incrémente le précédent, etc.).Le contrôle de validité est la ligne avec
.find
. Dans le cas où quelqu'un décide de lire mon code, je dois dire que ce programme stocke en fait la chaîne à l'envers, ce qui signifie qu'il ajoute des chiffres à l' avant . La vérification implique donc de rechercher des endroits où les premiersc
chiffres apparaissent à nouveau plus tard dans la chaîne (n'importe où après les premiersc
chiffres), et s'il existe de tels endroits, si la longueur intermédiaire est au plusc
.(Bien sûr, il inverse la chaîne avant l'impression.)
Cela pourrait aussi être facilement plus rapide; À l'origine, je l'avais quitté plusieurs boucles tôt pour plus d'efficacité, mais cela coûtait de précieux octets. Il fait toujours OK dans la gamme de
n=1000
, cependant.Quoi qu'il en soit, le programme semble montrer une préférence pour les petits chiffres, mais ce n'est pas une préférence très forte. Par exemple, l'exécuter avec
n=2000
m'a donné une chaîne avec des523
zéros, des502
uns, des497
deux et des478
trois, se terminant par30210312013021
. Donc, si quelqu'un d'autre travaille sur un algorithme gourmand, il peut peut-être confirmer ce résultat. Ou avecn=1000
j'ai obtenu[263, 251, 248, 238]
pour les comptes par chiffre.Enfin, je mentionnerais que ces dénombrements suggèrent une sorte de symétrie, presque (mais pas exactement) comme si nous avions commencé avec une distribution uniforme, puis converti certains des
3
`` en0
'' et quelques des2
`` en1
'' s. Mais évidemment, cela pourrait être juste une coïncidence. Je n'ai aucune idée!la source
Haskell, 115 (120 octets - 5 bonus)
Courez en ligne sur Ideone
Exemple d'exécution:
la source