Align columns: Difference between revisions
(Align columns of text) |
|||
Line 14: | Line 14: | ||
Further,$allow$for$each$word$in$a$column$to$be$either$left$ |
Further,$allow$for$each$word$in$a$column$to$be$either$left$ |
||
justified,$right$justified,$or$center$justified$within$its$column.</pre> |
justified,$right$justified,$or$center$justified$within$its$column.</pre> |
||
=={{header|OCaml}}== |
|||
<ocaml>#load "str.cma" |
|||
open Str |
|||
let 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." |
|||
let () = |
|||
let lines = split (regexp_string "\n") input in |
|||
let fields_l = List.map (split (regexp_string "$")) lines in |
|||
let fields_l = List.map Array.of_list fields_l in |
|||
let n = (* number of columns *) |
|||
List.fold_left |
|||
(fun n fields -> max n (Array.length fields)) |
|||
0 fields_l |
|||
in |
|||
let pads = Array.make n 0 in |
|||
List.iter ( |
|||
(* calculate the max padding for each column *) |
|||
Array.iteri |
|||
(fun i word -> pads.(i) <- max pads.(i) (String.length word)) |
|||
) fields_l; |
|||
let print f = |
|||
List.iter (fun fields -> |
|||
Array.iteri (fun i word -> |
|||
f word (pads.(i) - (String.length word)) |
|||
) fields; |
|||
print_newline() |
|||
) fields_l; |
|||
in |
|||
(* left column-aligned output *) |
|||
print (fun word pad -> |
|||
let spaces = String.make pad ' ' in |
|||
Printf.printf "%s%s " word spaces); |
|||
(* right column-aligned output *) |
|||
print (fun word pad -> |
|||
let spaces = String.make pad ' ' in |
|||
Printf.printf "%s%s " spaces word); |
|||
(* center column-aligned output *) |
|||
print (fun word pad -> |
|||
let pad1 = pad / 2 in |
|||
let pad2 = pad - pad1 in |
|||
let sp1 = String.make pad1 ' ' in |
|||
let sp2 = String.make pad2 ' ' in |
|||
Printf.printf "%s%s%s " sp1 word sp2); |
|||
;;</ocaml> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
Revision as of 08:05, 16 November 2008
You are encouraged to solve this task according to the task description, using any language you may know.
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.
Use the following text to test your programs:
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.
OCaml
<ocaml>#load "str.cma" open Str
let 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."
let () =
let lines = split (regexp_string "\n") input in let fields_l = List.map (split (regexp_string "$")) lines in let fields_l = List.map Array.of_list fields_l in let n = (* number of columns *) List.fold_left (fun n fields -> max n (Array.length fields)) 0 fields_l in let pads = Array.make n 0 in List.iter ( (* calculate the max padding for each column *) Array.iteri (fun i word -> pads.(i) <- max pads.(i) (String.length word)) ) fields_l;
let print f = List.iter (fun fields -> Array.iteri (fun i word -> f word (pads.(i) - (String.length word)) ) fields; print_newline() ) fields_l; in
(* left column-aligned output *) print (fun word pad -> let spaces = String.make pad ' ' in Printf.printf "%s%s " word spaces);
(* right column-aligned output *) print (fun word pad -> let spaces = String.make pad ' ' in Printf.printf "%s%s " spaces word);
(* center column-aligned output *) print (fun word pad -> let pad1 = pad / 2 in let pad2 = pad - pad1 in let sp1 = String.make pad1 ' ' in let sp2 = String.make pad2 ' ' in Printf.printf "%s%s%s " sp1 word sp2);
- </ocaml>
Python
<python>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 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 assert justification in 'LRC', "justification can be L, R, or C; (Left, Right, or Centered)." justifier = j2justifier[justification] fieldsbyrecord= [line.strip().split('$') for line in infile] # pad to same number of fields per record maxfields = max(len(record) for record in fieldsbyrecord) fieldsbyrecord = [fields + []*(maxfields - len(fields)) for fields in fieldsbyrecord] # rotate fieldsbycolumn = zip(*fieldsbyrecord) # 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 fieldsbyrecord = zip(*fieldsbycolumn)
return "\n".join( " ".join(record) for record in fieldsbyrecord)
for align in 'Left Right Center'.split():
infile = StringIO(textinfile) print "\n# %s Column-aligned output:" % align print aligner(infile, align[0])</python>
Example output:
# Left Column-aligned output: 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 Column-aligned output: 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. # Center Column-aligned output: 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.