Créer un carré de taille croissante en répliquant le code initial

45

Votre tâche consiste à écrire un programme de longueur paire , qui imprime un carré ASCII (décrit ci-dessous), qui augmente sa longueur de côté de 1 unité chaque fois que le code source original est collé au milieu du code actuel.

Il m'est difficile de définir très bien cette tâche. Je vais donc vous donner un exemple:

  • Disons que votre code initial était CODEet qu'il imprimait:

    0
    
  • Ensuite, insérez CODEau milieu: votre code devient COCODEDEet il devrait imprimer:

    00
    00
    
  • Réinsérez CODEau milieu: votre code devient COCOCODEDEDE et devrait imprimer:

    000
    000
    000
    
  • Etc. Votre réponse devrait théoriquement fonctionner après n'importe quel nombre d'itérations, mais je comprends si, en raison de limitations de performances langagières, elle ne peut pas fonctionner raisonnablement au-dessus d'un certain seuil.

Certaines règles:

  • Vous pouvez utiliser n’importe quel code ASCII imprimable (32-127) comme caractère à utiliser pour votre carré. Votre choix doit être constant (vous devez utiliser le même caractère pour chaque itération).

  • Le carré de sortie initial doit avoir la longueur de côté 1 .

  • Un carré ascii-art est défini comme une chaîne de N lignes (séparées par N-1 sauts de ligne / nouvelles lignes), chaque ligne contenant N copies du caractère choisi.

  • Votre sortie ne doit contenir aucun espace supplémentaire, autre qu'un retour à la ligne final.

  • Vous pouvez utiliser les valeurs par défaut pour les entrées et les sorties (les programmes ou les fonctions sont autorisés, mais pas les extraits).

  • Le milieu de votre code est défini comme le point où le code source peut être divisé en deux parties, de sorte que les deux soient égales.

  • Vos réponses seront notées en fonction de la longueur de votre programme d'origine , en octets. Le plus petit nombre d'octets gagne. En cas d'égalité des voix, la réponse soumise précédemment l'emporte.

  • Vous pouvez utiliser ce programme pour appliquer les insertions sans avoir à le faire à la main.


la source
1
Je dois avouer que cette quine question posée plus tôt m'a inspiré . Si les gens pensent que c'est trop proche, je supprimerai volontiers ceci. Excusez-moi également si j'ai commis des erreurs, je ne suis toujours pas trop familiarisé avec les règles ici. :)
2
Bienvenue chez PPCG! Je suggère d'utiliser le bac à sable pour vos futurs défis.
user202729
7
Bienvenue sur le site! Excellente utilisation d'un autre défi d'inspiration sans tomber dans le piège à la dupe :)
Shaggy
Votre programme d'assistance ne fonctionne pas pour les programmes comportant plusieurs lignes. Que diriez-vous de cette version modifiée de l'autre question?
Jo King
1
@ user77954 Mais mon code brainfuck est plus court que votre python :( (est-ce que quelqu'un l'a déjà dit?)
Jo King

Réponses:

41

Pyth , 2 octets


5

Essayez-le en ligne! Aussi Essayez - le doublé , triplé !

Comment ça marche?

\nest la commande qui affiche son argument avec une nouvelle ligne de fin, tout en le renvoyant simultanément. Ainsi, chaque fois que vous effectuez une insertion, vous transformez le littéral entier 5 en un nombre contenant N copies de 5 concaténées, et les nouvelles lignes majeures s’assurent essentiellement qu’elle est imprimée le nombre de fois approprié, en la gardant ainsi droite.

M. Xcoder
la source
6
Saint Frick c'est court ...
ETHproductions
Preuve de l'optimalité (: P): comme le nombre d'octets doit être pair et ne peut pas être négatif, le nombre d'octets minimum possible est de 0 octets. Il existe exactement 1 programme de 0 octet, qui ne remplit pas la tâche. Par conséquent, 2 octets est optimal.
M. Xcoder
10
Tout le monde (en particulier les électeurs du HNQ), votez également d’autres réponses et évitez l’effet FGITW.
user202729
25

JavaScript (ES6), 42 32 30 octets

s=[this.s]+0;  console.log(s);

Deuxième itération:

s=[this.s]+0;  s=[this.s]+0;  console.log(s);console.log(s);

Cela fonctionne en ajoutant un 0à schaque fois que la première moitié du code est exécuté et en imprimant slui-même chaque fois que la seconde moitié est exécutée. Profite de quatre bizarreries de JavaScript:

  1. L'environnement actuel peut être référencé avec this. Cela nous permet de faire this.sà la place de s.
  2. JavaScript revient lorsque vous accédez à une propriété qui n'a pas été définie sur un objet, au lieu de générer une erreur undefined.
  3. Un tableau plus un nombre retourne une chaîne. [1,2,3] + 4 === "1,2,34"
  4. Lors de la chaîne d'un tableau, il undefinedest converti en chaîne vide, ce qui signifie que [undefined] + 0 === "0".

Ensemble, cela signifie que nous pouvons exprimer la première moitié (générer une chaîne de zéros) en seulement 13 octets. Si utiliser alertau lieu de console.logest autorisé, nous pouvons économiser 4 octets supplémentaires en raccourcissant la seconde moitié.

ETHproductions
la source
Bravo, passe les tests que j'ai faits!
1
... Ingénieux! :)
Shaggy
17

Python 2 , 42 38 28 octets

id='%s@'%id  ;print id[22:];

Essayez-le en ligne! . Vous pouvez également essayer les 2ème et 3ème itérations

Barre
la source
Euh ... caractère, pas de chaîne.
user202729
@ user202729 merci pour le heads up, fixe =]
Rod
13

Python 2 , 22 octets

i=0;i+=1; i
print'*'*i

Essayez-le en ligne!

Doublé:

i=0;i+=1; ii=0;i+=1; i
print'*'*i
print'*'*i

Notez que la seconde moitié commence par un caractère de nouvelle ligne.

Xnor
la source
9

C (gcc) , 170 168 96 80 72 70 octets

Version beaucoup plus courte. J'espère toujours pouvoir trouver une solution sans préprocesseur.

i;main(n){for(;i++<n;)printf
#if 0

#endif
(" %*c",n=__LINE__/4, 10);}

Essayez-le en ligne!

Ancienne version de 168 octets:

#ifndef A
#define A p(c){putchar(c);}j,n;main(i){for(
#else
#define A n++,
#endif
A



#ifndef B
#define B i=++n;i--;p(10))for(j=n;j--;)p(64);}
#else
#define B
#endif
B

Essayez-le en ligne!

gastropner
la source
@ user202729 ah, oui. Je pensais avoir corrigé une faute de frappe mais introduit un bug. Revenant.
gastropner
8

Python 2 , 30 octets

False+=1      ;print'*'*False;

Essayez-le en ligne! , 2ème et 3ème itération

Cela tient compte du fait que les bools en Python sont essentiellement des noms Falseet qu'ils Trueont été réaffectés dans Python 2.

Python 1 , 32 octets

exit=exit+'*'  ;print exit[30:];

Essayez-le en ligne! , 2ème et 3ème itération

En Python 1 , les chaînes de BUILTIN exitet quitexiste pour informer l'utilisateur du shell interactif comment sortir il. La valeur par défaut est "Use Ctrl-D (i.e. EOF) to exit.".

ovs
la source
1
J'allais suggérer n=False+=1;print'*'*n;, mais j'oublie toujours que ce n'est pas une fonctionnalité Python ...
ETHproductions
6

Charbon de bois , 6 octets

⊞υωLυ⸿

Essayez-le en ligne! Explication:

  ω     Predefined empty string (any variable would do here)
 υ      Predefined initially empty list
⊞       Push

υ se termine avec une longueur du nombre de répétitions.

    υ   List
   L    Length
        Implicitly print as a row of `-`s
     ⸿  Move to start of next line
Neil
la source
6

Haskell , 68 octets

let s@(z:n)="0\n"in case lines<$>[]of(h:t):_->(h:h:t)>>(z:h++n);_->s

Essayez-le en ligne une fois , deux fois ou trois fois .

En raison de la paresse de Haskell, une expression comme celle ci-dessus compte comme une fonction qui ne prend aucun argument, comme dans cette question Meta .

Laikoni
la source
5

Brain-Flak , 74 octets

(((((()()()){}){}){}){})((()()()()()<>){})<>([]){({}[()]<(({})<>)<>>)}{}<>

Essayez-le en ligne!

Essayez-le doublé et triplé .

Explication

(((((()()()){}){}){}){}) # push 48 ("0") onto first stack
((()()()()()<>){})       # push 10 (\n) onto second stack
<>([]){({}[()]<          # a number of times equal to the height of the first stack:
  (({})<>)<>             #   copy the top of the first stack to the second stack
>)}{}<>                  # cleanup and return to second stack

Le point de rupture se trouve au milieu de la <>section "push 10". Casser cela laissera un 5 sur la troisième pile jusqu’à ce que nous atteignions la seconde moitié correspondante, après quoi appuyer sur 10 reprendra là où il s’était arrêté.

Bien qu’il soit possible de transmettre une valeur ASCII imprimable (espace) sur 22 octets, la centrale <>sera exécutée après le transfert 5. En ajoutant deux octets supplémentaires, j'ai pu déplacer le tout de <>manière à ce que toute la progression vers le transfert 10soit sur la troisième pile. En prime, cela a également rendu le carré résultant plus esthétique.

Nitrodon
la source
4

tinylisp , 112 octets

(load library) (d N((q((x)(i x(inc x)1)))(v(h(t(t(h(t(q())))))))))(join(repeat-val(string(repeat-val 42 N))N)nl)

Essayez-le en ligne! Aussi doublé et quintuple .

L'approche "Construire une chaîne dans la première moitié, l'imprimer dans la seconde moitié" que beaucoup de langues utilisent ne fonctionnera pas dans tinylisp, car il n'y a pas de variables mutables. Au lieu de cela, nous faisons une imbrication sérieuse de code.

Lorsqu'une deuxième copie du code est insérée, elle est placée à l'intérieur du (q()), ce qui l'enveloppe dans une liste. Puis (h(t(t(h(t(...))))))percer dans cette liste à la partie suivante (d N. (v(...))l'évalue; puis nous le passons à la fonction non nommée (q((x)(i x(inc x)1))), qui incrémente la valeur résultante s'il s'agit d'un nombre et renvoie 1 si c'est la liste vide. Le résultat final de la version imbriquée la plus externe du code est attribué à N. En substance, nous avons mis en place une étrange sorte de récursivité qui compte le nombre de niveaux de nidification.

La seconde moitié du code crée ensuite une chaîne d' Nastérisques, puis une liste de Ntelles chaînes, puis rejoint la liste sur les nouvelles lignes. Le résultat est affiché avec une nouvelle ligne de fin.

DLosc
la source
3

R , 44 octets

F=F+1;T=TRUE*TRUE+12;
write(strrep(1,F),"");

Essayez-le en ligne!

Imprime avec une nouvelle ligne. Le T=TRUE*TRUE+12est juste pour couvrir la longueur.

Essayez-le doublé et essayez-le triplé .

Giuseppe
la source
Vous pouvez éliminer 2 octets en supprimant les points-virgules. Je suppose qu'il y a un espace à la fin de la première ligne que vous pouvez remplacer par un #: F=F+1;T=TRUE*TRUE+12#<newline>write(strrep(1,F),"")
Andreï Kostyrka le
@ AndreïKostyrka, ce serait 43 octets, ce qui n’est malheureusement même pas le cas.
Giuseppe
3

Julia 0.6 , 29 octets

Toutes mes idées étaient plus longues que l’adaptation de la solution python intelligente de xnor.

i=0;i+=1;    i
println("0"^i)

Devient

i=0;i+=1;    ii=0;i+=1;    i
println("0"^i)
println("0"^i)

Essayez-le en ligne!

gggg
la source
3

SNOBOL4 (CSNOBOL4) , 130 à 68 octets

Maintenant sans commentaires! Voir l' historique d'édition pour une explication de l'ancien algorithme.

	X =X + 1
	A =ARRAY(X,DUPL(1,X));
I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

Essayez-le en ligne!

Essayez-le doublé et triplé

Explication:

	X =X + 1		;* increment X
	A =ARRAY(X,DUPL(1,X));	;* create an x-length array with 1 repeated x times for each element
I	I =I + 1		;* for i < x
	OUTPUT =A<I>	:S(I)	;* output a[i]
END

Parce qu'une ENDétiquette est requise et que tout ce qui suit la première ENDest ignoré, nous avons deux avantages pour ce défi:

  • les opérations dans la première moitié du programme sont répétées plusieurs Xfois pour les Xrépétitions
  • il n’existera (à l’interprète) qu’une copie de la seconde moitié, étiquettes comprises .

Cela suggère que nous utilisons la répétition pour la première moitié, puis nous pouvons utiliser une approche d'étiquetage plus "conventionnelle" pour répéter les Xtemps de sortie .

La première moitié est

	X =X + 1
	A =ARRAY(X,DUPL(1,X));

qui, lorsqu'il est répété, incrémente Xle nombre approprié de fois et crée un ARRAY Aavec des indices de 1à Xet où chaque élément de Aest la chaîne 1répétée plusieurs Xfois.

Alors peu importe combien de fois le programme est répété, l'interprète ne voit que:

I	I =I + 1
	OUTPUT =A<I>	:S(I)
END

Il s'agit d'un programme SNOBOL typique qui imprime les éléments Aun à la fois jusqu'à ce que l'index sorte des limites, puis termine le programme.

;est un terminateur de ligne facultatif habituellement réservé à une ligne EVALou à des CODEinstructions qui ramènent parfaitement le nombre d'octets à 68 et marque le point milieu, permettant ainsi l'ajout du code.

Giuseppe
la source
1

Zsh , 10 octets

s+=0
<<<$s

Essayez une suite de tests complète en ligne!

... ouais, c'est un peu mieux. Ajoutez à la chaîne N fois, puis imprimez N fois. Il s'avère que ça <<<foo<<<foofonctionne très bien.


Zsh , 64 octets

Caractère utilisé: (espace).

f(){printf '%*s\n' $1}
:<<'E'

E
repeat $[i=LINENO/3];f $i
exit

Essayez une suite de tests complète en ligne!

Le milieu se situe entre la deuxième Eet la nouvelle ligne qui le suit. Un heredoc se termine quand il y a une Eligne seule, ce qui se produit au milieu du code.

GammaFunction
la source
lol @ "légère" amélioration. pourrait aussi exprimer commes+=0;<<<$s
roblogic