Edição de quatro de julho: Imprimir linhas de um arquivo contendo múltiplos de um número específico

8

Crie um programa que use um argumento de linha de comando, nque será um número inteiro menor que 2147483648 (2 ^ 31) e, em seguida, leia um arquivo input.txte imprima as linhas input.txtque contêm qualquer substring que seja um múltiplo positivo (diferente de zero) de n. Você pode optar por ignorar múltiplos maiores que 2147483647.

Caso de teste

Se input.txtcontém

1. Delaware Dec. 7, 1787    
2. Pennsylvania Dec. 12, 1787   1682
3. New Jersey   Dec. 18, 1787   1660
4. Georgia  Jan. 2, 1788    1733
5. Connecticut  Jan. 9, 1788    1634
6. Massachusetts    Feb. 6, 1788    1620
7. Maryland Apr. 28, 1788   1634
8. South Carolina   May 23, 1788    1670
9. New Hampshire    June 21, 1788   1623
10. Virginia    June 25, 1788   1607
11. New York    July 26, 1788   1614
12. North Carolina  Nov. 21, 1789   1660
13. Rhode Island    May 29, 1790    1636
14. Vermont Mar. 4, 1791    1724
15. Kentucky    June 1, 1792    1774
16. Tennessee   June 1, 1796    1769
17. Ohio    Mar. 1, 1803    1788
18. Louisiana   Apr. 30, 1812   1699
19. Indiana Dec. 11, 1816   1733
20. Mississippi Dec. 10, 1817   1699
21. Illinois    Dec. 3, 1818    1720
22. Alabama Dec. 14, 1819   1702
23. Maine   Mar. 15, 1820   1624
24. Missouri    Aug. 10, 1821   1735
25. Arkansas    June 15, 1836   1686
26. Michigan    Jan. 26, 1837   1668
27. Florida Mar. 3, 1845    1565
28. Texas   Dec. 29, 1845   1682
29. Iowa    Dec. 28, 1846   1788
30. Wisconsin   May 29, 1848    1766
31. California  Sept. 9, 1850   1769
32. Minnesota   May 11, 1858    1805
33. Oregon  Feb. 14, 1859   1811
34. Kansas  Jan. 29, 1861   1727
35. West Virginia   June 20, 1863   1727
36. Nevada  Oct. 31, 1864   1849
37. Nebraska    Mar. 1, 1867    1823
38. Colorado    Aug. 1, 1876    1858
39. North Dakota    Nov. 2, 1889    1812
40. South Dakota    Nov. 2, 1889    1859
41. Montana Nov. 8, 1889    1809
42. Washington  Nov. 11, 1889   1811
43. Idaho   July 3, 1890    1842
44. Wyoming July 10, 1890   1834
45. Utah    Jan. 4, 1896    1847
46. Oklahoma    Nov. 16, 1907   1889
47. New Mexico  Jan. 6, 1912    1610
48. Arizona Feb. 14, 1912   1776
49. Alaska  Jan. 3, 1959    1784
50. Hawaii  Aug. 21, 1959   1820

depois find_multiples 4imprimirá o arquivo inteiro e find_multiples 40imprimirá

10. Virginia    June 25, 1788   1607
17. Ohio    Mar. 1, 1803    1788
21. Illinois    Dec. 3, 1818    1720
32. Minnesota   May 11, 1858    1805
40. South Dakota    Nov. 2, 1889    1859
41. Montana Nov. 8, 1889    1809
ojblass
fonte
1. Tem certeza de que quer dizer 32 bytes e não 32 bits? 2. Qual múltiplo de 4 está presente na linha 33. Oregon Feb. 14, 1859 1811? É o 4in 14, implicando que a correspondência é contra qualquer substring em vez de qualquer sequência de dígitos delimitada por não-dígitos ou final de linha?
Peter Taylor
sim, o 4 em 4 conta como um 4 porque é uma substring.
ojblass
3
Além disso, esse código é de golfe ou tem algum outro critério de vitória?
Peter Taylor
apenas codifique o golfe ... desculpe, apenas aprendendo aqui!
ojblass

Respostas:

4

Perl, 67 caracteres

open F,"input.txt";print grep/(\d+)(?(?{!$^N+$^N%$ARGV[0]})(*F))/,<F>

Observe que a contagem de caracteres fornecida está tirando proveito de um dos recursos mais terríveis do Perl, a saber, que uma variável especial do formulário $^Xpode ser escrita em dois caracteres em vez de três, substituindo-o ^Xpor um caractere literal ctrl- X .

E, é claro, essa solução não seria possível sem algumas extensões regex indiscutivelmente igualmente aterradoras, que permitem incorporar código real dentro de um padrão regex. (Mas pelo menos esses recursos estão claramente documentados como potencialmente assustadores.)

[EDITADO para corrigir bug no tratamento de argumentos devido à falta de leitura da descrição com cuidado.]

caixa de pão
fonte
Como posso ver, a solução não lê do arquivo input.txt.
Howard Howard
Hum. Enquanto eu o li, a descrição do problema afirma que o programa usa dois argumentos, o nome do arquivo de entrada e o número para pesquisar múltiplos de. Vejo agora que isso é modificado no final da descrição. Bela armadilha que você colocou para mim lá, Oscar Blass.
breadbox
2

Mathematica

dates=Import["input.txt"]
f[digits_]:=FromDigits/@Flatten[Table[Partition[digits,k,1],{k,1,Length[digits]}],1]
g[oneline_]:={FromDigits[oneline[[1]]],Complement[Union[Flatten[f/@oneline]],{0}]}
h[n_,{a_,b_}]:={a,MemberQ[Mod[#,n]&/@b,0]};

w[k_]:=Column@dates[[Cases[h[k,g[#]]&/@ToExpression@(Characters /@ (StringCases[#, DigitCharacter ..] & /@ dates)),{j_,True}:>j]]]

f remove todos os que não são dígitos;

g localiza todos os números que podem ser encontrados em uma única linha de data.

hverifica se Mod [x, n] é verdadeiro para qualquer um dos números retornados por g.

w chama as sub-rotinas e formata a saída.

Exemplos

n=40
w[n]

saída 40


 n=51
 w[n]

saída 51


 n=71
 w[n]

saída 71

DavidC
fonte
Ele retorna "ToExpression :: sntx: sintaxe inválida antes ou" 1. Delaware, 7 de dezembro de 1787 "." para mim
Dr. belisarius
@belisarius Eu suspeito que houve um problema com o seu arquivo "Input.txt". Tente configurar diretamente. dates={"1. Delaware Dec.7,1787"} Em seguida, tente w[17]. Ele deve retornar a mesma linha de informação.
DavidC
Está bem. Como devo salvar meu arquivo de entrada?
Dr. belisarius
Primeiro, coloque seus dados em uma lista:, dates = {"1. Delaware Dec.7,1787",...}então Export["input.txt",dates]. Você usa Import["input.txt", dates]para recuperá-lo.
21413
Ahh, certo. Alguma massagem era necessária. Obrigado!
Dr. belisarius
2

Q, 94

-1@m(&){0|/{(x>0)&0=x mod"I"$.z.x 0}"J"$sublist[;x]'[a cross a:(!)1+(#)x]}'[m:(0:)`input.txt];

Sem dúvida, há uma maneira mais graciosa de encontrar substrings em q.

$ q find_multiples.q 40 -q
10. Virginia    June 25, 1788   1607
17. Ohio    Mar. 1, 1803    1788
21. Illinois    Dec. 3, 1818    1720
32. Minnesota   May 11, 1858    1805
40. South Dakota    Nov. 2, 1889    1859
41. Montana Nov. 8, 1889    1809

.

$ q find_multiples.q 51 -q
19. Indiana Dec. 11, 1816   1733
25. Arkansas    June 15, 1836   1686
37. Nebraska    Mar. 1, 1867    1823
tmartin
fonte
2

Ruby 2.0, 129 caracteres

Com alguma ajuda de @chron:

IO.foreach('input.txt'){$><<$_ if$_.gsub(/\d+/).any?{(0..s=$&.size).any?{|i|(1..s).any?{|j|(v=$&[i,j].to_i)%$*[0].to_i<1&&v>0}}}}

Essa longa fila terminou um pouco:

IO.foreach('input.txt') {
    $> << $_ if $_.gsub(/\d+/).any? {
        (0..s=$&.size).any? { |i|
            (1..s).any? { |j|
                (v=$&[i,j].to_i) % $*[0].to_i < 1 && v>0 }}}}

Exemplo:

$ ruby july4.rb 40
10. Virginia    June 25, 1788   1607
17. Ohio    Mar. 1, 1803    1788
21. Illinois    Dec. 3, 1818    1720
32. Minnesota   May 11, 1858    1805
40. South Dakota    Nov. 2, 1889    1859
41. Montana Nov. 8, 1889    1809

$ ruby july4.rb 71
29. Iowa    Dec. 28, 1846   1788
daniero
fonte
2
Poucas economias para a segunda linha: IO.foreach('input.txt'){|l|puts l if l.scan(/\d+/).any?{|a|(0..s=a.size).any?{|i|(1..s).any?{|j|(v=a[i,j].to_i)%n<1&&v>0}}}}eu amo, #combinationmas é uma palavra tão longa!
Paul Prestidge
Graças chron! Sim, semanticamente, acho que minha resposta original era mais bonita, mas isso é bem mais curto; Agradável! Eu consegui extrair mais alguns caracteres tirando proveito de algumas $variáveis, então agora parece quase perl!
Daniero 04/07/2013
Parece bom! Olhando as especificações novamente, aparentemente nprecisa ser um argumento de linha de comando, e não um valor lido de stdin. Assim, você poderá excluir a sua primeira linha inteiramente e substituí nna segunda linha com$*[0].to_i
Paul Prestidge
Você está certo! obrigado.
Daniero