Ordnen Sie bis zu 10 in einem Array zu

8

Herausforderung

Berechnen Sie bei einem Array mit einstelligen Zahlen, ob zwei davon 10 ergeben, und drucken Sie sie aus

Beispiel

Eingang

(1,2,3,4,5,5,6,7)

Dies kehrt zurück ((4,6),(5,5),(3,7))

Eingang

(1,2,3,4,5)

Dies kehrt zurück (). da gibt es nur eine 5

Eingang

(5,5,5,5,5)

Dies kehrt zurück, ((5,5),(5,5))da es eine ungerade Anzahl von 5s gibt und jede 5 nur einmal verwendet werden kann

Regeln

Hier sind die Regeln!

  • Angenommen, die Eingabe ist nur ein unsortiertes Array positiver einstelliger Ganzzahlen
  • Jede Zahl wird nur einmal gepaart, dh wenn es drei 5er gibt, bildet sie nur 1 Paar (5,5). Wenn es (3,3,7) gibt, bildet es nur 1 Paar (3,7)
  • Für die Eingabe: Sie können jede Art von Klammern (oder das Fehlen von Klammern) verwenden, solange die Leser erkennen können, dass die Eingabe ein einzelnes Array von Zahlen ist.
  • Für die Ausgabe: Es muss wie ein Array von Paaren aussehen. Wenn das Array dieselbe Form wie Ihre Eingabe hat (Wenn Sie in Ihrer Eingabe keine Klammern verwendet haben, müssen Sie Symbole verwenden, damit jeder Leser erkennen kann, dass es sich um Paare in einem Array handelt.)

Testfälle

(1,2,3,4,5,5,6,7) =((4,6),(5,5),(3,7))
(1,2,3,4,5) = ()
(5,5,5,5,5) = ((5,5),(5,5))
(1,2,3,3,4,5,6,7)=((3,7),(4,6))
(9,8,7,6,4,4,3,1)=((9,1),(7,3),(6,4))

Viel Glück!

Die shorterAntwort lautet: Je besser!

Bearbeiten 1: Aktualisieren Sie die Regeln und Testfälle anhand von Kommentaren

Bearbeiten 2: Aktualisieren Sie die Regeln, um das Eingabeformat zu definieren.

Bearbeiten 3: Aktualisieren Sie die Regeln, um das Ausgabeformat zu definieren. versuchen, so entgegenkommend wie möglich zu sein.

user1655072
quelle
2
Sollte es nicht 10 verschiedene Kombinationen (5,5)für den endgültigen Testfall geben?
Gareth
@ Gareth Es sieht so aus, als würden die Werte aufgebraucht, wenn sie Paare bilden
Matt
Könnten Sie noch ein paar Testfälle posten? Vielleicht so etwas wie(1,2,3,3,4,5,6,7)
Matt
@Matt bearbeitet. Vielen Dank für das Feedback
user1655072
Muss die Eingabe die Klammern enthalten oder kann sie als eingegeben werden 1,2,3,4,5,5,6,7?
jdstankosky

Antworten:

7

GolfScript, 45 42 37 Zeichen

~{([.~11+.])@{1$=.{2$p!\}*!},\;\;.}do

Der neue Ansatz verwendet auch Arrays mit einem einzelnen Element als Eingabe. Darüber hinaus ist es einige Zeichen kürzer.

Vorherige Version:

~{$(\)@.2$+10-.{0>{\}*;+}{;[\]p}if.,1>}do;

Der in diesem Code verwendete Algorithmus wird wie folgt beschrieben:

  • Sortieren Sie das Array.
  • Nehmen Sie die Summe aus erstem und letztem Gegenstand.
    • Wenn die Summe 10 ist, drucken Sie beide Zahlen und entfernen Sie sie aus dem Array.
    • Wenn die Summe größer als 10 ist, verwerfen Sie die größere Zahl.
    • Wenn die Summe kleiner als 10 ist, verwerfen Sie die kleinere Zahl.
  • Schleife, bis das Array nur noch eine Ziffer enthält oder sogar leer ist.

Der Code erwartet in STDIN ein Array mit mindestens zwei Ziffern.

Beispiele (siehe online ):

>[9 8 7 6 4 4 3 1]
[1 9]
[3 7]
[4 6]

>[5 5 5 5 5]
[5 5]
[5 5]
Howard
quelle
9

Python 2.7 (70)

y=input()
while y:
 g=10-y.pop()
 if g in y:y.remove(g);print(g,10-g)

Testfälle:

$ echo '[1, 2, 3, 4, 5, 5, 6, 7]' | python p.py
(3, 7)
(4, 6)
(5, 5)

$ echo '[1,2,3,4,5]' | python p.py

$ echo '[5,5,5,5,5]' | python p.py
(5, 5)
(5, 5)

$ echo '[1,2,3,3,4,5,6,7]' | python p.py
(3, 7)
(4, 6)

$ echo '[9,8,7,6,4,4,3,1]' | python p.py
(9, 1)
(7, 3)
(6, 4)

Ein Byte extra für die schöne Klammer.

Daniel
quelle
Ich glaube, ich habe diese Methode in PHP repliziert, aber sie funktioniert nur gelegentlich und nicht bei allen Paaren. Irgendeine Idee warum? <?$a=fgetcsv(STDIN);while($a){$b=10-array_pop($a);if($a[$b]){unset($a[$b]);echo"($b,",10-$b,")";}}
jdstankosky
5

Javascript, 188 183 181 153 141 121 123 112 112 105 98 Zeichen

Golfen in JS ist etwas schwierig, aber ich wollte mich nur mit diesem Problem auseinandersetzen. Hier ist der Code:

for(a=eval(prompt(i=o=[]));k=a[j=++i];)for(;p=a[--j];)k+p-10||(k=a[i]=a[j]=-o.push([p,k]));console.log(o)

Eingabe: zB [1,2,3,3,4,5,6,7]. Ausgabe zB [[4,6],[3,7]]an die Konsole.

105-> 98: Verwendet Daniels großartigen Algorithmus, um den Code komplett neu zu schreiben! In seiner Antwort finden Sie einen lesbaren Algorithmus. Völlig durcheinander gebrachtes Zeug, also auf 105 Zeichen zurückgesetzt.

112-> 105: Auf iNull initialisiert , Ausgabe von o.pushto set k( k=a[i]=a[j]=-o.push...) verwendet und Ausgabe an Konsole protokolliert, anstatt zu eliminieren, "["+und +"]"da die Konsole bereits gut ausgibt.

123-> 112: Jetzt äußere Klammern in der Ausgabe entfernt, da Golfscript möglicherweise :) Auch endlich Vorschlag zum Entfernen angewendet |=0.

121-> 123: Geändert o+="("+p+","+k+"),"zu o.push("("+[p,k]+")")(fügt 2 Zeichen hinzu :() und oein Array anstelle eines Strings ( o=""-> o=[]) erstellt. Jetzt ist die Ausgabe nicht mehr falsch (wie ((5,5),(5,5),)).

141-> 121: Von nun angenommen , auf dass die Frage bedeutet , dass wir Eingang in der Sprache der Array - Format bekommen könnten, den Fall in JS ist ist [a,b,c,...]und gemacht o, der Ausgang „Akkumulator“ eine Zeichenfolge anstelle einem Arrays ( o.push(...),-> o+=...,).

153-> 141: Array-Einträge zurücksetzen, anstatt sie nach der Verwendung zu entfernen.

181-> 153: Angewandte Änderungen an u=[], neu angeordnete Schleifen, a[i]& a[j]-> temporäre Variablen, konvertiert wenn Logik und konvertiert int Logik in a[i]|=0.

183-> 181: Ersetzt i<=0durch i+1und das gleiche für j.

188-> 183: Platziert o=[]innen prompt()( ;) und ersetzt for(j=i;mit for(j=i-1;( i==j&&).

(Danke Mellamokb, Paul Walls und Ryan!)

Tomsmeding
quelle
1
Sie können ersetzen i>=0mit i+1und j>=0mit j+12 Zeichen zu speichern.
Mellamokb
1
Ich habe die Änderung auf ein Bitfeld-Array ( u=[]anstelle von x) angewendet , die Schleifen neu angeordnet, um von 0 aufwärts zu gehen, Variablen zugewiesen a[i]und a[j]temporär, um wiederholte Referenzen zu speichern, einige Variableninitialisierungen in andere Anweisungen verschoben, die ifLogik in verkettete ||Logik konvertiert und konvertiert das int parsing auf das prägnantere a[i]|=0, um eine Gesamteinsparung von 30 Zeichen zu erhalten :). Hier ist mein Testgeschirr, das die Genauigkeit der Lösung demonstriert: jsfiddle.net/GKUDb/8 und die 151-stellige Golf-Arbeitslösung: jsfiddle.net/DVtW2 .
Mellamokb
1
Array.toString () speichert Ihnen auch einige Zeichen (dh o+="("+[p,k]+")").
Paul Walls
1
Wenn Sie mit einer Ausgabe wie der von golfscript einverstanden sind, können Sie dies tun : for(a=eval(prompt(o=[])),i=-1;k=a[j=++i]|=0;)for(;p=a[--j];)k+p-10||(o.push("["+[p,k]+"]"),k=a[i]=a[j]=-1);alert(o), bringt sie auf 115
Ryan
1
Sie haben vergessen , meinen Vorschlag i auf 0 initialisieren Sie falten können a=eval(prompt(o=[])),i=-1in a=eval(prompt(i=o=[]))ohne Verlust der Treue, für weitere 3 Charakter Einsparungen.
Mellamokb
3

J, 54 53 50 46 45 44 Zeichen

(>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/

Verwendungszweck:

   (>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/5 5 5 5 5
5 5
5 5
   (>:,.9&-)I.<.4({.,-:@{::)(<.|.)+/|:(1+i.9)=/9 8 7 6 4 4 3 1
1 9
3 7
4 6

Der Algorithmus ist im Grunde:

  • Zählen Sie die Instanz jeder Nummer +/|:(1+i.9)=/
  • Paar die Zählungen jedes Paares, die sich zu 10 addieren würden (<.|.)(also 1 und 9, 2 und 8 usw.)
  • Nehmen Sie das Minimum dieser Zählungen (wenn Sie also drei Neuner, aber nur eine 1 haben, haben Sie nur ein 1 9Paar) und lassen Sie alles nach den ersten fünf Paaren fallen
  • Die 5s sind ein Sonderfall. Teilen Sie diese durch 2 ( <.4({.,-:@{::)implementiert beide vorherigen Schritte).
  • Nehmen Sie die ersten fünf Elemente der Liste und geben Sie die Nummer und 10 -die Nummer aus(>:,.9&-)I.
Gareth
quelle
3

Python (142)

Die Eingabe sollte in eckigen Klammern statt in runden Klammern erfolgen. http://ideone.com/p2QR11

from itertools import*
a=input()
c=lambda:[i for i in product(a,a[1:])if sum(i)==10]
d=c()
while d:print d[0];[a.remove(j)for j in d[0]];d=c()

Algorithmus:

1. Get input
2. Generate all pairs of input where the sum is 10
3. If there are no pairs, then END PROGRAM
4. Take the first pair's items and remove them from the input
5. Go back to step 2

Wenn eine ernsthaft fehlerhafte Ausgabe zulässig ist (90) : http://ideone.com/GR762f

a=input()
c=a.count
for i in range(6):print(`i`+`10-i`+' ')*(min(c(i),c(10-i))/(1+(i==5)))
beary605
quelle
3

C 142 , 138 , 124

char*p,*q;
main(int a,char**s){
    for(p=s[1];*p;p++)
        if(q=strchr(p+1,106-*p))a=*q=printf("%c(%c,%c)",38+a,*p,*q);
    puts("()"+a/6);
}

Testen:

./a.out "(1,2,3,4,5,5,6,7)"
((3,7),(4,6),(5,5))

./a.out "(1,2,3,4,5)"
()

./a.out "(5,5,5,5,5)"
((5,5),(5,5))

./a.out "(1,2,3,3,4,5,6,7)"
((3,7),(4,6))

./a.out "(9,8,7,6,4,4,3,1)"
((9,1),(7,3),(6,4))

Implementierungshinweise:

  • anfangs a = 2 (Programm hat zwei Argumente), auf 6 gesetzt (printf druckt 6 Zeichen), sobald eine Übereinstimmung auftritt
  • 106 = '0' + '0' + 10, dh es wird die Summe der ASCII-Codes verwendet
  • 38 + a ist entweder 44/40, dh '(' oder ','
  • Durch Setzen von Zeichenfolgen auf 6 wird sichergestellt, dass sie bei anderen Durchläufen nicht zu 106 addiert werden
  • "()" + a / 6 ist entweder "()" oder ")"
Baby-Kaninchen
quelle
3

Perl 52

perl -ne '$a{$y=9-$_}&&0*$a{$y++}--*print"$y,$_"or$a{$_-1}++'

Beweis:

> cat test
1
2
3
4
5
5
6
7
> perl -ne '$a{$y=9-$_}&&0*$a{$y++}--*print"$y,$_"or$a{$_-1}++' < test
5,5
4,6
3,7

Und es gibt einen ungolfed kommentierten Code:

while(<>) {     # made by the -n option

    # We are looking for (P,Q) pairs where P+Q=10
    # Each P entry will come in $_="P\n" (because $_ will not be chopped)
    # We choose to store the number of occurence of P in $a{P-1}
    # (For instance, if there have been five '3's in the input, then $a{2}=5)

    $y=9-$_;        # if Q=P-10, then $y=Q-1
    if ($a{$y}) {   # check if there was a Q (so $a{Q-1} != 0)
        $a{$y++}--;   # If so 'consume' this Q, and let $y=Q
        print"$y,$_"; # ... and output "Q,P\n"
    } else {
        $a{$_-1}++;   # P is not forming a new pair, so 'count it'.
                    # $a{$_} would not work because of the un-chopped \n, thus the '-1'
    }

}

Vielleicht sehen die Erklärungen wie Pidgin-Französisch aus (ich bin kein englischer Schriftsteller). Wenn also jemand sie bearbeiten und verständlicher machen möchte, tun Sie dies bitte.

Orabîg
quelle
Im Ernst, nicht einmal ein Punkt dafür, mit den Erklärungen und allem? ... :(
Orabîg
3

Javascript - 131 129 125 Zeichen

for(i=eval(prompt(r=[])),k=j=i.length;j--;)for(m=k;m--;)if(m!=j&&i[j]+i[m]==10)r.push([i[j],i[m]]),i[j]=i[m]=0;console.log(r)

Ich gehe davon aus, dass die Reihenfolge und in den verschachtelten Ergebnisarrays nicht obligatorisch ist :)

Bewertete Testfälle:

[1,2,3,4,5,5,6,7] returns [[7,3],[6,4],[5,5]]
[1,2,3,4,5]       returns []
[5,5,5,5,5]       returns [[5,5],[5,5]]
[1,2,3,3,4,5,6,7] returns [[7,3],[6,4]]
[9,8,7,6,4,4,3,1] returns [[1,9],[3,7],[4,6]]

Bearbeiten : Da die Problembeschreibung "Array" lautet, sprechen wir über die sprachspezifische Notation eines Arrays, oder?

Codeporn
quelle
2

Mathematica 70

Cases[#//.{x___,n_,y___,d_,z___}/;n+d==10:>{x,y,z,n~f~d},a_~f~b_:>{a,b}]&

Verwendungszweck

Cases[# //. {x___, n_, y___, d_, z___} /; n + d == 10 :> {x, y, z, n~f~d}, 
a_~f~b_ :> {a,b}] &[{1, 2, 3, 4, 5, 5, 6, 7}]

{{3, 7}, {4, 6}, {5, 5}}

DavidC
quelle
2

PostScript (46)

Dies verwendet handcodierte binäre Token, daher hier ein Hexdump:

00000000  7b 7b 92 1a 92 3f 7b 32  92 19 92 01 31 30 92 3d  |{{...?{2....10.=|
00000010  7b 32 92 09 92 0b 3d 3d  5b 92 40 7d 69 66 92 1a  |{2....==[.@}if..|
00000020  31 92 87 7d 92 83 92 75  7d 92 65 7d 92 a3        |1..}...u}.e}..|
0000002e

Ich habe die Binärdatei hochgeladen, wenn Sie sie ausprobieren möchten.

Dies erwartet, dass sich die Zahlen auf dem Stapel befinden. Sie können dem Code vorangestellt oder in der Befehlszeile angegeben werden, z. B. wenn Sie Ghostscript wie folgt verwenden:

gsnd -c 2 8 5 5 @ 10_golfed.ps

Wenn Sie auf einer Array-Syntax für die Eingabe bestehen, sind aload popgleich zu Beginn zwei weitere Token ( ) erforderlich . In binären Token sind dies vier weitere Bytes.

Ungolf und kommentiert:

{ % stopped                   % we use stopped because we want to catch a
                              % stackunderflow when all numbers have been used up
  { % loop                    % repeat until all numbers have been popped off the stack
    % Test for all numbers on the stack whether they add up to 10 with the topmost number
    count{                    % ... nextNumber number currentTestNumber
      exch                    % ... nextNumber currentTestNumber number 
      2 copy add 10 eq{       % ... nextNumber currentTestNumber number
        2 array astore ==     % ... nextNumber
        % We push "[" on the stack because we want to pop the topmost object after each iteration.
        % As [ is a one byte self delimiting token, this is nice for golfing.
        [ exit                % ... nextNumber [
      }if                     % ... nextNumber currentTestNumber number
      count 1 roll            % number ... nextNumber currentTestNumber 
    }repeat                   % number ... nextNumber currentTestNumber
    pop                       % number ... nextNumber
  }loop                       
}stopped
Thomas W.
quelle
2

Python 84

Erfordert die Eingabe in Klammern anstelle von Klammern.

a=input();r=[]
while a:
 n=a.pop(0);m=10-n
 if m in a:a.remove(m);r+=[(n,m)]
print r

Für ungefähr die gleiche Antwort, die besser gespielt wird, siehe Daniels Antwort .

Steven Rumbalski
quelle
2

PHP 150 149 148 146 142 -> 140

Verwendung mit PHP CLI.

<?$a=fgetcsv(STDIN);for($i=0;$i<$c=count($a);$i++){for($j=$i+1;$j<$c;$j++)if($a[$i]+$a[$j]==10){echo"({$a[$i]},{$a[$j]})";$a[$i]=$a[$j]=0;}}

Eingang: 1,2,3,4,5,5,6,7

Ausgabe: (3,7)(4,6)(5,5)

Nicht Golf:

<?php

$a = fgetcsv(STDIN);
$c = count($a);
for ($i = 0; $i < $c; $i++) {
    for ($j = ($i + 1); $j < $c; $j++) {
        if ($a[$i] + $a[$j] == 10) {
            echo "({$a[$i]},{$a[$j]})";
            $a[$i] = 0;
            $a[$j] = 0;
        }
    }
}

?>
jdstankosky
quelle
1

SED, 112 Zeichen

Wahrscheinlich etwas einfacher als die anderen Lösungen

s/.*/@&;12345678987654321/
:
s/\(@.*\)\(.\)\(.*\)\(.\)\(.*;.*\2.\{7\}\4\)/(\2,\4),\1\3\5/
t
s/^\(.*\),@.*/(\1)/
Hasturkun
quelle
1

Perl, 72 mit der -pFlagge

perl -p -e 's/^/@/;1while s/(@.*)(.)(.*)((??{10-$2}))/($2,$4)$1$3/;s/(.*)@.*/($1)/'
Hasturkun
quelle
Ich denke, das -psollte gezählt werden, da das Äquivalent hinzufügen würdeLINE: while (<ARGV>){...}continue{die "-p destination: $!\n" unless print $_}
Brad Gilbert b2gills
Auf jedem automatisierten #!perl -pGolfserver würde dies als 80 Byte gezählt, da dies den Shebang plus Newline erfordert .
Primo