Combinação simples

1. Combinação simples

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 22/04/2022 - 09:38h

Pessoas ... tenho um CSV com 5 colunas e trocentas linhas, os campos são dezenas de 25 a 50, preciso de um shell que me mostre todas as combinações simples de 3 dezenas possíveis e conte quantas vezes elas se repetem no CSV.

ajudem aí que estou todo embananado com isso aqui.

Abçs.


  


2. Re: Combinação simples

leandro peçanha scardua
leandropscardua

(usa Ubuntu)

Enviado em 22/04/2022 - 23:20h


Cada linha tem 5 colunas sendo compostas por no máximo 3 números não repetidos? O critério de corte são os números não repetidos em alguma ordem específica, em qualquer ordem, a linha exata ou os elementos de cada linha em qualquer ordem?


3. Re: Combinação simples

Ricardo Groetaers
ricardogroetaers

(usa Linux Mint)

Enviado em 23/04/2022 - 00:31h

Mauriciodez escreveu:... mostre todas as combinações simples de 3 dezenas possíveis e conte quantas vezes elas se repetem no CSV..

Não sei o que é CSV e não entendo de scripts.

Apenas uma observação:
n -> é o número de elementos distintos disponíveis.
p -> é o número de elementos de cada grupo formado com os elementos disponíveis.

Nos arranjos a ordem dos elementos nos grupos formados diferenciam os grupos formados:
(a ; b ) é diferente de (b ; a)

Nas combinações a ordem dos elementos nos grupos formados não diferenciam os grupos formados:
(a ; b) = (b ; a)

Nos arranjos e combinações simples, por definição, não há repetição de elementos nos grupos formados.
Se houver repetição de elementos nos grupos formados não será arranjo ou combinação simples e sim arranjo ou combinação com repetição.

A fórmula (sem demonstração) do número de grupos formados com a combinação simples dos "n" elementos disponíveis em grupos com "p" elementos é:
C (n,p) = n! / (p! . (n - p)!)
onde:
C (n,p) -> leia-se "combinação simples dos "n" elementos disponíveis em grupos de "p" elementos".
! -> significa fatorial
. -> é o sinal de multiplicação, equivalente a "x".

No caso proposto:
n = 26 (25 e 50 estão inclusos)
p = 3

26! / (3! x (26 - 3)!) = 2.600


4. Re: Combinação simples

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 23/04/2022 - 20:55h


Mauriciodez escreveu:

Pessoas ...
tenho um CSV com 5 colunas e trocentas linhas, os campos são dezenas de 25 a 50,
preciso de um shell que me mostre todas as combinações simples de 3 dezenas possíveis e conte quantas vezes elas se repetem no CSV.

ajudem aí que estou todo embananado com isso aqui.

Abçs.

Boa noite Mauricio,
Sugestão: .....
Com cinco dezenas em cada linha,
considerando as "repetições", você tem 125 combinações:
echo $((5**3))
125
----------------------------------------------------------------------------------------------------------------
Exemplo:
x="{25,30,35,40,49}"
eval echo $x:$x:$x|sed 's/ /\n/g' > teste.txt
O comando:
eval echo $x:$x:$x 

Gera todas combinações com 3 dezenas, das 5 disponíveis. (na linha do seu arquivo)
----------------------------------------------------------------------------
Eliminando os nºs repetidos dessa combinação:
while read line;do 
echo -e ${line//:/\\n}|sort -u|paste -sd ':' >> SAIDA.txt;
done<teste.txt

sort -u => ordena e elimina os repetidos
paste -sd ':' => junta as dezenas, usando ":" como separador.
-----------------------------------------------------------------------------
"Pega" as linhas com 3 registros, ordena e elimina os repetidos do arquivo em questão.
awk -F":" 'NF==3{print $0}' SAIDA.txt|sort -u
25:34:35
25:34:40
25:34:49
25:35:40
25:35:49
25:40:49
34:35:40
34:35:49
34:40:49
35:40:49


---------------------------------------------------------------------------------------------------------------
Isso é para cada linha do seu arquivo.csv

______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________



5. Re: Combinação simples

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 23/04/2022 - 22:21h

Vou exemplificar aqui para vc's entenderem o que eu preciso

Arquivo CSV
25;26;27;28;29
36;37;38;39;40
26;27;28;39;40


preciso que ele gere todas as combinações (de 3 dezenas) possíveis de 25 a 50 e conte quantas vezes elas aparecem no CSV

25;25;25;0
25;25;26;0
...
26;27;28;2
...
38;39;40;1
38;39;41;0
...
50;50;50;0


NOTA: no exemplo de saída eu não coloquei a contagem de todas as combinações !!!

pensei a principio gerar 3 variáveis ( que são as 3 trincas de dezenas ) D1;D2:D3 ...
* Daria o valor inicial 25 para elas pois é a primeira combinação possível
* faria o primeiro loop no "BD.csv" contando linha por linha e escrevendo digamos em "Saída.csv".
* criaria if's para incrementar as variaveis .

pra mim parece ser isso a fazer, só que já começo a me embananar na hora de gerar as combinações !!!

Caso eu não tenha sido claro por favor peçam mais esclarecimentos !!!

Abçs

EDIT: as dezenas do arquivo CSV real estão escritas em ordem aleatoria !!!


------------------------------------------------------| Linux User #621728 |------------------------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------------------| Linux User #621728 |------------------------------------------------------




6. Re: Combinação simples

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 24/04/2022 - 00:58h

Mauriciodez escreveu:

Vou exemplificar aqui para vc's entenderem o que eu preciso

Arquivo CSV
25;26;27;28;29
36;37;38;39;40
26;27;28;39;40


preciso que ele gere todas as combinações (de 3 dezenas) possíveis de 25 a 50 e conte quantas vezes elas aparecem no CSV

25;25;25;0
25;25;26;0
...
26;27;28;2
...
38;39;40;1
38;39;41;0
...
50;50;50;0


NOTA: no exemplo de saída eu não coloquei a contagem de todas as combinações !!!

pensei a principio gerar 3 variáveis ( que são as 3 trincas de dezenas ) D1;D2:D3 ...
* Daria o valor inicial 25 para elas pois é a primeira combinação possível
* faria o primeiro loop no "BD.csv" contando linha por linha e escrevendo digamos em "Saída.csv".
* criaria if's para incrementar as variaveis .

pra mim parece ser isso a fazer, só que já começo a me embananar na hora de gerar as combinações !!!

Caso eu não tenha sido claro por favor peçam mais esclarecimentos !!!

Abçs

EDIT: as dezenas do arquivo CSV real estão escritas em ordem aleatoria !!!


------------------------------------------------------| Linux User #621728 |------------------------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------------------| Linux User #621728 |------------------------------------------------------


Estou começando a entender ....
No meu exemplo, fiz as combinações para cada linha do arq.csv, ERREI....
----------------------------------------------------------------------------------------------------------------
Considerando repetidos,
São "17.576" Combinações
----------------------------------------------------------------------------------------------------------------
Sugestão:
x="{$(echo {25..50}|sed 's/ /,/g')}";
eval echo $x:$x:$x|sed 's/ /\n/g' > comb.txt
Em comb.txt tem todas combinações.
Agora é ler linha a linha de comb.txt, e buscar no arq.csv

Gera arq.csv:
for((x=1;x<=2000;x++)) { shuf -i 25-50 -n5|paste -sd',' >> arq.csv;}
-----------------------------------------------------------------------------------------------------------------
Vejo que o mais pratico é com o sed,
Exemplo:
Busca pelas dezenas, independente da ordem
sed '/25/!d; /26/!d; /27/!d;' arq.csv
É isso....
______________________________________________________________________
Att.: Marcelo Oliver
______________________________________________________________________



7. Re: Combinação simples

Leomar de Oliveira
leoCCB

(usa Slackware)

Enviado em 24/04/2022 - 02:32h

Mauriciodez escreveu:

Vou exemplificar aqui para vc's entenderem o que eu preciso

Arquivo CSV
25;26;27;28;29
36;37;38;39;40
26;27;28;39;40


preciso que ele gere todas as combinações (de 3 dezenas) possíveis de 25 a 50 e conte quantas vezes elas aparecem no CSV

25;25;25;0
25;25;26;0
...
26;27;28;2
...
38;39;40;1
38;39;41;0
...
50;50;50;0


NOTA: no exemplo de saída eu não coloquei a contagem de todas as combinações !!!

pensei a principio gerar 3 variáveis ( que são as 3 trincas de dezenas ) D1;D2:D3 ...
* Daria o valor inicial 25 para elas pois é a primeira combinação possível
* faria o primeiro loop no "BD.csv" contando linha por linha e escrevendo digamos em "Saída.csv".
* criaria if's para incrementar as variaveis .

pra mim parece ser isso a fazer, só que já começo a me embananar na hora de gerar as combinações !!!

Caso eu não tenha sido claro por favor peçam mais esclarecimentos !!!

Abçs

EDIT: as dezenas do arquivo CSV real estão escritas em ordem aleatoria !!!


------------------------------------------------------| Linux User #621728 |------------------------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------------------| Linux User #621728 |------------------------------------------------------


Acho que a primeira parte seria
echo -e {25..50}.{25..50}.{25..50}.{0..2} | xargs -n 5 | sed 's/ / /g'
onde e echo -e gera na primeira chave números de 25 a 50 com as demais fixas, depois a segunda varia com as demais fixas, e assim por diante... tentei com vírgula entre as chaves aqui mas não rolou, nada q um sed não resolva; o xargs -5 agrupa de 5 em 5 e o sed eu troquei um espaço em branco por 3 brancos, só pra separar melhor.... a quarta dupla de chaves eu variei de 0 a 2 pq no exemplo q vc passou só variava ali, mas vc muda aí conforme sua necessidade, é mais exemplo mesmo.
aí eu não entendi as repetições... por exemplo, "25,26,27,1"=="27,26,25,1"? pois todas as dezenas que tem de um lado tem do outro? ou a ordem ali importa?



8. Re: Combinação simples

Leomar de Oliveira
leoCCB

(usa Slackware)

Enviado em 24/04/2022 - 03:08h


Mauriciodez escreveu:

Vou exemplificar aqui para vc's entenderem o que eu preciso

Arquivo CSV
25;26;27;28;29
36;37;38;39;40
26;27;28;39;40


preciso que ele gere todas as combinações (de 3 dezenas) possíveis de 25 a 50 e conte quantas vezes elas aparecem no CSV

25;25;25;0
25;25;26;0
...
26;27;28;2
...
38;39;40;1
38;39;41;0
...
50;50;50;0


NOTA: no exemplo de saída eu não coloquei a contagem de todas as combinações !!!

pensei a principio gerar 3 variáveis ( que são as 3 trincas de dezenas ) D1;D2:D3 ...
* Daria o valor inicial 25 para elas pois é a primeira combinação possível
* faria o primeiro loop no "BD.csv" contando linha por linha e escrevendo digamos em "Saída.csv".
* criaria if's para incrementar as variaveis .

pra mim parece ser isso a fazer, só que já começo a me embananar na hora de gerar as combinações !!!

Caso eu não tenha sido claro por favor peçam mais esclarecimentos !!!

Abçs

EDIT: as dezenas do arquivo CSV real estão escritas em ordem aleatoria !!!


------------------------------------------------------| Linux User #621728 |------------------------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------------------| Linux User #621728 |------------------------------------------------------



echo -e {25..50}.{25..50}.{25..50}.{0..2} | xargs -n 1 | nl

só gera uma coluna e o nl enumera as linhas... a quantidade de linhas é a quantidade de cobinações... agora falta tirar as repetições, se for o caso.


9. Re: Combinação simples

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/04/2022 - 05:27h

Cada linha do arquivo vai ter o seguinte formato (onde A, B, C, D e E são valores inteiros, em formas de dezenas, podendo haver valores repetidos entre eles).
A;B;C;D;E 


Assim sendo, após ler cada linha, haverá até cinco valores possíveis de dezenas individuais, e exatamente três sequências com três dezenas (A;B;C, B;C;D e C;D;E).

Usando arrays associativos (um recurso interno do bash e do ksh, de modo que não precisa nem invocar um comando externo que funciona como outra linguagem de programação, tal como o awk) você pode lembrar de todas as dezenas individuais possíveis, bem como já ir contando cada sequência de três dezenas que ocorre no arquivo, e faz isso tão logo lê cada linha.

No final da execução, você pode usar o array associativo d chaves individuais para formar todas as possíveis sequências de três caracteres, e então usar cada elemento desse conjunto de possibilidades para consultar o array associativo de sequências presentes no arquivo, de modo que se aquela sequência existir no array, a quantidade é a que está armazenada na associação, e, se não existir, a quantidade é zero.

Acho que não tem como fazer de modo mais simples do que isso que eu disse acima. A resposta final é só converter para shell o algoritmo dado.


Eu não acredito muito em dar resposta pronta na forma final. Vai que a pergunta é um trabalho de faculdade ou curso: dar a resposta pronta vai servir como uma enganação não apenas para o professor, mas para o próprio aluno que a recebeu, criando a ilusão de que sabe algo pelo qual não teve de fazer grande esforço.

Entretanto, eu já dei a resposta semi-pronta acima, em Português em vez de shell script. Assim sendo, para não parecer que eu estou apenas blefando, vou dar outra resposta semi-pronta em outra linguagem: Perl.

#!/usr/bin/perl

# Respondendo ao tópico https://www.vivaolinux.com.br/topico/Shell-Script/Combinacao-simples/


#### FASE 1: Leitura do dados de entrada ####

# Laço de repetição que lê linhas na entrada.
while(<>){
chomp; # Descarta caráter de fim de linha (desnecessário em shell).

# Opcional: descarta linhas que não atendem ao formato especificado.
next unless /^\s*\d+;\d+;\d+;\d+;\d+$/;

($a, $b, $c, $d, $e)=split(/;/);
# Opcional (e não implementado): verifica se os valores de $a, $b, $c, $d e $e
# estão dentro da faixa aceitável.

# Para cada dezena, alimenta (incrementando a contagem de ocorrências) o
# array associativo de dezenas (elementos inicialmente inexistentes contam
# como zero no contexto de operações numéricas, o que facilita a vida).
foreach $n ($a, $b, $c, $d, $e){
++$dezenas{$n};
}

# Para cada sequência de três elementos que ocorre na linha, incrementa o
# array associativo de sequências.
++$sequencias{"$a;$b;$c"};
++$sequencias{"$b;$c;$d"};
++$sequencias{"$c;$d;$e"};
}


#### FASE 2: Produz a saída ####

# Produz uma lista ordenada de todas as dezenas encontradas.
@dezenas_ordenadas=sort(keys(%dezenas));

foreach $elem1 (@dezenas_ordenadas){
foreach $elem2 (@dezenas_ordenadas){
foreach $elem3 (@dezenas_ordenadas){
$tupla="$elem1;$elem2;$elem3";
# De novo, valho-me do fato de que elementos que não existem são
# interpretados como zero no contexto de operações numéricas.
printf("%s;%d\n", $tupla, $sequencias{$tupla});
}
}
}



... Então Jesus afirmou de novo: “(...) eu vim para que tenham vida, e a tenham plenamente.” (João 10:7-10)


10. Re: Combinação simples

Mauriciodez
Mauriciodez

(usa Debian)

Enviado em 08/05/2022 - 21:44h


ainda não tive tempo para mexer com isso, assim que der mando aqui o que fiz !!!

abçs !!!

------------------------------------------------------| Linux User #621728 |------------------------------------------------------

" Nem sempre é amigo aquele que te tira do buraco !!! ( Saddam Hussein )"

------------------------------------------------------| Linux User #621728 |------------------------------------------------------