Align columns: Difference between revisions
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|ALGOL 68}}== |
|||
<pre> |
|||
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</pre> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
<ocaml>#load "str.cma" |
<ocaml>#load "str.cma" |
Revision as of 21:23, 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.
ALGOL 68
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
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.