Okay, here's one. I just finished helping someone worth through this. So it's pretty fun.

Write a program in Python, that can accept a paragraph string and and page
width and return an array of left AND right justified strings. NOTE: No words
should be broken, the beginning and end of the line should be characters).

You should provide instructions on how to execute your program and provide a
sample output.

Example:

Sample input:

Paragraph = "This is a sample text but a complicated problem to be solved, so
we are adding more text to see that it actually works."

Page Width = 20

Output should look like this:

Array [1] = "This is a sample"
Array [2] = "text but a"
Array [3] = "complicated problem"
Array [4] = "to be solved, so we"
Array [5] = "are adding more text"
Array [6] = "to see that it"
Array [7] = "actually works.”

Follow

Octave solution 

@Absinthe

Matlab normally represents strings as 1D arrays of chars. It's not usual to put chars in an 2D array because all the rows would have to be the same length, and that's pretty inflexible. Octave is happy to make such an array just as it would with any other type, though, and here that's exactly what we want.

function array = justify_text(string, width)
words = strtrunc(strsplit(string), width);
array = zeros(0, width);
line_length = 0;
start_index = 1;
for word_index = 1:numel(words)
this_word = words{word_index};
if line_length + numel(this_word) > width
array = [array; render_words(start_index, word_index - 1)];
start_index = word_index;
line_length = numel(this_word) + 1;
else
line_length += numel(this_word) + 1; end; end;
array = [array; render_words(start_index, numel(words))];
function this_line = render_words(start_index, end_index)
chars_raw = cellfun(@numel, words(start_index:end_index));
total_padding = width - sum(chars_raw);
if start_index == end_index
this_line = [words{start_index} repmat(' ', 1, total_padding)];
else
base_padding = floor(total_padding / (end_index - start_index));
extra_padding = rem(total_padding, end_index - start_index);
next_char = 1;
for index = start_index:end_index
this_padding = 0;
if index < end_index
this_padding = base_padding;
if index - start_index < extra_padding
this_padding++; end; end;
this_line(next_char:(next_char + chars_raw(index - start_index + 1) - 1)) = words{index};
next_char += chars_raw(index - start_index + 1);
this_line(next_char:(next_char + this_padding - 1)) = repmat(' ', 1, this_padding);
next_char += this_padding; end; end; end; end;

Invoking the Octave solution 

Call with two arguments, both mandatory: a string to justify and a linewidth to justify to. Returns a 2D array of chars. Where it can, the words touch both sides simultaneously. Sometimes it's not possible to fit more than one word on a line, in which case it is left justified, padded with spaces.

> justify_text('I walked until midnight in the storm, then I went home and took a sauna for an hour and a half. It was all clear. I listened to my heart and saw if there were any signs of my destiny in the sky, and there were none - there were just snowflakes.', 16)
ans =

I walked until
midnight in the
storm, then I
went home and
took a sauna for
an hour and a
half. It was all
clear. I
listened to my
heart and saw if
there were any
signs of my
destiny in the
sky, and there
were none -
there were just
snowflakes.

Sign in to participate in the conversation
Qoto Mastodon

QOTO: Question Others to Teach Ourselves
An inclusive, Academic Freedom, instance
All cultures welcome.
Hate speech and harassment strictly forbidden.