Add all the A tasks
This commit is contained in:
parent
2dd7375f96
commit
051504d65b
1608 changed files with 18584 additions and 0 deletions
22
Task/Align-columns/0DESCRIPTION
Normal file
22
Task/Align-columns/0DESCRIPTION
Normal 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.
|
||||
2
Task/Align-columns/1META.yaml
Normal file
2
Task/Align-columns/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Text processing
|
||||
77
Task/Align-columns/ABAP/align-columns.abap
Normal file
77
Task/Align-columns/ABAP/align-columns.abap
Normal 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.
|
||||
66
Task/Align-columns/ALGOL-68/align-columns.alg
Normal file
66
Task/Align-columns/ALGOL-68/align-columns.alg
Normal 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
|
||||
34
Task/Align-columns/AWK/align-columns.awk
Normal file
34
Task/Align-columns/AWK/align-columns.awk
Normal 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 ""
|
||||
}
|
||||
}
|
||||
65
Task/Align-columns/Ada/align-columns.ada
Normal file
65
Task/Align-columns/Ada/align-columns.ada
Normal 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;
|
||||
50
Task/Align-columns/AutoHotkey/align-columns.ahk
Normal file
50
Task/Align-columns/AutoHotkey/align-columns.ahk
Normal 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))
|
||||
}
|
||||
41
Task/Align-columns/Clojure/align-columns.clj
Normal file
41
Task/Align-columns/Clojure/align-columns.clj
Normal 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))
|
||||
48
Task/Align-columns/CoffeeScript/align-columns-1.coffee
Normal file
48
Task/Align-columns/CoffeeScript/align-columns-1.coffee
Normal 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
|
||||
25
Task/Align-columns/CoffeeScript/align-columns-2.coffee
Normal file
25
Task/Align-columns/CoffeeScript/align-columns-2.coffee
Normal 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.
|
||||
68
Task/Align-columns/Erlang/align-columns.erl
Normal file
68
Task/Align-columns/Erlang/align-columns.erl
Normal 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
|
||||
70
Task/Align-columns/Forth/align-columns.fth
Normal file
70
Task/Align-columns/Forth/align-columns.fth
Normal 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
|
||||
61
Task/Align-columns/Go/align-columns.go
Normal file
61
Task/Align-columns/Go/align-columns.go
Normal 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)
|
||||
}
|
||||
25
Task/Align-columns/Haskell/align-columns.hs
Normal file
25
Task/Align-columns/Haskell/align-columns.hs
Normal 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)
|
||||
31
Task/Align-columns/JavaScript/align-columns.js
Normal file
31
Task/Align-columns/JavaScript/align-columns.js
Normal 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);
|
||||
60
Task/Align-columns/Lua/align-columns-1.lua
Normal file
60
Task/Align-columns/Lua/align-columns-1.lua
Normal 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
|
||||
12
Task/Align-columns/Lua/align-columns-2.lua
Normal file
12
Task/Align-columns/Lua/align-columns-2.lua
Normal 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")
|
||||
47
Task/Align-columns/PHP/align-columns.php
Normal file
47
Task/Align-columns/PHP/align-columns.php
Normal 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);
|
||||
|
||||
?>
|
||||
56
Task/Align-columns/Perl/align-columns-1.pl
Normal file
56
Task/Align-columns/Perl/align-columns-1.pl
Normal 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" ;
|
||||
}
|
||||
24
Task/Align-columns/Perl/align-columns-2.pl
Normal file
24
Task/Align-columns/Perl/align-columns-2.pl
Normal 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
|
||||
21
Task/Align-columns/PicoLisp/align-columns.l
Normal file
21
Task/Align-columns/PicoLisp/align-columns.l
Normal 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
|
||||
79
Task/Align-columns/Prolog/align-columns.pro
Normal file
79
Task/Align-columns/Prolog/align-columns.pro
Normal 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).
|
||||
45
Task/Align-columns/Python/align-columns-1.py
Normal file
45
Task/Align-columns/Python/align-columns-1.py
Normal 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])
|
||||
21
Task/Align-columns/Python/align-columns-2.py
Normal file
21
Task/Align-columns/Python/align-columns-2.py
Normal 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
|
||||
25
Task/Align-columns/R/align-columns.r
Normal file
25
Task/Align-columns/R/align-columns.r
Normal 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)
|
||||
49
Task/Align-columns/REXX/align-columns-1.rexx
Normal file
49
Task/Align-columns/REXX/align-columns-1.rexx
Normal 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
|
||||
35
Task/Align-columns/REXX/align-columns-2.rexx
Normal file
35
Task/Align-columns/REXX/align-columns-2.rexx
Normal 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*/
|
||||
43
Task/Align-columns/REXX/align-columns-3.rexx
Normal file
43
Task/Align-columns/REXX/align-columns-3.rexx
Normal 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*/
|
||||
34
Task/Align-columns/Racket/align-columns.rkt
Normal file
34
Task/Align-columns/Racket/align-columns.rkt
Normal 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)
|
||||
50
Task/Align-columns/Ruby/align-columns.rb
Normal file
50
Task/Align-columns/Ruby/align-columns.rb
Normal 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
|
||||
28
Task/Align-columns/Scala/align-columns-1.scala
Normal file
28
Task/Align-columns/Scala/align-columns-1.scala
Normal 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
|
||||
}
|
||||
}
|
||||
22
Task/Align-columns/Scala/align-columns-2.scala
Normal file
22
Task/Align-columns/Scala/align-columns-2.scala
Normal 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
|
||||
48
Task/Align-columns/Tcl/align-columns.tcl
Normal file
48
Task/Align-columns/Tcl/align-columns.tcl
Normal 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 ""
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue