posts - 20, comments - 570, trackbacks - 57

NQuiz #1 - Soluzioni

Il problema da risolvere era il seguente:

Dato un array di N numeri interi, array, con N - 1 numeri dispari e 1 numero pari, si chiede di implementare la funzione:

public static int FindEvenValue(int[] array)

che ritorni il numero pari contenuto nell'array. NON si ammettono istruzioni di selezione, istruzioni di iterazione oppure dell'operatore condizionale "?". Si presuppone che i parametri siano validi e che l'implementazione non richieda una verifica di questi.

Comincio col proporre la mia soluzione e poi elencherò quelle dei partecipanti (in ordine di arrivo).

La mia soluzione si basa sul principio che per conoscere il numero pari bisogna prima di tutto conoscere la sua posizione nell'array. Per determinare l'indice abbiamo due possibilità: o lo cerchiamo nell'array esistente (la soluzione più ovvia se potessimo fare un ciclo) oppure modifichiamo l'array in modo che il numero pari venga spostato in una posizione che conosciamo, ben definita, per esempio la posizione 0. Una modifica, senza usare istruzioni di iterazione o di selezione, è la chiamata del metodo statico Array.Sort, che nella sua versione classica dispone i valori dell'array in ordine crescente, dal più piccolo al più grande.

Tuttavia, questo ordinamento non ci è molto di aiuto perché il numero pari continuerebbe a nascondersi fra quelli dispari e la sua posizione resterebbe un'incognita. Però, se osserviamo con più attenzione, Array.Sort ha una dichiarazione in cui accetta un IComparer, la guida per effettuare l'ordinamento, un'interfaccia che possiamo implementare secondo le nostre esigenze per dire al framework che due oggetti non rispettano le solite regole e si susseguono secondo una logica probabilmente nuova. Siccome abbiamo solo un numero pari, possiamo ordinare l'array in modo che i numeri pari risultino più piccoli di quelli dispari, così il nostro risultato finirà magicamente nella posizione 0.

La classe che ho implementato per questo scopo si chiama OddEvenComparer, con il metodo Compare che restituisce -1 se x < y,  0 se x = y e 1 se x > y:

public class OddEvenComparer: IComparer {
  public int Compare(object x, object y) {
    int a = Convert.ToInt32(x);
    int b = Convert.ToInt32(y);
    return Math.Abs(a) % 2 - Math.Abs(b) % 2;
  }
}

Richiamare Math.Abs sugli interi diventa fondamentale per gestire i numeri negativi, che altrimenti rischierebbero di far impazzire :-) la funzione.

L'implementazione del metodo FindEvenValue è banale:

public static int FindEvenValue(int[] array) {
  Array.Sort(array, new OddEvenComparer());
  return array[0];
}

Questa è la mia soluzione, ma qui sotto ne troverete anche di più belle :-)

// Luca Mauri (1)

public static int FindEvenValue(int[] array) {
  int eval = 0;
  try {
    ArrayList list = new ArrayList(array);
    eval = (int)list[0];
    eval = 1 / (eval % 2);
    list.RemoveAt(0);
    return FindEvalValue((int[])list.ToArray(typeof(int)));
  }
  catch {
    return eval;
  }
}

Matteo Flora (2) ha pensato la mia stessa soluzione.

// Massimo Prota (3)

public static int FindEvenValue(int[] array) {
  BitArray ba = new BitArray(array);
  ArrayList al = ArrayList.Repeat(0x1, array.Length);
  BitArray mask = new BitArray((int[])al.ToArray(typeof(int)));
  ba.And(mask);
  int[] result = new int[array.Length];
  ba.CopyTo(result, 0);
  return array[Array.IndexOf(result, 0)];
}

// Andrea Cavallari (4)

public static int FindEvenValue(int[] array) {
  int tot =  (1 + (array.Length - (array.Length % 2))) * ((array.Length + (array.Length % 2)) / 2);
  return array[tot - Ricorsion(array, 0) - 1];
}

private static int Ricorsion(int[] array, int index) {
  try {
    return ((index + 1) * (Math.Abs(array[index]) % 2)) +  Ricorsion(array, index + 1);
  }
  catch {
    return 0;
  }
}

// Cristiano Muzi (5)

public class MyObj {
  public int Value = 0;

  public override bool Equals(object obj) {
    int remainder;
    Math.DivRem((int)obj, 2, out remainder);
    remainder = Math.Abs(remainder);
    Value -= (int)obj * (remainder - 1);
    return false;
  }

  public override int GetHashCode() {
    return 0;
  }
}

public static int FindEvenValue(int[] array) {
  MyObj myObj = new MyObj();
  Array.IndexOf(array, myObj);
  return myObj.Value;
}

// Adrian Florea (6)

public static int FindEvenValue(int[] array) {
  XmlSerializer xs = new XmlSerializer(typeof(int[]));
  MemoryStream ms = new MemoryStream();
  XmlDocument xd = new XmlDocument();
  xs.Serialize(ms, array);
  ms.Position = 0;
  xd.Load(ms);
  ms.Close();
  return Convert.ToInt32(
    xd.SelectSingleNode("ArrayOfInt/int[node() = node() * ((node() * node() + 1) mod 2)]"
 
).InnerText);
}

Ad Adrian il riconoscimento per la soluzione più originale :-)

Grazie e complimenti a tutti.

flavio.polesello(@)adriacom(.)it

Print | posted on martedì 20 luglio 2004 10:57 |

Feedback

Gravatar

# Happy New Year

Shop at Etsy to find unique and handmade happy new year 2018 related items directly from our sellers.
17/05/2017 16:25 | Happy New Year
Gravatar

# re: NQuiz #1 - Soluzioni

The propeller planes of the company were replaced with Jets in 1960. Delta Airline made its first international venture to Europe in 1970’s followed by Pacific in 1980’s. The Delt Air Service got merged with Northwest Airlines on April 14, 2008, to create the world’s largest Airline service.

28/12/2017 17:46 | deltanet
Gravatar

# re: NQuiz #1 - Soluzioni

Really i appreciate the attempt you done according to piece the knowledge. This is without a doubt a great enter because of sharing. Keep such above. Thanks because of sharing.
13/04/2018 14:42 | phd dissertation writer
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET