Test your skills (2006)
Author |
Message |
wtd
|
Posted: Fri Jul 14, 2006 2:33 pm Post subject: (No subject) |
|
|
Arrays work somewhat differently in Java, so it really wouldn't be much of a challenge.
That said, if you want to try, then go for it. |
|
|
|
|
|
Sponsor Sponsor
|
|
|
Null
|
Posted: Fri Jul 14, 2006 9:00 pm Post subject: (No subject) |
|
|
Quote:
Another C++ TYS.
code: |
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <cstddef>
template<typename T>
void print_all(const T *foo, size_t size) {
std::copy(foo, foo + size, typename std::ostream_iterator<T>(std::cout, "\n"));
}
int main() {
std::string foo[] = { "Hello", "world" };
print_all(foo, 2);
}
|
Partial answer. Everything is there (and in 1 line), except I don't know how you'd find the length of an array. It's just a pointer to memory.
On a related note, I don't find these challenges test one's skill, but rather they test their familiarity with the intricacies of a single language. |
|
|
|
|
|
OneOffDriveByPoster
|
Posted: Fri Jul 14, 2006 9:47 pm Post subject: (No subject) |
|
|
wtd wrote: Another C++ TYS.
code: | #include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string foo[] = {"Hello", "world"};
print_all(foo);
return 0;
} |
Make this work, such that the output is:
You may not use "sizeof" or hard-code the size of the array. In other words, it must still work if the size of the array changes.
It must also work if the type of the array is changed. For instance, if foo were an array of five integers.
Bonus points if the body of the print_all function is only one line long.
My STL is not that good, but I think this is a full solution:
code: | #include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
template <typename T, size_t N>
void print_all(T (&t)[N]) {
for (size_t i = 0; i < N; ++i) cout << t[i] << endl;
}
int main()
{
string foo[] = {"Hello", "world"};
print_all(foo);
return 0;
} |
|
|
|
|
|
|
[Gandalf]
|
Posted: Fri Jul 14, 2006 10:07 pm Post subject: (No subject) |
|
|
Just about. Though that for loop should really be two lines.
Here's wtd's solution:
c++: | #include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
template <typename T, size_t N>
void print_all(T (&arr)[N])
{
copy(arr, arr + N, ostream_iterator<T>(cout, "\n"));
}
int main()
{
string foo[] = {"Hello", "world"};
print_all(foo);
return 0;
} |
Some crazy code, I must say. |
|
|
|
|
|
Aziz
|
Posted: Fri Jul 14, 2006 11:30 pm Post subject: (No subject) |
|
|
wtd wrote: Another C++ TYS.
code: | #include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
string foo[] = {"Hello", "world"};
print_all(foo);
return 0;
} |
Make this work, such that the output is:
You may not use "sizeof" or hard-code the size of the array. In other words, it must still work if the size of the array changes.
It must also work if the type of the array is changed. For instance, if foo were an array of five integers.
Bonus points if the body of the print_all function is only one line long.
Java: | public class PrintAll
{
public static void main (String[] args )
{
String foo [] = {"Hello", "world"};
print_all (foo );
}
public static void print_all (Object[] o )
{
int i = 0;
while (true)
{
try
{
System. out. println(o [i++ ]);
}
catch (ArrayIndexOutOfBoundsException e )
{
break;
}
}
}
} |
I don't think it's quite as difficult as in c++, though? |
|
|
|
|
|
Andy
|
Posted: Sat Jul 15, 2006 12:08 am Post subject: (No subject) |
|
|
not even close... it wouldnt be an error in c++.. it would just output garbage. |
|
|
|
|
|
OneOffDriveByPoster
|
Posted: Sat Jul 15, 2006 12:09 am Post subject: (No subject) |
|
|
wtd wrote: C++ today.
code: | #include <iostream>
#include <string>
#include <algorithm>
using namespace std;
char upcase(const char original);
string capitalize(const string& s);
int main(int argc, char **argv)
{
string *args = new string[argc - 1];
copy(argv + 1, argv + argc, args);
transform(args, args + argc - 1, args, capitalize);
for (int i = 0; i < argc - 1; i++)
{
cout << i << " " << args[i] << endl;
}
delete args;
return 0;
}
char upcase(const char ch)
{
return (ch >= 97 && ch <= 122) ? ch - 32 : ch;
}
string capitalize(const string& s)
{
string dup = s;
if (dup.length() > 0)
{
dup[0] = upcase(dup[0]);
}
return dup;
}
|
I have done something wrong here. Find and explain the mistake.
The obvious one is:
which should be
.
I am not so clear about the explanation though, so here is my try at it:
argc can be 1;
args can point to a zero-length array and be distinct from a pointer to any other object;
using "plain" delete on args in such a case causes undefined behaviour (afaik).
I suspect that
is also a cause of undefined behaviour when argc is 1. |
|
|
|
|
|
OneOffDriveByPoster
|
Posted: Sat Jul 15, 2006 12:19 am Post subject: (No subject) |
|
|
[Gandalf] wrote: Just about. Though that for loop should really be two lines.
Here's wtd's solution:
c++: | #include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
template <typename T, size_t N>
void print_all(T (&arr)[N])
{
copy(arr, arr + N, ostream_iterator<T>(cout, "\n"));
}
int main()
{
string foo[] = {"Hello", "world"};
print_all(foo);
return 0;
} |
Some crazy code, I must say.
For loop is one line now (unless if I messed the code up):
code: | template <typename T, size_t N>
void print_all(T (&t)[N]) {
for (size_t i = 0; i < N; cout << t[i++] << endl);
}
|
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
[Gandalf]
|
Posted: Sat Jul 15, 2006 1:09 am Post subject: (No subject) |
|
|
Andy wrote: dump the contents of the array into the vector, and use iterators to access them?
That was my original guess as well, but how would you "dump the contents of the array into a vector" under these circumstances?
Aziz, why do that when arrays already keep track of their size in Java? Just use o.length. |
|
|
|
|
|
Aziz
|
Posted: Sat Jul 15, 2006 8:19 am Post subject: (No subject) |
|
|
[Gandalf] wrote: Andy wrote: dump the contents of the array into the vector, and use iterators to access them?
That was my original guess as well, but how would you "dump the contents of the array into a vector" under these circumstances?
Aziz, why do that when arrays already keep track of their size in Java? Just use o.length.
Trying to follow to question as much as possible...
Quote: You may not use "sizeof" or hard-code the size of the array. In other words, it must still work if the size of the array changes. |
|
|
|
|
|
wtd
|
Posted: Sat Jul 15, 2006 8:37 am Post subject: (No subject) |
|
|
OneOffDriveByPoster wrote: The obvious one is:
which should be
.
Yes.
OneOffDriveByPoster wrote: I am not so clear about the explanation though, so here is my try at it:
argc can be 1;
args can point to a zero-length array and be distinct from a pointer to any other object;
using "plain" delete on args in such a case causes undefined behaviour (afaik).
I suspect that
is also a cause of undefined behaviour when argc is 1.
This is simply pointer arithmetic. If argc is one, then one minus one is zero, and we get the same args pointer back.
The reason we use:
Is that using just delete would treat the start of the dynamic array as a pointer to a single string object. It would free the memory for that one object, but not for the remainder of the array. The correct form of delete in this case frees all of the memory used by the array.
Yes, the run-time does track information about how long the array is, so that it can do this. |
|
|
|
|
|
OneOffDriveByPoster
|
Posted: Sat Jul 15, 2006 10:58 am Post subject: (No subject) |
|
|
wtd wrote: OneOffDriveByPoster wrote: I suspect that
is also a cause of undefined behaviour when argc is 1.
This is simply pointer arithmetic. If argc is one, then one minus one is zero, and we get the same args pointer back.
I was not thinking straight--argc does not have to be 1 for the code to be wrong.
adds argc to args before subtracting one.
The result of
is undefined, afaik.
To get what you want, you need
|
|
|
|
|
|
wtd
|
Posted: Sat Jul 15, 2006 11:07 am Post subject: (No subject) |
|
|
OneOffDriveByPoster wrote: The result of
is undefined, afaik.
To get what you want, you need
It is not undefined.
args is a pointer. argc is an integer, as is "argc - 1". Adding a pointer and an integer is not undefined. It is in fact the way array access works.
Is equivalent to:
|
|
|
|
|
|
OneOffDriveByPoster
|
Posted: Sat Jul 15, 2006 11:19 am Post subject: (No subject) |
|
|
wtd wrote: OneOffDriveByPoster wrote: The result of
is undefined, afaik.
To get what you want, you need
It is not undefined.
args is a pointer. argc is an integer, as is "argc - 1". Adding a pointer and an integer is not undefined. It is in fact the way array access works.
Is equivalent to:
Seriously:
causes undefined behaviour since argc is greater than the length of args[].
I guess I was wrong to say that it is "undefined", as the operation is defined (I guess). |
|
|
|
|
|
wtd
|
Posted: Sat Jul 15, 2006 11:23 am Post subject: (No subject) |
|
|
It only produces undefined behavior if you dereference it. My code never does that. |
|
|
|
|
|
|
|