Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Generic algorithms

Name: Anonymous 2008-11-28 11:31

Implement a single function that takes two arguments and returns the bigger of the two. Assume you don't know the type of the  arguments and you don't know if the types can be compared. Assume that if a type can be compared, it will always be implemented by following a single standard. Use the latest standard of your language. Write the simplest program
that will pass an integer 1(one) and a float 1.1(one point one) into the function and write the result to standard output.

Post the compiler you used, the code and the result.
Write what will happen if the max function is called with broken syntax (I'm looking at you C macros).
Write what will happen if the objects of a type can't be compared.

I'll start with C and C++.
Compiler: gcc 4.3.2 20081105 (Red Hat 4.3.2-7)
#include <iostream>
template<class F>
F& max(F& a, F& b) { return (a < b) ? b : a; }
int main() { std::cout << max(1, 1.1) << '\n'; }

Results: Compile time error:
max.cpp: In function ‘int main()’:
max.cpp:6: error: no matching function for call to ‘max(int, double)’

Bad syntax: Standard compile-time error
No comparison: Standard compile-time error about undefined operator<

#define max(a, b) (less(a, b) ? b : a)
#include <stdio.h>
int less(int a, int b) { return a < b; }
int main() { printf("%f\n", max(1, 1.1)); }

Result: Bad output
1.000000
Bad syntax: Depends on the error in the syntax. Can either compile and cause undefined behaviour or fail at compile time with strange syntax errors.
No comparison: Standard compile-time error about an undefined function.

Name: Anonymous 2008-11-28 11:55

sub max($$){
    my($a,$b)=@_;
   
    $a>$b?$a:$b
}

print max 1,1.1

Name: Anonymous 2008-11-28 14:01

This is biased towards weakly-typed languages, since 1 > 1.1 may not even be possible in strongly-typed languages.

Haskell
I'll assume the caller calls fromInteger. There's already a built-in max function, but for the purposes of demonstration,

max x y | x >= y = x
        | otherwise = y

main = print $ max (fromInteger 1) 1.1


Result: 1.1
Bad syntax: Fails to compile.
No comparison: Compile-time error about the missing Ord type class instance.

C++0x (theoretical, I haven't tried it)

#include <iostream>

template<typename T1, typename T2>
where LessThanComparable<T1, T2>
auto max(const T1& a, const T1& b) -> decltype(a + b) //This works by promoting the smaller type.
{
    if(a < b)
        return b;
    return a;
}

int main() {
    endl(std::cout << max(1, 1.1));
}


Result: 1.1
Bad syntax: compile-time error.
No comparison: compile-time error (comprehensible).

Ruby
def max a, b; a < b ? b : a; end

puts (max 1, 1.1)

Result: 1.1
Bad syntax: syntax error.
No comparison: runtime error.

INSTANT.EXE
Just press a few buttons and it's done.
Result: 1.1
Bad syntax: not possible.
No comparison: everything is comparable.

Name: Anonymous 2008-11-28 14:22

Common Lisp
(defun mymax (a b) (max a b))
or
(defun mymax (a b) (if (a > b) a b))

Name: Anonymous 2008-11-28 14:25

>>4
Obviously I skipped writing to standard output because that's for retards.

Name: Anonymous 2008-11-28 16:22

>>1,3
They have this exact example in the Wiki about Sepplesox:


template<typename T> requires LessThanComparable<T>
const T& min(const T &x, const T &y)
{
  return y < x ? y : x;
}

auto concept LessThanComparable<typename T>
{
  bool operator<(T, T);
}

Name: Anonymous 2008-11-28 16:28

>>6
Surely that would suffer the same problem as >>1, because the argument types aren't the same.

Name: Anonymous 2008-11-28 18:04

>>7

int main() { std::cout << min(1, 1.1) << '\n'; }
1

Name: Anonymous 2008-11-28 18:14

Is the challenge to use some old faggy language with a weak set of libraries?

If you used a modern development framework like .Net you would just use the Math.Max function. That only works for numeric types though. If you want to compare non-numeric or dissimilar types you just implement the iComparable or iComparable<T> interfaces and maybe a TypeConverter.

public class Compare<T> where T : IComparable<T>
{
     public static T Max(T a, T b)
     {
         return (a.CompareTo(b)) ? b : a;
     }
}

Call it like:
Compare.Max<double>(1, 1.1);

Although int and double are not the same type, it will compile and run just fine. int implements a TypeConverter to convert from int to double for the comparison. So this function can be used for any type implementing the standard iComparable interface and if they are dissimilar types, one type needs a TypeConver implemented to convert to the other type.

Why anyone continues to use the abortion that is C++ for anything except legacy maintenance is beyond any sane developer.

Name: Anonymous 2008-11-28 18:16

Fuck, I meant Compare<double>.Max(1, 1.1);

Name: Anonymous 2008-11-28 18:23

>>9
There's no challenge in doing this exercise in your omg abstracted languages. Try doing this in x86, you vagabond.

Name: Anonymous 2008-11-28 19:29

>>8
Oh, I see.

I just realised >>1 was stupid and didn't provide a max that works on const F&. I assumed the compiler error was that int != double.

Name: Anonymous 2008-11-28 19:46

>>6
What did you compile that with?

Name: Anonymous 2008-11-28 19:50

>>9
POST. FUCKING. RESULTS.

Name: Anonymous 2008-11-28 20:11

>>14
Had to clean up the code a bit:

public class Compare<T> where T : IComparable<T>
    {
        public static T Max(T a, T b)
        {
            return (a.CompareTo(b) < 0) ? b : a;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Compare<double>.Max(1, 1.1));
        }
    }

Prints 1.1

Name: Anonymous 2008-11-28 20:12

>>14
Had to clean up the code a bit:

public class Compare<T> where T : IComparable<T>
    {
        public static T Max(T a, T b)
        {
            return (a.CompareTo(b) < 0) ? b : a;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Compare<double>.Max(1, 1.1));
        }
    }

Prints 1.1

Name: Anonymous 2008-11-28 21:39


#include <stdio>

#define bigger(a, b) (sizeof(b) > sizeof(a) ? (b) : (a))
#define str(x) #x

int main(void){
 puts(str(bigger(1, 1.1)));
 return 0;
}


Result: 1.1
Bad syntax: syntax error
No comparison: not possible

Name: Anonymous 2008-11-29 1:05

Language: x86 Asm
Compiler: Human Brain
Results: 1.1
Bad syntax: Assembler complains
No comparison: Bits are bits, it'll compare them anyway

Name: Anonymous 2008-11-29 4:46

>>17
Clever but that's not what I meant.
Your supposed to compare instances of the same type with a supplied comparison function/operator/whatever. Yours doesn't  compare an integer 1 with a 2 properly.

Name: Anonymous 2008-11-29 7:17

>>19
Implement a single function that takes two arguments and returns the bigger of the two.
if that's not what you meant, you should have said what you meant instead.

Name: Anonymous 2008-11-29 7:25

>>20
Are you blind? I've supplied two code examples. tl;dr, huh?

Name: Anonymous 2008-11-29 7:47

>>8
$ gcc -std=c++0x max.cpp
max.cpp: In function ‘int main()’:
max.cpp:12: error: no matching function for call to ‘max(int, double)’

Am I doing something wrong here?

Name: Anonymous 2008-11-29 8:07

>>21
you said you wanted the bigger of the two. your code examples are both broken, and therefore not very useful for trying to figure out what you wanted to do.

Name: Anonymous 2008-11-29 8:57

>>22
Using Sepplesox?

Name: Anonymous 2008-11-29 9:15

using System;

class OPIsAFaggot {
 public static T max<T>(T a, T b) where T : IComparable<T> {
  return a.CompareTo(b) < 0 ? b : a;
 }

 public static void Main(){
  Console.WriteLine(max<Double>(1, 1.1));
 }
}


result: 1.1
broken syntax: compile-time syntax error
no comparison: compile-time type error

Name: Anonymous 2008-11-29 10:24


T_INT = 0
T_FLOAT = 1
struct val {
    .type rb 1
    .value rq 1
}
section .data

inty: val T_INT, 1
floaty: val T_FLOAT, 1.1
printy: db "%d", 10, 0

section .text
max:
    cmp T_INT, byte [rdi]
    je .int
.float:
    cmp T_FLOAT, byte [rsi]
    je .floats
    push rdi
    mov rsi, rdi
    call convertToFloat
    pop rdi
.floats:
    jmp maxOfFloats
.int:
    cmp T_INT, byte [rsi]
    je .ints
    call convertToFloat
    jmp .float
.ints:
    jmp maxOfInts

main:
    mov rdi, inty
    mov rsi, floaty
    xor rax, rax
    call max
    mov rsi, rax
    mov rdi, printy
    xor rax, rax
    call printf
    xor rax, rax
    ret


The maxOfFloats, maxOfInts, convertToFloat, and customized printf function is left as an exercise to the reader.

prints: 1.1
broken syntax: You get laughed at.
no comparison: They are compared as floats.

Name: Faggot OP 2008-11-29 12:23

>>4
This one is interesting. How do I define a comparison function for non-primitive types so that I can use it with types other than numbers?

>>23
How is it broken? They both compile and run fine. If you can't run a compiler properly then at least write an example in something that won't tax your pair of brain cells too much (like FIOC). and stop trolling.

Name: Anonymous 2008-11-29 15:28

>>26
rax
0/10

Name: Anonymous 2008-11-29 15:55

>>22
Yes, for you see yhbt.

Name: Anonymous 2008-11-29 17:21

>>16

Thank you sir. For extra credit I would love to see someone implement a single function like that (not using managed C++) that can correctly return on these inputs.
Console.WriteLine(Compare<double>.Max(1, 1.1));
Console.WriteLine(Compare<double>.Max("1", 1.1));
Console.WriteLine(Compare<double>.Max(1, "1.1"));
Console.WriteLine(Compare<double>.Max("1", "1.1"));

All of those will return 1.1 calling the same function with no modifications.

Name: Anonymous 2008-11-29 17:52

static class Compare<T>
    where T : IComparable<T>
{
    public static T Max<A1, A2>(A1 a1, A2 a2)
        where A1 : IConvertible
        where A2 : IConvertible
    {
        T t1 = (T)a1.ToType(typeof(T), System.Globalization.CultureInfo.InvariantCulture);
        T t2 = (T)a2.ToType(typeof(T), System.Globalization.CultureInfo.InvariantCulture);
        return t1.CompareTo(t2) < 0 ? t2 : t1;
    }
}

Console.WriteLine(Compare<double>.Max(1, 1.1));
Console.WriteLine(Compare<double>.Max("1", 1.1));
Console.WriteLine(Compare<double>.Max(1, "1.1"));
Console.WriteLine(Compare<double>.Max("1", "1.1"));

Name: Anonymous 2008-11-29 18:57

This thread is pure ENTERPRISE generic bullshite.

Name: Anonymous 2008-11-29 20:22

System.Globalization.CultureInfo.InvariantCulture
what

Name: Anonymous 2008-11-30 0:49

>>33
It sounds to me like you need to learn to respect other people's InvariantCulture.

Name: Anonymous 2008-11-30 1:00

>>30
Console.WriteLine(Compare<double>.Max("1", 1.1));
Console.WriteLine(Compare<double>.Max(1, "1.1"));
Console.WriteLine(Compare<double>.Max("1", "1.1"));

error CS0029: Cannot implicitly convert type `string' to `double'

Name: Anonymous 2008-11-30 12:44


#include <iostream>
#include <algorithm>
#include <boost/lexical_cast.hpp>

using namespace std;

template<typename T, typename A, typename B>
T max(const A& a, const B& b)
{
    return max(boost::lexical_cast<T>(a), boost::lexical_cast<T>(b));
}

int main()
{
    cout << max<double>(1, 1.1) << endl;
    cout << max<double>("1", 1.1) << endl;
    cout << max<double>(1, "1.1") << endl;
    cout << max<double>("1", "1.1") << endl;
    return 0;
}

Name: Anonymous 2008-11-30 17:31

>>33

Holy fuck, so many amateurs on this fucking board. Can;t even use Google. Insist on posting first to make themselves look like an idiot.

When you grow up and write programs that actually people actually use, you will find out some of those people do not live in the same fucking country as you. Some data is formatted differently depending if you are an American or a terrorist(Rest of the World).

What date is this: 01/02/2009?

If you are an American you would say January 2nd. If you are a terrorist you would say it February 1st. So when converting and comparing types that contain data that is formatted in a way specific to a region, you need to take in to account how faggy that region is. If you are developing on some faggy legacy language and/or framework, it probably does not have these conventions built in. .Net does because it is not faggy.

But I think >>31 should have used System.Threading.Thread.CurrentThread.CurrentCulture.

Name: Anonymous 2008-11-30 17:42

.Net does because it is not faggy.
because it is not faggy.
is not faggy.
not faggy.

Name: Anonymous 2008-11-30 17:47

>>37
But I think >>31 should have used System.Threading.Thread.CurrentThread.CurrentCulture.
Yeah, if he was a fucking retard.  Globalization is there to make things more compatible, not to give your program a chance to blow up whenever it's run in a different region.

Name: ID: Heaven 2008-11-30 18:10

To expand upon >>39's post:

InvariantCulture is for things that the user doesn't see (such as configuration files, perhaps), CurrentUICulture for localizing string and bitmap resources, and CurrentCulture for formatting dates and numbers displayed to the user.

____________________
http://blogs.msdn.com/michkap/archive/2007/01/11/1449754.aspx

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List