Corresponder até 10 em uma matriz

8

Desafio

Dada uma matriz de número de um dígito, calcule se dois deles somam 10 e imprima-os

Exemplo

Entrada

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

Isso retorna ((4,6),(5,5),(3,7))

Entrada

(1,2,3,4,5)

Isso retorna (). como existe apenas um 5

Entrada

(5,5,5,5,5)

Isso retorna ((5,5),(5,5))como existe um número ímpar de 5s e cada 5 pode ser usado apenas uma vez

Regras

Aqui estão as regras!

  • Suponha que a entrada seja apenas uma matriz não classificada de números inteiros positivos de um dígito
  • Cada número será emparelhado apenas uma vez, o que significa que, se houver três 5s, formará apenas 1 par (5,5). Se houver (3,3,7), formará apenas 1 par (3,7)
  • Para a entrada: você pode usar qualquer tipo de parênteses (ou falta de), desde que os leitores possam dizer que a entrada é uma única matriz de números.
  • Para a saída: deve se parecer com uma matriz de pares. Onde a matriz é da mesma forma que a sua entrada (se você não usou parênteses na entrada, é necessário usar algum tipo de símbolo para que qualquer leitor possa dizer que são pares em uma matriz)

Casos de teste

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

Boa sorte!

A shorterresposta é, melhor!

Editar 1: atualizar as regras e casos de teste a partir de comentários

Edição 2: atualize as regras para definir o formato da entrada.

Edit 3: atualize as regras para definir o formato da saída. tentando ser o mais flexível possível.

user1655072
fonte
2
Não deveria haver 10 combinações diferentes (5,5)para o caso de teste final?
Gareth
@Gareth Parece que os valores se acostumar-se quando fazem pares
Matt
Você poderia postar mais alguns casos de teste? Talvez algo como(1,2,3,3,4,5,6,7)
Matt
@Matt editado. Obrigado pelo feedback
user1655072
A entrada precisa incluir os parênteses ou pode ser inserida como 1,2,3,4,5,5,6,7?
Jdstankosky

Respostas:

7

GolfScript, 45 42 37 caracteres

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

A nova abordagem também aceita matrizes com um único item como entrada. Além disso, é vários caracteres mais curtos.

Versão anterior:

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

O algoritmo usado neste código é descrito da seguinte maneira:

  • Classifique a matriz.
  • Pegue a soma do primeiro e do último item.
    • Se a soma for 10, imprima os dois números e remova-os da matriz.
    • Se a soma for maior que 10, descarte o número maior.
    • Se a soma for menor que 10, descarte o número menor.
  • Faça um loop até que o array contenha apenas um dígito ou esteja vazio.

O código espera uma matriz de pelo menos dois dígitos em STDIN.

Exemplos (veja 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
fonte
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 teste:

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

Um byte extra para o bom parêntese.

Daniel
fonte
Eu acho que repliquei esse método no PHP, mas ele só funciona ocasionalmente e não com todos os pares. Alguma idéia do porquê? <?$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

Jogar golfe no JS é um pouco difícil, mas eu só queria ter uma ideia do problema, então aqui está o 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: por exemplo [1,2,3,3,4,5,6,7]. Saída, por exemplo, [[4,6],[3,7]]para o console.

105-> 98: Utilizou o incrível algoritmo de Daniel para reescrever completamente o código! Veja a resposta dele para um algoritmo legível. Coisas completamente bagunçadas e revertidas para 105 caracteres.

112-> 105: Inicializado ipara zero, usou a saída de o.pushpara set k( k=a[i]=a[j]=-o.push...) e registrou a saída para o console em vez de alertar para eliminar "["+e, +"]"já que o console já possui uma saída agradável.

123-> 112: Agora foram removidos os colchetes externos na saída, pois o golfscript pode :) Também finalmente se aplicou a sugestão de remoção |=0.

121-> 123: Alterado o+="("+p+","+k+"),"para o.push("("+[p,k]+")")(adiciona 2 caracteres :() e criou ouma matriz em vez de uma sequência ( o=""-> o=[]). Agora a saída não está mais errada (como ((5,5),(5,5),)).

141-> 121: A partir de agora assumimos que a pergunta significava que poderíamos obter entrada no formato de matriz da linguagem, que no caso de JS é [a,b,c,...]e é feito o, a saída "acumula" uma string em vez de uma matriz ( o.push(...),-> o+=...,).

153-> 141: Redefina as entradas da matriz em vez de removê-las após o uso.

181-> 153: alterações aplicadas a u=[], loops reorganizados e a[i]& a[j]-> temp vars, convertidas se lógicas e int lógicas convertidas em a[i]|=0.

183-> 181: Substituído i<=0por i+1e o mesmo para j.

188-> 183: Colocado o=[]dentro prompt()( ;) e substituído for(j=i;por for(j=i-1;( i==j&&).

(Obrigado mellamokb, Paul Walls e ryan!)

tomsmeding
fonte
1
Você pode substituir i>=0por i+1e j>=0com j+1para salvar 2 caracteres.
mellamokb
1
Apliquei a alteração em uma matriz de campo de bits (em u=[]vez de x), reorganizei os loops para ir de 0 para cima, atribuai a[i]e a[j]para variáveis ​​temporárias para salvar referências repetidas, movi algumas inicializações de variáveis ​​para outras instruções, converti a iflógica em ||lógica encadeada e converti o int parsing para o mais sucinto a[i]|=0, para obter uma economia total de 30 caracteres :). Aqui está o meu equipamento de teste demonstrando a precisão da solução: jsfiddle.net/GKUDb/8 e a solução de trabalho com 151 caracteres: jsfiddle.net/DVtW2 .
Novell
1
Array.toString () também salvará alguns caracteres (por exemplo o+="("+[p,k]+")").
Paul Wall
1
Se você estiver ok com saída como a de golfscript, então você pode fazer isso: 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), traz-lo para baixo a 115
Ryan
1
Você esqueceu minha sugestão para inicializar i a 0. Você pode dobrar a=eval(prompt(o=[])),i=-1em a=eval(prompt(i=o=[]))sem perda de fidelidade, por mais 3 poupanças 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

O algoritmo é basicamente:

  • conte a instância de cada número +/|:(1+i.9)=/
  • emparelhe as contagens de cada par que seriam adicionadas a 10 (<.|.)(então 1 e 9, 2 e 8 etc.)
  • faça o mínimo dessas contagens (portanto, se você tiver três 9s, mas apenas um 1, terá apenas um 1 9par) e descarte tudo após os primeiros cinco pares
  • os 5s são um caso especial, então divida que por 2 ( <.4({.,-:@{::)implementa as duas etapas anteriores)
  • pegue os cinco primeiros itens da lista e imprima o número e 10 -o número(>:,.9&-)I.
Gareth
fonte
3

Python (142)

A entrada deve ser fornecida com colchetes em vez de colchetes. 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

Se uma saída seriamente malformada for permitida (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
fonte
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);
}

Teste:

./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 implementação:

  • inicialmente a = 2 (o programa possui dois argumentos), definido como 6 (printf imprime 6 caracteres) quando ocorre uma correspondência
  • 106 = '0' + '0' + 10, ou seja, usa a soma dos códigos ascii
  • 38 + a, é 44/40, ou seja, '(' ou ','
  • Ao definir caracteres de seqüência de caracteres para 6, garante que eles não sejam adicionados a 106 em outras passagens
  • "()" + a / 6, é "()" ou ")"
coelho bebê
fonte
3

Perl 52

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

Prova:

> 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

E há um código comentado não destruído:

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

}

Talvez as explicações pareçam francês pidgin (eu não sou um escritor nativo de inglês), portanto, se alguém quiser editá-lo e torná-lo mais compreensível, faça-o.

Orabîg
fonte
Sério, nem mesmo um ponto para isso, com as explicações e tudo ... :(?
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)

Presumo que a ordem e as matrizes de resultados aninhados não sejam obrigatórias :)

Casos de teste avaliados:

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

Edit : Como a descrição do problema diz 'Matriz', estamos falando sobre a notação específica de linguagem de uma matriz, certo?

codeporn
fonte
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
fonte
2

PostScript (46)

Isso usa tokens binários codificados manualmente, portanto, aqui está um 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

Eu carregado o arquivo binário se você quiser experimentá-lo.

Isso espera que os números estejam na pilha. Eles podem ser anexados ao código ou fornecidos na linha de comando, por exemplo, ao usar o Ghostscript da seguinte maneira:

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

Se você insiste na sintaxe da matriz para entrada, isso exige mais dois tokens ( aload pop) logo no início. Em tokens binários, são mais quatro bytes.

Sem jogar golfe e comentou:

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

Python 84

Requer entrada entre colchetes, em vez de parênteses.

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

Pois aproximadamente a mesma resposta foi melhor, veja a resposta de Daniel .

Steven Rumbalski
fonte
2

PHP 150 149 148 146 142 -> 140

Use com a CLI do PHP.

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

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

Sem golfe:

<?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
fonte
1

SED, 112 caracteres

Provavelmente um pouco mais simples que as outras soluções

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

Perl, 72 com a -pbandeira

perl -p -e 's/^/@/;1while s/(@.*)(.)(.*)((??{10-$2}))/($2,$4)$1$3/;s/(.*)@.*/($1)/'
Hasturkun
fonte
Eu acho que o -pdevem ser contados desde o equivalente acrescentariaLINE: while (<ARGV>){...}continue{die "-p destination: $!\n" unless print $_}
Brad Gilbert b2gills
Em todo servidor de golfe automatizado, isso seria contado como 80 bytes, pois requer o shebang #!perl -pplus newline.
Primo