• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Warrior

[3] Números amigos - Nível de aprendizagem

25 mensagens neste tópico

Título:

Números amigos

Objectivo:

Recentemente aprendi no programa "Sabe mais do que um miúdo de 10 anos?" o que são números amigos.

Para aqueles que não sabem: dois números são amigos se a sua soma der origem a um número cujo algarismo das unidades seja 0. Ou seja, que possa ser expresso como dezenas sem casas decimais.

Por exemplo, o 26 e o 4 são amigos, pois a sua soma dá 30. O 26 e o 5 já não.

O que se pretende é que, dada uma lista de números (não necessariamente diferentes), nos digam quantos pares não ordenados e diferentes de números amigos existem.

Explicação de Input

Linha 1 - um inteiro N (2 <= N <= 5000), representando o número de inteiros a ler. (não deve ser considerado)

Linhas 2 - N+1 - N inteiros a ser considerados

Exemplo de input/output

Input:

6

1

9

2

8

4

22

Output:

3

(1,9), (2,8) e (8,22) são os três pares.

Input

4

1

9

9

1

Output:

1

(1,9) é o único par considerado.

Material de apoio:

Não aplicável.

Restrições:

Não aplicável.


Discussão do problema em:

http://www.portugal-a-programar.pt/index.php?showtopic=16590

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

#include <stdio.h>
#define MAX 5000

int num, counter=0, i, j, nums[MAX];
int seen[MAX][MAX];

int main()
{
scanf("%d", &num);
for(i=0; i<num; i++)
	scanf("%d", &nums[i]);
for(i=0; i<num; i++)
	for(j=i; j<num; j++)
		if((nums[i]+nums[j])%10==0 && !seen[nums[i]][nums[j]])
		{
			counter++;
			seen[nums[i]][nums[j]]=1;
			seen[nums[j]][nums[i]]=1;
		}
printf("%d", counter);
return 0;
}


Comment do moderador: os números podem ser inteiros, não necessariamente < 5000.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em php:

<?php
$nums = array(6, 1, 9, 2, 8, 4, 22);
$quantd = 0;
for ($i = 0; $i < count($nums); $i++) {
for ($j=$i+1; $j < count($nums); $j++) {
	if ( (($nums[$i]+$nums[$j]) % 10) == 0 ) {
		$quantd++;
		echo "(" . $nums[$i] . "," . $nums[$j] . ")<br />";
	}
}
}
echo $quantd;
?>

Adaptar o Input é fácil :thumbsup: mas dava mt trabalho tar a pôr ai uns post e uns forms :).

E para este desafio só vou escrever em PHP, porque o C já está escrito e porque em Perl e JavaScript é só adaptar o que já foi feito no PHP dando assim hipóteses ao godeen :D


Comment do moderador: Não verifica soluções já adicionadas/invertidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

VB.NET

   Dim nums(6)
        nums(0) = 6
        nums(1) = 1
        nums(2) = 9
        nums(3) = 2
        nums(4) = 8
        nums(5) = 4
        nums(6) = 22
        Dim quantd = 0
        Dim i As Integer = 0
        Dim j As Integer = 0
        For i = 0 To 6
            For j = 0 To 6
                If (nums(i) + nums(j)) Mod 10 = 0 Then
                    quantd = quantd + 1
                    ListBox1.Items.Add(nums(i) & "," & nums(j))
                End If
            Next j
       Next i

ai esta :)

Magician : Apenas coloquem aqui as soluções os comentarios devem ser feitos em Discussão :thumbsup:


Comment do moderador: Não verifica soluções já adicionadas/invertidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Python - 2a Solução apresentada

teste = [6,1,9,2,8,4,22]

def amigos(array):
    if array[0] < 5001:
        results = [0]

        for num_1 in array[1:]:
            for num_2 in array[1:]:
                if ((num_2, num_1) not in results) and ((num_1, num_2) not in results)and ((num_1+num_2)%10 == 0):
                    results[0] += 1
                    results.append((num_1, num_2))
                    print '(',int(num_1),',',int(num_2),')'
    
        return results[0]
    else:
        return 'Demasiados numeros pa...'

print amigos(teste)

------------

Achei piada por uma solução alternativa. Esta solução não trata os números como inteiros, mas como strings. Just for fun :thumbsup:

## Desafio 3
## Numeros Amigos
## Proposta alternativa

teste_1 = [6,1,9,2,8,4,22]

teste_2 = [4,1,9,9,1]

def num_amigos(array):
    
    for num in range(len(array)):
        array[num] = str(array[num])
    
    results = []
    amigos = {'1':'9', '2':'8', '3':'7', '4':'6', '5':'5'}
    
    for num in array[1:]:
        for other_num in array[1:]:
            if num[-1] in amigos:
                if (amigos[num[-1]] == other_num[-1]):
                    results.append((num, other_num))

            elif other_num[-1] in amigos:
                if amigos[other_num[-1]] == num[-1]:
                    results.append((other_num, num))   

    
    for i in set(results):
        print i
    
    return len(set(results))

print num_amigos(teste_1)

print num_amigos(teste_2)


Comment do moderador: Não verifica soluções já adicionadas/invertidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

c# Praticamente igual a vb.net :|

      int[] nums = new int[7];
            nums[0] = 6;
            nums[1] = 1;
            nums[2] = 9;
            nums[3] = 2;
            nums[4] = 8;
            nums[5] = 4;
            nums[6] = 22;
            int quantd = 0;
            int i = 0;
            int j = 0;
            for (i = 0; i <= 6; i++)
            {
                for (j = 0; j <= 6; j++)
                {
                    if ((nums[i] + nums[j]) % 10 == 0)
                    {
                        quantd = quantd + 1;
                        listBox1.Items.Add(nums[i] + "," + nums[j]);
                    }
                }

            }


Comment do moderador: Não verifica soluções já adicionadas/invertidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

import Data.Char (digitToInt)
import Data.List (tails, nub)

main = getContents >>= print . sum . map fun . tails . map (digitToInt . last) . nub . tail . lines

fun [] = 0
fun (dig:digs) = length $ filter (dig'==) digs
   where dig' = 10 - dig

Bem assim de imediato fiz desta maneira.

Esta solução também não é perfeita, com input com dois 5's ele vai eliminar o segundo 5 perdendo esse par, obviamente o mesmo acontece para todos os números repetidos acabados em 5.

Também está longe de ser eficiente.

Depois quando tiver mais tempo, tento fazer uma maneira mais eficaz, talvez dado uso a um Map.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Feito em Java! Foi feito assim rapido, mas aho que funciona para todos os casos!

public class Main {
    private static String Inverter(String a){
        char[] f = a.toCharArray();
        String i = new String("");
        int j = f.length - 1;
        for(int h = 0 ; h < f.length; h++)
            i+=f[j--];
        
        return i;
    }
    private static String numerosAmigos(int n,int[] numeros){
        String txt = new String("");
        int total = 0;
        for(int i = 0; i < n - 1; i ++ )
            for(int f = i + 1; f < n ; f++)
                if((numeros[i] + numeros[f]) % 10 == 0){
                    txt += ( numeros[i] + "," + numeros[f] + " ");
                    total++;
                }
       
        String[] pares = txt.split(" ");
        for(int i = 0; i < pares.length - 1; i ++ )
            for(int f = i + 1; f < pares.length; f++){
               
                if(pares[i].equals(pares[f]) || pares[i].equals(Inverter(pares[f]))){
                    
                    pares[i] = "f";
                    total--;
                }
            }
        txt = "";
        for(int i = 0; i < pares.length; i++){
            if(!pares[i].equals("f"))
               txt += "(" + pares[i] + "), ";
        }
                
            
        return "" + total + "\n\n" + txt.substring(0,txt.length()-2);
    }
    public static void main(String[] args) {
        int [] n = {1,1,1,1};

        int max = 4;
        System.out.print(numerosAmigos(max, n));

    }

}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

#include <iostream>
#include <fstream>

using namespace std;

class lista {
class par {
public:
	int _a, _b;
	par *next;
	par(int a, int b): _a(a), _b(b), next(NULL) {
	}
};
par *first, *last;
public:
lista(): first(NULL), last(NULL) {}

void add(int a, int b) {
	for (par *p=first; p!=NULL; p=p->next)
		if (( (p->_a == a) && (p->_b == b) ) || ( (p->_a == b) && (p->_b == a) ))
			return;
	par *p = new par(a,b);
	if (first == NULL) first = p;
	if (last != NULL) last->next = p;
	last = p;
}
int contagem() {
	int i=0;
	for (par *p=first; p!=NULL; ++i, p=p->next);
	return i;
}
};

int main() {
ifstream nfile("amigos.txt");
if (!nfile) {
	cout << "amigos.txt nao encontrado." << endl;
	return 1;
}

int total_numeros;
nfile >> total_numeros;
int *tabnumeros = new int[total_numeros];

for (int i = 0; i<total_numeros; ++i)
	nfile >> tabnumeros[i];

lista l;

for (int i = 0; i<total_numeros-1; ++i) {
	for (int j = i+1; j<total_numeros; ++j) {
		if ((tabnumeros[i] + tabnumeros[j]) % 10 == 0) l.add(tabnumeros[i], tabnumeros[j]);
	}
}
cout << "Total de conjuntos de numeros amigos: " << l.contagem() << endl;

return 0;
}

C++ com STL

#include <iostream>
#include <fstream>
#include <utility>
#include <list>
#include <algorithm>
#include <vector>

using namespace std;

int main() {
ifstream nfile("amigos.txt");
if (!nfile) {
	cout << "amigos.txt nao encontrado." << endl;
	return 1;
}

int total_numeros;
nfile >> total_numeros;
vector<int> tabnumeros;

{
	int j;

	for (int i = 0; i<total_numeros; ++i) {
		nfile >> j;
		tabnumeros.push_back(j);
	}

}
list<pair<int, int>> l;

for (vector<int>::iterator i = tabnumeros.begin(); i!=tabnumeros.end()-1; ++i) {
	for (vector<int>::iterator j = i+1; j!=tabnumeros.end(); ++j) {
		if ((*i + *j) % 10 == 0)
			if (find(l.begin(), l.end(), make_pair(*i, *j) ) == l.end() && find(l.begin(), l.end(), make_pair(*j, *i) ) == l.end())
				l.push_back(make_pair(*i, *j));
	}
}
cout << "Total de conjuntos de numeros amigos: " << l.size() << endl;

return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

def par(x, y):
if cmp(x, y) is 1: return [y, x]
else: return [x, y]

pares = []
numbs = []

tmp = open("input", "r")
for i in range(0, int(tmp.readline())): numbs.append(int(tmp.readline()))

for x in numbs:
for y in numbs:
	if not (x+y) % 10 and not par(x, y) in pares:
		pares.append(par(x, y))

print "Total de conjuntos de numeros amigos: %s" % len(pares)

Solução elegante em Python. ;)

EDIT: Adicionada a função par(). Código antigo abaixo.

pares = []
numbs = []

tmp = open("input", "r")
for i in range(0, int(tmp.readline())): numbs.append(int(tmp.readline()))

for x in numbs:
for y in numbs:
	if not (x+y) % 10 and not [x, y] in pares and not [y, x] in pares:
		pares.append([x, y])

print "Total de conjuntos de numeros amigos: %s" % len(pares)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem e então fica aqui a versão corrigida de Haskell.

Se não me enganei a analisar, penso que o algoritmo esteja em O(log n) O(n^2). Quer dizer, estará pior, já que a estrutura do Set é internamente uma espécie de árvore, por isso, cada insert também será O(log n). Uma forma de contornar isso seria dar uso a uma HashTable que liga internamente a código C, obtendo assim O(1), mas já teria que andar a trabalhar sobre a Monad IO o que iria "sujar" o código, e penso que assim seja, em termos de eficiência, mais que suficiente.

import Data.Char (digitToInt)
import Data.List (tails)
import Control.Arrow ((&&&))
import Data.Set (empty, insert, size)

main = getContents >>= print . size . foldl procPares empty . tails . map fun . tail . lines
   where fun :: String -> (Integer, Int)
         fun = read &&& digitToInt . last

procPares s [] = s
procPares s ((n,d):l) = foldl (inserePar n) s $ filter ((dig ==) . snd) l
   where dig = if d == 0 then 0 else 10 - d

inserePar n1 s (n2,_) = insert par s
   where par = if n1 <= n2 then (n1,n2) else (n2,n1)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Como só é pedido o número de pares de números, não é preciso calculá-los mesmo. Apenas precisamos calcular os conjuntos pares de números em que a soma do último digito é 10. Assim, se soubermos quantos números distintos existem com último digito 0,1,2,3...9 podemos fazer umas simples contas.

Se nums[ i ] tiver a quantidade de números cujo último digito é i (ou seja resto da divisão por 10 é i),  (UD: Ultimo Digito)

A resposta é a soma dos pares de números com UD= 0 com os números UD = 0, pares de numeros com UD=1 com numeros UD=9 , 2 e 8 , 3 e 7 , 4 e 6, 5 e 5 .

No caso de 0 com 0 e 5 com 5, o número de pares distintos é num * (num-1) / 2 , nos outros é num[ i ] * num[ j ].

Solução em O( n log n ):

#include <set>
#include <iostream>
using namespace std;

int main()
{
int N , i , j;
set<int> num[10]; // num[i] : conjunto de números distintos cujo ultimo digito e' "i"

cin >> N;
while (N--) {
	cin >> i;
	num[ i%10 ].insert( i ); // se 'i' ja la estiver e' ignorado
}
int resp = num[0].size() * (num[0].size()-1) / 2 + num[5].size() * (num[5].size()-1) / 2;

for (i = 1 , j = 9 ; i < j ; i++ , j-- ) 
	resp += num[i].size() * num[j].size();
cout << resp << endl;
return 0;
}

Se soubermos o limite máximo do valor dos números, podemos transformar o uso do set, numa simples verificação dum array para uma solução em O(N):

#include <iostream>
using namespace std;
#define MAX 100001
char used[MAX];

int main()
{
int N , i , j , num[10] = {0}; // num[i] : quantidade de numeros distintos com ultimo digito 'i'

cin >> N;
while (N--) {
	cin >> i;
	if ( ! used[i] ) {
		used[i] = 1;
		num[ i%10 ]++;
	}
}
int resp = num[0] * (num[0]-1) / 2 + num[5] * (num[5]-1) / 2;

for (i = 1 , j = 9 ; i < j ; i++ , j-- ) 
	resp += num[i] * num[j];
cout << resp << endl;
return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

$nums = array(4, 1, 9, 9, 1, 6, 1, 9, 2, 8, 4, 22);
for ($i = 0; $i < count($nums); $i++) {
for ($j=$i+1; $j < count($nums); $j++) {
	$coiso = $nums[$i];
	$tal = $nums[$j];
	if (!eregi($coiso, $quejaestao) AND !eregi($tal, $quejaestao)) {
	if ( (($nums[$i]+$nums[$j]) % 10) == 0 ) {
		$quantd++;
		echo "(" . $nums[$i] . "," . $nums[$j] . ")<br />";
		$quejaestao = $quejaestao . $nums[$i] . $nums[$j];
	}
}
}
}
echo $quantd;

Um bocado rupestre mas já funciona bem ;) ( acho eu :) )

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
#include <stdio.h>
#define MAX 5000

int num, counter=0, i, j, nums[MAX];
char pares[256]=" ";

int main()
{
        scanf("%d", &num);
        for(i=0; i<num; i++)
                scanf("%d", &nums[i]);

        for(i=0; i<num; i++)
                for(j=i; j<num; j++)
                        if((nums[i]+nums[j])%10==0)
                        {
                                counter++;
                                pares=pares+"("+nums[i]+","+nums[j]+")"+" ";
                        }
        printf("%d", counter);
        printf("\n\n%s são os pares numeros amigos!!!",pares);
        return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem, já está aí em Java mas como supostamente isto é nível de aprendizagem, acho mais facil quem está a aprender o seguinte código... ah e no enunciado falta um par 6 e 4  :biggrin:

public class ddd 
{
public static void main(String[] args) 
{
	int i,x,count=0;
	int[] num = new int[] {6,1,9,2,8,4,22};

	for (i=0;i<=6;i++)
	{
		for(x=i;x<=6;x++)
		{
			if ((num[i]+num[x])%10==0)
			{
				System.out.println(+num[i]+" e "+num[x]);
				count++;
			}
		}
	}
	System.out.println("Há "+count+" pares");
}
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Coloquei de 1 a 5 mas é a mesma coisa é so alterar de 1 pra 6 colocando mais um valor nao prestei atenção e fiz assim

Feito no ConsoleApplication do Vb.Net

Module Module1
   Sub Main()
    Dim v(5) As Integer
    v(1) = Console.ReadLine
    v(2) = Console.ReadLine
    v(3) = Console.ReadLine
    v(4) = Console.ReadLine
    v(5) = Console.ReadLine
    Dim quantd = 0
    Dim i As Integer = 0
    Dim j As Integer = 0
    For i = 1 To 5
	    For j = 1 To 5
		    If (v(i) + v(j)) Mod 10 = 0 Then
			    quantd = quantd + 1
			    Console.WriteLine(v(i) & "," & v(j))
		    End If
	    Next j
    Next i
    Console.ReadLine()
   End Sub
End Module

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Coloquei de 1 a 5 mas é a mesma coisa é so alterar de 1 pra 6 colocando mais um valor nao prestei atenção e fiz assim

Feito no ConsoleApplication do Vb.Net

Module Module1
Sub Main()
	Dim v(5) As Integer
	v(1) = Console.ReadLine
	v(2) = Console.ReadLine
	v(3) = Console.ReadLine
	v(4) = Console.ReadLine
	v(5) = Console.ReadLine
	Dim quantd = 0
	Dim i As Integer = 0
	Dim j As Integer = 0
	For i = 1 To 5
		For j = 1 To 5
			If (v(i) + v(j)) Mod 10 = 0 Then
				quantd = quantd + 1
				Console.WriteLine(v(i) & "," & v(j))
			End If
		Next j
	Next i
	Console.ReadLine()
End Sub
End Module

Esse código tem vários erros que já foram referidos anteriormente. Testa com todos os inputs fornecidos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Esse código tem vários erros que já foram referidos anteriormente. Testa com todos os inputs fornecidos.

Desculpa ontem o sono bateu forte e fiz um bocado á pressa eis o código e a dar perfeitamente

Module Module1    
Sub Main()        
Dim v(6) As Integer
       v(0) = Console.ReadLine
       v(1) = Console.ReadLine 
      v(2) = Console.ReadLine  
     v(3) = Console.ReadLine   
    v(4) = Console.ReadLine 
      v(5) = Console.ReadLine  
     v(6) = Console.ReadLine     
  Dim quantd = 0    
   Dim i As Integer = 0 
      Dim j As Integer = 0  
     For i = 0 To 6     
      For j = 0 To 6    
           If (v(i) + v(j)) Mod 10 = 0 Then 
                  quantd = quantd + 1      
             Console.WriteLine(v(i) &amp; "," &amp; v(j)) 
              End If          
 Next j        Next i      
 Console.ReadLine()   
End Sub
End Module

SZCG5.png

Eis o resultado ... Decidi deixar os numeros em cima para caso o utilizador não se lembre dos dados que introduziu mas se quiseres que não esteje lá é so fazer Console.Clear antes de inciar os ciclos for

Ps:Já descobri do que falavas vou ver isso ( em relação a sairem numeros iguais )

Editado por Lukas S.
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
#include <stdio.h>

int main()
{
int conta_pares, N, nums[5000], i, j, unidade;
conta_pares = 0;

//num de inteiros
scanf( "%d", &N );

//inteiros
for( i=0; i<N; i++ ) { scanf( "%d", &nums[i] ); }

//calculos
for( i=0; i<N; i++ )
{
 for( j=i+1; j<N; j++ )
 {
  unidade = (nums[i]+nums[j])%10;
  if( unidade == 0 )
   conta_pares++;
 }
}

//result
printf( "%d\n", conta_pares );

return 0;
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Continuam com imensos erros. Leiam o enunciado por favor.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A minha 1.ª tentativa em Lua. Tenham piedade que isto ainda me faz um pouco de confusão :P

function printlist(list)
 table.foreach(list,function (c,d) io.write(d .. " ") end)
 io.write("\n")
end

function isrepetido(a1,b1)
 table.sort(a1);
 table.sort(b1);
 if (a1[1]==b1[1] and a1[2]==b1[2]) then return true
 else return false
 end
end

function existe(valor,lista)
 if table.getn(lista)==0 then return false
 end
 for i,w in ipairs(lista) do
	  if isrepetido(valor,w)==true then return true
	  end
 end
 return false
end

function isfriend (y)
 if (string.byte(y,string.len(y))==48) then return true
 else return false
 end
end

function pares(x,lista)
 results={}
 --io.write(x .. " ")
 --table.foreach(lista, function (a,b) io.write(b .. " ") end)
 io.write("\n")
 for i1,v1 in ipairs(lista) do
	  --print(x,v1,x+v1)
	  if isfriend((x+v1) .. "") then
		   --print("found")
		   table.insert(results,{x,v1})
	  end
 end
 return results
end


x = {4,1,9,9,1}
y={}
j=0
max = table.getn(x)
while j<max do
 v = x[1]
 table.remove(x,1)
 --z=pares(v,x)
 for i,w in ipairs(pares(v,x)) do
	  if existe(w,y)==false then
	  table.insert(y,w)
	  end
 end
j=j+1
end
print(table.getn(y))
--table.foreach(y,function (a,b) printlist(b) end)

EDIT: Uma versão mais elegante, derivada de umas primeiras brincadeiras com túpolos


function Par(_x1,_x2)
    return function(fn) return fn(_x1,_x2) end
end
function x1(_x1,_x2) return _x1 end
function x2(_x1,_x2) return _x2 end

function isamigo(_x1,_x2)
    str=tostring(_x1+_x2)
    return string.byte(str,string.len(str)) == 48 and true or false
end
function Pares(valor, restolista)
    ret={}
    for _,v in ipairs(restolista) do
         table.insert(ret,Par(valor,v))
    end
    return ret
end

function isequal(p1,p2)
    return ((p1(x1)==p2(x1) and p1(x2)==p2(x2)) or (p1(x1)==p2(x2) and p1(x2) == p2(x1))) and true or false
end

function isInList(p1,list)
    for _,v in ipairs(list) do
         if (isequal(p1,v)) then return true
         end
    end
    return false
end

x={1,9,2,8,4,22}
y={}
j=0
max=#x
while j~=max-1 do
    v=x[1]
    table.remove(x,1)
    temp=Pares(v,x)
    for _,w in ipairs(temp) do
        if w(isamigo)==true and isInList(w,y)==false then
             table.insert(y,w)
        end
    end
    j=j+1
end
print(#y)
--for i,v in ipairs(y) do
-- v(print)
--end

EDIT: Segunda versão editada para garantir compatibilidade com a versão 5.2 da Lua :P

(table.getn -> #)

Editado por Flinger
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O tópico já é antigo, eu sei, mas o meu aprendiz de Pascal pegou-se a este desafio e eu meti-me a resolvê-lo. Lá cheguei por fim a uma solução optimizada, e que cumpre todos os requisitos, e ele disse-me para o colocar aqui... e o "mestre" seguiu o aprendiz :D

http://ideone.com/y3jK25 (com os inputs do desafio)

program friends_challenge;
uses crt;

type TPair = record
       a, b : byte;
    end;
    TList = array of byte;
    TFrs  = array of TPair;

procedure Pause; begin repeat until readkey = #13; end;

procedure GetNumbers(const q : byte; var list : TList);
var i : byte;
begin
   SetLength(list, q);
   for i:=0 to q-1 do
       readln(list[i]);
end;

procedure GetFriends(const list : TList; var frs : TFrs);
const MAX = 255;
var i, j : byte;
   seen : array [0..MAX, 0..MAX] of boolean;
begin
   for i:=0 to MAX do for j:=0 to MAX do seen[i,j]:=false;

   for i:=low(list) to high(list)-1 do
       for j:=i+1 to high(list) do
           if ((list[i] + list[j]) mod 10 = 0) and not seen[list[i], list[j]] then begin
               SetLength(frs, Length(frs)+1);
               frs[Length(frs)-1].a := list[i];
               frs[Length(frs)-1].b := list[j];
               seen[list[i], list[j]] := true;
               seen[list[j], list[i]] := true;
           end;
end;

var n : byte;
   numbers : TList;
   friends : TFrs;
   elem : TPair;

begin
   repeat
       readln(n);
       if (n < 2) then writeln('Erro, deve ser >=2 !');
   until (n >= 2);

   GetNumbers(n, numbers);
   GetFriends(numbers, friends);

   write('Os ', Length(friends), ' pares amigos sao: ');
   for elem in friends do write('(', elem.a, ',', elem.b, ') ');
   Pause;
end.

Editado por thoga31
1

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E duas soluções possíveis em Haskell feitas por um novato nesta LP :D

import Data.List (nubBy)

friends xs = nubBy f [(a, b) | a <- xs, b <- xs, ((a + b) `mod` 10) == 0]
 where
   f (a1, b1) (a2, b2) = (a1 == b2) && (a2 == b1)

main :: IO()
main = do
   a <- (readLn :: IO [int])
   let frs = friends a
   putStrLn $ "Ha " ++ (show $ length frs) ++ " pares:"
   mapM_ putStrLn $ map show frs

import Control.Monad (guard)
import Data.List (nubBy)

friends xs = do
   a <- xs
   b <- xs
   guard $ (a + b) `mod` 10 == 0
   return $ (a, b)

main :: IO()
main = do
   a <- (readLn :: IO [int])
   let frs = nubBy f $ friends a
   putStrLn $ "Ha " ++ (show $ length frs) ++ " pares:"
   mapM_ putStrLn $ map show frs
 where
   f (a1, b1) (a2, b2) = (a1 == b2) && (a2 == b1)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Um posivel solucao em perl:

#!/usr/bin/env perl

use v5.12;
use warnings;
use autodie;
use utf8;

my $n = <STDIN>;
chomp $n;
$n = int $n;
$n = $n > 4999 ? 4999 : $n;

my @nums;
for (1 .. $n) {
 my $num = <STDIN>;
 chomp $num;
 push @nums, $num;
}

@nums = keys {map {$_ => 'Just Another Perl Hacker'} @nums};
@nums = sort {$a <=> $b} @nums;

my @fnums;
$n = scalar @nums;

for (my $i = 0; $i < $n; ++$i) {
 for (my $j = $i + 1; $j < $n; ++$j) {
push @fnums, "($nums[$i], $nums[$j])" unless ($nums[$i] + $nums[$j]) % 10;
 }
}

{
 local $" = ', ';
 say scalar @fnums;
 say "@fnums";
}

Editado por eatg75
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora