Écrivez un programme qui imprime la ligne de 80 caractères suivante:
Ce programme de codegolf.stackexchange.com se permute pour encoder une chaîne.
accepte ensuite une ligne d'entrée, puis imprime son code source avec ses points de code éventuellement réorganisés (aucun ajouté et aucun supprimé). Lorsque ce code est exécuté, la même chose doit se produire, sauf que la ligne imprimée serait la ligne d'entrée la plus récente.
Le regex de style Perl ^[A-Za-z0-9. ]{80}$
correspondra à n'importe quelle ligne d'entrée. Vous ne pouvez faire aucune hypothèse supplémentaire.
Le score d'une soumission est le nombre de points de code dans son code source moins 94 . Plus c'est bas, mieux c'est.
Le code ne doit rien faire qui serait inacceptable dans une quine ( par exemple la lecture d'un fichier). En particulier, toute soumission avec un score négatif doit tricher d'une manière ou d'une autre, comme 93! est inférieur à 64 80 .
Ajouté le 21/04/2014: Le code source complet de votre programme doit être bien formé dans l'encodage des caractères sous lequel vous comptez les points de code. Par exemple, vous ne pouvez pas utiliser 80 octets consécutifs dans la plage d'octets de fin UTF-8 (80..BF) et compter chacun comme un seul caractère de remplacement U + FFFD (ou pire, comme pas un point de code du tout).
De plus, si l'encodage permet plusieurs façons de coder un point de code ( par exemple SCSU ), votre programme, ainsi que tous les programmes qu'il génère directement ou indirectement, ne doivent utiliser qu'un seul d'entre eux (ou au moins tous doivent être traités de manière équivalente dans tout le code ).
Réponses:
GolfScript,
231162131Comment ça fonctionne
Nous commençons par choisir 94 caractères différents qui seront permutés pour encoder une chaîne. 94 caractères fonctionneraient, mais nous choisissons ce qui suit à des fins de golf:
Appelons le tableau de ces caractères «&».
La ligne d'entrée contiendra toujours 81 caractères (y compris le LF). Tous ces caractères sont présents dans les 65 premiers caractères de «&». C'est la seule raison de choisir des caractères dans les 128 octets supérieurs.
Nous remplaçons chaque caractère de la chaîne par son index dans «&», donc LF devient 0, l'espace devient 1, etc.
Nous considérons les 81 nombres obtenus comme les chiffres d'un seul nombre de base 65. Appelons ce numéro «N».
Maintenant, nous énumérons toutes les permutations possibles de «&» et récupérons la permutation correspondant au nombre ci-dessus. Ceci est réalisé de la manière suivante:
c = 1
etA = []
.N % c
àA
.N = N / c
etc = c + 1
.c < 95
, revenez à 2.i = 0
ets = ""
.&[A[i]]
, ajoutez-le à «s» et supprimez-le de «&».i = i + 1
.i < 94
retournez à 6.Supposons que nous ayons des blocs de code «E» et «D» qui codent et décodent une chaîne comme expliqué ci-dessus.
Maintenant, nous avons besoin d'un wrapper pour ces blocs de code qui est conforme aux exigences de la question:
Cela fait ce qui suit:
{…}.~
définit un bloc, le duplique et exécute la deuxième copie. La première copie restera sur la pile.\.$
échange la chaîne codée avec le bloc et crée une copie de la chaîne codée, avec des caractères triés.[{}/]:&;
convertit la chaîne ci-dessus en un tableau, l'enregistre dans «&» et la supprime.D puts
décode la chaîne encodée et imprime le résultat.'"#{`head -1`}"'~
lit une ligne d'entrée en s'exécutanthead -1
dans le shell.E "'".@+\+
encode la chaîne et ajoute et ajoute une seule citation.\'.~'
échange la chaîne codée et le bloc et ajoute la chaîne'.~'
.Une fois le bloc exécuté, GolfScript imprime le contenu de la pile (chaîne codée, bloc
'.~'
) et quitte."E" peut être défini comme suit:
«D» peut être défini comme suit:
Golf final:
Remplacez
\.$[{}/]:&;0&@
par0@.$[{}/]:&\
pour enregistrer deux caractères.Définissez la fonction
{;65base}:b
pour enregistrer un caractère.Supprimez tous les espaces sauf le LF de fin et le LF dans la chaîne.
Exemple
la source
Perl,
14281099Celui-ci contient 1193 caractères ASCII (dont 960 chiffres binaires permutés). 1193 - 94 = 1099
Mon premier design
Avant de prendre une suggestion de Dennis pour passer au binaire, mon programme permutait les chiffres octaux.
Mon premier design encode chaque chaîne en 160 chiffres octaux, avec 2 chiffres par caractère. Cet encodage a 100 8 = 64 caractères différents. Le système octal a 8 chiffres différents. Le programme doit avoir 160 copies de chaque chiffre, donc il permute 8 × 160 = 1280 chiffres.
Je garde 160 chiffres
$s
et les 1120 autres chiffres$t
. Je commence avec un programme qui n'est pas une quine, mais imprime uniquement les affectations vers$s
et$t
pour la prochaine exécution. Ça y est:(() = $s =~ /$_/g))
est une affectation à une liste vide de variables. Je prends cette astuce dans le didacticiel de contexte de PerlMonks . Il force le contexte de liste sur l'opérateur de correspondance=~
. Dans un contexte scalaire, la correspondance serait vraie ou fausse, et j'aurais besoin d'une boucle comme$i++ while ($s =~ /$_/g)
pour compter les correspondances. Dans un contexte de liste,$s =~ /$_/g
est une liste de correspondances. J'ai placé cette liste dans le contexte scalaire d'une soustraction, donc Perl compte les éléments de la liste.Pour faire une quine, je reprends le formulaire
$_=q{print"\$_=q{$_};eval"};eval
des quines Perl de Rosetta Code . Celui-ci affecte une chaîneq{...}
à$_
puis appelleeval
, afin que je puisse avoir mon code dans une chaîne et l'exécuter également. Mon programme devient une quine lorsque j'encapsule ma troisième à la dernière ligne dans$_=q{
et};eval
, et change ma dernièreprint
enprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Enfin, je joue à mon programme en remplaçant la première affectation
$t
par un commentaire et en supprimant les caractères supplémentaires.Cela a 1522 caractères ASCII (dont 1280 chiffres octaux permutés).
1522 - 94 = 1428
Le passage au binaire
Dans les commentaires, Dennis a remarqué que 960 chiffres binaires permutés seraient inférieurs à 1280 chiffres octaux. J'ai donc représenté graphiquement le nombre de chiffres permutés pour chaque base de 2 à 16.
Bien que la base 8 soit un minimum local, les bases 2 et 3 et 4 sont égales pour la meilleure base, à 960 chiffres permutés. Pour le golf de code, la base 2 est la meilleure car Perl a des conversions pour la base 2.
Le remplacement de 1280 chiffres octaux par 960 chiffres binaires enregistre 320 caractères.
Passer d'un code octal à un code binaire coûte 8 caractères:
oct
desoct'0b'.$_
coûts 7./../g
des/.{6}/g
coûts 2."%02o"
pour "% 06b" `coûte 0.160
des480
coûts 0.0..7
en0,1
sauvegardes 1.J'ai appris quelques conseils de golf Perl . Ils sauvent 14 caractères:
'A'..'Z','a'..'z','0'..'9'
enA..Z,a..z,0..9
utilisant des mots nus et des nombres nus, enregistre 12 caractères."\n"
pour$/
enregistrer 2 caractères.J'enregistre 3 caractères en déplaçant le
#$t
commentaire à la fin du fichier. Cela supprime la nouvelle ligne qui termine le commentaire et un littéral\n
dans la quine.Ces modifications permettent d'économiser un total de 329 caractères et de réduire mon score de 1428 à 1099.
la source