Paarkondensatoren

12

Kondensatoren sind dafür bekannt, dass sie mit hohen Toleranzen hergestellt werden. Dies ist in vielen Fällen akzeptabel, aber manchmal ist eine Kapazität mit engen Toleranzen erforderlich. Eine übliche Strategie, um eine Kapazität mit dem genauen Wert zu erhalten, den Sie benötigen, besteht darin, zwei sorgfältig abgemessene Kondensatoren parallel zu verwenden, so dass sich ihre Kapazitäten zu etwas in dem Bereich summieren, den Sie benötigen.

Das Ziel bei dieser Herausforderung besteht darin, die Kondensatoren bei einem (Mehr-) Satz von Kapazitäten so zu koppeln, dass die Gesamtkapazität jedes Paares in einem bestimmten Bereich liegt. Sie müssen auch den besten Satz von Paaren finden, dh den Satz von Paaren, so dass so viele Paare wie möglich gefunden werden.

Einschränkungen

  1. Die Eingabe erfolgt in einem Format Ihrer Wahl
    • eine ungeordnete Liste von Kapazitäten, die die (Mehr-) Menge von Kondensatoren darstellt, die Sie haben
    • ein Kapazitätspaar, das die Unter- und Obergrenze des Zielbereichs darstellt (einschließlich)
  2. Alle Kapazitäten in der Eingabe sind positive ganze Zahlen kleiner als 2 30 , die Einheit ist pF (nicht das, was zählt).
  3. Zusätzlich zu der Liste der Kapazitäten im Eingang die Menge der Kondensatoren, die Sie haben enthält auch eine unendliche Menge von Kondensatoren mit einem Wert von 0 pF.
  4. Die Ausgabe umfasst in einem Format der Wahl eine Liste von Kapazitätspaaren, so dass die Summe jedes Paares im Zielbereich liegt . Weder die Reihenfolge der Paare noch die Reihenfolge der Kapazitäten innerhalb eines Paares ist festgelegt.
  5. Möglicherweise wird keine Kapazität im Ausgang häufiger angezeigt als in den vorhandenen Kondensatoren . Mit anderen Worten: Die von Ihnen ausgegebenen Paare dürfen sich nicht überlappen.
  6. Es darf keine Ausgabe geben, die die Bedingungen 4 und 5 erfüllt und mehr Kapazitätspaare enthält als die Ausgabe, die Ihr Programm erzeugt.
  7. Ihr Programm endet in der Zeit O ( n !), In der n die Länge der Liste ist, die den Satz von Kondensatoren darstellt, die Sie haben
  8. Lücken dürfen nicht missbraucht werden
  9. Der Zielbereich darf nicht leer sein

Wertung

Ihre Punktzahl ist die Länge Ihrer Lösung in Oktetten. Wenn Ihre Lösung es schafft, dieses Problem in der Polynomzeit O ( n k ) für einige k zu lösen , dividieren Sie Ihre Punktzahl durch 10. Ich weiß nicht, ob dies tatsächlich möglich ist.

Probeneingabe

  • Bereich 100 bis 100, Eingangsarray 100 100 100 , gültige Ausgabe:

    0 100
    0 100
    0 100
    
  • Bereich 100 bis 120, Eingangsarray 20 80 100 , gültige Ausgabe:

    0 100
    20 80
    

    Die Ausgabe 20 100ist ungültig

  • Bereich 90 bis 100, Eingabearray 50 20 40 90 80 30 60 70 40, gültige Ausgabe:

    0 90
    20 80
    30 70
    40 60
    40 50
    
  • Bereich 90 bis 90, Eingabearray 20 30 40 40 50 60 70 80 90, gültige Ausgabe:

    0 90
    20 70
    30 60
    40 50
    
  • Bereich 90 bis 110, Eingabearray 40 60 50, gültige Ausgabe:

    40 60
    
FUZxxl
quelle
3
Ich bin mir ziemlich sicher, dass dies leicht in O (n log n) gelöst werden kann. Koppeln Sie zunächst einen Kondensator im Bereich 1 mit 0 pF. Sortiere den Rest. Koppeln Sie den niedrigsten und den höchsten Kondensator weiter, wenn dieser über dem Bereich liegt. Verwerfen Sie den höchsten, wenn er unter dem niedrigsten Wert liegt.
Orlp
1
Einige Ein- / Ausgabetests wären nett.
Orlp
@orlp Ich habe bereits gefragt, das OP arbeitet daran
Beta Decay
2
Der Algorithmus von @ orlp funktioniert, aber der Beweis ist ein Schatten lang für einen Kommentar. Im Wesentlichen muss ein minimales Gegenbeispiel a <= b <= c <= dsolche haben, a + d, a + c, b + ddie alle im Bereich liegen, aber b + cnicht sind, aber das gibt einen Widerspruch.
Peter Taylor
@orlp Ist die bereitgestellte Beispieleingabe für Sie hilfreich?
FUZxxl

Antworten:

1

CJam, 5.6

Dies ist eine direkte Neuimplementierung des Algorithmus in der Antwort von orlp . Wenn Sie meine Antwort positiv bewerten, stellen Sie bitte sicher, dass Sie diese Antwort ebenfalls positiv bewerten . Ich schlage auch vor, dass die Antwort mit dem ursprünglichen Algorithmus akzeptiert wird, weil ich sehr bezweifle, dass ich herausgefunden hätte, wie man dies elegant in O (n * log (n)) löst.

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

Probieren Sie es online aus

Beispieleingabe:

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

Erläuterung:

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.
Reto Koradi
quelle
Sie können das Ausgabeformat ändern, um es an Ihre Sprache anzupassen. Das genaue Ausgabeformat ist nicht angegeben, nur die auszugebenden Daten.
FUZxxl
6

Python 2, 11.5

Ein Python-Golf für einmal:

(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)]

Ich füge einen 0 pF Kondensator für jeden regulären hinzu, es wird nie mehr benötigt. Dann sortieren wir die Kondensatoren und koppeln weiterhin den niedrigsten und den höchsten Kondensator. Wenn die Summe innerhalb des zulässigen Bereichs liegt, drucken wir sie, wenn sie über dem Bereich liegt, verwerfen wir die höchste, wenn sie unter dem niedrigsten Wert liegt, verwerfen wir die niedrigste.

Beispiel Ein- / Ausgabe:

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

0 90
20 80
30 70
40 60
40 50
orlp
quelle