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 programming quiz

Friday programming quiz

Scheduled Pinned Locked Moved The Lounge
linqcsharpdata-structuresjsonfunctional
46 Posts 24 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.
  • J Offline
    J Offline
    jesarg
    wrote on last edited by
    #1

    I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

    int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
    int closest = // put a LINQ lambda expression here

    If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

    A L B J S 16 Replies Last reply
    0
    • J jesarg

      I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

      int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
      int closest = // put a LINQ lambda expression here

      If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

      A Offline
      A Offline
      AspDotNetDev
      wrote on last edited by
      #2

      Your sample solution has at least two issues I can see:

      1. It may explode if inputs is empty. Then again, the expected behavior for that case isn't defined, so that may be fine.
      2. The variable "avg" seems to have been created out of thin air.

      Thou mewling ill-breeding pignut!

      J A 2 Replies Last reply
      0
      • A AspDotNetDev

        Your sample solution has at least two issues I can see:

        1. It may explode if inputs is empty. Then again, the expected behavior for that case isn't defined, so that may be fine.
        2. The variable "avg" seems to have been created out of thin air.

        Thou mewling ill-breeding pignut!

        J Offline
        J Offline
        jesarg
        wrote on last edited by
        #3

        Fixed issue number 2 by copy-pasting the correct code this time. Didn't think too much about issue number 1, and seeing as this is my first posted programming quiz, I should get a little slack.

        H 1 Reply Last reply
        0
        • J jesarg

          Fixed issue number 2 by copy-pasting the correct code this time. Didn't think too much about issue number 1, and seeing as this is my first posted programming quiz, I should get a little slack.

          H Offline
          H Offline
          Henry Minute
          wrote on last edited by
          #4

          jesarg wrote:

          I should get a little slack.

          Here ya go[^].

          Henry Minute Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.” I wouldn't let CG touch my Abacus! When you're wrestling a gorilla, you don't stop when you're tired, you stop when the gorilla is. Cogito ergo thumb - Sucking my thumb helps me to think.

          1 Reply Last reply
          0
          • A AspDotNetDev

            Your sample solution has at least two issues I can see:

            1. It may explode if inputs is empty. Then again, the expected behavior for that case isn't defined, so that may be fine.
            2. The variable "avg" seems to have been created out of thin air.

            Thou mewling ill-breeding pignut!

            A Offline
            A Offline
            A Orozco
            wrote on last edited by
            #5

            In order to get rid of the avg variable so that it doesn't look like created out of thin air, you can replace it with inputs.Average(). As for the unexpected behaviour when the inputs array is empty, you can substitute First() with FirstOrDefault(). This prevents the code from exploding but, as you mentioned, since the expected behaviour is not defined, the result might not be the desired. I must say though, the proposed solution has a nested Lambda expression which contradicts the quiz requirement to use a "Single LINQ Lambda statement" Cheers!

            J L 2 Replies Last reply
            0
            • J jesarg

              I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

              int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
              int closest = // put a LINQ lambda expression here

              If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

              L Offline
              L Offline
              leppie
              wrote on last edited by
              #6

              jesarg wrote:

              inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

              You seem to like O^42 complexity :)

              IronScheme
              ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x)))

              J 1 Reply Last reply
              0
              • A A Orozco

                In order to get rid of the avg variable so that it doesn't look like created out of thin air, you can replace it with inputs.Average(). As for the unexpected behaviour when the inputs array is empty, you can substitute First() with FirstOrDefault(). This prevents the code from exploding but, as you mentioned, since the expected behaviour is not defined, the result might not be the desired. I must say though, the proposed solution has a nested Lambda expression which contradicts the quiz requirement to use a "Single LINQ Lambda statement" Cheers!

                J Offline
                J Offline
                jesarg
                wrote on last edited by
                #7

                Already replaced the avg with inputs.Average() before you posted. :) I triple-checked the post before posting it the first time, but still made that mistake; hopefully, nobody else sees it. As for the nested Lambda expression, it only has one semi-colon in it, so to me it counts as a single LINQ lambda statement. Maybe I should say "LINQ lambda statement with only one semi-colon at the end", but that would be confusing, and I'd get a ton of people asking for clarification. In any case, thank you for the feedback, and I'll be sure to refine my quiz-posting skills from all this. In the meantime, somebody should try and post their own solution; it's not much of a programming quiz without a few more solutions.

                P 1 Reply Last reply
                0
                • A A Orozco

                  In order to get rid of the avg variable so that it doesn't look like created out of thin air, you can replace it with inputs.Average(). As for the unexpected behaviour when the inputs array is empty, you can substitute First() with FirstOrDefault(). This prevents the code from exploding but, as you mentioned, since the expected behaviour is not defined, the result might not be the desired. I must say though, the proposed solution has a nested Lambda expression which contradicts the quiz requirement to use a "Single LINQ Lambda statement" Cheers!

                  L Offline
                  L Offline
                  leppie
                  wrote on last edited by
                  #8

                  Andres Orozco Correa wrote:

                  FirstOrDefault()

                  I think DefaultOrEmpty() is preferred.

                  IronScheme
                  ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x)))

                  1 Reply Last reply
                  0
                  • L leppie

                    jesarg wrote:

                    inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                    You seem to like O^42 complexity :)

                    IronScheme
                    ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x)))

                    J Offline
                    J Offline
                    jesarg
                    wrote on last edited by
                    #9

                    Although I don't know how the LINQ is resolved, it looks like it can't be worse than O(N^3). The Average() function costs N, the Min() costs N, the Where equals costs N, and the Select Average costs N * N. The worst nesting is N * N * N. Edited: it's at worst O(N^3).

                    L K 2 Replies Last reply
                    0
                    • J jesarg

                      Although I don't know how the LINQ is resolved, it looks like it can't be worse than O(N^3). The Average() function costs N, the Min() costs N, the Where equals costs N, and the Select Average costs N * N. The worst nesting is N * N * N. Edited: it's at worst O(N^3).

                      L Offline
                      L Offline
                      leppie
                      wrote on last edited by
                      #10

                      jesarg wrote:

                      it's at worst O(N^3).

                      See you in a few years when a billion iterations finish ;p

                      IronScheme
                      ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x)))

                      J 1 Reply Last reply
                      0
                      • L leppie

                        jesarg wrote:

                        it's at worst O(N^3).

                        See you in a few years when a billion iterations finish ;p

                        IronScheme
                        ((λ (x) `(,x ',x)) '(λ (x) `(,x ',x)))

                        J Offline
                        J Offline
                        jesarg
                        wrote on last edited by
                        #11

                        It remains sub-second time up until around 450 elements, so any test case you manually type should work fine. You think you can put together a solution that's O(N^2)?

                        Y 1 Reply Last reply
                        0
                        • J jesarg

                          I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                          int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                          int closest = // put a LINQ lambda expression here

                          If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                          B Offline
                          B Offline
                          BillWoodruff
                          wrote on last edited by
                          #12

                          +5 Interesting challenge, even though far beyond my linquidity. Would like to take a course in Linq from you, because I feel "stymied" in my attempts to advance beyond kindergarten-level using it, assuming I am constitutionally linquidable, that is. best, Bill

                          "It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle

                          J J 2 Replies Last reply
                          0
                          • J jesarg

                            I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                            int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                            int closest = // put a LINQ lambda expression here

                            If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                            J Offline
                            J Offline
                            Johnny J
                            wrote on last edited by
                            #13

                            "We don't do homework!" AND "No programming questions in the Lounge..." ;P

                            Why can't I be applicable like John? - Me, April 2011
                            -----
                            Beidh ceol, caint agus craic againn - Seán Bán Breathnach
                            -----
                            Da mihi sis crustum Etruscum cum omnibus in eo!
                            -----
                            Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932

                            P 1 Reply Last reply
                            0
                            • J jesarg

                              I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                              int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                              int closest = // put a LINQ lambda expression here

                              If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                              S Offline
                              S Offline
                              Samuel Cragg
                              wrote on last edited by
                              #14

                              Not a very efficient approach (and hope I'm not cheating, there is only one semi-colon!) but here goes:

                              int closest = (from t in
                              from i in inputs
                              let avg = inputs.Average()
                              select new { Number = i, Delta = Math.Abs(i - avg) }
                              orderby t.Delta
                              select t.Number).FirstOrDefault();

                              J K 2 Replies Last reply
                              0
                              • J jesarg

                                I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                                int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                                int closest = // put a LINQ lambda expression here

                                If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                                R Offline
                                R Offline
                                Ravi Bhavnani
                                wrote on last edited by
                                #15

                                Won't work when inputs is of zero length. :) /ravi

                                My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                A 1 Reply Last reply
                                0
                                • B BillWoodruff

                                  +5 Interesting challenge, even though far beyond my linquidity. Would like to take a course in Linq from you, because I feel "stymied" in my attempts to advance beyond kindergarten-level using it, assuming I am constitutionally linquidable, that is. best, Bill

                                  "It is the mark of an educated mind to be able to entertain a thought without accepting it." Aristotle

                                  J Offline
                                  J Offline
                                  Johnny J
                                  wrote on last edited by
                                  #16

                                  BillWoodruff wrote:

                                  linquidity

                                  Interesting term... I think I'll adopt that! :-D

                                  Why can't I be applicable like John? - Me, April 2011
                                  -----
                                  Beidh ceol, caint agus craic againn - Seán Bán Breathnach
                                  -----
                                  Da mihi sis crustum Etruscum cum omnibus in eo!
                                  -----
                                  Just because a thing is new don’t mean that it’s better - Will Rogers, September 4, 1932

                                  1 Reply Last reply
                                  0
                                  • R Ravi Bhavnani

                                    Won't work when inputs is of zero length. :) /ravi

                                    My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                    A Offline
                                    A Offline
                                    AspDotNetDev
                                    wrote on last edited by
                                    #17

                                    Ahem.

                                    Thou mewling ill-breeding pignut!

                                    R 1 Reply Last reply
                                    0
                                    • A AspDotNetDev

                                      Ahem.

                                      Thou mewling ill-breeding pignut!

                                      R Offline
                                      R Offline
                                      Ravi Bhavnani
                                      wrote on last edited by
                                      #18

                                      :thumbsup: /ravi

                                      My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com

                                      1 Reply Last reply
                                      0
                                      • J jesarg

                                        I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                                        int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                                        int closest = // put a LINQ lambda expression here

                                        If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                                        P Offline
                                        P Offline
                                        PIEBALDconsult
                                        wrote on last edited by
                                        #19

                                        jesarg wrote:

                                        you must use nothing but a single LINQ lambda statement

                                        Frack that; I thought you said this was a programming quiz.

                                        1 Reply Last reply
                                        0
                                        • J jesarg

                                          I promised a programming quiz a couple weeks ago, so here's one: Given an array of integers, select the integer in the array that is the closest to the average of all integers in the array; you must use nothing but a single LINQ lambda statement. If more than one integer is the closest, then any of the closest integers will do. For example, the following code should assign "14" to the int "closest":

                                          int[] inputs = {1, 2, 3, 5, -1, 7, 145, -33, 22, 14};
                                          int closest = // put a LINQ lambda expression here

                                          If you're up for actually figuring out your own solution, ignore the rest of this post. OR If you're lazy and unethical, feel free to copy-paste the sample solution in the small text below and claim it as your own. inputs.Where(x => Math.Abs(x - inputs.Average()) == inputs.Select(y => Math.Abs(y - inputs.Average())).Min()).First();

                                          D Offline
                                          D Offline
                                          Daniel Grunwald
                                          wrote on last edited by
                                          #20

                                          int closest = inputs.OrderBy(i => Math.Abs(i - inputs.Average())).FirstOrDefault();

                                          This is O(N²) as Average() gets called for every sort key that gets calculated. We can do better by storing the average in a variable. And we can use LINQ to introduce variables within an expression:

                                          int closest = (from avg in new[] { inputs.Average() }
                                          from i in inputs
                                          orderby Math.Abs(i - avg)
                                          select i).FirstOrDefault();

                                          This is O(N log N), but note that instead of sorting, we just need to find the minimum. Sadly, all the Min() methods compare the element itself, not just a key. However, we can build a suitable implementation using Aggregate():

                                          int closest = (from avg in new[] { inputs.Average() }
                                          select inputs.Aggregate((a, b) => Math.Abs(a - avg) < Math.Abs(b - avg) ? a : b)
                                          ).Single();

                                          This runs in linear time, and does pretty much the same as an implementation using a loop would do.

                                          J A 2 Replies 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