Empareja hasta 10 en una matriz

8

Desafío

Dado un conjunto de números de un solo dígito, averigüe si 2 de ellos suman 10 e imprímalos

Ejemplo

Entrada

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

Esto vuelve ((4,6),(5,5),(3,7))

Entrada

(1,2,3,4,5)

Esto vuelve (). ya que solo hay un 5

Entrada

(5,5,5,5,5)

Esto regresa ((5,5),(5,5))ya que hay un número impar de 5s y cada 5 se puede usar solo una vez

Reglas

¡Estas son las reglas!

  • Suponga que la entrada solo será una matriz sin clasificar de enteros positivos de un solo dígito
  • Cada número se emparejará solo una vez, lo que significa que si hay tres 5, solo formará 1 par (5,5). Si hay (3,3,7) solo formará 1 par (3,7)
  • Para la entrada: puede usar cualquier tipo de paréntesis (o falta) siempre y cuando los lectores puedan decir que la entrada es un conjunto único de números.
  • Para la salida: debe verse como una matriz de pares. Donde la matriz tiene la misma forma que su entrada (si no usó ningún paréntesis en su entrada, debe usar algún tipo de símbolos para que cualquier lector pueda decir que son pares en una matriz)

Casos de prueba

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

¡Buena suerte!

La shorterrespuesta es, ¡mejor!

Edición 1: actualice las reglas y las pruebas de los comentarios

Edición 2: actualizar las reglas para definir el formato de entrada.

Edición 3: actualizar las reglas para definir el formato de salida. tratando de ser lo más complaciente posible.

usuario1655072
fuente
2
¿No debería haber 10 combinaciones diferentes de (5,5)para el caso de prueba final?
Gareth el
@Gareth Parece que los valores se agotan cuando hacen pares
Matt
¿Podría publicar algunos casos de prueba más? Tal vez algo como(1,2,3,3,4,5,6,7)
Matt
@Matt editado. Gracias por los comentarios
user1655072
¿La entrada tiene que incluir los paréntesis o se puede ingresar como 1,2,3,4,5,5,6,7?
jdstankosky

Respuestas:

7

GolfScript, 45 42 37 caracteres

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

El nuevo enfoque también toma matrices con un solo elemento como entrada. Por otra parte, es varios caracteres más cortos.

Versión previa:

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

El algoritmo utilizado en este código se describe a continuación:

  • Ordenar la matriz.
  • Tome la suma del primer y el último artículo.
    • Si la suma es 10, imprima ambos números y quítelos de la matriz.
    • Si la suma es mayor que 10, descarte el número mayor.
    • Si la suma es inferior a 10, descarte el número más pequeño.
  • Haga un bucle hasta que la matriz contenga solo un dígito o incluso esté vacía.

El código espera una matriz de al menos dos dígitos en STDIN.

Ejemplos (ver en línea ):

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

>[5 5 5 5 5]
[5 5]
[5 5]
Howard
fuente
9

Python 2.7 (70)

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

Casos de prueba:

$ 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)

Un byte extra para el bonito paréntesis.

Daniel
fuente
Creo que repliqué este método en PHP, pero solo funciona ocasionalmente y no con todos los pares. ¿Alguna idea de por qué? <?$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 105 98 caracteres

Jugar al golf en JS es algo difícil, pero solo quería tener una fiesta sobre este problema, así que aquí está el código:

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)

Entrada: ej [1,2,3,3,4,5,6,7]. Salida, por ejemplo, [[4,6],[3,7]]a la consola.

105-> 98: ¡Utilicé el asombroso algoritmo de Daniel para reescribir completamente el código! Vea su respuesta para un algoritmo legible. Completamente desordenado, por lo que se convirtió en 105 caracteres.

112-> 105: Inicializado ia cero, usó la salida de o.pushset k( k=a[i]=a[j]=-o.push...) y la salida registrada a la consola en lugar de alertar para eliminar "["+y +"]"ya que la consola ya sale bien.

123-> 112: Ahora se eliminaron los corchetes externos en la salida, ya que golfscript puede :) También finalmente se aplicó la sugerencia de eliminación |=0.

121-> 123: Cambiado o+="("+p+","+k+"),"a o.push("("+[p,k]+")")(agrega 2 caracteres :() e hizo ouna matriz en lugar de una cadena ( o=""-> o=[]). Ahora la salida ya no está mal (como ((5,5),(5,5),)).

141-> 121: a partir de ahora asumí que la pregunta significaba que podíamos obtener información en el formato de matriz del lenguaje, que en el caso de JS es [a,b,c,...]y hecho o, la salida "acumula" una cadena en lugar de una matriz ( o.push(...),-> o+=...,).

153-> 141: restablezca las entradas de la matriz en lugar de eliminarlas después del uso.

181-> 153: Cambios aplicados a u=[], reorganizados bucles, a[i]y a[j]-> temp vars, convertidos si es lógico y convertido a lógico int a[i]|=0.

183-> 181: reemplazado i<=0por i+1y lo mismo para j.

188-> 183: Colocado o=[]dentro prompt()( ;) y reemplazado for(j=i;con for(j=i-1;( i==j&&).

(¡Gracias mellamokb, Paul Walls y Ryan!)

tomsmeding
fuente
1
Puede reemplazar i>=0con i+1y j>=0con j+1para guardar 2 caracteres.
mellamokb
1
Apliqué el cambio a una matriz de campo de bits (en u=[]lugar de x), reorganicé los bucles para ir de 0 hacia arriba, asigné a[i]y a[j]a variables temporales para guardar referencias repetidas, moví algunas inicializaciones de variables a otras declaraciones, convertí la iflógica a ||lógica encadenada y convertí el int analizando a los más concisos a[i]|=0, para obtener un ahorro total de 30 caracteres :). Aquí está mi arnés de prueba que demuestra la precisión de la solución: jsfiddle.net/GKUDb/8 , y la solución de trabajo de golf de 151 caracteres: jsfiddle.net/DVtW2 .
mellamokb
1
Array.toString () también le ahorrará algunos caracteres (es decir o+="("+[p,k]+")").
Paul Walls
1
Si está de acuerdo con resultados como el de golfscript, puede hacer esto: 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)lo reduce a 115
Ryan
1
Se le olvidó mi sugerencia para inicializar i a 0. Se puede plegar a=eval(prompt(o=[])),i=-1en a=eval(prompt(i=o=[]))sin pérdida de fidelidad, durante 3 ahorro de caracteres.
mellamokb
3

J, 54 53 50 46 45 44 caracteres

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

Uso:

   (>:,.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

El algoritmo es básicamente:

  • contar la instancia de cada número +/|:(1+i.9)=/
  • empareje los recuentos de cada par que sumarían 10 (<.|.)(entonces 1 y 9, 2 y 8, etc.)
  • tome el mínimo de esos recuentos (por lo tanto, si tiene tres 9 pero solo uno 1, solo tendrá un 1 9par) y suelte todo después de los primeros cinco pares
  • los 5 son un caso especial, así que divídalo entre 2 ( <.4({.,-:@{::)implementa los dos pasos anteriores)
  • tomar los primeros cinco elementos de la lista y generar el número y 10 -el número(>:,.9&-)I.
Gareth
fuente
3

Pitón (142)

La entrada debe darse entre corchetes en lugar de corchetes. 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()

Algoritmo:

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

Si se permiten resultados con malformaciones graves (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
fuente
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);
}

Pruebas:

./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))

Notas de implementación:

  • inicialmente a = 2 (el programa tiene dos argumentos), establecido en 6 (printf imprime 6 caracteres) una vez que se produce una coincidencia
  • 106 = '0' + '0' + 10, es decir, utiliza la suma de los códigos ascii
  • 38 + a, es 44/40, es decir, '(' o ','
  • Al establecer caracteres de cadena en 6, se garantiza que no se agregarán a 106 en otras pasadas
  • "()" + a / 6, es "()" o ")"
conejo bebé
fuente
3

Perl 52

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

Prueba:

> 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

Y hay un código comentado sin golf:

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'
    }

}

Tal vez las explicaciones se vean como pidgin francés (no soy un escritor nativo de inglés), así que si alguien quiere editarlo y hacerlo más comprensible, hágalo.

Orabîg
fuente
En serio, ¿ni siquiera un punto para esto, con las explicaciones y todo? ... :(
Orabîg
3

Javascript - 131 129 125 caracteres

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)

Supongo que el orden de y en las matrices de resultados anidados no es obligatorio :)

Casos de prueba evaluados:

[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]]

Editar : como la descripción del problema dice 'Array', estamos hablando de la notación específica del lenguaje de una matriz, ¿verdad?

codeporn
fuente
2

Mathematica 70

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

Uso

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
fuente
2

PostScript (46)

Esto usa tokens binarios codificados a mano, por lo tanto, aquí hay un 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

Me subido el archivo binario si quieres probarlo.

Esto espera que los números estén en la pila. Pueden anteponerse al código o suministrarse en la línea de comando, por ejemplo, cuando se usa Ghostscript de la siguiente manera:

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

Si insiste en la sintaxis de matriz para la entrada, esto requiere dos tokens más ( aload pop) al principio. En tokens binarios, esto es cuatro bytes más.

Sin golf y comentado:

{ % 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.
fuente
2

Python 84

Requiere entrada entre paréntesis en lugar de paréntesis.

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

Para obtener más o menos la misma respuesta, mejor ve la respuesta de Daniel .

Steven Rumbalski
fuente
2

PHP 150 149 148 146 142 -> 140

Usar con 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;}}

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

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

Sin 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
fuente
1

SED, 112 caracteres

Probablemente algo más simple que las otras soluciones.

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

Perl, 72 con la -pbandera

perl -p -e 's/^/@/;1while s/(@.*)(.)(.*)((??{10-$2}))/($2,$4)$1$3/;s/(.*)@.*/($1)/'
Hasturkun
fuente
Creo que -pdebería contarse ya que el equivalente agregaríaLINE: while (<ARGV>){...}continue{die "-p destination: $!\n" unless print $_}
Brad Gilbert b2gills
En cada servidor de golf automatizado, esto se contabilizaría como 80 bytes, ya que requiere shebang #!perl -pplus newline.
primo