Alignement des lignes!

31

Alignement des lignes!

Étant donné un caractère et une chaîne multiligne, votre travail consiste à remplir chaque ligne de la chaîne afin qu'ils s'alignent entre le délimiteur donné.

Exemples

Contribution:

,
Programming, Puzzles
And, Code golf

Sortie:

Programming, Puzzles
        And, Code golf

Contribution

L'entrée sera une chaîne multiligne et un caractère (sur lequel vous vous alignerez), vous pouvez les prendre dans n'importe quel ordre / format que vous souhaitez. Le caractère apparaîtra exactement une fois par ligne. Chaque ligne de l'entrée peut être de longueur différente.

L'entrée peut se faire via des arguments de fonction ou STDIN.

Sortie

La sortie doit être la même chaîne centrée. Vous avez droit à une nouvelle ligne de fin et aucun espace de fin.

La sortie doit être complétée avec le minimum d'espaces. Vous ne pouvez supprimer aucun espace de tête dans l'entrée (s'il existe).

La sortie peut provenir du retour de fonction ou de STDOUT.

Downgoat
la source
L'entrée dans un programme complet peut-elle provenir d'arguments de ligne de commande, ou est-ce interdit?
DLosc
@DLosc Oui, bien sûr
Downgoat
1. Pour les arguments de fonction / ligne de commande, devrions-nous lire une seule chaîne ou une ligne par argument serait-elle admissible? 2. Faut-il remplir les lignes avec le minimum d'espaces?
Dennis
@Dennis Vous pouvez le prendre en une seule chaîne. Ou une ligne par argument. "vous pouvez les prendre dans l'ordre que vous souhaitez" . Oui, vous devez remplir les lignes avec le minimum d'espaces. Je vais modifier les spécifications
Downgoat
@vihan Les fonctions peuvent-elles prendre une ligne par argument?
xnor

Réponses:

5

Pyth, 18 octets

V.z+*d-eSxRz.zxNzN
orlp
la source
13

APL (37)

APL n'est tout simplement pas très bon pour le traitement des cordes (ou je ne suis pas bon pour le golf, bien sûr).

{⌽∊R,¨' '/⍨¨(⌈/-+)⍺⍳⍨¨⌽¨R←S⊂⍨S=⊃S←⌽⍵}

Cela prend le caractère comme argument de gauche et la chaîne multiligne comme argument de droite. On suppose que la chaîne multiligne se termine par un saut de ligne (par exempleA\nB\nC\n plutôt queA\nB\nC .) Comme je peux utiliser "n'importe quel format [je] le souhaite", et c'est également le format conventionnel pour les fichiers texte, je pense que cela est raisonnable.

Explication:

  • S←⌽⍵: inverser la chaîne et la stocker dans S .
  • R←S⊂⍨S=⊃S: Divisé S sur son premier caractère et stocker le tableau de chaînes dans R.
  • ⍺⍳¨⌽¨R: inverser chaque chaîne dans R , puis recherchez l'index de ⍺ (le caractère) dans chaque chaîne.
  • (⌈/-+): soustrayez chacun des indices du plus grand indice, en donnant le nombre d'espaces nécessaires
  • ' '/⍨¨: pour chacune de ces valeurs, générez autant d'espaces
  • R,¨: ajouter les espaces à chaque chaîne dans R .
  • : joindre toutes les chaînes ensemble
  • : inversez-le (pour récupérer la commande d'origine)

Exemple:

      NL←⎕UCS 10 ⍝ newline
      test←'Programming, Puzzles',NL,'And, Code golf',NL
      test ⍝ test string
Programming, Puzzles                
And, Code golf                      

      ⍝ run the function
      +X←','{⌽∊R,¨' '/⍨¨(⌈/-+)⍺⍳⍨¨⌽¨R←S⊂⍨S=⊃S←⌽⍵}test
Programming, Puzzles                        
        And, Code golf                      

      ⍴X ⍝ result is really a string with newlines, not a matrix
44
marinus
la source
9

CJam, 23 22 20 octets

Merci à Dennis d'avoir économisé 2 octets.

ea_rf#_:e>\fm.{S*\N}

Cela lit les lignes des arguments de ligne de commande et le caractère de STDIN.

L'interpréteur en ligne ne prend pas en charge les arguments de ligne de commande, mais vous pouvez tester une version équivalente ici.

Explication

ea    e# Get the lines from ARGV.
_rf#  e# Duplicate input, read the character and find index of character in each line.
_:e>  e# Duplicate indices and find maximum.
\fm   e# Subtract each index from the maximum index.
.{    e# Apply this block to each pair of line and (max_index - index).
  S*  e#   Get a string with the right amount of spaces.
  \N  e#   Swap spaces with line and push a line feed.
}
Martin Ender
la source
9

Pip , 22 20 18 + 1 = 19 octets

Y_@?qMgsX(MXy)-y.g

Prend des chaînes comme arguments de ligne de commande et délimiteur de STDIN ( idée empruntée à la réponse CJam de Martin ). Utilise l' -nindicateur pour imprimer les valeurs de sortie sur des lignes distinctes.

                    g is list of cmdline args; s is space (implicit)
    q               Read the delimiter from stdin
 _@?                Construct a lambda function that takes a string and returns
                       the index of the delimiter in it
     Mg             Map that function to each remaining item in g
Y                   Yank the resulting list of indices into the variable y

         (MXy)-y    Take the max of y minus each element in y
       sX           Space, repeated that many times...
                .g  ... concatenated to each item in g
                    Print, newline-separated (implicit, -n flag)

Et un exemple de course:

C:\Users\dlosc> pip.py -ne Y_@?qMgsX(MXy)-y.g "Programming, Puzzles" "And, Code golf"
,
Programming, Puzzles
        And, Code golf
DLosc
la source
7

JavaScript ES 2015, 113 octets

f=(c,s)=>s.split`
`.map((e,_,a)=>' '.repeat(a.map(j=>j.indexOf(c)).reduce((g,h)=>g>h?g:h)-e.indexOf(c))+e).join`
`

Pas aussi court que les langues de golf publiées jusqu'à présent. Prend l'entrée comme deux arguments de fonction, par exemple f(',','Programming, Puzzles\nAnd, Code golf'). L'extrait ci-dessous n'est pas golfé et comprend une méthode facile à tester.

f=function(c,s){
  return s
    .split('\n')
    .map(function(e,_,a){
      return ' '.repeat(
        a.map(function(f){
          return f.indexOf(c)
        }).reduce(function(g,h){
          return g>h?g:h
        })-e.indexOf(c)
      )+e
    })
    .join('\n')
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('char').value,document.getElementById('string').value)};document.getElementById('run').onclick=run;run()
<label>Character: <input type="text" id="char" value="," maxlength="1" /></label>
<textarea id="string" rows="4" cols="30" style="display:block">
Programming, Puzzles
And, Code Golf</textarea><button id="run">Run</button><br />
<pre id="output"></pre>

NinjaBearMonkey
la source
6

Pyth, 27 24 octets

V.z+.[deSmxdz.z<NJxNz>NJ

Mis à jour pour le dernier Pyth .

Démo en direct.

Version 27 octets

jbm+.[eSmxkz.z<dJxdz\ >dJ.z

Démo en direct.

kirbyfan64sos
la source
Chaque fois que vous voyez jbmau début de votre réponse, vous devriez immédiatement commencer à y penser V.
orlp
Ou supprimez simplement leb
Jakube
5

Julia, 117 octets

f(c,t)=(s=[split(l,c)for l=split(t,"\n")];join(map(i->lpad(i[1],maximum(map(i->length(i[1]),s))," ")*c*i[2],s),"\n"))

Ungolfed:

function f(c::String, t::String)
    # Create an array of arrays by splitting on newlines and
    # then on the given delimiter
    s = [split(l, c) for l in split(t, "\n")]

    # Find the maximum length on the left side of the delimiter
    m = maximum(map(i -> length(i[1]), s))

    # Rejoin on the delimiter and pad each line with spaces,
    # and rejoin this with newlines
    join(map(i -> lpad(i[1], m, " ") * d * i[2], s), "\n")
end
Alex A.
la source
5

Python 3, 85 (IDLE 3.2.2, Windows)

c,*s=input().split('\n')
for x in s:print(' '*(max(z.find(c)for z in s)-x.find(c))+x)

Assez simple. Cela trouve la position du caractère dans la chaîne deux fois: une fois pour trouver le max (enfin, une fois par ligne), et une fois pour trouver le décalage. J'ai essayé de les combiner mais c'était plus long.

Python 3 est utilisé pour le déballage d'entrée. MON IDLE semble prendre en entrée des chaînes multilignes.

Xnor
la source
@DLosc Fonctionne pour moi dans le collage IDLE dans une chaîne multiligne.
2015
Hmm. Lorsque je fais cela (IDLE 3.3.4, Windows 7), cobtient le délimiteur et sobtient une liste vide. Appels ultérieurs pour input()renvoyer les lignes restantes une par une.
DLosc
@DLosc Strange. Je copie-colle la chaîne directement depuis mon navigateur dans l'invite de veille. Faites-vous de même? IDLE 3.2.2, Windows 7 au cas où cela compte.
xnor
Même. Voici une capture d'écran ...
DLosc
@DLosc fonctionne toujours pour moi ( capture d'écran ). Bien que je ne comprenne pas ce qui se passe, je vais dire que c'est un comportement spécifique au compilateur ou à l'environnement , et j'ai édité pour essayer de spécifier les informations pertinentes. La version de la fonction est plus longue de 3 caractères en Python 2.
xnor
3

Gelée , 12 octets

Ỵ©w€µạṀ⁶ẋż®Y

Essayez-le en ligne!

Fait et joué au golf avec caird coinheringaahing à J elly H yper T raining (JHT) , notre salle de chat d'entraînement Jelly.

Comment ça marche

Le troisième argument de ligne de commande (première entrée) doit être la chaîne multiligne et le caractère doit être le quatrième argument de ligne de commande (deuxième entrée).

Ỵ © w € µạṀ⁶ẋż®Y ~ Programme complet.

Ỵ ~ Divisez la chaîne par des sauts de ligne.
 © ~ Copiez le résultat dans le registre.
  w € ~ Récupère l'index de la première occurrence du caractère sur chaque ligne.
      Ṁ ~ Prenez le maximum.
    µạ ~ Et soustrayez-le de chaque indice, en prenant la valeur absolue.
       ⁶ẋ ~ Répétez un espace plusieurs fois (vectorise).
         ż® ~ Entrelacer avec ce qui était stocké dans le registre.
           Y ~ Rejoignez par des nouvelles lignes et imprimez implicitement.

Je ne sais pas si la prise d'entrée en tant que liste de lignes est autorisée, donc cela prend une chaîne multiligne en entrée. Si cela était autorisé:

10 octets

w€µạṀ⁶ẋż³Y

Essayez-le en ligne!

M. Xcoder
la source
1
c'est là que vous savez que vous avez créé une salle réussie
Erik the Outgolfer
2

Matlab / Octave, 106 octets

Fonction qui utilise trois arguments distincts pour caractère, chaîne, chaîne; et donne un résultat en sortie standard:

function f(c,s,t)
p=find(s==c)-find(t==c);disp([repmat(32,1,max(-p,0)) s]),disp([repmat(32,1,max(p,0)) t])

Exemple dans Matlab:

>> f(',', 'Programming, Puzzles', 'And, Code golf')
Programming, Puzzles
        And, Code golf

Ou essayez-le en ligne avec l'interprète Octave.

Luis Mendo
la source
2

Julia, 80 octets

f(c,s)=(t=split(s,'
');u=[search(i,c)for i=t];join([" "].^(maxabs(u)-u).*t,'
'))

Ungolfed:

function f(c,s)
  # converts multiline string to array of single-line strings
  t=split(s,'\n')

  # creates array of positions of delimiter
  u=[search(i,c)for i=t]

  # Appends appropriate number of spaces to each line
  # (uses elementwise operations to achieve this result)
  v=[" "].^(maxabs(u)-u).*t

  # Recombines array of strings to multiline string and returns
  return join(v,'\n')
end
Glen O
la source
2

JavaScript (ES6), 105

En utilisant des chaînes de modèle, les 2 nouvelles lignes sont significatives et comptées.

Testez l'exécution de l'extrait dans n'importe quel navigateur compatible EcmaScript 6 (c'est-à-dire FireFox. Chrome ne prend pas en charge les paramètres par défaut)

f=(s,c,p=(s=s.split`
`).map(r=>m<(v=r.indexOf(c))?m=v:v,m=0))=>s.map((r,i)=>' '.repeat(m-p[i])+r).join`
`

// Ungolfed
f=(s,c)=>{
  s=s.split('\n')
  p=s.map(r=>r.indexOf(c))
  m=Math.max(...p)
  s=s.map((r,i)=>' '.repeat(m-p[i])+r)
  return s.join('\n')
}  

// TEST
out=x=>O.innerHTML+=x+'\n'

out(f(`Programming, Puzzles
And, Code golf`,','))
<pre id=O></pre>

edc65
la source
2

Python 2, 93 octets

def f(x,y,z):
 p=y.index(x)-z.index(x)
 if p<0:y=" "*abs(p)+y
 else:z=" "*p+z
 print y+'\n'+z

Appelé ainsi:

f(',','Programming, Puzzles','And, Code Golf')
Alpha Decay
la source
2

C # 4.0, 329 320 307 octets

using System;class P{static void Main(){Func<char,dynamic>f=(d)=>Console.ReadLine().Split(d);var c=f(' ')[0][0];var m=0;var l=new string[9999][];var z=0;for (l[z]=f(c);l[z].Length==2;l[z]=f(c)){m=Math.Max(l[z][0].Length,m);z++;}for(var i=0;i<z;i++){Console.WriteLine("{0,"+m+"}"+c+"{1}",l[i][0],l[i][1]);}}}

Version non golfée:

using System;
class P
{
    static void Main()
    {
        // lamba to to read a line and split on a char, returns an array of 
        Func<char,dynamic>f=(d)=>Console.ReadLine().Split(d); 
        // read the separator char by taking the first char of the first string 
        // in the array
        // use our lambda
        var c=f(' ')[0][0];
        var m=0; // max position where char is found
        var l=new string[9999][]; // hold all input
        var z=0; // count valid entries in l
        // loop until the input doesn't contain an
        // array with 2 elements
        // here we use our lambda agian, twice
        for (l[z]= f(c);l[z].Length==2;l[z] = f(c))
        {
            // calculate max, based on length 
            // of first element from the string array
            m=Math.Max(l[z][0].Length,m);
            z++; // increase valid items
        }
        // loop over all valid items
        for(var i=0;i<z;i++)
        {
        // use composite formatting with the padding option
        // use the max to create a format string, when max =4 
        // and seperator char is , this will give
        // "{0,4},{1}"
            Console.WriteLine("{0,"+ m +"}"+c+"{1}",l[i][0],l[i][1]);
        }
    }
}

Il accepte un maximum de 9999 lignes ...

rene
la source
2

Dyalog APL , 22 20 16 octets

-4 grâce à ngn.

APL n'est en fait pas si mauvais au niveau du traitement des chaînes, s'il est autorisé à travailler avec des tableaux. Dans ce défi, nous pouvons choisir le format le plus approprié, qui pour APL signifie un vecteur de vecteurs de texte comme argument gauche, et le délimiteur comme argument scalaire droit. Cela gère même plusieurs délimiteurs par ligne et aligne le premier de chaque ligne.

⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨

⊣,¨⍨ ajouter à chaque ligne

' '⍴¨⍨ autant d'espaces que

⌈.⍳ l'index le plus à droite du caractère parmi les lignes

- moins

⍳¨ l'index du caractère dans chaque ligne

Essayez APL en ligne! ( ajouté pour imprimer la sortie verticalement)

Prime? Fonctionne pour n'importe quel nombre de chaînes et délimiteurs (aligne par l'extrême gauche).

Adam
la source
⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨
ngn
Oui bien sûr.
Adám
1

C #, 191

En tant que fonction. En gros un portage de ma réponse JS.

using System.Linq;string f(string s,char c){var q=s.Split('\n');int m=0,v;Array.ForEach(q,x=>m=m<(v=x.IndexOf(c))?v:m);return String.Join("\n",q.Select(x=>new String(' ',m-x.IndexOf(c))+x));}
edc65
la source
1

Rubis, 74 octets

l=lambda{|d,s|s.each{|e|puts ' '*(s.map{|f|f.index(d)}.max-e.index(d))+e}}

et l'appelle comme

l.call ',',['Programming, Puzzles','And, Code golf']
golgappa
la source
1

R, 68 octets

function(c,x,y,r=regexpr)cat(x,"\n",rep(" ",r(c,x)-r(c,y)),y,sep="")

Fonction sans nom qui accepte les 3entrées; cqui est le caractère à aligner, xest la première chaîne et yla deuxième chaîne.

Dans R, la fonction regexprrenvoie la position d'un motif donné dans une chaîne. La solution fonctionne en appliquant regexprsur les deux chaînes et en répétant les espaces blancs correspondant à la différence, puis en imprimant simplement les deux entrées séparées par une nouvelle ligne.

Billywob
la source
0

Python 2, 67 66 octets

def a(d,l):
 i=l[0].index(d)
 for e in l:print' '*(i-e.index(d))+e

Appelé avec:

a(',', ['Programming, Puzzles', 'And, Code golf'])
Celeo
la source
0

Moonscript, 138 octets

(n)=>
 i=0
 @='
'..@
 l=[b-a for a,b in @gmatch "
().-()"..n]
 m=math.max unpack l
 (@gsub '
',(a)->
  i=i+1
  a..(' ')\rep m-l[i])\sub(2)

Cela renvoie une fonction qui prend 2 arguments. Le premier est la chaîne, le second est le caractère sur lequel s'aligner. Ces arguments sont l'argument implicite @ et n.

Tout d'abord, j'ajoute une nouvelle ligne à la chaîne, pour faciliter le traitement.

@='
'..@

Maintenant, je génère une liste des positions de chaque caractère d'alignement, en utilisant gmatch . Ensuite, je remplace la nouvelle ligne avant chaque ligne par le nombre correct d'espaces, puis je coupe la nouvelle ligne que j'ai ajoutée au début.

Ryan Russell
la source
0

Lua, 169 octets

function a(d,t)m={}for k,v in pairs(t)do m[#m+1]=string.find(v,d)end o=math.max(unpack(m))for k,v in pairs(t)do print(string.rep(" ",o-(string.find(v,d)or 0))..v)end end

Pas aussi court que les autres réponses mais c'est ma première: D

Sygmei
la source
0

Rétine , 71 octets

+`^((.)(.*¶)*)((.)*\2.*¶)((?<-5>.)*(?(5)\2|(.)\2).*)
$1$#7$* $4$#5$* $6

Essayez-le en ligne! Remarque: Cela laisse le caractère d'alignement dans la sortie; il peut être supprimé au coût de 4 octets. Si seulement deux chaînes doivent être alignées, alors pour 52 octets:

^(.)¶((.)*\1.*¶)((?<-3>.)*(.)*\1.*)
$#5$* $2$#3$* $4

Explication:

^(.)¶

Cela correspond au caractère d'alignement.

((.)*\1.*¶)

Cela correspond à la première ligne et permet également de suivre le nombre de caractères avant le caractère d'alignement. (.NET conserve une pile de correspondance pour chaque variable, dans ce cas $3,.)

((?<-3>.)*(.)*\1.*)

Cela correspond à la deuxième ligne, en essayant de prendre en compte autant de caractères que nous avons trouvés sur la première ligne. ?<-3>fait que la correspondance éclate la pile pour chaque caractère, jusqu'à ce qu'elle soit vide, à quel point la correspondance échoue, (.)*puis correspond aux caractères restants avant le caractère d'alignement. À ce stade, nous avons les variables suivantes:

  • $1 contient le caractère d'alignement
  • $2 contient la première ligne
  • $3 contient une pile dont la longueur est le premier préfixe de ligne moins le deuxième préfixe de ligne
  • $4 contient la deuxième ligne
  • $5 contient une pile dont la longueur est le deuxième préfixe de ligne moins le premier préfixe de ligne

$#5$* puis préfixe le nombre nécessaire d'espaces pour aligner la première ligne sur la seconde, et vice versa pour $#3$* .

Une logique similaire s'applique à la réponse principale, sauf qu'ici, nous devons trouver deux lignes qui ne s'alignent pas pour que nous puissions les aligner (c'est là ?(5)qu'intervient le), puis répéter l'alignement sur toutes les lignes jusqu'à ce qu'elles soient toutes également alignées .

Neil
la source
0

Lisp commun, 101 octets

(lambda(c l)(dolist(x l)(format t"~,,v@a~%"(-(apply'max(mapcar(lambda(x)#1=(position c x))l))#1#)x)))

Le premier paramètre est le caractère, le second est une liste de chaînes à aligner.

Essayez-le en ligne!

Renzo
la source