Multiplication par auto-modification

33

... au moins pour une définition de "auto-modification".

La tâche

Dans ce défi, votre tâche est d'écrire trois chaînes A, Bet Cqui satisfont les propriétés suivantes.

  • La chaîne Ba une longueur d'au moins 1.

  • Pour chaque n ≥ 0chaîne, la chaîne est un programme valide (c'est-à-dire un programme exécutable complet ou une définition de fonction) dans le langage de programmation de votre choix. La répétition de la désigne superscript, donc ce moyen les cordes , , , etc. Chaque programme prend une chaîne en entrée, et retourne une chaîne en sortie.ABnCACABCABBCABBBC

  • Pour tout m, n ≥ 0, si le programme est exécuté avec une entrée , il retourne . Pour les entrées qui ne sont pas de cette forme, le programme peut faire n'importe quoi, y compris un plantage.ABmCABnCABm*n+1C

Quelques exemples dans le format program(input) -> output:

AC(AC) -> ABC
ABC(AC) -> ABC
ABBBBBC(AC) -> ABC
AC(ABC) -> ABC
AC(ABBBBC) -> ABC
ABC(ABC) -> ABBC
ABBC(ABC) -> ABBBC
ABBBBC(ABBBC) -> ABBBBBBBBBBBBBC
ABBBC(ABBBBBBC) -> ABBBBBBBBBBBBBBBBBBBC

Règles et notation

Votre score est la longueur totale de AetC , le score le plus bas étant meilleur. Notez que bien que Bne soit pas compté dans la partition, il doit être produit par Aet Ccomme dans le premier exemple.

Les failles standard sont interdites. Les programmes ne sont pas autorisés à accéder directement ou indirectement à leur propre code source (sauf quand ils le reçoivent en entrée). Vous devez identifier les chaînes A, Bet Cdans votre réponse d'une manière ou d'une autre, et les encourager à expliquer votre solution.

Zgarb
la source

Réponses:

16

CJam, 9 à 8 octets

A: 1
B: 0
C:  r,(#0q

Essayez-le en ligne dans l' interprète CJam .

Comment ça marche

(ABcode) e# Push the integer 10 ** len(Bcode).
<SP>     e# Noop. Separates (AB) and C for input reading.
r        e# Read the first whitespace-separated token from STDIN (ABinput).
,(       e# Push the string length minus 1: len(Binput)
#        e# Power operator: 10 ** len(Bcode) len(Binput) # ->
         e#   (10 ** len(Bcode)) ** len(Binput) = 10 ** (len(Bcode) * len(Binput))
0        e# Push an additional 0 to complete len(Bcode) * len(Binput) + 1 zeroes.
q        e# Read the remaining input (C).
Dennis
la source
12

CJam, 15 13 11 octets

A: rl"
B: <SP>
C: <LF>",(*SNq

Essayez-le en ligne dans l' interprète CJam .

Comment ça marche

e# A

r     e# Read a whitespace-separated token from STDIN.
      e# This reads the input up to the first space, but does not consume it.
l     e# Read the rest of the first line from STDIN.
      e# This reads up to the first linefeed and consumes it.

"     e# Initiate a string.

e# B

<SP>  e# Fill the string with as many spaces as there are copies of B.

e# C

<LF>" e# Terminate the string with a linefeed.
      e# This serves as a delimiter for the `l' command.
,(    e# Compute the length of the string minus 1 (to account for the LF).
*     e# Repeat the string read by `l' that many times.
SN    e# Push a space and a linefeed.
q     e# Read the remaining input (i.e., the second line) from STDIN.

A la fin, la pile contient le jeton lu par r, l'espace produit par *, l'espace et le saut de ligne poussés par SNet la ligne lue par q. CJam imprime tout cela automatiquement.

Dennis
la source
Hah, bonne utilisation des guillemets ici: D
Optimizer
9

Pyth, 10

A: w*\0hl*w[<newline>
B: 0
C: <empty>

Nous avons divisé la source en deux lignes. La première ligne est A, la deuxième ligne sont les Bs. Comme A est sur la première ligne, le premier wimprime simplement A - facile, c'est fait.

En Pythme, les zéros de tête sont des jetons séparés, il [00)en est de même [0, 0]. Notez que la première ligne se termine par l[et la deuxième ligne est constituée de 0000.... Donc, l[compte réellement le nombre de Bs dans ce programme. La seconde wlit dans la seconde ligne de l'entrée - c'est le nombre de Bs de l'entrée. À partir de là, il suffit de multiplier, incrémenter et afficher autant de zéros.

orlp
la source
9

Retina , 25 19 octets

A: ]\]<LF>
B: ]]
C: <LF>m`^]*$<LF>]$0]

<LF> stands for newline

Exemple de ABCcode:

]\]
]]
m`^]*$
]$0]

Le code a deux étapes de substitution:

  • changer l'entrée AB^mCen AB^(m*n)Cen changeant chaque Ben B^n:

    • ]\]correspond à tous Bdans l'entrée et rien d'autre grâce à échapper dans les lignes de modèle
    • ]]...]] est B^n
  • changer B^(m*n)à B^(m*n+1)par

    • m`^]*$en prenant la ligne avec seulement ]« s
    • ]$0]l'ajout d'une paire supplémentaire de ]]manière à ce que cette ligne ne corresponde pas à la première expression régulière

J'ai ajouté 3 octets à la partition pour l' -sindicateur multiligne nécessaire afin que tout le code Retina puisse figurer dans un fichier.

2 octets enregistrés grâce à @ MartinBüttner.

randomra
la source
8

Python 3, 51 octets

A: lambda s:s[:28]+"x"*(1+len("
B: x
C: ")*(len(s)-51))+s[-23:]

Exemple d'utilisation:

>>> f=lambda s:s[:28]+"x"*(1+len("xx")*(len(s)-51))+s[-23:]
>>> f('lambda s:s[:28]+"x"*(1+len("xxx")*(len(s)-51))+s[-23:]')
'lambda s:s[:28]+"x"*(1+len("xxxxxxx")*(len(s)-51))+s[-23:]'

La fonction calcule n*m+1avec (1+len("xxx")*(len(s)-51))où il y a m xs dans la chaîne (la xxxpartie est la B^m). Multiplier la chaîne "x"avec ce nombre donne B^(n*m+1)et la fonction prend Aet Csort de l'entrée et concatène tous ceux-ci à obtenir AB^(n*m+1)C.

La même approche dans J:

J, 35 octets

A: (19{.]),('x'#~1+(#'
B: x
C: ')*35-~#),_16{.]
randomra
la source
5

CJam, 22

A:<empty>
B:{])`\,q,K/(*))*"_~"}
C:{])`\,q,K/(*))*"_~"}_~

Exemple d'exécution:

ABBC(ABC) -> ABBBC

ce qui se traduit par

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

avec entrée comme

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

ce qui donne la sortie suivante:

{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Comment ça marche :

Jetons un coup d'œil à quels programmes ACet à quoi ABCressemble:

AC :{])`\,q,K/(*))*"_~"}_~
ABC:{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Nous remarquons que C=B_~

Regardons ce qui Bse passe:

{])`\,q,K/(*))*"_~"}

{                  }    e# This is a code block. Alone, this does nothing except
                        e# pushing this block to stack as is
 ]                      e# Wrap everything on stack in an array
  )`                    e# Take out the last part and convert it to its string representation
    \,                  e# Take length of remaining array
      q,K/              e# Read the input, take its length and int divide by K (i.e. 20)
          (*            e# Decrement and multiply by the array length on stack
            ))          e# Add two to the product
              *         e# Repeat the string representation on stack that many times
               "_~"     e# Put this string on stack

Voyons maintenant ce que faire ACsans entrée fera:

{])`\,q,K/(*))*"_~"}_~                      e# Copy the block and run it
{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}~   e# Block is copied, run it
{      ...         } ])                     e# Wrapped array has the block in it.
                       `\,                  e# Stringify it and take length of remaining = 0
                          q,K/              e# No input so 0
                              (*))          e# 0 * -1 = 0. 0 + 2 = 2
                                  *         e# Repeat the stringified block 2 times:
                                            e# "{])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}"
                                   "_~"     e# Put this string. Program ends, so print stack:
                                            e# {])`\,q,K/(*))*"_~"}{])`\,q,K/(*))*"_~"}_~

Wow, la sortie est ABC.

Nous comptons essentiellement combien Bil en existe dans le code. Puis combien sont en entrée (en utilisant la longueur). Multipliez-les, incrémentez deux fois (depuis a Cégalement B) et ajoutez _~pour obtenirC

Essayez-le en ligne ici

Optimiseur
la source
3

Haskell , 50 octets

fest une fonction prenant et retournant un String.

La chaîne B n'est qu'un seul espace, alors que C commence par un.

A:_:b="
B: 
C: ";f s|a:c<-words s=unwords$a:(drop 50s>>b):c

Essayez-le en ligne!

  • _:b=" "assigne à tous les espaces du littéral chaîne, à l'exception du premier b, ce qui est égal aux m m copies du programme.
  • sest la chaîne d'entrée. a:c<-words sla scinde en mots séparés par des espaces, de sorte que cela adevienne A et cdevienne une liste de mots constituant C. Les copies B sont ignorées car wordspressent de multiples espaces (ce que le reste du programme évite).
  • drop 50sest une chaîne de longueur égale au nombre n de B copies en entrée. drop 50s>>bconcatène autant de copies de b, en donnant des espaces mn .
  • unwords$a:(drop 50s>>b):crelie toutes les chaînes avec des espaces. Puisqu'il y a un "mot" supplémentaire (drop 50s>>b)inséré dans la liste, il y a aussi un espace de jonction supplémentaire, ajoutant automatiquement le +1 à la multiplication.
Ørjan Johansen
la source
2

Matlab, 85

C'était la première fois que je faisais un défi aussi abstrait, alors pour moi, c'était plus un défi de codage qu'un défi de golf-code!

Les trois chaînes sont, sans les guillemets:

A:    "X=strsplit(input('','s'));m=0 "
B:    "+1 "
C:    ";[X{1},32,repmat(['+1',32],1,m*(length(X)-2)+1),X{end}]"

Comment cela fonctionne: Je divise l'argument d'entrée en espaces, je npeux donc le déterminer à partir du nombre de parties de chaîne. B fonctionne comme une sorte de compteur à obtenir m. Pour reconstituer la réponse, j'utilise A et C à partir de la scission, répétez B m * n + 1 fois et j'insère les espaces en utilisant leur valeur ASCII, afin d'éviter toute scission indésirable dans C.

EDIT: whoops, compté accidentellement A + B

Oebele
la source
1

C (gcc) , 81 octets

L'obligation d'identifier les chaînes semble contredire le fait que nous soyons autorisés à adopter un comportement arbitraire pour entrée illégale, à moins que nous n'ayons des normes assez laxistes en ce qui concerne l'identification. Naturellement, j'ai pris l'interprétation qui met le plus d'octets.

Essayez-le en ligne!

A: m;f(char*s){m=strrchr(s+66,32)-s-65;printf("%.66s%*s",s,m*strlen("
B: <SPACE>
C: ")+16,s+m+66);}
gastropner
la source
Par identification , je voulais juste dire qu'il devrait être clair de votre réponse que des extraits de code sont A , B et C . Ce n'est pas une exigence pour le programme.
Zgarb
1

TI-Basic (série 83), 65 octets

Segment A (33 octets):

Input Str1:sub(Str1,1,27:For(I,0,(length(Str1)-55)(length("

Segment B:

X

Segment C (32 octets):

Y")-1:Ans+"X":End:Ans+sub(Str1,length(Str1)-27,28

Je suis vraiment excité de trouver ce défi quine! La plupart des quines ne fonctionnent pas dans TI-Basic sans au moins un peu de triche, car il n’ya aucun moyen d’échapper au "symbole. (Dans les deux sens du mot "évasion".) Mais ici, nous obtenons une chaîne de saisie via la Inputcommande, et taper "dedans est parfaitement correct.

Il reste encore un peu de bêtise de TI-Basic à contourner: une chaîne vide est invalide, donc la solution naïve d'insérer la chaîne "XXX...XX"dans une boucle ne fonctionnera pas lorsque n = 0. Au lieu de cela, nous calculons manuellement la valeur de mn + 1 et insérons la chaîne "X"autant de fois que nécessaire.

Les constantes magiques 27et 28dans le programme sont légèrement des octets compte 33 et 32, parce que Str1, sub(et length(sont seulement qui contribuent jetons à deux octets 1 à la longueur d'une chaîne.

Si nous utilisons des nouvelles lignes au lieu de :, il semble que vous pouvez économiser quelques octets en laissant de côté les guillemets, mais cela ne fonctionne pas. Tout d'abord, vous avez besoin d'un éditeur hexadécimal avant de pouvoir ajouter le caractère de nouvelle ligne dans une chaîne: vous ne pouvez pas simplement le saisir, car si vous appuyez sur la touche Entrée pendant une Inputcommande, il soumet l'entrée. Lorsque j'ai essayé l'approche de l'éditeur hexadécimal, j'ai eu une erreur de débordement de mémoire tampon étrange qui a modifié le contenu de mon programme. N'essayez donc pas cela à la maison avec votre calculatrice coûteuse.

Misha Lavrov
la source
0

Java 11, 135 65 + 26 = 91 octets

UNE

s->{var p=s.split("\\(\"|\"\\.");return p[0]+"(\"B"+p[1].repeat("

B

B

C

".length())+'"'+'.'+p[2];}

Essayez-le en ligne ici (TIO n’ayant pas encore Java 11, il s’agit d’une méthode d'assistance au lieu de String::repeat()).

Ungolfed:

s -> { // lambda taking and returning a String
    var p = s.split("\\(\"|\"\\."); // split input into parts A, B^n, C (where n may be 0) at the "(\"" and "\"."
    return p[0] + "(\"B" + // put it back together: A plus the part the split shaved off, plus an extra B ...
    p[1].repeat("BBB".length()) + // ... plus B^(n*m)
    '"' + '.' + p[2]; // plus C, with the part the split shaved off reattached
}
OOBalance
la source