Encontre um divisor “moderadamente grande” de um determinado número?

1

Depois de processar alguns dados, recebo um arquivo com um certo número de pontos de dados - um por linha. Eu preciso passar esses pontos de dados para outra ferramenta que fará mais processamento de números - na ferramenta, eu preciso definir o "tamanho do lote" para uma determinada execução:

./gen_data.sh > data.txt
./process_data.sh < data.txt > parsed.bin
./crunch_data.sh --total=$(wc -l < data.txt) --batch_size=N --infile=parsed.bin

Um tamanho de lote N que é muito baixo levará muito tempo para ser processado; um tamanho de lote muito alto me dará uma saída de baixa qualidade. O tamanho do lote deve dividir o número de pontos de dados, dado por M=$(wc -l < data.txt) . Os valores de N em torno de M/10 parecem ser muito bons. Não é grande coisa se o tamanho do lote fizer algo estranho em casos estranhos (por exemplo, N=M para um primo M --- esse caso quase certamente não ocorrerá, então não estou preocupado com isso).

Existe uma maneira engenhosa de fazer isso com ferramentas shell? Eu sei que posso obter os fatores de M com factor . Em Python eu poderia escrever algo como:

total_portion = 1
for factor in factors(M):
    total_portion *= factor
    if total_portion > 10:
        return M/total_portion

E agora eu tenho uma fração de M que é um pouco menor que 1/10 dela, dependendo de quantos fatores M tiveram.

Não sei ao certo como faço isso como um script de shell ou quais ferramentas posso usar para facilitar. Isso pode ser feito bem? Eu estou melhor apenas passando a lista de fatores para um pequeno script Python e fazendo a lógica lá?

    
por Patrick Collins 24.11.2015 / 11:55

1 resposta

2

Aqui está uma versão shell do seu algoritmo python usando o GNU factor :

#! /bin/bash

function total_portion() {
    local M="$1"
    local total_portion=1

    for factor in $(factor "$M" | sed -e 's/^[0-9]\+: //'); do
        ((total_portion *= factor))
        if [ "$total_portion" -gt 10 ] ; then
            echo $((M / total_portion))
            return 
        fi
    done
}

M=$(wc -l < data.txt)

tp=$(total_portion "$M")
    
por 24.11.2015 / 12:37