Add all the A tasks

This commit is contained in:
Ingy döt Net 2013-04-10 14:58:50 -07:00
parent 2dd7375f96
commit 051504d65b
1608 changed files with 18584 additions and 0 deletions

View file

@ -0,0 +1,22 @@
Given a text file of many lines, where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
<br clear=all>Use the following text to test your programs:
<pre>Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.</pre>
Note that:
# The example input texts lines may, or may not, have trailing dollar characters.
# All columns should share the same alignment.
# Consecutive space characters produced adjacent to the end of lines are insignificant for the purposes of the task.
# Output text will be viewed in a mono-spaced font on a plain text editor or basic terminal.
# The minimum space between columns should be computed from the text and not hard-coded.
# It is ''not'' a requirement to add separating characters between or around columns.

View file

@ -0,0 +1,2 @@
---
note: Text processing

View file

@ -0,0 +1,77 @@
report z_align no standard page header.
start-of-selection.
data: lt_strings type standard table of string,
lv_strings type string.
append: 'Given$a$text$file$of$many$lines,$where$fields$within$a$line$' to lt_strings,
'are$delineated$by$a$single$''dollar''$character,$write$a$program' to lt_strings,
'that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$' to lt_strings,
'column$are$separated$by$at$least$one$space.' to lt_strings,
'Further,$allow$for$each$word$in$a$column$to$be$either$left$' to lt_strings,
'justified,$right$justified,$or$center$justified$within$its$column.' to lt_strings.
types ty_strings type standard table of string.
perform align_col using 'LEFT' lt_strings.
skip.
perform align_col using 'RIGHT' lt_strings.
skip.
perform align_col using 'CENTER' lt_strings.
form align_col using iv_just type string iv_strings type ty_strings.
constants: c_del value '$'.
data: lv_string type string,
lt_strings type table of string,
lt_tables like table of lt_strings,
lv_first type string,
lv_second type string,
lv_longest type i value 0,
lv_off type i value 0,
lv_len type i.
" Loop through the supplied text. It is expected at the input is a table of strings, with each
" entry in the table representing a new line of the input.
loop at iv_strings into lv_string.
" Split the current line at the delimiter.
split lv_string at c_del into lv_first lv_second.
" Loop through the line splitting at every delimiter.
do.
append lv_first to lt_strings.
lv_len = strlen( lv_first ).
" Check if the length of the new string is greater than the currently stored length.
if lv_len > lv_longest.
lv_longest = lv_len.
endif.
if lv_second na c_del.
" Check if the string is longer than the recorded maximum.
lv_len = strlen( lv_second ).
if lv_len > lv_longest.
lv_longest = lv_len.
endif.
append lv_second to lt_strings.
exit.
endif.
split lv_second at c_del into lv_first lv_second.
enddo.
append lt_strings to lt_tables.
clear lt_strings.
endloop.
" Loop through each line of input.
loop at lt_tables into lt_strings.
" Loop through each word in the line (Separated by specified delimiter).
loop at lt_strings into lv_string.
lv_off = ( sy-tabix - 1 ) * ( lv_longest + 2 ).
case iv_just.
when 'LEFT'.
write : at (lv_longest) lv_string left-justified.
when 'RIGHT'.
write at (lv_longest) lv_string right-justified.
when 'CENTER'.
write at (lv_longest) lv_string centered.
endcase.
endloop.
skip.
sy-linno = sy-linno - 1.
endloop.
endform.

View file

@ -0,0 +1,66 @@
STRING nl = REPR 10;
STRING text in list := "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"+nl+
"are$delineated$by$a$single$'dollar'$character,$write$a$program"+nl+
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"+nl+
"column$are$separated$by$at$least$one$space."+nl+
"Further,$allow$for$each$word$in$a$column$to$be$either$left$"+nl+
"justified,$right$justified,$or$center$justified$within$its$column.";
MODE PAGE = FLEX[0,0]STRING;
PAGE page;
PROC flex page = (PAGE in page, INT row, col)PAGE:(
HEAP FLEX[row, col]STRING out page;
out page[:1 UPB in page, :2 UPB in page] := in page;
FOR r TO row DO
FOR c FROM 2 UPB in page + 1 TO col DO out page[r,c]:="" OD
OD;
FOR r FROM 1 UPB in page + 1 TO row DO
FOR c FROM 1 TO col DO out page[r,c]:="" OD
OD;
out page
);
FILE text in file;
associate(text in file, text in list);
make term(text in file, "$");
on physical file end(text in file, (REF FILE skip)BOOL: stop iteration);
on logical file end(text in file, (REF FILE skip)BOOL: stop iteration);
FOR row DO
on line end(text in file, (REF FILE skip)BOOL: stop iteration);
FOR col DO
STRING tok;
getf(text in file, ($gx$,tok));
IF row > 1 UPB page THEN page := flex page(page, row, 2 UPB page) FI;
IF col > 2 UPB page THEN page := flex page(page, 1 UPB page, col) FI;
page[row,col]:=tok
OD;
stop iteration:
SKIP
OD;
stop iteration:
SKIP;
BEGIN
PROC aligner = (PAGE in page, PROC (STRING,INT)STRING aligner)VOID:(
PAGE page := in page;
[2 UPB page]INT max width;
FOR col TO 2 UPB page DO
INT max len:=0; FOR row TO UPB page DO IF UPB page[row,col]>max len THEN max len:=UPB page[row,col] FI OD;
FOR row TO UPB page DO page[row,col] := aligner(page[row,col], maxlen) OD
OD;
printf(($n(UPB page)(n(2 UPB page -1)(gx)gl)$,page))
);
PROC left = (STRING in, INT len)STRING: in + " "*(len - UPB in),
right = (STRING in, INT len)STRING: " "*(len - UPB in) + in,
centre = (STRING in, INT len)STRING: ( INT pad=len-UPB in; pad%2*" "+ in + (pad-pad%2)*" " );
[]STRUCT(STRING name, PROC(STRING,INT)STRING align) aligners = (("Left",left), ("Left",right), ("Centre",centre));
FOR index TO UPB aligners DO
print((new line, "# ",name OF aligners[index]," Column-aligned output:",new line));
aligner(page, align OF aligners[index])
OD
END

View file

@ -0,0 +1,34 @@
BEGIN {
FS="$"
lcounter = 1
maxfield = 0
# justistification; pick up one
#justify = "left"
justify = "center"
#justify = "right"
}
{
if ( NF > maxfield ) maxfield = NF;
for(i=1; i <= NF; i++) {
line[lcounter,i] = $i
if ( longest[i] == "" ) longest[i] = 0;
if ( length($i) > longest[i] ) longest[i] = length($i);
}
lcounter++
}
END {
just = (justify == "left") ? "-" : ""
for(i=1; i <= NR; i++) {
for(j=1; j <= maxfield; j++) {
if ( justify != "center" ) {
template = "%" just longest[j] "s "
} else {
v = int((longest[j] - length(line[i,j]))/2)
rt = "%" v+1 "s%%-%ds"
template = sprintf(rt, "", longest[j] - v)
}
printf(template, line[i,j])
}
print ""
}
}

View file

@ -0,0 +1,65 @@
with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
with Ada.Text_IO; use Ada.Text_IO;
with Strings_Edit; use Strings_Edit;
procedure Column_Aligner is
Text : constant String :=
"Given$a$text$file$of$many$lines,$where$fields$within$a$line$" & NUL &
"are$delineated$by$a$single$'dollar'$character,$write$a$program" & NUL &
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$" & NUL &
"column$are$separated$by$at$least$one$space." & NUL &
"Further,$allow$for$each$word$in$a$column$to$be$either$left$" & NUL &
"justified,$right$justified,$or$center$justified$within$its$column." & NUL;
File : File_Type;
Width : array (1..1_000) of Natural := (others => 0);
Line : String (1..200);
Column : Positive := 1;
Start : Positive := 1;
Pointer : Positive;
begin
Create (File, Out_File, "columned.txt");
-- Determining the widths of columns
for I in Text'Range loop
case Text (I) is
when '$' | NUL =>
Width (Column) := Natural'Max (Width (Column), I - Start + 1);
Start := I + 1;
if Text (I) = NUL then
Column := 1;
else
Column := Column + 1;
end if;
when others =>
null;
end case;
end loop;
-- Formatting
for Align in Alignment loop
Column := 1;
Start := 1;
Pointer := 1;
for I in Text'Range loop
case Text (I) is
when '$' | NUL =>
Put -- Formatted output of a word
( Destination => Line,
Pointer => Pointer,
Value => Text (Start..I - 1),
Field => Width (Column),
Justify => Align
);
Start := I + 1;
if Text (I) = NUL then
Put_Line (File, Line (1..Pointer - 1));
Pointer := 1;
Column := 1;
else
Column := Column + 1;
end if;
when others =>
null;
end case;
end loop;
end loop;
Close (File);
end Column_Aligner;

View file

@ -0,0 +1,50 @@
lines =
(
|$|$|$|$|$|$|$|$|$|$|$|
Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.
)
Clipboard := ColumnJustify(lines, "l")
MsgBox, , Column Justify, The clipboard now contains the justified text. Paste it into a text editor to see it.
ColumnJustify(lines, lcr = "l", del="$")
{
Loop, Parse, lines, `n, `r
Loop, Parse, A_LoopField, %del%
{
If ((t := StrLen(A_LoopField)) > c%A_Index% )
c%A_Index% := t
If (t > max)
max := t
}
blank := Fill( " ", max )
If (lcr = "l") ;left-justify
Loop, Parse, lines, `n, `r
Loop, Parse, A_LoopField, %del%
out .= (A_Index = 1 ? "`n" : " ") SubStr(A_LoopField blank, 1, c%A_Index%)
Else If (lcr = "r") ;right-justify
Loop, Parse, lines, `n, `r
Loop, Parse, A_LoopField, %del%
out .= (A_Index = 1 ? "`n" : " ") SubStr(blank A_LoopField, -c%A_Index%+1)
Else If (lcr = "c") ;center-justify
Loop, Parse, lines, `n, `r
Loop, Parse, A_LoopField, %del%
out .= (A_Index = 1 ? "`n" : " ") SubStr(blank A_LoopField blank
, (Ceil((max * 2 + StrLen(A_LoopField))/2) - Ceil(c%A_Index%/2) + 1)
, c%A_Index%)
return SubStr(out, 2)
}
Fill(chr, len)
{
static y
if !y
VarSetCapacity(x, 64), VarSetCapacity(x, 0), y := True
return x, VarSetCapacity(x, len, Asc(chr))
}

View file

@ -0,0 +1,41 @@
(ns rosettacode.align-columns
(:require [clojure.contrib.string :as str]))
(def data "Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.")
(def table (map #(str/split #"\$" %) (str/split-lines data)))
(defn col-width [n table] (reduce max (map #(try (count (nth % n))
(catch Exception _ 0))
table)))
(defn spaces [n] (str/repeat n " "))
(defn add-padding
"if the string is too big turncate it, else return a string with padding"
[string width justification]
(if (>= (count string) width) (str/take width string)
(let [pad-len (int (- width (count string))) ;we don't want rationals
half-pad-len (int (/ pad-len 2))]
(case justification
:right (str (spaces pad-len) string)
:left (str string (spaces pad-len))
:center (str (spaces half-pad-len) string (spaces (- pad-len half-pad-len)))))))
(defn aligned-table
"get the width of each column, then generate a new table with propper padding for eath item"
([table justification]
(let [col-widths (map #(+ 2 (col-width % table)) (range (count(first table))))]
(map
(fn [row] (map #(add-padding %1 %2 justification) row col-widths))
table))))
(defn print-table
[table]
(do (println)
(print (str/join "" (flatten (interleave table (repeat "\n")))))))
(print-table (aligned-table table :center))

View file

@ -0,0 +1,48 @@
pad = (n) ->
s = ''
while n > 0
s += ' '
n -= 1
s
align = (input, alignment = 'center') ->
tokenized_lines = (line.split '$' for line in input)
col_widths = {}
for line in tokenized_lines
for token, i in line
if !col_widths[i]? or token.length > col_widths[i]
col_widths[i] = token.length
padders =
center: (s, width) ->
excess = width - s.length
left = Math.floor excess / 2
right = excess - left
pad(left) + s + pad(right)
right: (s, width) ->
excess = width - s.length
pad(excess) + s
left: (s, width) ->
excess = width - s.length
s + pad(excess)
padder = padders[alignment]
for line in tokenized_lines
padded_tokens = (padder(token, col_widths[i]) for token, i in line)
console.log padded_tokens.join ' '
input = [
"Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
"are$delineated$by$a$single$'dollar'$character,$write$a$program"
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
"column$are$separated$by$at$least$one$space."
"Further,$allow$for$each$word$in$a$column$to$be$either$left$"
"justified,$right$justified,$or$center$justified$within$its$column."
]
for alignment in ['center', 'right', 'left']
console.log "\n----- #{alignment}"
align input, alignment

View file

@ -0,0 +1,25 @@
> coffee align_columns.coffee
----- center
Given a text file of many lines, where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
----- right
Given a text file of many lines, where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
----- left
Given a text file of many lines, where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.

View file

@ -0,0 +1,68 @@
-module (align_columns).
-export([align_left/0, align_right/0, align_center/0]).
-define (Lines,
["Given\$a\$text\$file\$of\$many\$lines\$where\$fields\$within\$a\$line\$",
"are\$delineated\$by\$a\$single\$'dollar'\$character,\$write\$a\$program",
"that\$aligns\$each\$column\$of\$fields\$by\$ensuring\$that\$words\$in\$each\$",
"column\$are\$separated\$by\$at\$least\$one\$space.",
"Further,\$allow\$for\$each\$word\$in\$a\$column\$to\$be\$either\$left\$",
"justified,\$right\$justified,\$or\$center\$justified\$within\$its\$column."].
align_left()-> align_columns(left).
align_right()-> align_columns(right).
align_center()-> align_columns(centre).
align_columns(Alignment) ->
Words = [ string:tokens(Line, "\$") || Line <- ?Lines ],
Words_length = lists:foldl( fun max_length/2, [], Words),
Result = [prepare_line(Words_line, Words_length, Alignment)
|| Words_line <- Words],
[ io:fwrite("~s~n", [lists:flatten(Line)]) || Line <- Result],
ok.
max_length(Words_of_a_line, Acc_maxlength) ->
Line_lengths = [length(W) || W <- Words_of_a_line ],
Max_nb_of_length = lists:max([length(Acc_maxlength), length(Line_lengths)]),
Line_lengths_prepared = adjust_list (Line_lengths, Max_nb_of_length, 0),
Acc_maxlength_prepared = adjust_list(Acc_maxlength, Max_nb_of_length, 0),
Two_lengths =lists:zip(Line_lengths_prepared, Acc_maxlength_prepared),
[ lists:max([A, B]) || {A, B} <- Two_lengths].
adjust_list(L, Desired_length, Elem) ->
L++lists:duplicate(Desired_length - length(L), Elem).
prepare_line(Words_line, Words_length, Alignment) ->
All_words = adjust_list(Words_line, length(Words_length), ""),
Zipped = lists:zip (All_words, Words_length),
[ apply(string, Alignment, [Word, Length + 1, $\s])
|| {Word, Length} <- Zipped].
=== Output
1> c(align_columns).
{ok,align_columns}
2> align_columns:align_center().
Given a text file of many lines where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
ok
3> align_columns:align_left().
Given a text file of many lines where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
ok
4> align_columns:align_right().
Given a text file of many lines where fields within a line
are delineated by a single 'dollar' character, write a program
that aligns each column of fields by ensuring that words in each
column are separated by at least one space.
Further, allow for each word in a column to be either left
justified, right justified, or center justified within its column.
ok

View file

@ -0,0 +1,70 @@
\ align columns
: split ( addr len char -- addr len1 addr len-len1 )
>r 2dup r> scan 2swap 2 pick - ;
variable column
: for-each-line ( file len xt -- )
>r begin #lf split r@ execute 1 /string dup 0<= until 2drop rdrop ;
: for-each-field ( line len xt -- )
0 column !
>r begin '$ split r@ execute 1 column +! 1 /string dup 0<= until 2drop rdrop ;
0 value num-columns
: count-columns ( line len -- )
['] 2drop for-each-field
num-columns column @ max to num-columns ;
: find-num-columns ( file len -- )
0 to num-columns
['] count-columns for-each-line ;
0 value column-widths
: column-width ( field len -- )
column-widths column @ + c@
max
column-widths column @ + c!
drop ;
: measure-widths ( line len -- )
['] column-width for-each-field ;
: find-column-widths ( file len -- )
num-columns allocate throw to column-widths
column-widths num-columns erase
['] measure-widths for-each-line ;
\ type aligned, same naming convention as standard numeric U.R, .R
: type.l ( addr len width -- )
over - >r type r> spaces ;
: type.c ( addr len width -- )
over - dup 2/ spaces >r type r> 1+ 2/ spaces ;
: type.r ( addr len width -- )
over - spaces type ;
defer type.aligned
: print-field ( field len -- )
column-widths column @ + c@ type.aligned space ;
: print-line ( line len -- ) cr ['] print-field for-each-field ;
: print-fields ( file len -- ) ['] print-line for-each-line ;
\ read file
s" columns.txt" slurp-file ( file len )
\ scan once to determine num-columns
2dup find-num-columns
\ scan again to determine column-widths
2dup find-column-widths
\ print columns, once for each alignment type
' type.l is type.aligned 2dup print-fields cr
' type.c is type.aligned 2dup print-fields cr
' type.r is type.aligned 2dup print-fields cr
\ cleanup
nip free throw
column-widths free throw

View file

@ -0,0 +1,61 @@
package main
import (
"fmt"
"strings"
)
const text = `Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.`
type formatter struct {
text [][]string
width []int
}
func newFormatter(text string) *formatter {
var f formatter
for _, line := range strings.Split(text, "\n") {
words := strings.Split(line, "$")
for words[len(words)-1] == "" {
words = words[:len(words)-1]
}
f.text = append(f.text, words)
for i, word := range words {
if i == len(f.width) {
f.width = append(f.width, len(word))
} else if len(word) > f.width[i] {
f.width[i] = len(word)
}
}
}
return &f
}
const (
left = iota
middle
right
)
func (f formatter) print(j int) {
for _, line := range f.text {
for i, word := range line {
fmt.Printf("%-*s ", f.width[i], fmt.Sprintf("%*s",
len(word)+(f.width[i]-len(word))*j/2, word))
}
fmt.Println("")
}
fmt.Println("")
}
func main() {
f := newFormatter(text)
f.print(left)
f.print(middle)
f.print(right)
}

View file

@ -0,0 +1,25 @@
import Data.List
import Control.Monad
import Control.Arrow
dat = "Given$a$text$file$of$many$lines,$where$fields$within$a$line$\n" ++
"are$delineated$by$a$single$'dollar'$character,$write$a$program\n" ++
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$\n" ++
"column$are$separated$by$at$least$one$space.\n" ++
"Further,$allow$for$each$word$in$a$column$to$be$either$left$\n" ++
"justified,$right$justified,$or$center$justified$within$its$column.\n"
brkdwn = takeWhile (not.null) . unfoldr (Just . second (drop 1) . span ('$'/=))
format j ls = map (unwords. zipWith align colw) rows
where
rows = map brkdwn $ lines ls
colw = map (maximum. map length) . transpose $ rows
align cw w =
case j of
'c' -> (replicate l ' ') ++ w ++ (replicate r ' ')
'r' -> (replicate dl ' ') ++ w
'l' -> w ++ (replicate dl ' ')
where
dl = cw-length w
(l,r) = (dl `div` 2, dl-l)

View file

@ -0,0 +1,31 @@
var justification="center",
input=["Given$a$text$file$of$many$lines,$where$fields$within$a$line$",
"are$delineated$by$a$single$'dollar'$character,$write$a$program",
"that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$",
"column$are$separated$by$at$least$one$space.",
"Further,$allow$for$each$word$in$a$column$to$be$either$left$",
"justified,$right$justified,$or$center$justified$within$its$column."],
x,y,cols,max,cols=0,diff,left,right
String.prototype.repeat=function(n){return new Array(1 + parseInt(n)).join(this);}
for(x=0;x<input.length;x++) {
input[x]=input[x].split("$");
if(input[x].length>cols) cols=input[x].length;
}
for(x=0;x<cols;x++) {
max=0;
for(y=0;y<input.length;y++) if(input[y][x]&&max<input[y][x].length) max=input[y][x].length;
for(y=0;y<input.length;y++)
if(input[y][x]) {
diff=(max-input[y][x].length)/2;
left=" ".repeat(Math.floor(diff));
right=" ".repeat(Math.ceil(diff));
if(justification=="left") {right+=left;left=""}
if(justification=="right") {left+=right;right=""}
input[y][x]=left+input[y][x]+right;
}
}
for(x=0;x<input.length;x++) input[x]=input[x].join(" ");
input=input.join("\n");
document.write(input);

View file

@ -0,0 +1,60 @@
local tWord = {} -- word table
local tColLen = {} -- maximum word length in a column
local rowCount = 0 -- row counter
--store maximum column lengths at 'tColLen'; save words into 'tWord' table
local function readInput(pStr)
for line in pStr:gmatch("([^\n]+)[\n]-") do -- read until '\n' character
rowCount = rowCount + 1
tWord[rowCount] = {} -- create new row
local colCount = 0
for word in line:gmatch("[^$]+") do -- read non '$' character
colCount = colCount + 1
tColLen[colCount] = math.max((tColLen[colCount] or 0), #word) -- store column length
tWord[rowCount][colCount] = word -- store words
end--for word
end--for line
end--readInput
--repeat space to align the words in the same column
local align = {
["left"] = function (pWord, pColLen)
local n = (pColLen or 0) - #pWord + 1
return pWord .. (" "):rep(n)
end;--["left"]
["right"] = function (pWord, pColLen)
local n = (pColLen or 0) - #pWord + 1
return (" "):rep(n) .. pWord
end;--["right"]
["center"] = function (pWord, pColLen)
local n = (pColLen or 0) - #pWord + 1
local n1 = math.floor(n/2)
return (" "):rep(n1) .. pWord .. (" "):rep(n-n1)
end;--["center"]
}
--word table padder
local function padWordTable(pAlignment)
local alignFunc = align[pAlignment] -- selecting the spacer function
for rowCount, tRow in ipairs(tWord) do
for colCount, word in ipairs(tRow) do
tRow[colCount] = alignFunc(word, tColLen[colCount]) -- save the padded words into the word table
end--for colCount, word
end--for rowCount, tRow
end--padWordTable
--main interface
--------------------------------------------------[]
function alignColumn(pStr, pAlignment, pFileName)
--------------------------------------------------[]
readInput(pStr) -- store column lengths and words
padWordTable(pAlignment or "left") -- pad the stored words
local output = ""
for rowCount, tRow in ipairs(tWord) do
local line = table.concat(tRow) -- concatenate words in one row
print(line) -- print the line
output = output .. line .. "\n" -- concatenate the line for output, add line break
end--for rowCount, tRow
if (type(pFileName) == "string") then
local file = io.open(pFileName, "w+")
file:write(output) -- write output to file
file:close()
end--if type(pFileName)
return output
end--alignColumn

View file

@ -0,0 +1,12 @@
input =
[[Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.]]
outputLeft = alignColumn(input)
outputRight = alignColumn(input, "right")
alignColumn(input, "center", "output.txt")

View file

@ -0,0 +1,47 @@
<?php
$j2justtype = array('L' => STR_PAD_RIGHT,
'R' => STR_PAD_LEFT,
'C' => STR_PAD_BOTH);
/**
Justify columns of textual tabular input where the record separator is the newline
and the field separator is a 'dollar' character.
justification can be L, R, or C; (Left, Right, or Centered).
Return the justified output as a string
*/
function aligner($str, $justification = 'L') {
global $j2justtype;
assert(array_key_exists($justification, $j2justtype));
$justtype = $j2justtype[$justification];
$fieldsbyrow = array();
foreach (explode("\n", $str) as $line)
$fieldsbyrow[] = explode('$', $line);
$maxfields = max(array_map('count', $fieldsbyrow));
foreach (range(0, $maxfields-1) as $col) {
$maxwidth = 0;
foreach ($fieldsbyrow as $fields)
$maxwidth = max($maxwidth, strlen($fields[$col]));
foreach ($fieldsbyrow as &$fields)
$fields[$col] = str_pad($fields[$col], $maxwidth, ' ', $justtype);
unset($fields); // see http://bugs.php.net/29992
}
$result = '';
foreach ($fieldsbyrow as $fields)
$result .= implode(' ', $fields) . "\n";
return $result;
}
$textinfile = 'Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$\'dollar\'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.';
foreach (array('L', 'R', 'C') as $j)
echo aligner($textinfile, $j);
?>

View file

@ -0,0 +1,56 @@
#/usr/bin/perl -w
use strict ;
die "Call : perl columnaligner.pl <inputfile> <printorientation>!\n" unless
@ARGV == 2 ; #$ARGV[ 0 ] contains example file , $ARGV[1] any of 'left' , 'right' or 'center'
die "last argument must be one of center, left or right!\n" unless
$ARGV[ 1 ] =~ /center|left|right/ ;
sub printLines( $$$ ) ;
open INFILE , "<" , "$ARGV[ 0 ]" or die "Can't open $ARGV[ 0 ]!\n" ;
my @lines = <INFILE> ;
close INFILE ;
chomp @lines ;
my @fieldwidths = map length, split /\$/ , $lines[ 0 ] ;
foreach my $i ( 1..$#lines ) {
my @words = split /\$/ , $lines[ $i ] ;
foreach my $j ( 0..$#words ) {
if ( $j <= $#fieldwidths ) {
if ( length $words[ $j ] > $fieldwidths[ $j ] ) {
$fieldwidths[ $j ] = length $words[ $j ] ;
}
}
else {
push @fieldwidths, length $words[ $j ] ;
}
}
}
printLine( $_ , $ARGV[ 1 ] , \@fieldwidths ) foreach @lines ;
################################################################## ####
sub printLine {
my $line = shift ;
my $orientation = shift ;
my $widthref = shift ;
my @words = split /\$/, $line ;
foreach my $k ( 0..$#words ) {
my $printwidth = $widthref->[ $k ] + 1 ;
if ( $orientation eq 'center' ) {
$printwidth++ ;
}
if ( $orientation eq 'left' ) {
print $words[ $k ] ;
print " " x ( $printwidth - length $words[ $k ] ) ;
}
elsif ( $orientation eq 'right' ) {
print " " x ( $printwidth - length $words[ $k ] ) ;
print $words[ $k ] ;
}
elsif ( $orientation eq 'center' ) {
my $left = int( ( $printwidth - length $words[ $k ] ) / 2 ) ;
my $right = $printwidth - length( $words[ $k ] ) - $left ;
print " " x $left ;
print $words[ $k ] ;
print " " x $right ;
}
}
print "\n" ;
}

View file

@ -0,0 +1,24 @@
use List::Util qw(max);
sub columns {
my @lines = map [split /\$/] => split /\n/ => shift;
my $pos = {qw/left 0 center 1 right 2/}->{+shift};
for my $col (0 .. max map {$#$_} @lines) {
my $max = max my @widths = map {length $_->[$col]} @lines;
for my $row (0 .. $#lines) {
my @pad = map {' ' x $_, ' ' x ($_ + 0.5)} ($max - $widths[$row]) / 2;
for ($lines[$row][$col])
{$_ = join '' => @pad[0 .. $pos-1], $_, @pad[$pos .. $#pad]}
}
}
join '' => map {"@$_\n"} @lines
}
print columns <<'END', $_ for qw(left right center);
Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.
END

View file

@ -0,0 +1,21 @@
(let Sizes NIL # Build a list of sizes
(let Lines # and of lines
(make
(in "input.txt" # Reading input file
(while (split (line) "$") # delimited by '$'
(let (L (link (mapcar pack @)) S Sizes)
(setq Sizes # Maintain sizes
(make
(while (or L S)
(link
(max
(inc (length (pop 'L)))
(pop 'S) ) ) ) ) ) ) ) ) )
(for L Lines # Print lines
(prinl (apply align L (mapcar - Sizes))) ) # left aligned
(prinl)
(for L Lines
(prinl (apply align L Sizes)) ) # right aligned
(prinl)
(for L Lines
(prinl (apply center L Sizes)) ) ) ) # and centered

View file

@ -0,0 +1,79 @@
aligner :-
L ="Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.",
% read the lines and the words
% compute the length of the longuest word.
% LP is the list of lines,
% each line is a list of words
parse(L, 0, N, LP, []),
% we need to add 1 to aligned
N1 is N+1,
% words will be left aligned
sformat(AL, '~~w~~t~~~w|', [N1]),
% words will be centered
sformat(AC, '~~t~~w~~t~~~w|', [N1]),
% words will be right aligned
sformat(AR, '~~t~~w~~~w|', [N1]),
write('Left justified :'), nl,
maplist(affiche(AL), LP), nl,
write('Centered justified :'), nl,
maplist(affiche(AC), LP), nl,
write('Right justified :'), nl,
maplist(affiche(AR), LP), nl.
affiche(F, L) :-
maplist(my_format(F), L),
nl.
my_format(_F, [13]) :-
nl.
my_format(F, W) :-
string_to_atom(W,AW),
sformat(AF, F, [AW]),
write(AF).
parse([], Max, Max) --> [].
parse(T, N, Max) -->
{ parse_line(T, 0, N1, T1, L, []),
( N1 > N -> N2 = N1; N2 = N)},
[L],
parse(T1, N2, Max).
parse_line([], NF, NF, []) --> [].
parse_line([H|TF], NF, NF, TF) -->
{code_type(H, end_of_line), !},
[].
parse_line(T, N, NF, TF) -->
{ parse_word(T, 0, N1, T1, W, []),
( N1 > N -> N2 = N1; N2 = N)},
[W],
parse_line(T1, N2, NF, TF).
% 36 is the code of '$'
parse_word([36|T], N, N, T) -->
{!},
[].
parse_word([H|T], N, N, [H|T]) -->
{code_type(H, end_of_line), !},
[].
parse_word([], N, N, []) --> [].
parse_word([H|T], N1, NF, TF) -->
[H],
{N2 is N1 + 1},
parse_word(T, N2, NF, TF).

View file

@ -0,0 +1,45 @@
from StringIO import StringIO
textinfile = '''Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.'''
j2justifier = dict(L=str.ljust, R=str.rjust, C=str.center)
def aligner(infile, justification = 'L'):
''' \
Justify columns of textual tabular input where the row separator is the newline
and the field separator is a 'dollar' character.
justification can be L, R, or C; (Left, Right, or Centered).
Return the justified output as a string
'''
assert justification in j2justifier, "justification can be L, R, or C; (Left, Right, or Centered)."
justifier = j2justifier[justification]
fieldsbyrow= [line.strip().split('$') for line in infile]
# pad to same number of fields per row
maxfields = max(len(row) for row in fieldsbyrow)
fieldsbyrow = [fields + ['']*(maxfields - len(fields))
for fields in fieldsbyrow]
# rotate
fieldsbycolumn = zip(*fieldsbyrow)
# calculate max fieldwidth per column
colwidths = [max(len(field) for field in column)
for column in fieldsbycolumn]
# pad fields in columns to colwidth with spaces
fieldsbycolumn = [ [justifier(field, width) for field in column]
for width, column in zip(colwidths, fieldsbycolumn) ]
# rotate again
fieldsbyrow = zip(*fieldsbycolumn)
return "\n".join( " ".join(row) for row in fieldsbyrow)
for align in 'Left Right Center'.split():
infile = StringIO(textinfile)
print "\n# %s Column-aligned output:" % align
print aligner(infile, align[0])

View file

@ -0,0 +1,21 @@
txt = """Given$a$txt$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column."""
parts = [line.rstrip("$").split("$") for line in txt.splitlines()]
max_widths = {}
for line in parts:
for i, word in enumerate(line):
max_widths[i] = max(max_widths.get(i, 0), len(word))
for i, justify in enumerate([str.ljust, str.center, str.rjust]):
print ["Left", "Center", "Right"][i], " column-aligned output:\n"
for line in parts:
for j, word in enumerate(line):
print justify(word, max_widths[j]),
print
print "- " * 52

View file

@ -0,0 +1,25 @@
# Read in text
lines <- readLines(tc <- textConnection("Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.")); close(tc)
#Split words by the dollar
words <- strsplit(lines, "\\$")
#Reformat
maxlen <- max(sapply(words, length))
words <- lapply(words, function(x) {length(x) <- maxlen; x})
block <- matrix(unlist(words), byrow=TRUE, ncol=maxlen)
block[is.na(block)] <- ""
leftjust <- format(block)
rightjust <- format(block, justify="right")
centrejust <- format(block, justify="centre")
# Print
print0 <- function(x) invisible(apply(x, 1, function(x) cat(x, "\n")))
print0(leftjust)
print0(rightjust)
print0(centrejust)

View file

@ -0,0 +1,49 @@
/*REXX*/
z.1 = "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
z.2 = "are$delineated$by$a$single$'dollar'$character,$write$a$program"
z.3 = "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
z.4 = "column$are$separated$by$at$least$one$space."
z.5 = "Further,$allow$for$each$word$in$a$column$to$be$either$left$"
z.6 = "justified,$right$justified,$or$center$justified$within$its$column."
word. = ""
width. = 0
maxcol = 0
do row = 1 to 6
line = z.row
do col = 1 by 1 until length(line) = 0
parse var line word.row.col "$" line
if length(word.row.col) > width.col then width.col = length(word.row.col)
end
if col > maxcol then maxcol = col
end
say "align left:"
say
do row = 1 to 6
out = ""
do col = 1 to maxcol
out = out || left(word.row.col,width.col+1)
end
say out
end
say
say "align right:"
say
do row = 1 to 6
out = ""
do col = 1 to maxcol
out = out || right(word.row.col,width.col+1)
end
say out
end
say
say "align center:"
say
do row = 1 to 6
out = ""
do col = 1 to maxcol
out = out || center(word.row.col,width.col+1)
end
say out
end

View file

@ -0,0 +1,35 @@
/*REXX program to display various alignments. */
cols=0; size=0; wid.=0; t.=; @.=
t.1 = "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
t.2 = "are$delineated$by$a$single$'dollar'$character,$write$a$program"
t.3 = "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
t.4 = "column$are$separated$by$at$least$one$space."
t.5 = "Further,$allow$for$each$word$in$a$column$to$be$either$left$"
t.6 = "justified,$right$justified,$or$center$justified$within$its$column."
do r=1 while t.r\==''
_=strip(t.r,,'$')
do c=1 until _==''
parse var _ @.r.c '$' _
wid.c=max(wid.c,length(@.r.c))
end /*c*/
cols=max(cols,c)
end /*r*/
rows=r-1 /*adjust ROWS, it's 1 too big*/
do k=1 for cols; size=size+wid.k; end /*find width of biggest line.*/
do j=1 for 3; say
say center(word('left right center',j) "aligned",size+cols-1,"=")
do r=1 for rows; _=
do c=1 for cols; x=@.r.c
if j==1 then _=_ left(x,wid.c)
if j==2 then _=_ right(x,wid.c)
if j==3 then _=_ centre(x,wid.c)
end /*c*/
say substr(_,2)
end /*r*/
say
end /*j*/

View file

@ -0,0 +1,43 @@
/*REXX program to display various alignments. */
cols=0; parse var cols size 1 wid. t. /*initializations.*/
t.1 = "Given$a$text$file$of$many$lines,$where$fields$within$a$line$"
t.2 = "are$delineated$by$a$single$'dollar'$character,$write$a$program"
t.3 = "that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$"
t.4 = "column$are$separated$by$at$least$one$space."
t.5 = "Further,$allow$for$each$word$in$a$column$to$be$either$left$"
t.6 = "justified,$right$justified,$or$center$justified$within$its$column."
do r=1 while t.r\==''
t.r=translate(t.r,,'$')
do c=1 until word(t.r,c)==''
wid.c=max(wid.c,length(word(t.r,c)))
end /*c*/
cols=max(cols,c)
end /*r*/
rows=r-1 /*adjust ROWS, it's 1 too big*/
do k=1 for cols; size=size+wid.k; end /*find width of biggest line.*/
do j=1 for 3; say
say center(word('left right center',j) "aligned",size+cols,"="); say
do r=0 to rows; _=; !=''; if r==0 then !=''
do c=1 for cols; x=word(t.r,c)
if r==0 then x=copies("",wid.c+1)
else x=word(t.r,c)
if j==1 then _=_ || ! || left(x,wid.c)
if j==2 then _=_ || ! || right(x,wid.c)
if j==3 then _=_ || ! || centre(x,wid.c)
end /*c*/
if r==0 then do; _=''substr(_,2,length(_)-2)""
bot=''substr(_,2,length(_)-2)""
end
say _
end /*r*/
say translate(bot,'',""); say; say
end /*j*/

View file

@ -0,0 +1,34 @@
#lang racket
(define (display-aligned text #:justify [justify 'left])
(define lines
(for/list ([line (regexp-split #rx"\n" text)])
(regexp-split #rx"\\$" line)))
(define width
(add1 (for*/fold ([m 0]) ([line lines] [word line])
(max m (string-length word)))))
(define spaces (make-string width #\space))
(for ([line lines])
(for* ([word line]
[strs (let ([spc (substring spaces (string-length word))])
(case justify
[(left) (list word spc)]
[(right) (list spc word)]
[(center) (let ([i (quotient (string-length spc) 2)])
(list (substring spc i)
word
(substring spc 0 i)))]))])
(display strs))
(newline)))
(define text
"Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.")
(display-aligned text)
(display-aligned #:justify 'right text)
(display-aligned #:justify 'center text)

View file

@ -0,0 +1,50 @@
require 'stringio'
textinfile = <<END
Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.
END
J2justifier = {'L' => String.instance_method(:ljust),
'R' => String.instance_method(:rjust),
'C' => String.instance_method(:center)}
=begin
Justify columns of textual tabular input where the record separator is the newline
and the field separator is a 'dollar' character.
justification can be L, R, or C; (Left, Right, or Centered).
Return the justified output as a string
=end
def aligner(infile, justification = 'L')
justifier = J2justifier[justification]
fieldsbyrow = infile.map {|line| line.strip.split('$')}
# pad to same number of fields per record
maxfields = fieldsbyrow.map {|row| row.length}.max
fieldsbyrow.map! {|row|
row + ['']*(maxfields - row.length)
}
# calculate max fieldwidth per column
colwidths = fieldsbyrow.transpose.map {|column|
column.map {|field| field.length}.max
}
# pad fields in columns to colwidth with spaces
fieldsbyrow.map! {|row|
row.zip(colwidths).map {|field, width|
justifier.bind(field)[width]
}
}
fieldsbyrow.map {|row| row.join(" ")}.join("\n")
end
for align in %w{Left Right Center}
infile = StringIO.new(textinfile)
puts "\n# %s Column-aligned output:" % align
puts aligner(infile, align[0..0])
end

View file

@ -0,0 +1,28 @@
object ColumnAligner {
val eol = System.getProperty("line.separator")
def getLines(filename: String) = scala.io.Source.fromPath(filename).getLines(eol)
def splitter(line: String) = line split '$'
def getTable(filename: String) = getLines(filename) map splitter
def fieldWidths(fields: Array[String]) = fields map (_ length)
def columnWidths(txt: Iterator[Array[String]]) = (txt map fieldWidths).toList.transpose map (_ max)
def alignField(alignment: Char)(width: Int)(field: String) = alignment match {
case 'l' | 'L' => "%-"+width+"s" format field
case 'r' | 'R' => "%"+width+"s" format field
case 'c' | 'C' => val padding = (width - field.length) / 2; " "*padding+"%-"+(width-padding)+"s" format field
case _ => throw new IllegalArgumentException
}
def align(aligners: List[String => String])(fields: Array[String]) =
aligners zip fields map Function.tupled(_ apply _)
def alignFile(filename: String, alignment: Char) = {
def table = getTable(filename)
val aligners = columnWidths(table) map alignField(alignment)
table map align(aligners) map (_ mkString " ")
}
def printAlignedFile(filename: String, alignment: Char) {
alignFile(filename, alignment) foreach println
}
}

View file

@ -0,0 +1,22 @@
def pad(s:String, i:Int, d:String) = {
val padsize = (i-s.length).max(0)
d match {
case "left" => s+" "*padsize
case "right" => " "*padsize+s
case "center" => " "*(padsize/2) + s + " "*(padsize-padsize/2)
}
}
val lines = scala.io.Source.fromFile("c:\\text.txt").getLines.map(_.trim())
val words = lines.map(_.split("\\$").toList).toList
val lens = words.map(l => l.map(_.length)).toList
var maxlens = Map[Int,Int]() withDefaultValue 0
lens foreach (l =>
for(i <- (0 until l.length)){
maxlens += i -> l(i).max(maxlens(i))
}
)
val padded = words map ( _.zipWithIndex.map{case(s,i)=>pad(s,maxlens(i),"center")+" "} )
padded map (_.reduceLeft(_ + _)) foreach println

View file

@ -0,0 +1,48 @@
package require Tcl 8.5
set text {Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.}
array set max {}
foreach line [split $text \n] {
set col 0
set thisline [split $line \$]
lappend words $thisline
foreach word $thisline {
set max([incr col]) [expr {[info exists max($col)]
? max($max($col), [string length $word])
: [string length $word]
}]
}
}
proc justify {word position width} {
switch -exact -- $position {
left {
return [format "%-*s" $width $word]
}
center {
set lpadw [expr {($width - [string length $word])/2}]
return [format "%s%-*s" [string repeat " " $lpadw] [incr width -$lpadw] $word]
}
right {
return [format "%*s" $width $word]
}
}
}
foreach position {left center right} {
foreach thisline $words {
set col 0
set line ""
foreach word $thisline {
append line [justify $word $position $max([incr col])] " "
}
puts [string trimright $line]
}
puts ""
}