400 - Unix ls

All about problems in Volume 4. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

Adrian Kuegel
Guru
Posts: 724
Joined: Wed Dec 19, 2001 2:00 am
Location: Germany

Post by Adrian Kuegel »

Your compile error is probably because of the filenames[x].length(). It must be filenames[x].size(). And the Runtime error is because of %0 and /0. They occur because 60/(longest+2) is not the correct value. After the last column there should be no two spaces.
zhartley
New poster
Posts: 8
Joined: Tue Jul 23, 2002 2:38 am
Location: High Point, North Carolina / Goodlettsville, Tennesee
Contact:

Post by zhartley »

Ok, thanks for pointing out the use of size() instead of length() and the extra two spaces at the end of the line. However, I'm afraid I'm confused by the following:
And the Runtime error is because of %0 and /0. They occur because 60/(longest+2) is not the correct value.
I do not have any idea what you mean by %0 and /0. And I assume 60/(longest+2) is wrong because the last column, unlike the ones before it, does not need 2 spaces at the end. Or am I completely misunderstanding you? Thanks
Adrian Kuegel
Guru
Posts: 724
Joined: Wed Dec 19, 2001 2:00 am
Location: Germany

Post by Adrian Kuegel »

There are words of length 60, therefore 60/(longest+2) is 0, and filenames.size() % columns and filenames.size() / columns gives runtime error.
zhartley
New poster
Posts: 8
Joined: Tue Jul 23, 2002 2:38 am
Location: High Point, North Carolina / Goodlettsville, Tennesee
Contact:

Post by zhartley »

Thanks, I got accepted! One of these days, I swear I'll learn to better test corner cases.... :lol:
liusu
New poster
Posts: 22
Joined: Thu Aug 01, 2002 10:26 am

HELP ME please

Post by liusu »

i got wa many times...coulld you help me?

:oops: [pascal]var
s:array[1..102] of string;
i:integer;

procedure order(t:integer);
var
m,n:integer;
st:string;
begin
for m:=1 to t-1 do
for n:=m+1 to t do
if(s[m]>s[n]) then
begin
st:=s[m];
s[m]:=s[n];
s[n]:=st;
end;
end;

procedure print(t:integer);
var
i:integer;
begin
for i:=1 to t do
write(' ');
end;

procedure ru;
var
i,t,l,c,r,x,y:integer;
begin
l:=1;
readln(t);
for i:=1 to t do
begin
readln(s);
if length(s)>l then
l:=length(s);
end;
order(t);
for i:=1 to 60 do
write('-');
writeln;
c:=trunc(60/(l+2));
r:=trunc(t/c);
if(t/c<>r) then
inc(r);
l:=l+2;
for i:=1 to r do
begin
x:=i;
for y:=1 to c do
begin
if(x<=t) then
begin
write(s[x]);
print(l-length(s[x]));
end;
x:=x+r;

end;
writeln;
end;

// writeln(s.str);
end;

begin
while not eof do
begin
ru;
end;
end.[/pascal]
23756AW
New poster
Posts: 5
Joined: Mon Sep 30, 2002 1:00 am

400 - Solution with Full Documentation

Post by 23756AW »

[cpp]
/* @JUDGE_ID: 23756AW 400 C++ "IO Manipulators and Sorted Vector" */

/*
PROBLEM_ID: 400
SYNOPSIS:
This program has two real traps.
The first is that the last column in a row is equal the maximum
filename length. All the other preceding columns in the row are equal
to the maximum filename length + 2 (" "). This will impact the
calculation you use to determine how many filenames get outputted per
row (and how conversely how many rows are required to display all the
filenames).
The second problem is in the fact that the filenames are sorted,
and displayed in column order rather than row order. This means that
you cannot simply use a sorted list and output the elements in order.

CODE NOTES;
The rest of the problem is trivial as it only relates to formatting.
I have chosen the IO manipulators approach, but printf with format
specifiers also words. The nice thing about the IO manipulators is that
they are much more readable, and in my opinion offer a robust set of
options that can be used in later programs.
I chose to use the STL vector for the filenames because of the
ability to directly access filenames. This ability is important because
of the way the files are sorted going down the column. If they were
sorted across the row I would have used the STL list container class
instead which has a little less overhead and its own sort method.
STL sort algorithm works perfectly with an STL vector, and it can
be used later in other programs in a more complex manner. This program
is a good way to get used to the rudimentary usage of SORT and IO
manipulators.

SOLUTION NOTES:
1. The items_per_row calcuation will be
((MAX_LINE_LEN - max_filename_len)/(max_filename_len + 2)) + 1
2. The row_count calculation will be (total_filenames/items_per_row)
* If there is a remainder (total_filenames % items_per_row) then increment.
3. Each column of each row can be represented as
filenames[row_index + (col_index * row_count)]

KNOWN ISSUES:
1. This is accepted but has a P.E.
2. IO manipulators implementation (like "left") are not supported by
the compiler that JUDGE is using.

AUTHOR NOTES:
Scott Lane

If you have any problems with this program or want an explanation about the
code feel free to email me at scolane@comcast.net.
*/
#if WIN32
#pragma warning (disable:4786)
#endif

#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>
using namespace std;

#define MAX_LINE_LEN 60

void main ()
{
int count = 0;
string filename;
vector<string> flist;
int max_len = 0;
int items_per_line = 1;
int row_count = 1;
int row_index = 0;
int col_index = 0;
int item_count = 0;

while (cin >> count)
{
if (! count)
break;

/*
| This is a slick way of outputting the 60 dashes without any errors.
*/
cout << setw(60) << setfill('-') << "" << endl;

/*
Need to reset the fill character to spaces before any more output.
This could have been done by passing the IO manipulator into the
cout stream (like cout << setfill(' ') << filename), but I wanted
to demonstrate that there are two approaches in C++ to achieve the
same result.
*/
cout.fill(' ');
max_len = 0;

while (count--)
{
cin >> filename;
if (filename.length() > max_len)
max_len = filename.length();
flist.push_back(filename);
}

/*
| Calculate how many filenames will be outputted on each line.
| The calculation is based on the fact that the last column has
| a column width different than the other columns. Therefore to
| get the right calculation you must do the following:
| 1. Subtract the column width of the last column from the allowed line length.
| 2. Divide the column width of the other columns (last_col_width + 2) into the
| maximum line length - the last_col_width.
| 3. The result of #2 is the number of items that can precede the last column,
| therefore you must add 1 to the items_per_line variable.
*/
items_per_line = (MAX_LINE_LEN - max_len)/(max_len + 2);
++items_per_line;

/*
| Now we want to know how many rows will be outputted. Once we
| have the items_per_line all we have to do is divide that into
| the total number of files. Because of integer division round-off
| errors we may need to add 1 if there is a remainder in the division.
| For example: if items_per_line=5 and file_count=19 then 19/5 = 3 rows,
| but we need a 4th row to store the 16th through 19th files.
*/
row_count = flist.size()/items_per_line;
if (flist.size() % items_per_line)
++row_count;

sort(flist.begin(),flist.end());

/*
| Outputting the file list is a little tricky because the sort goes down
| the column instead of across the row. As a result we are fortunate to
| have a sorted array like structure that allows us direct access to the
| files by an index value. To calculate what index should be used for the
| row output we simply take the current row index and add the row count.
| IE: Suppose we have a vector in form A,B,C,C,D,F,G,G and the row_count is 3:
| row0,col0 = vector[0]
| row0,col1 = vector[0+3]
| row0,col2 = vector[0+6]
| repeat using form rowX,colY = vector[X + (Y*row_count)]
| The above would give us A C G
| B D G
| C F
| We need to be sure that if we exceed the vector's boundary that we exit the output
| because we are obviously done.
*/
for (row_index = 0; row_index < row_count; ++row_index)
{
/*
| Set cout to left justify the output and have a fixed width equal the maximum
| filename length. I normally would have used the IO manipulator "left"
| (like cout << left << filename) but the Online Judge's compiler does not
| seem to like that, even though the Visual C++ compiler allows it. To work
| around it I set the IO stream flags directly.
*/
cout.setf(ios::left);
cout << setw(max_len) << flist[row_index];
for (col_index = 1; col_index<items_per_line; ++col_index)
{
int findex = row_index + (col_index * row_count);
if (findex >= flist.size())
col_index = items_per_line;
else
cout << " " << setw(max_len) << flist[findex];
}
cout << endl;
}
/*
| Flush the vector and prepare for a new file list.
*/
flist.clear();
}
}[/cpp][cpp][/cpp]
alun
New poster
Posts: 3
Joined: Sun Oct 14, 2001 2:00 am

400 pe

Post by alun »

i always got PE for this problem...
anyone know the right answer ?
thx in advance
Jalal
Learning poster
Posts: 65
Joined: Sun Jun 02, 2002 8:41 pm
Location: BANGLADESH
Contact:

Post by Jalal »

P.E is not a error about the code algorithm.
Maximum time its happens for not printing the out put
as the judge need.
such as not printing "\n"
so its not great problem u have got ur problem accepted
that the main thing u did 8)
User avatar
ridwan
New poster
Posts: 2
Joined: Thu Apr 03, 2003 4:44 am
Location: bangladesh
Contact:

400(calculation)

Post by ridwan »

[c]

i cannot calculate the row and columns needed.
someone help on this matter.[/c]
rcotta
New poster
Posts: 6
Joined: Fri Jan 18, 2002 2:00 am
Location: Brazil

Problems on problem 400 (Unix ls)

Post by rcotta »

Ok, forget this post.. I was just too stupid :oops:
Calvin
New poster
Posts: 5
Joined: Sat Mar 08, 2003 12:50 pm

PB 400 > UNIX LS | WA

Post by Calvin »

I got wa for this problem ! Could anyone try to explain to me where the matter is ?? Thanks a lot..
[c]
#include <stdio.h>
#include <stdlib.h>

int compare(char*a,char*b)
{
int i=0;

while (a==b)
{
i++;
}

return(a-b);
}

void space(char*tab,int len)
{
int i;
printf("%s", tab);
for (i=strlen(tab);i<len;i++) printf(" ");
}

int main()
{
unsigned int num,i,max,num_row,tmp,num_col;
char files[100][61];

while (scanf("%u",&num)==1)
{
max=1;
num_row=0;

for (i=0;i<num;i++)
{
scanf("%s", files);
if (strlen(files)>max) max=strlen(files);
}

qsort(files,num,61,compare);

do
{
num_row++;
tmp=0;

for(i=0;i<num-num_row;i+=num_row)
{
tmp+=(max+2);
}

tmp+=max;


} while (tmp>60);

printf("------------------------------------------------------------\n");

for (i=0;i<num_row;i++)
{
num_col=num/num_row;
if (num%num_row!=0) num_col++;

for (tmp=0;tmp<num_col-1;tmp++)
{
if (i+tmp*num_row<num)
{
space(files[i+tmp*num_row],max+2);
}
}

space(files[i+tmp*num_row],max);

printf("\n");
}

}

return 0;
}[/c]
Dominik Michniewski
Guru
Posts: 834
Joined: Wed May 29, 2002 4:11 pm
Location: Wroclaw, Poland
Contact:

Post by Dominik Michniewski »

Names of files could contians spaces ...

Best regards
DM
If you really want to get Accepted, try to think about possible, and after that - about impossible ... and you'll get, what you want ....
Born from ashes - restarting counter of problems (800+ solved problems)
deddy one
Experienced poster
Posts: 120
Joined: Tue Nov 12, 2002 7:36 pm

400 unix is WA

Post by deddy one »

looked easy sounded easy but WA... :cry:

any trick here?? :-?

I'll send my source code or post it here if it's
necessary, although I prefer sending my source
code to anyone who wants to help :wink:
jaywinyeah
New poster
Posts: 19
Joined: Sun Aug 17, 2003 10:40 pm

Post by jaywinyeah »

I am in the same boat as you. It seems like an easy problem. Are you using Java?
LL Cool Jay
The Formula Wizard
Jason Winokur
deddy one
Experienced poster
Posts: 120
Joined: Tue Nov 12, 2002 7:36 pm

Post by deddy one »

I'm using C language.

I tried to looked back in previous post (waaay back),
apparently someone already posted AC source code
here, he use some formula to indicated terminating condition.

I haven't tried that, but in my source code everytime I print
I increment the counter and I check if counter==inputsize
then break the loop. but it gave me WA
Post Reply

Return to “Volume 4 (400-499)”