Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reverse and Alphabetize in under 2kb

9 views
Skip to first unread message

Chad

unread,
Mar 2, 2010, 6:13:52 PM3/2/10
to
Here is the job interview question that I drew a blank on.

Make a C program that:

Accepts a string input
Displays the original string
Reverses the order of words in the string ("This is a string" =
"string a is This")
Alphabetizes the letters in each word individually ("hisT is a
ginrst")

It all has to be under 2kb and I can't use strtok().

Eric Sosman

unread,
Mar 2, 2010, 6:23:21 PM3/2/10
to

Seems simple enough except for the "under 2kb" part.
What's that supposed to mean? Less than 2KB of source code?
All other "2KB" measures I can think of (code size, data
size, stack size, heap size, ...) would be entirely platform-
dependent and not directly controllable by the way you use
the C language. Even HelloWorld probably takes more than
2KB of executable code on most implementations.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Chad

unread,
Mar 2, 2010, 6:39:11 PM3/2/10
to

Yeah, the 2kb part is what confused me. I was just assuming they meant
the size of the executable file.

bartc

unread,
Mar 2, 2010, 6:39:19 PM3/2/10
to

"Chad" <cda...@gmail.com> wrote in message
news:d66e64ad-0553-4127...@c37g2000prb.googlegroups.com...

> Here is the job interview question that I drew a blank on.
>
> Make a C program that:
>
> Accepts a string input
> Displays the original string
> Reverses the order of words in the string ("This is a string" =
> "string a is This")
> Alphabetizes the letters in each word individually ("hisT is a
> ginrst")

What do you mean by alphabetize? And what happened to reversal, or did you
want this separately from the alphabetizing?

I got:

"ginrst a is This"

by reversing the words and sorting the characters in each word (but all
upper case come before all lower case).

--
Bartc

Chad

unread,
Mar 2, 2010, 7:06:42 PM3/2/10
to
On Mar 2, 3:39 pm, "bartc" <ba...@freeuk.com> wrote:
> "Chad" <cdal...@gmail.com> wrote in message

I figured they wanted reversal and alphabetizing done separately.

rudolf

unread,
Mar 2, 2010, 10:45:14 PM3/2/10
to
In article
<8a7fb132-246f-4212...@s25g2000prd.googlegroups.com>,
Chad <cda...@gmail.com> wrote:

You know that you can ask the interviewer questions, right? If you
don't understand what they are asking of you, ask them them to clarify
the question.

pete

unread,
Mar 2, 2010, 10:52:11 PM3/2/10
to
Eric Sosman wrote:
> On 3/2/2010 6:13 PM, Chad wrote:
>
>> Here is the job interview question that I drew a blank on.
>>
>> Make a C program that:

>> It all has to be under 2kb and I can't use strtok().


>
>
> Seems simple enough except for the "under 2kb" part.
> What's that supposed to mean?

The assignment as stated, is to make a C program.

A C program is composed of text files.

--
pete

Richard Heathfield

unread,
Mar 3, 2010, 1:40:18 AM3/3/10
to

The trick to this question is to realise that the third stage (reversing
the word order) is greatly simplified by the fourth stage (alphabetising
the letters in each word). In stage 3, it is sufficient to reverse the
entire string; you don't need to detect word boundaries at that point.

Stage 4 then becomes a simple parse-and-qsort loop.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Michael Foukarakis

unread,
Mar 3, 2010, 2:15:27 AM3/3/10
to
On Mar 3, 1:13 am, Chad <cdal...@gmail.com> wrote:
> Here is the job interview question that I drew a blank on.
>
> Make a C program that:
>
> Accepts a string input
> Displays the original string
> Reverses the order of words in the string ("This is a string" =
> "string a is This")

Is the output from this stage needed to be made visible?

> Alphabetizes the letters in each word individually ("hisT is a
> ginrst")

I assume, from your parenthesized example, this is independent
(conceptually) from stage 3?

Willem

unread,
Mar 3, 2010, 4:12:08 AM3/3/10
to
Chad wrote:
) Here is the job interview question that I drew a blank on.
)
) Make a C program that:
)
) Accepts a string input
) Displays the original string
) Reverses the order of words in the string ("This is a string" =
) "string a is This")

) Alphabetizes the letters in each word individually ("hisT is a
) ginrst")
)

) It all has to be under 2kb and I can't use strtok().

- How is the string delivered ?
- Can you use strpbrk, strcspn, strchr or whatever ?
- What exactly is, and isn't, a word ?
- Is it only required that the results are printed, or do they also
have to be present as actual strings somewhere during execution ?
- Does 'alphabetize' mean case-insensitive ?
- Can you use the character values to sort on, other than case ?
- What exactly has to be 'under 2kb' ?

Assumed answers:
- On the commandline, as a single argument (so it's argv[1])
- Yes
- A word is anyting that is not a ' ' character
- They only need to be printed
- Yes, case-insensitive
- Yes you can (works both in ASCII and EBCDIC)
- The source code, after whitespace is removed where possible

Although a lot of those are pretty arbitrary.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT

Richard Heathfield

unread,
Mar 3, 2010, 4:25:32 AM3/3/10
to

The problem with making code size the only priority is that you end up
with something like this:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef size_t i;
void r(char*s){char t;i
n=strlen(s),b=0,e=n-1;if(n>1)while(b<e)t=s[b],s[b++]=s[e],s[e--]=t;}int
c(const void *l, const void *r){const char *b=l,*e=r;return
(*b>*e)-(*b<*e);}int g(char*l,i m,FILE*f,i*n){int
c;*n=0;--m;while(*n<m&&(c=getc(f))!=EOF&&c!=EOF&&c!='\n')*l++=c,++*n;*l=0;return
c==EOF;}i a(const char*s){i c=0;while(*s==' ')++c,++s;return c;}i
z(const char *s){i c=0;while(*s&&*s!=' ')++s,++c;return c;}int
main(){char l[128];i n=0,b,t;while(!g(l,sizeof
l,stdin,&n)){b=0,r(l);while(b<n)b+=a(l+b),t=z(l+b),qsort(l+b,t,1,c),printf("%.*s
",(int)t,l+b),b+=t;putchar('\n');}return 0;}

Willem

unread,
Mar 3, 2010, 5:07:50 AM3/3/10
to
Richard Heathfield wrote:
) pete wrote:
)> Eric Sosman wrote:
)>> On 3/2/2010 6:13 PM, Chad wrote:
)>>
)>>> Here is the job interview question that I drew a blank on.
)>>>
)>>> Make a C program that:
)>
)>>> It all has to be under 2kb and I can't use strtok().
)>>
)>>
)>> Seems simple enough except for the "under 2kb" part.
)>> What's that supposed to mean?
)>
)> The assignment as stated, is to make a C program.
)>
)> A C program is composed of text files.
)
) The problem with making code size the only priority is that you end up
) with something like this:

<snip excellent example of compressed code>

Well, actually 2Kb is a pretty reasonable size for this exercise.
Even if you use sensible variable and function names, and straightforward
algorithms, you're unlikely to breach that requirement. My first try
(for both exercises) reached about 600 bytes, which is easily compressed
down to under 500:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
void r(char *s)
{
if(!*s)return;
size_t l=strcspn(s," \t\n");
if(s[l]){
r(s+l+1);
putchar(s[l]);
}
fwrite(s,l,1,stdout);
}
void a(char *s)
{
while(*s){
size_t i,l=strcspn(s," \t\n");
int c;
for(c='a';c<='z';c++)
for(i=0;i<l;i++)
if(tolower(s[i])==c)
putchar(s[i]);
s+=l;
if(*s)putchar(*s++);
}
}
int main(int c, char *v[])
{
r(v[1]);putchar('\n');
a(v[1]);putchar('\n');
return 0;
}


Ben Bacarisse

unread,
Mar 3, 2010, 9:25:18 AM3/3/10
to
Richard Heathfield <r...@see.sig.invalid> writes:

> Chad wrote:
>> Here is the job interview question that I drew a blank on.
>>
>> Make a C program that:
>>
>> Accepts a string input
>> Displays the original string
>> Reverses the order of words in the string ("This is a string" =
>> "string a is This")
>> Alphabetizes the letters in each word individually ("hisT is a
>> ginrst")
>>
>> It all has to be under 2kb and I can't use strtok().
>
> The trick to this question is to realise that the third stage
> (reversing the word order) is greatly simplified by the fourth stage
> (alphabetising the letters in each word). In stage 3, it is sufficient
> to reverse the entire string; you don't need to detect word boundaries
> at that point.

That does not match the example though. Applying stage 4 to the
result of stage 3 would yield "ginrst a is hisT". Of course, the
trouble is that the only specified output is the original string, so
your guess about what is expected is a good as mine.

> Stage 4 then becomes a simple parse-and-qsort loop.

I assumed the trick was to abstract the idea of "doing something to a
word" so that the strings specified in both stage 3 and, separately,
stage 4 could be produced with minimal code.

--
Ben.

Chad

unread,
Mar 3, 2010, 11:29:52 AM3/3/10
to
On Mar 2, 11:15 pm, Michael Foukarakis <electricde...@gmail.com>
wrote:

> On Mar 3, 1:13 am, Chad <cdal...@gmail.com> wrote:
>
> > Here is the job interview question that I drew a blank on.
>
> > Make a C program that:
>
> > Accepts a string input
> > Displays the original string
> > Reverses the order of words in the string ("This is a string" =
> > "string a is This")
>
> Is the output from this stage needed to be made visible?
>
Uh.... I guess.

> > Alphabetizes the letters in each word individually ("hisT is a
> > ginrst")
>
> I assume, from your parenthesized example, this is independent
> (conceptually) from stage 3?

Yes

Keith Thompson

unread,
Mar 3, 2010, 1:10:29 PM3/3/10
to
Willem <wil...@snail.stack.nl> writes:
> Chad wrote:
> ) Here is the job interview question that I drew a blank on.
> )
> ) Make a C program that:
> )
> ) Accepts a string input
> ) Displays the original string
> ) Reverses the order of words in the string ("This is a string" =
> ) "string a is This")
> ) Alphabetizes the letters in each word individually ("hisT is a
> ) ginrst")
> )
> ) It all has to be under 2kb and I can't use strtok().
>
> - How is the string delivered ?
> - Can you use strpbrk, strcspn, strchr or whatever ?
> - What exactly is, and isn't, a word ?
> - Is it only required that the results are printed, or do they also
> have to be present as actual strings somewhere during execution ?
> - Does 'alphabetize' mean case-insensitive ?
> - Can you use the character values to sort on, other than case ?
> - What exactly has to be 'under 2kb' ?
>
> Assumed answers:
> - On the commandline, as a single argument (so it's argv[1])

The program "Accepts a string input". The word "input" tends to imply
reading from stdin. Also, argv doesn't give you a string; it gives
you a list of strings. You can arbitrarily construct a single string
by, say, joining the arguments with spaces, but that's not specified
in the problem statement.

If argv[1] is "one two" and argv[2] is "three four", is that two words
or four?

> - Yes
> - A word is anyting that is not a ' ' character

I'm sure you didn't mean to say that "abc" is three words. One
reasonable definition is that a word is a maximal non-empty substring
consisting only of non-whitespace characters, but that needs to be
clarified.

> - They only need to be printed
> - Yes, case-insensitive

Hmm, I'm not sure I would have assumed case-insensitivity, but the
word "alphabetizes" does tend to imply it. But this should
be clarified.

> - Yes you can (works both in ASCII and EBCDIC)
> - The source code, after whitespace is removed where possible

The stated requirements don't imply to me that whitespace may be
removed; I would assume it's the full size of the source file.
(Which argues for using a Unix-like system rather than Windows,
so each end-of-line is only 1 byte rather than 2.)

> Although a lot of those are pretty arbitrary.

Yup.

Turning unclear requirements into clear requirements is an important
skill for a programmer. A job interview is a good opportunity to
demonstrate this skill. (In one interview, I spent so much time
discussing the requirements for a problem that I never actually
had to solve the problem itself. Yes, I got the job.)

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Willem

unread,
Mar 3, 2010, 6:14:28 PM3/3/10
to
Keith Thompson wrote:
) Willem <wil...@snail.stack.nl> writes:
)> - Yes
)> - A word is anyting that is not a ' ' character
)
) I'm sure you didn't mean to say that "abc" is three words. One
) reasonable definition is that a word is a maximal non-empty substring
) consisting only of non-whitespace characters, but that needs to be
) clarified.

That's roughly what I meant, yes.

)> - They only need to be printed
)> - Yes, case-insensitive
)
) Hmm, I'm not sure I would have assumed case-insensitivity, but the
) word "alphabetizes" does tend to imply it. But this should
) be clarified.

The example given by the OP also implies case-insensitivity.

)> - Yes you can (works both in ASCII and EBCDIC)
)> - The source code, after whitespace is removed where possible
)
) The stated requirements don't imply to me that whitespace may be
) removed; I would assume it's the full size of the source file.
) (Which argues for using a Unix-like system rather than Windows,
) so each end-of-line is only 1 byte rather than 2.)

Then you could make a 'better' program by removing the whitespace yourself.
Note I said 'where possible', meaning to imply that the result should still
compile and work.

As it turns out, it can be done quite easily in 1Kb, though.

Peter Nilsson

unread,
Mar 3, 2010, 8:40:02 PM3/3/10
to
Willem <wil...@snail.stack.nl> wrote:
<snip>

> As it turns out, it can be done quite easily in 1Kb, though.

Indeed.

% type obfuscate.c
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define q1(q2,q3) (((q3)<(q2))-((q2)<(q3)))
int q4(const void*q5,const void*q6){const char*q7="abcdefgh"
"ijklmnopqrstuvwxyz";const unsigned char*q8=q5;const unsigned
char*r9=q6;unsigned char q10=tolower(*q8);unsigned char q11=
tolower(*r9);const char*q12=strchr(q7,q10);const char*q13=
strchr(q7,q11);if(q12&&q13)return q1(q12-q7,q13-q7);if(q12)
return-1;if(q13)return+1;return q1(q10,q11);}void q14(char*
q15,char*q16){if(!q16)q16=q15+strlen(q15);if(q15!=q16)for(;
q15<--q16;q15++){char q17;q17=*q15;*q15=*q16;*q16=q17;}}int
main(void){static char q18[1024];char*q15,*q16;if(fgets(q18,
sizeof q18,stdin)){char*q19=strchr(q18,'\n');if(q19)*q19=0;
puts(q18);q14(q18,0);for(q15=q18;*q15;q15=q16){q15=q15+strspn
(q15," \t");q16=q15+strcspn(q15," \t");q14(q15,q16);}puts(
q18);for(q15=q18;*q15;q15=q16){q15=q15+strspn(q15," \t");q16
=q15+strcspn(q15," \t");qsort(q15,q16-q15,1,q4);}puts(q18);}
return 0;}

% acc obfuscate.c -o homework.exe

% type input.txt
This is a string

% homework.exe < input.txt
This is a string
string a is This
ginrst a is hisT

% dir obfuscate.c
Volume in drive E is USB DISK
Volume Serial Number is 14CC-F5A9

Directory of E:\C

04/03/2010 12:30 PM 1,000 obfuscate.c
1 File(s) 1,000 bytes
0 Dir(s) 906,080,256 bytes free

%

--
Peter

Willem

unread,
Mar 4, 2010, 12:04:30 PM3/4/10
to
Peter Nilsson wrote:
) Willem <wil...@snail.stack.nl> wrote:
)<snip>
)> As it turns out, it can be done quite easily in 1Kb, though.
)
) Indeed.
)
) % type obfuscate.c

<snip 1000-byte very obfuscated code>

With reasonable variable and function names, I get 666 bytes:
(Note that the original has tabs for indent, which I substituted
for spaces for usenet purposes.)

#include <stdio.h>
#include <string.h>
#include <ctype.h>

void reverse(char *str)
{
if(!*str) return;
size_t len = strcspn(str," \t\n");
if(str[len]) {
reverse(str+len+1);
putchar(str[len]);
}
fwrite(str, len, 1, stdout);
}

void sortwords(char *str)
{
while(*str) {
size_t i, len = strcspn(str," \t\n");
int c;
for(c = 'a'; c <= 'z'; c++) {
for(i = 0; i < len; i++) {
if(tolower(str[i]) == c) {
putchar(str[i]);
}
}
}
str += len;
if(*str) {
putchar(*str++);
}
}
}

int main()
{
char str[1024];
if (fgets(str, sizeof str, stdin)) {
reverse(str);
putchar('\n');
sortwords(str);


putchar('\n');
}
return 0;
}

Which just goes to show that algorithmic improvements are an
order of magnitude more important than peephole optimizations.

0 new messages