Coppia di condensatori


12

I condensatori sono noti per essere fabbricati con tolleranze elevate. Ciò è accettabile in molti casi, ma a volte è richiesta una capacità con tolleranze strette. Una strategia comune per ottenere una capacità con il valore esatto necessario è quella di utilizzare due condensatori attentamente misurati in parallelo in modo che le loro capacità si sommino a qualcosa nell'intervallo di cui hai bisogno.

L'obiettivo di questa sfida è, dato un (multi) set di capacità, accoppiare i condensatori in modo tale che la capacità totale di ciascuna coppia sia in un dato intervallo. È inoltre necessario trovare il miglior set di accoppiamenti, ovvero il set di accoppiamenti in modo tale da trovare quante più coppie possibili.

vincoli

  1. L'input comprende un formato a scelta
    • un elenco non ordinato di capacità che rappresentano il (multi) set di condensatori che hai
    • una coppia di capacità che rappresentano il limite inferiore e superiore dell'intervallo target (inclusivo)
  2. tutte le capacità in ingresso sono numeri interi positivi inferiori a 2 30 , l'unità è pF (non è quello che conta).
  3. Oltre all'elenco delle capacità in ingresso, l'insieme di condensatori che hai contiene anche una quantità infinita di condensatori con un valore di 0 pF.
  4. L'output comprende in un formato a scelta un elenco di coppie di capacità tali che la somma di ciascuna coppia sia nell'intervallo target specificato. Non viene specificato né l'ordine delle coppie né l'ordine delle capacità all'interno di una coppia.
  5. Nessuna capacità nell'output può apparire più spesso di quanto appaia nel set di condensatori che hai . In altre parole: le coppie che emetti non devono sovrapporsi.
  6. Non devono esserci output possibili che soddisfino le condizioni 4 e 5 che contengano più coppie di capacità rispetto all'output prodotto dal programma.
  7. Il programma terminerà tra O ( n !) Tempo in cui n è la lunghezza della lista che rappresenta l'insieme di condensatori che hai
  8. Le scappatoie non devono essere abusate
  9. L' intervallo target non deve essere vuoto

punteggio

Il tuo punteggio è la lunghezza della tua soluzione in ottetti. Se la tua soluzione riesce a risolvere questo problema nel tempo polinomiale O ( n k ) per qualche k , dividi il tuo punteggio per 10. Non so se questo sia effettivamente possibile.

Input di esempio

  • intervallo da 100 a 100, array di input 100 100 100, output valido:

    0 100
    0 100
    0 100
    
  • intervallo da 100 a 120, array di input 20 80 100, output valido:

    0 100
    20 80
    

    l'output 20 100non è valido

  • intervallo da 90 a 100, array di input 50 20 40 90 80 30 60 70 40, output valido:

    0 90
    20 80
    30 70
    40 60
    40 50
    
  • intervallo da 90 a 90, array di input 20 30 40 40 50 60 70 80 90, output valido:

    0 90
    20 70
    30 60
    40 50
    
  • intervallo da 90 a 110, array di input 40 60 50, output valido:

    40 60
    

3
Sono abbastanza sicuro che questo possa essere facilmente risolto in O (n log n). Innanzitutto, associare qualsiasi condensatore all'interno dell'intervallo a uno con 0 pF. Ordina il resto. Continuare ad accoppiare il condensatore più basso e più alto, se questo è al di sopra dell'intervallo scartare il più alto, se al di sotto scartare il più basso.
Orlp,

1
Alcuni test di input / output sarebbero belli.
Orlp,

@orlp Ho già chiesto, l'OP ci sta lavorando
Decadimento beta

2
L'algoritmo di @ orlp funziona, ma la prova è lunga per un commento. In sostanza, un controesempio minimo deve avere a <= b <= c <= dtali che a + d, a + c, b + dsono tutti nella gamma ma b + cnon lo sono, ma ciò dà una contraddizione.
Peter Taylor,

@orlp L'input di esempio fornito ti è stato utile?
FUZxxl,

Risposte:


1

CJam, 5.6

Questa è una reimplementazione diretta dell'algoritmo nella risposta di orlp . Se voti la mia risposta, assicurati di votare anche questa risposta . Suggerisco anche che la risposta con l'algoritmo originale sia accettata, perché dubito fortemente che avrei capito come risolverlo elegantemente in O (n * log (n)).

l~_,0a*+${(\)@_2$+4$~2$\>{;;\;\+}{<{;+}{oSop}?}?_,1>}g;;

Provalo online

Input di esempio:

[90 100] [50 20 40 90 80 30 60 70 40]

Spiegazione:

l~      Get and interpret input.
_,      Get length of resistor list.
0a*+    Append the same number of 0 values.
$       Sort the list.
{       Loop until less than 2 entries in list.
  (       Pop off first value.
  \)      Pop off last value.
  @_      Pull first value to top, and copy it.
  2$      Copy last value to top.
  +       Add first and last value.
  4$~     Copy specified range to top, and unwrap the two values.
  2$      Copy sum to top.
  \>      Swap and compare for sum to be higher than top of range.
  {       It's higher.
    ;;\;    Some stack cleanup.
    \+      Put first value back to start of resistor list.
  }
  {       Not higher, so two cases left: value is in range, or lower.
    <       Compare if sum is lower than bottom of range.
    {       It's lower.
      ;+      Clean up stack and put last value back to end of resistor list.
    }
    {       Inside range, time to produce some output.
      o       Output first value.
      So      Output space.
      p       Output second value and newline.
    }?      Ternary operator for comparison with lower limit.
  }?      Ternary operator for comparison with upper limit.
  _,      Get length of remaining resistor list.
  1>      Check if greater 1.
}g      End of while loop for processing resistor list.
;;      Clean up stack, output was generated on the fly.

Puoi modificare il formato di output per renderlo più adatto alla tua lingua. Il formato esatto dell'output non è specificato, lo sono solo i dati che devi emettere.
FUZxxl

6

Python 2, 11.5

Un golf Python per una volta:

(a,b),l=input()
l=[0]*len(l)+sorted(l)
while l:
 e=l[0]+l[-1]
 if a<=e<=b:print l[0],l[-1]
 l=l[e<=b:len(l)-(a<=e)]

Aggiungo un condensatore 0 pF per ogni normale, non ce ne sono mai più necessari. Quindi ordiniamo i condensatori e continuiamo ad accoppiare il condensatore più basso e più alto. Se la somma rientra nell'intervallo consentito, la stampiamo, se è al di sopra dell'intervallo, scartiamo il massimo, se al di sotto scarta il minimo.

Esempio di input / output:

[[90,100], [20,30,40,40,50,60,70,80,90]]

0 90
20 80
30 70
40 60
40 50
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.