Écriture d'escalier

35

Ecrivez un programme ou une fonction qui produira une chaîne donnée en escalier, en écrivant chaque partie d'un mot commençant par une voyelle une ligne au-dessous de la partie précédente.

Par exemple:

Input: Programming Puzzles and Code Golf


Output: Pr          P           C    G
          ogr        uzzl   and  od   olf
             amm         es        e
                ing

Contribution

Une chaîne ne contenant que des lettres et des espaces.

La chaîne peut être passée via STDINou des arguments de fonction ou tout équivalent.

Les lettres peuvent être minuscules ou majuscules.

Les entrées sont toujours supposées suivre ces règles, vous n'avez pas besoin de vérifier les entrées incorrectes.

Sortie

Chaque fois qu'une voyelle (qui est, a, e, i, o, uou y) se rencontre en un mot, vous devez sortir le reste du mot sur la ligne suivante (la voyelle rencontrée inclus), à la position horizontale correcte. Cette règle est récursive, ce qui signifie que s'il y a n voyelles, le mot sera écrit sur n + 1 lignes.

  • La voyelle doit être écrite au début de la ligne suivante et non à la fin de la ligne précédente quand on en rencontre une.

  • Chaque mot commence sur la première ligne et doit donc être formaté indépendamment des autres mots. Deux mots sont séparés par un espace.

  • Si un mot commence par une voyelle, vous devez l'écrire à partir de la deuxième ligne.

Cas de test

  • Contribution: Programming Puzzles and Code Golf

Sortie:

Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing
  • Contribution: The quick brown fox jumps over the lazy dog

Sortie:

Th  q     br    f   j          th  l    d
  e  u      own  ox  umps ov     e  az   og
      ick                   er        y
  • Contribution: aeiouy

Sortie:

 
a
 e
  i
   o
    u
     y
  • Contribution: YEAh UppErcAsE VOwEls

Sortie:

               V
Y    Upp        Ow
 E      Erc       Els
  Ah       As  
             E
  • Contribution: If you only knew the power of the Dark Side

Sortie:

            kn   th  p        th  D    S
If y   onl    ew   e  ow   of   e  ark  id
    o     y             er                e
     u

Notation

C'est du , donc le code le plus court gagne.

Fataliser
la source
Le troisième exemple de sortie semble incompatible avec la règle "Si un mot commence par une voyelle, vous devez l'écrire à partir de la deuxième ligne".
JohnE
1
Y est Y une voyelle?
Optimiseur
1
@JohnE en effet c'était, je l'ai réparé. Merci.
Fataliser
2
The vowel should be written at the beginning of the next line, and not at the end of the previous line when one is encountered.Après réflexion, je comprends que cela signifie que le passage à la ligne suivante doit avoir lieu avant que la voyelle ne soit imprimée, mais pas après, mais cela vaut peut-être la peine d’énoncer cela d’une manière tout à fait compréhensible - cela m’a pris un certain temps.
Trichoplax
3
Le retour à la ligne / les espaces sont-ils autorisés?
Loovjo

Réponses:

18

Retina , 50 44 34 (+10) 32 30 octets

Merci à Dennis d’avoir enregistré 14 octets en utilisant les caractères de contrôle réels.

i`[aeiouy]
<VT>$0#
+`#(\S*)
$1<ESC>[A

Sur la base de cette réponse , j'utilise des codes d'échappement ANSI pour déplacer le curseur du terminal verticalement. Le <ESC>doit être remplacé par le caractère de contrôle 0x1B et <VT>par la tabulation verticale 0x0B. Pour des tests plus simples, vous pouvez également remplacer <ESC>par \e, <VT>avec \vet alimenter la sortie printf.

Pour le comptage, chaque ligne est placée dans un fichier séparé. Cependant, pour des raisons pratiques, il est plus simple de coller le code dans un fichier unique et d’appeler Retina avec l’ -soption.

Le premier remplacement entoure chaque voyelle dans \v...#, où le \vcurseur est déplacé vers le bas et le #est un marqueur pour la deuxième étape. La i`est la notation de Retina pour la correspondance insensible à la casse.

Ensuite, la deuxième étape ( +`) supprime a #de manière répétée a d'un mot et place un a e\[Aà la fin du mot qui déplace le curseur vers le haut. Cela s'arrête une fois que la chaîne cesse de changer, c'est-à-dire qu'il n'y a plus de #marqueurs dans la chaîne.

Martin Ender
la source
Tu n'as pas besoin printf. Il suffit de remplacer \epar l'octet ESC (0x1b).
Dennis
@ Dennis Oh, c'est beaucoup mieux, merci.
Martin Ender
1
C'est vraiment génial !!!
kirbyfan64sos
Cette réponse est la raison pour laquelle personne ne prend Retina au sérieux;)
Christopher Wirt
@ChristopherWirt S'il vous plaît élaborer :) (Bien que je serais vraiment terrifié si quelqu'un prenait Retina au sérieux.)
Martin Ender
8

CJam, 39 36 octets

0000000: 6c 7b 5f 65 6c 22 61 65 69 6f 75 79 22  l{_el"aeiouy"
000000d: 26 7b 22 1b 5b 41 22 27 0b 6f 5c 7d 26  &{".[A"'.o\}&
000001a: 5f 53 26 7b 5d 7d 26 6f 7d 2f           _S&{]}&o}/

Ce qui précède est un vidage xxd réversible, car le code source contient le caractère non imprimable VT (point de code 0x0b) et ESC (point de code 0x1b).

Comme cette réponse , il utilise des tabulations verticales et des séquences d'échappement ANSI .

Cela nécessite un terminal vidéo texte compatible, qui inclut la plupart des émulateurs de terminal non Windows.

Essai

Avant d'exécuter le code actuel, nous allons désactiver l'invite et effacer l'écran.

$ PS1save="$PS1"
$ unset PS1
$ clear

Cela garantit que la sortie est affichée correctement.

echo -n Programming Puzzles and Code Golf | cjam <(xxd -ps -r <<< 6c7b5f656c226165696f757922267b221b5b4122270b6f5c7d265f53267b5d7d266f7d2f)
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing

Pour restaurer l'invite, exécutez ceci:

PS1="$PS1save"

Comment ça marche

Nous insérons une tabulation verticale avant chaque voyelle pour déplacer le curseur vers le bas et suffisamment de copies de la séquence d'octets 1b 5b 41 ( "\e[A") après chaque espace pour ramener le curseur sur la première ligne.

l           e# Read a line from STDIN.
{           e# For each character C:
  _el       e#   Push lowercase(C).
  "aeiouy"& e#   Intersect with "aeiouy".
  {         e#   If the intersection is non-empty:
    ".[A"   e#     Push "\e[A" (will be printed later).
    '.o     e#     Print "\v".
    \       e#     Swap "\e[A" with C.
  }&        e#
  _S&       e#   Intersect C with " ".
  {         e#   If the intersection is non-empty:
    ]       e#     Wrap the entire stack in an array.
  }&
  o         e#   Print C or the entire stack.
}/          e#
Dennis
la source
N'oubliez pas unset PS1saveaprès.
usandfriends
5

Java, 428 octets

void s(String s){int l=s.length(),m=0;char[][]c=new char[l][];for(int i=0;i<c.length;java.util.Arrays.fill(c[i++],' '))c[i]=new char[l];String v="aeiouyAEIOUY";String[]a=s.split(" ");for(int r=0,p=0;r<a.length;r++){String u=a[r]+" ";int o=v.indexOf(u.charAt(0))>=0?1:0,x=p;for(;x<u.length()-1+p;o+=v.indexOf(u.charAt(x++-~-p))>=0?1:0)c[o][x]=u.charAt(x-p);p+=u.length();m=m<o?o:m;}for(int i=0;i<=m;i++)System.out.println(c[i]);}

Je sais, c'est horrible. Il y a probablement des personnages dont on peut se débarrasser, mais je suis trop paresseux pour le faire.

Loovjo
la source
Vous pouvez probablement déclarer plusieurs de vos intvariables ( à savoir i, r, p, oet x) où vous initialisez let mcar ils vont donner des valeurs plus tard. Vous pouvez également faire String v="...",a[]=...;et faire comme ci-dessus pour String u. Cela devrait réduire votre score un peu.
TNT
J'aime lax++-~-p
Ypnypn
4

Perl, 31 octets

0000000: 24 5c 3d 22 1b 5b 41 22 78 20 73 2f 5b 61  $\=".[A"x s/[a
000000e: 65 69 6f 75 79 5d 2f 0b 24 26 2f 67 69     eiouy]/.$&/gi

Ce qui précède est un vidage xxd réversible, car le code source contient le caractère non imprimable VT (point de code 0x0b) et ESC (point de code 0x1b).

Le code a une longueur de 27 octets et nécessite les commutateurs 040p(4 octets).

Le programme nécessite un terminal vidéo texte prenant en charge les onglets verticaux et les séquences d'échappement ANSI , qui inclut la plupart des émulateurs de terminal non Windows.

Essai

Avant d'exécuter le code actuel, nous allons désactiver l'invite et effacer l'écran.

$ PS1save="$PS1"
$ unset PS1
$ clear

Cela garantit que la sortie est affichée correctement.

echo -n Programming Puzzles and Code Golf | perl -040pe "$(xxd -ps -r <<< 245c3d221b5b41227820732f5b6165696f75795d2f0b24262f6769)"
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e 
        ing

Pour restaurer l'invite, exécutez ceci:

PS1="$PS1save"

Comment ça marche

  • perl -040plit automatiquement l'entrée sous forme de tokens ( -040) séparés par des espaces , enregistre chaque jeton dans $_( -p) et exécute le programme.

  • s/[aeiouy]/.$&/gieffectue une recherche globale et insensible à la casse $_des voyelles et remplace chaque voyelle par le caractère de contrôle VT (déplace le curseur vers le bas), suivi de la voyelle elle-même.

  • srenvoie le nombre de remplacements effectués, $\=".[A"x s...enregistre donc plusieurs copies de la séquence d'octets 1b 5b 41 (déplace le curseur vers le haut) $\, une pour chaque voyelle.

  • À la fin du programme, Perl imprime automatiquement à "$_$\"cause du -pcommutateur.

Dennis
la source
4

C, 200 190 octets

i,j,k,l,M;f(char*s){M=strlen(s)+1;char t[M*M];for(;i<M*M;++i)t[i]=(i+1)%M?32:10;for(i=0;i<M-1;++i)k=(strspn(s+i,"aeiouyAEIOUY")?++j:s[i]==32?j=0:j)*M+i,l<k?l=k:0,t[k]=s[i];t[l+1]=0;puts(t);}

Ungolfed:

i,j,k,l,M;
f(char *s){
    M = strlen(s)+1;
    char t[M*M];
    for(; i<M*M; ++i) t[i] = (i+1)%M ? 32 : 10;
    for(i=0; i<M-1; ++i)
        k = (strspn(s+i,"aeiouyAEIOUY") ? ++j : s[i]==32 ? j=0 : j) * M + i,
        l<k ? l=k : 0,
        t[k] = s[i];
    t[l+1]=0;
    puts(t);
}

Il alloue un tampon rectangulaire (en fait un carré), le remplit d'espaces et de nouvelles lignes, puis traverse la chaîne donnée. À la fin, il ajoute un caractère nul pour éviter les retours à la ligne.

Techniquement, ce n'est pas une fonction puisqu'elle contient des globaux; en fait, il ne peut pas être appelé plus d'une fois ( jet ldoit être 0 au début). Pour se conformer, i,j,k,l,M;peut être déplacé vers int i,j=0,k,l=0,M;au début de la fonction.

jcai
la source
char*t=malloc(M*M);-> char t[M*M];et for(i=0;i<M*M;++i)->for(;i<M*M;++i)
Spikatrix le
Bonnes prises, éditées.
jcai
N'est-ce pas seulement dû à C99 char t[M*M]?
Zacharý
4

CJam, 47 ans

Oui, c'est un peu long, mais ce n'est pas "tricher" avec les codes ANSI :)

q_{_S&!\el"aeiouy"-!U+*:U}%_0|$])\zff{~@-S@?}N*

Essayez-le en ligne

L'idée est de calculer un numéro de ligne pour chaque caractère (en commençant à 0, en incrémentant les voyelles et en revenant à 0 en espace), puis pour chaque ligne, répétez la chaîne en remplaçant les caractères qui ont un numéro de ligne différent par un espace. .

Aditsu
la source
3

K, 81 72 70 66 octets

Eh bien, c'est un début:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x}

Exemples d'utilisation:

  `0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x} "Programming Puzzles and Code Golf"
Pr          P           C    G   
  ogr        uzzl   and  od   olf
     amm         es        e     
        ing                      
  `0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x} "YEAh UppErcAsE VOwEls"
               V     
Y    Upp        Ow   
 E      Erc       Els
  Ah       As        
             E       

Modifier 1:

Mieux. Quelques améliorations au niveau de la surface:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/{+\{12>"aeiouyAEIOUY"?x}'x}'(0,&~{"  "?x}'x)_ x}
`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}

J'ai notamment inversé les arguments en faveur de ?la recherche de voyelles et éliminé ainsi le besoin d'un lambda, effectué la même inversion que _lorsque je divisais les mots sur des espaces, et je me suis rendu compte que ~{" "?x}'xc'était une façon de dire vraiment stupide et trop compliquée " "=x.

Edit 2:

Une autre modification de niveau de surface - savant de l’appliquer sur le lambda, en économisant les parens à l’intérieur:

`0:{+{(-z)!y,x#" "}[|/s].'x,'s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}
`0:{+{z!y,x#" "}[|/s].'x,'-s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}

Edit 3:

OK, adoptons une approche différente pour calculer le décalage pour chaque caractère. Au lieu de scinder la séquence au niveau des espaces et de calculer une somme courante ( +\) des positions des voyelles, nous pouvons agir sur la chaîne en entrée entière en un seul passage, en multipliant la somme courante par 0 chaque fois que nous rencontrons un espace. J'ai besoin de la négation de cette séquence pour pouvoir soustraire au lieu d'ajouter et numériser et utiliser number-of-distinct ( #?) au lieu de max ( |/) lorsque je calcule la quantité de remplissage vertical.

`0:{+{z!y,x#" "}[|/s].'x,'-s:,/(+\12>?["aeiouyAEIOUY"]')'_[0,&" "=x]x}
`0:{+{z!y,x#" "}[#?s].'x,'s:1_0{(~" "=y)*x-12>"aeiouyAEIOUY"?y}\x}

Cela sauve 4 autres personnages. Phew!

JohnE
la source
2

Ruby: 135 131 124 115 112 caractères

a=[]
y=l=0
gets.split(r=/(?=[aeiouy ])/i).map{|w|w=~r&&y+=1
w<?A&&y=0
a[y]='%*s%s'%[-l,a[y],w]
l+=w.size}
puts a

Échantillon échantillon:

bash-4.3$ ruby staircase.rb <<< 'Programming Puzzles and Code Golf'
Pr          P           C    G
  ogr        uzzl   and  od   olf
     amm         es        e
        ing
homme au travail
la source
Si je ne me trompe pas, vous pouvez raccourcir votre regex à /(?=[aeiouy ])/i.
Alex A.
Ah, tu as raison @Alexa. L'espace en tant que mot séparé n'était important que pour une théorie antérieure. Merci.
manatwork
2

C, 192 octets

f(char*s){int l=0,r=1,v,c;for(;r;l=1){v=l;r=0;char*p;for(p=s;*p;++p){c=*p;if(c==' ')v=l,putchar(c);else if((strchr("aoeuiyAOEUIY",c)?--v:v)<0)r=1,putchar(' ');else*p=' ',putchar(c);}puts(p);}}

Cela parcourt la chaîne en effaçant les caractères au fur et à mesure qu'il les imprime. Il se répète jusqu'à ce qu'il ne reste plus de caractères autres que des espaces à imprimer. C'est un C portable, ne supposant rien sur l'encodage des caractères.

Version lisible

f(char *s) {
    int l=0,       /* true if we've done the first line (no vowels) */
        r=1,       /* true if characters remain in buffer */
        v,         /* how many vowels to print from current word */
        c;         /* current character value */
    for (l=0; r; l=1) {
        v = l;
        r = 0;
        char *p;
        for (p=s;*p;++p) {
            c=*p;
            if (c==' ') {       /* a space - reset vowel counter */
                v=l;
                putchar(c);
            } else if ((strchr("aoeuiyAOEUIY",c)?--v:v)<0) {
                /* vowel conter exceeded - print a space */
                putchar(' ');
                r=1;
            } else {
                /* print it, and obliterate it from next line of output */
                putchar(c);
                *p=' ';
            }
        }
        puts(p); /* p points at the NUL, so this just prints a newline */
    }
}
Toby Speight
la source
' '-> 32et f(char*s){int l=0,r=1,v,c;->l,r=1,v,c;f(char*s){
Spikatrix
@Cool - ' ' peut- être 32, mais cela dépend de l'encodage des caractères, et comme je l'ai dit, j'ai créé ce lecteur C. portable. Abandonner l'explicite, intc'est génial, mais je ne sais pas pourquoi j'ai oublié ça!
Toby Speight le
2

Python 3, 265 207 202 185 177 caractères

i=input()
w,e=i.split(" "),lambda:[[" "]*len(i)]
o,x=e(),0
for p in w:
    y=0
    for c in p:
        if c in"AEIOUYaeiouy":o+=e();y+=1
        o[y][x],x=c,x+1
    x+=1
for l in o:print("".join(l))

C'est terrible et je ne suis pas fier. Je sais que cela peut être raccourci, mais je pensais publier de toute façon.

Inspiré par la version C, il crée une liste qui est ensuite remplie en traversant la chaîne d'entrée.

InputUsername
la source
2

GNU Sed, 151 + 1

(+1 car il faut le -rdrapeau)

s/^/ /;h;s/[aoeuiy]/_/ig;:a;s/_[^ _]/__/;ta;y/_/ /;g;:x;:b;s/ [^ aoeuiy]/  /i;tb;h;s/([^ ])[aoeuiy]/\1_/ig;:c;s/_[^ _]/__/;tc;y/_/ /;g;s/ [^ ]/  /ig;tx

Je pensais que sed serait l'outil pour ce travail, mais je l'ai trouvé étonnamment difficile.

Version lisible:

#!/bin/sed -rf

# make sure the string starts with a space
s/^/ /
h

# print leading consonants, if any
s/[aoeuiy]/_/ig
:a
s/_[^ _]/__/
ta
y/_/ /
p
g

:x
# strip the consonants just printed
:b
s/ [^ aoeuiy]/  /i
tb
h

s/([^ ])[aoeuiy]/\1_/ig
:c
s/_[^ _]/__/
tc
y/_/ /
p
g
# remove leading vowel of each word
s/ [^ ]/  /ig
tx
Toby Speight
la source
Je crains que cela ne soit 128 caractères. Il manque un dans la version à une ligne p, aussi ne produit-il rien. Un petit problème est que les sorties commencent par un espace supplémentaire. Un gros problème est que ce premier texte commençant par une voyelle disparaisse.
Manatwork
Je suis sûr que cela fonctionnait plus tôt. Je vais regarder et voir ce que j'ai cassé. Merci pour le heads-up, @manatwork!
Toby Speight le
J'avais tort de sauter en boucle c, à cause de la ligne juste avant tx. J'ai rétabli une version antérieure avec sa boucle similaire et j'aurai une autre tentative plus tard.
Toby Speight le
2

Python 2, 145 142 octets

N’est probablement pas aussi compétitif que d’autres méthodes, mais j’ai pensé que c’était une façon amusante d’utiliser regex.

import re;s=I=input()[::-1]+" ";i=0
while s.strip()or i<2:s=re.sub("(?!([^aeiouy ]*[aeiouy]){%s}[^aeiouy]* )."%i," ",I,0,2)[::-1];print s;i+=1

La regex (?!([^aeiouy ]*[aeiouy]){N}[^aeiouy]* ).correspond à n'importe quel caractère ne faisant pas partie du Nième groupe de lettres à partir de la fin d'un mot. Puisqu'il compte depuis la fin du monde, j'inverse la chaîne avant et après, et je dois aussi ajouter un espace à la fin, mais après cela, il devient simple de re.subremplacer toutes les occurrences de ces caractères par un espace. Il le fait pour chaque valeur de N jusqu'à ce que la chaîne soit vide.

KSab
la source
Comme il est agréable à utiliser et lisible re.I, vous pouvez économiser 3 octets en substituant la valeur de drapeau appropriée, c.-à-d 2.
Sp3000
1
@ Sp3000 Seuls dans le code-golf ont des associations négatives avec "agréable et lisible"
KSab
1

Octave, 132 129 caractères

p=1;x=[];y=input(0);for j=1:numel(y);if regexpi(y(j),'[aeiouy]');p+=1;elseif y(j)==" ";p=1;end;x(p,j)=y(j);end;x(x==0)=32;char(x)

Tester

Contribution: "YEAh UppErcAsE VOwEls"

Sortie:

               V     
Y Upp Ow   
 E Erc Els
  Ah comme        
             E       
sudo rm -rf slash
la source
1

Gema : 53 48 caractères

/[aeiouyAEIOUY]/=@append{u;^[[A}^K$1
 = $u@set{u;}

Notez que ^[(x1b) et ^K(x0b) sont des caractères uniques. (Dans l'exemple ci-dessous, j'utilise leurs copieurs-copieurs \eet leurs \véquivalents, au cas où vous souhaiteriez l'essayer.)

Échantillon échantillon:

bash-4.3$ gema '/[aeiouyAEIOUY]/=@append{u;\e[A}\v$1; = $u@set{u;}' <<< 'Programming Puzzles and Code Golf'
Pr          P           C    G    
  ogr        uzzl   and  od   olf 
     amm         es        e 
        ing 
homme au travail
la source
1

Gelée , 42 octets (non compétitif?)

Ḳµe€Øyœṗ⁸⁶ṁ$;¥\z⁶Zµ€µḷ/⁶ṁW⁸;ḣ®µ€L€Ṁ©$¡ZK€Y

Essayez-le en ligne!

Pourquoi gelée, pourquoi? :-(

Erik le golfeur
la source
Plus long que CJam semble bizarre
Fataliser
@Fatalize C'est parce que Jelly ne va tout simplement pas avec des ficelles ... en général. En outre, vous ne pouvez pas vraiment comparer différents paradigmes de programmation (cjam est basé sur une pile, jelly est tacite).
Erik the Outgolfer