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.


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:



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

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.
}

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

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>



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

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.


@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!


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.


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

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>


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')

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 ...


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).


⊣,¨⍨' '⍴¨⍨⌈.⍳-⍳¨
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));}

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']

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.


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'])

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.


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


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 .


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!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.