Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Friday's Coding Challenge

Friday's Coding Challenge

Scheduled Pinned Locked Moved The Lounge
c++architectureperformancehelplounge
76 Posts 35 Posters 6 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Chris Maunder

    What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

    cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

    Y Offline
    Y Offline
    YvesDaoust
    wrote on last edited by
    #57

    If you don't care about time, sort the whole array and parameter n is virtually useless !

    S(a, m); // Solution in a[0..n-1]

    where S stands for some sorting algorithm on an array. Slightly shorter in Python, assuming a has length m:

    S(a) # Solution in a[0..n-1]

    1 Reply Last reply
    0
    • C Chris Maunder

      What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

      cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

      G Offline
      G Offline
      George Danila
      wrote on last edited by
      #58

      var nSmallestNumbers = numbers.OrderBy(x => x).Take(n);

      1 Reply Last reply
      0
      • G Gary Wheeler

        You win the "We Can't Judge Your Submission Because It's Incomprehensible" award.

        Software Zen: delete this;

        B Offline
        B Offline
        BobJanova
        wrote on last edited by
        #59

        Thanks but it's actually simple and the same as everyone else's:

        f←{
        sorted←⍵⌷⍨⍋⍵; // sorts the right argument
        ⍺↑sorted // first n items (n = left argument)
        }

        1 Reply Last reply
        0
        • C Chris Maunder

          What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

          cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

          U Offline
          U Offline
          User 8615306
          wrote on last edited by
          #60

          maybe in F# (doesn't check if n < X.Length): let nsmallest X n = (Array.sort X).[0..(n-1)]

          1 Reply Last reply
          0
          • C Chris Maunder

            What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

            cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

            S Offline
            S Offline
            Spectre_001
            wrote on last edited by
            #61

            // Setup
            int n = 2;
            int[] m = { 3, 5, 7, 1, 8, 4, 2 };
            int[] smallest = (int[])Array.CreateInstance(typeof(int), n);

            // My answer
            Array.Sort(m); Array.ConstrainedCopy(m, 0, smallest, 0, n);

            Kevin Rucker, Application Programmer QSS Group, Inc. United States Coast Guard OSC Kevin.D.Rucker@uscg.mil "Programming is an art form that fights back." -- Chad Hower

            1 Reply Last reply
            0
            • C Chris Maunder

              What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

              cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

              E Offline
              E Offline
              eltashi
              wrote on last edited by
              #62

              Hi there, nice challenge ! Didn't want to use language built in array sorting, since that makes the solution obvious. Ok ok, recursion is dangerous, but looks nice :)

              function reduceTo(arr,n){

              if (n==arr.length) return arr;
              var next=Array();
              	
              for (i=0,max=0; i\=arr\[max\]) {
              		if (max!=i) next\[next.length\]=arr\[max\];
              		max=i;
              	}
              	else{
              		next\[next.length\]=arr\[i\];
              	}
              }
              
              return reduceTo(next,n);
              

              }

              1 Reply Last reply
              0
              • C Chris Maunder

                What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

                cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                F Offline
                F Offline
                faceless5579
                wrote on last edited by
                #63

                in Java :-) (without dublicates handling) // given an array of ints: m // and a number n, for example n =4 // we can use a java.util.TreeSet (that is, ordered set) to do the job: TreeSet result = new TreeSet (); for (int mcnt=0; mcnt < m.length ; mcnt++) if (result.size() < n) { result.add(m[mcnt]); continue; } else { int curMax = result.last(); if (curMax > m[mcnt]) { result.remove(curMax); result.add(m[mcnt]); } }

                1 Reply Last reply
                0
                • C Chris Maunder

                  What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

                  cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                  T Offline
                  T Offline
                  Trajan McGill
                  wrote on last edited by
                  #64

                  A submission in C:

                  #include
                  int*f(int*s,int m,int n){int i,c,*a=(int*)malloc(n*sizeof(int));for(;n;m--,s++){for(i=1,c=0;i
                  Assumptions: the numbers are integers, "smaller" for negative numbers means "more negative", and the initial set of numbers is stored as an array. A different data structure would require reworking the algorithm, but the first two assumptions are easy to change with a few extra bytes-- for instance, for doubles, we can do it as:

                  #include
                  #define D double
                  D*f(D*s,int m,int n){int i,c;D*a=(D*)malloc(n*sizeof(D));for(;n;m--,s++){for(i=1,c=0;i
                  and for a "closer to zero" definition of smaller numbers, the integer version would change to:

                  #include
                  #include
                  int*f(int*s,int m,int n){int i,c,*a=(int*)malloc(n*sizeof(int));for(;n;m--,s++){for(i=1,c=0;i
                  If you test it, don't forget to free() the returned array. And for heaven's sake, don't ever write real code like this (and I don't just mean the formatting).

                  1 Reply Last reply
                  0
                  • Y YvesDaoust

                    Slightly modified Straight Selection Sort will do the trick (moves n lowest elements first):

                    for (int i= 0; i < n; i++)
                    {
                    int k = i;
                    for (int j= i; j < m; j++)
                    {
                    if (a[k] > a[j])
                    {
                    k = j;
                    }
                    }

                    int swap= a\[i\]; a\[i\]= a\[k\]; a\[k\]= swap;
                    

                    }

                    IMHO, allowing function calls makes the challenge nonsensical, as the solutions reduces to S(a, m, n), where S is the function that does just that.

                    T Offline
                    T Offline
                    Trajan McGill
                    wrote on last edited by
                    #65

                    Ahh, shoot, you're right. The requirements didn't specify a non-destructive algorithm. Your method, turned into an actual function, with a few optimizations and a bit of non-essential character elimination, reduces to:

                    void g(int*a,int m,int n){int i=0,j,k,t;for(;ia[j])k=j;}

                    which beats mine by 50 characters (49 if I chop out the one removable whitespace character I missed in my solution). If we modify it further to toss out the array notation and instead do horrible things with pointers, we can even save 6 more:

                    void g(int*a,int m,int n){int*i=a,*j,*k,t;for(;i*j)k=j;}

                    Y 2 Replies Last reply
                    0
                    • C Chris Maunder

                      What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

                      cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                      B Offline
                      B Offline
                      Bob Beechey
                      wrote on last edited by
                      #66

                      If our list is the_list in Python we have new_list = sorted(the_list)[:n]

                      1 Reply Last reply
                      0
                      • P PIEBALDconsult

                        SELECT TOP n FROM Sample ORDER BY Value Edit: How should we handle duplicates?

                        K Offline
                        K Offline
                        KP Lee
                        wrote on last edited by
                        #67

                        That won't work in sql. :) (n isn't a number and value isn't selected)

                        1 Reply Last reply
                        0
                        • T Trajan McGill

                          Ahh, shoot, you're right. The requirements didn't specify a non-destructive algorithm. Your method, turned into an actual function, with a few optimizations and a bit of non-essential character elimination, reduces to:

                          void g(int*a,int m,int n){int i=0,j,k,t;for(;ia[j])k=j;}

                          which beats mine by 50 characters (49 if I chop out the one removable whitespace character I missed in my solution). If we modify it further to toss out the array notation and instead do horrible things with pointers, we can even save 6 more:

                          void g(int*a,int m,int n){int*i=a,*j,*k,t;for(;i*j)k=j;}

                          Y Offline
                          Y Offline
                          YvesDaoust
                          wrote on last edited by
                          #68

                          And as said in my next post (have a look into the future), passing argument n is unessential, use m instead and spare 6 characters.

                          T 1 Reply Last reply
                          0
                          • T Trajan McGill

                            Ahh, shoot, you're right. The requirements didn't specify a non-destructive algorithm. Your method, turned into an actual function, with a few optimizations and a bit of non-essential character elimination, reduces to:

                            void g(int*a,int m,int n){int i=0,j,k,t;for(;ia[j])k=j;}

                            which beats mine by 50 characters (49 if I chop out the one removable whitespace character I missed in my solution). If we modify it further to toss out the array notation and instead do horrible things with pointers, we can even save 6 more:

                            void g(int*a,int m,int n){int*i=a,*j,*k,t;for(;i*j)k=j;}

                            Y Offline
                            Y Offline
                            YvesDaoust
                            wrote on last edited by
                            #69

                            You can also get rid of variable i by working backwards, and benefit from a little of C's syntaxic sugar:

                            void g(int a[], int m)
                            {
                            while (m)
                            {
                            int k= --m, j= m;
                            while (j)
                            k= a[k] < a[--j] ? k : j;

                            	int s= a\[m\]; a\[m\]= a\[k\]; a\[k\]= s;
                            }
                            

                            }

                            (This code guaranteed unchecked for correctness :-)) Applying your transforms should give something shorter than ever.

                            1 Reply Last reply
                            0
                            • C Chris Maunder

                              What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

                              cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                              Y Offline
                              Y Offline
                              YvesDaoust
                              wrote on last edited by
                              #70

                              This is a straight selection sort, processing back to front and doing immediate swaps to avoid index bookeeping.

                              void g(int a[], int m)
                              {
                              for (int s, p; p= --m;)
                              while (p--)
                              if (s= a[m], a[p] > s)
                              a[m]= a[p], a[p]= s;
                              }

                              or, said shortly,

                              void g(int*a,int m){for(int s,p;p=--m;)while(p--)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                              The requested solution lies in a[0..n-1]. I guess it will be hard to improve on this straight selection approach, given that - two nested loops are required, - two decreasing indexes are required (m and p), - a swap variable is required (s), - a key comparison is required, - three assignments are required for the swaps, wherever they take place.

                              T 1 Reply Last reply
                              0
                              • Y YvesDaoust

                                And as said in my next post (have a look into the future), passing argument n is unessential, use m instead and spare 6 characters.

                                T Offline
                                T Offline
                                Trajan McGill
                                wrote on last edited by
                                #71

                                Good point, once you're doing a sort like this, you might as well just sort the whole array.

                                Y 2 Replies Last reply
                                0
                                • T Trajan McGill

                                  Good point, once you're doing a sort like this, you might as well just sort the whole array.

                                  Y Offline
                                  Y Offline
                                  YvesDaoust
                                  wrote on last edited by
                                  #72

                                  Yep, they say running time is for free...

                                  1 Reply Last reply
                                  0
                                  • T Trajan McGill

                                    Good point, once you're doing a sort like this, you might as well just sort the whole array.

                                    Y Offline
                                    Y Offline
                                    YvesDaoust
                                    wrote on last edited by
                                    #73

                                    And by the way, I have explored an approach where the high values in the array are allowed to be destroyed. Just passing parameter n spoils this effort !

                                    1 Reply Last reply
                                    0
                                    • Y YvesDaoust

                                      This is a straight selection sort, processing back to front and doing immediate swaps to avoid index bookeeping.

                                      void g(int a[], int m)
                                      {
                                      for (int s, p; p= --m;)
                                      while (p--)
                                      if (s= a[m], a[p] > s)
                                      a[m]= a[p], a[p]= s;
                                      }

                                      or, said shortly,

                                      void g(int*a,int m){for(int s,p;p=--m;)while(p--)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                                      The requested solution lies in a[0..n-1]. I guess it will be hard to improve on this straight selection approach, given that - two nested loops are required, - two decreasing indexes are required (m and p), - a swap variable is required (s), - a key comparison is required, - three assignments are required for the swaps, wherever they take place.

                                      T Offline
                                      T Offline
                                      Trajan McGill
                                      wrote on last edited by
                                      #74

                                      Actually, we can do away with one of the loops if we make use of some evaluation short circuiting trickery to make one loop act like two. Thus this:

                                      void g(int*a,int m){for(int s,p;p=--m;)while(p--)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                                      becomes this:

                                      void g(int*a,int m){for(int s,p=0;p--||(p=--m);)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                                      which saves us one whole character. :) It might be possible to figure out a way to cut off a couple more, I'm not sure. I've considered, but not had enough time to exhaust, possibilities like going forward vs. backward on either one or both of the iterators, using a pointer rather than an index into the array, whether sorting in reverse order (putting the smallest elements at the end of the array rather than the beginning) might help, and the possibility of somehow using the array itself for swapping to eliminate a variable, but probably most of these are going to add code rather than reduce it. There's also the possibility of a recursive solution, but I haven't really tried that at all. I have to go do some real work, unfortunately, but this C solution is getting surprisingly close in length to some of the solutions using languages with handy built-in functions to do this sort of thing.

                                      Y 1 Reply Last reply
                                      0
                                      • T Trajan McGill

                                        Actually, we can do away with one of the loops if we make use of some evaluation short circuiting trickery to make one loop act like two. Thus this:

                                        void g(int*a,int m){for(int s,p;p=--m;)while(p--)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                                        becomes this:

                                        void g(int*a,int m){for(int s,p=0;p--||(p=--m);)if(s=a[m],a[p]>s)a[m]=a[p],a[p]=s;}

                                        which saves us one whole character. :) It might be possible to figure out a way to cut off a couple more, I'm not sure. I've considered, but not had enough time to exhaust, possibilities like going forward vs. backward on either one or both of the iterators, using a pointer rather than an index into the array, whether sorting in reverse order (putting the smallest elements at the end of the array rather than the beginning) might help, and the possibility of somehow using the array itself for swapping to eliminate a variable, but probably most of these are going to add code rather than reduce it. There's also the possibility of a recursive solution, but I haven't really tried that at all. I have to go do some real work, unfortunately, but this C solution is getting surprisingly close in length to some of the solutions using languages with handy built-in functions to do this sort of thing.

                                        Y Offline
                                        Y Offline
                                        YvesDaoust
                                        wrote on last edited by
                                        #75

                                        Nice trick !

                                        1 Reply Last reply
                                        0
                                        • C Chris Maunder

                                          What's the smallest code you can come up with to find the n smallest numbers in a random sample of m numbers where n < m. Any language, speed is not an issue.

                                          cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP

                                          M Offline
                                          M Offline
                                          Member 8085210
                                          wrote on last edited by
                                          #76

                                          Let x be such a sample. Then x[rank(x)<=n] is such a subsample, in R. If there are elements in the sample that are repeated and you want the first n different numbers, it is a bit more complicated, since you have to check first that there are at least n different elements in your sample, using ux<-unique(x), for instance.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups