Sobre macaca, macaca-de-auditório, macacal, macacão, macacar, macacarecuia, macacaria, macaco, macacoa*, macaco-adufeiro, macaco-aranha, macaco-barrigudo, macaco-cabeludo, macaco-da-meia-noite, macaco-da-noite macaco-de-bando, macaco-de-cheiro, macaco-inglês, macaco-japonês, macaco-narigudo, macaco-patrona, macaco-prego, macaco-prego-do-peito-amarelo e TI.

sábado, agosto 25, 2007

Code Contest: Em tempos de Mega Sena Acumulada

Um pequeno desafio:

Escrever em qualquer linguagem de programação um programa que realize 100.000 sorteios de um numero entre 1 e 60 e mostre na tela os 6 mais freqüentes.

Ganha quem fizer o programa com o menor numero de linhas possíveis, lembrando que a linha considerada é a linha da unidade léxica da linguagem, portanto a seguinte linha em Java seria considerada duas: int i =0; sysout(i);

Fiz com 3 linhas em Ruby:

hist = Hash.new(0)
100000.times{|e| hist[1 + rand(60)] += 1}
hist.sort{|a,b| b[1]<=>a[1]}.to_a.slice(0,6).each{|e| puts "#{e[0]} --> #{e[1]}"}


Será possível fazer em menos linhas com Python, Groovy, Haskell ou Prolog? Em Ruby da pra fazer com menos? Citei essas porque acho quase impossível fazer com menos do que isso com Java, C/C++ ou C#, mas se alguém quiser provar o contrario...

Update II

Para ficar mais organizado novas Contribuições estão sendo postadas aqui.

Update

O ZehOliveira do GUJ fez com 3 linhas na interessantísima IO (Valeu Zé!):

h := Map;

100000
repeat(if(h hasKey(n := Random value(1, 60) round asString), h atPut(n, h at(n)+1), h atPut(n, 1)))

h asList sortBy(block(f, s, f at(1) > s at(1))) slice(v, 6) foreach(k, writeln(k at(0), " --> ", k at(1)))

O Daniel Martins também fez com 3 linhas em Groovy e em SmallTalk(Value Daniel!):

def hist = [:], v
100000
.times{hist[v = 1 + Math.random() * 60 as int] = !hist[v] ? 1 : hist[v] + 1}
println hist.keySet().toList().sort{-hist[it]}[0..5].sort().join(‘,’)


| s |
s
:= ((OrderedCollection withAll: ((1 to: 100000) collect: [:each | 60 atRandom])) groupBy: [:each | each] having: [:each | true]) asSortedCollection: [:a :b | b size < style="">].
1 to: 6 do: [:each | Transcript show: ((s at: each) at: 1); cr]


E os grandes vencedores até agora são o
Walter Cruz e o Bernado Rufino Perder eles não perdem, só se inventarem a meia linha. O caras fizeram em uma inacreditável linha:

Versão em Python do Walter Cruz:

x = [item for item in sorted([(k, len(list(g))) for k, g in groupby(sorted([randrange(1,61) for item in xrange(0,100000)]))],key=itemgetter(1),reverse=True)][:6]
print(x)

Versão em Ruby do Bernado Rufino:
Array.new(100000){rand(60)+1}.inject(Hash.new(0))
{|hash, i| hash if hash[i] += 1}.invert.sort.reverse[0..6].each{|t, n| puts "#{n}
repeated #{t} times"}
Por problemas no layout( que ja passou da hora de ser revisto) tive que quebrar a linha, mas acreditem é uma só;

48 Comments:

At 12:02 PM, Anonymous Anônimo said...

Realmente a linguagem é expressiva, em detrimento da legibilidade do código. Em Perl deve ser possível fazer com o mesmo número de linhas de código ou menos...

 
At 5:10 PM, Anonymous Anônimo said...

Fiz em io language, em três linhas também: http://joseoliveira.com/2007/08/26/code-contest-em-tempos-de-mega-sena-acumulada/

Usando a mesma lógica que tu usou. :D

 
At 7:58 PM, Blogger RodrigoSol said...

Pois é.

Nesse caso o critério legibilidade foi para o espaço.

No dia-a-dia o bom senso nos impede (ou pelo menos deveria) de escrever esses ninhos.

Por outro lado, o que eu queria destar é flexibilidade dessa nova geração de linguagens dinâmicas que eu simplesmente acho fantástico!

 
At 7:59 PM, Blogger RodrigoSol said...

Zeh.

Tomei a liverdade de postar seu codigo de IO aqui! Ficou muito legal!!!

 
At 9:07 PM, Anonymous Anônimo said...

Tomei a liberdade de escrever um programa em Groovy para solucionar esse desafio que você propôs (que, por sinal, é bem oportuno). :P

Abraço.

 
At 8:10 PM, Blogger Unknown said...

Com 1 linha em Ruby! Code Contest: Mega Sena em 1 linha!:
http://bermonruf.wordpress.com/2007/09/01/code-contest-mega-sena-em-1-linha

 
At 11:50 PM, Blogger Walter Cruz said...

Hehehe.. Tirando as linhas dos import, foi praticamente só uma linha em python também :D. Mas esse código do Bernardo é uma coisa de doido sô!

 
At 11:59 AM, Blogger RodrigoSol said...

Perdão Walter.

Nao conheco Python. Quando abri seu blog o print(x) tava na linha de baixo. Me enganei.

Irei atualizar aqui. Aproveito para perguntar: Lexicamente como eh uma linha em Python?

Abracos

 
At 1:06 PM, Blogger Walter Cruz said...

:)

Bom, na verdade, lexicamente, a versão que te mandei são 5 linhas mesmo :(

Dá pra colocar em 4 linhas colocando o print em volta do cálculo, mas ainda assim são 3 a mais!

Então, apesar do cálculo ter sido em uma única linha, foram 3 de import, o que me deixa de fato, 4 linhas acima do campeão :D

 
At 1:47 PM, Blogger Unknown said...

Mas o que vale é a lógica e não os imports, por mim em uma linha também.
Aproveita e atualiza lá em cima, coloca o print em volta do cálculo.

 
At 2:02 PM, Blogger RodrigoSol said...

Opa...

Os imports pra mim tambem nao conta.
Mera formalidade.

Daqui a pouco atualizo lá.

[]'s

 
At 5:49 PM, Blogger Walter Cruz said...

Tem a versão do Daniel Martins em smalltalk agora!

 
At 9:12 AM, Blogger RodrigoSol said...

Atualizado!

To querendo aprender smalltalk. Alguém indica um começo?

 
At 10:36 AM, Blogger Micox - Náiron J. C. G. said...

Este comentário foi removido pelo autor.

 
At 11:00 AM, Blogger Micox - Náiron J. C. G. said...

Opa, acho que fiz com 2 linhas em javascript. Alguém dá um bizu pra ver se tá valendo?

 
At 1:30 PM, Anonymous Anônimo said...

Macaco Chefe, por favor valida minah solução:

http://www.mouseoverstudio.com/blog/?p=23

 
At 9:32 PM, Anonymous Anônimo said...

Olá, uma possível solução em c++:
int main() { for(int freq[] =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,
35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60},
i = 0; i == 100000 ? printf("%d %d %d %d %d %d\n", freq[59]%100,
freq[58]%100, freq[57]%100, freq[56]%100, freq[55]%100,
freq[54]%100)*0 : 1;sort(freq, freq+sizeof(freq)/sizeof(int)), i++,
freq[rand()%60]+=100); }

 
At 6:24 AM, Blogger Rodrigo Fante said...

Em javascript modificando o codigo do Micox e do Diego Carrion:

http://www.fazedordesite.com/blog/2007/09/07/code-contest-mega-sena-acumulada/

 
At 3:06 PM, Anonymous Anônimo said...

Opa, em Perl, isso vale como 2 linhas?:

for $i (1 .. 100000) { $h{int(rand()*60)+1}++; }
print join(' ', (sort { $h{$b} <=> $h{$a} } keys %h)[0..5]) . "\n";

 
At 4:08 PM, Anonymous Anônimo said...

Opa, eu também consegui uma solução em apenas uma linha, em python, tentei ao maximo fazer diferente da solução do Walter Cruz.

segue..
sorted([ (y,k) for x in [[ random.randint(1,60) for z in xrange(100000) ]] for k in xrange(1,60) for y in [x.count(k)] ], reverse=True)[:6]

 
At 4:13 PM, Anonymous Anônimo said...

Uma linha de Perl, muito parecida com a solução de Rafael em C++:

for (1..100001) { ($_ == 100001) ? print join(" ", (sort { $h{$b} <=> $h{$a} } keys %h)[0..5]) . "\n": $h{int(rand()*60+1)}++ }

 
At 4:54 PM, Anonymous Anônimo said...

outra versão em c++:
int main() {
for(vector< int> v(60,0),i(0,0); i[0] == 100060 ? printf("%d %d %d %d %d %d\n", v[59]%70, v[58]%70, v[57]%70, v[5 6]%70, v[55]%70, v[54]%70)*0 : 1; v[i[0] < 60 ? 59 - i[0] : (rand()%60)]+= i[0] < 60 ? i[0]+1 : 70, i[0]++, sort(v.begin(), v.end()));
}

 
At 4:58 PM, Anonymous Anônimo said...

Vi que na minha solução o for sobre y é completamente desnecessario.
Ficando como solução:

sorted([ (x.count(k),k) for x in [[ random.randint(1,60) for z in xrange(100000) ]] for k in xrange(1,61) ], reverse=True)[:6]

O resultado fica no formato
[(qntidade, numero), ...]

Caso seja necessario o formato (numero, qntidade) pode-se usar como parâmetro key na função sorted o itemgetter(1) como o Walter Cruz utilizou ou key=lambda x: x[1].

Segue a resposta noutro formato:

sorted([ (k,x.count(k)) for x in [[ random.randint(1,60) for z in xrange(100000) ]] for k in xrange(1,61) ], key=itemgetter(1), reverse=True)[:6]

 
At 6:04 PM, Anonymous Anônimo said...

Sim... só deixando de claro que a solução em Perl eu tomei cuidado só para usar recursos da linguagem, nada de importar módulos (use).

 
At 12:23 PM, Blogger RodrigoSol said...

Pessoal,

To viajando... Quando chegar atualizo o blog com as novas versões.

Abraços.

 
At 11:26 PM, Anonymous Anônimo said...

Cara, tá aí o meu em PHP. 1 linha.

for ($i=0, $ns = array(); $i<=100000; $i++, $ns[rand(1, 60)]++, arsort($ns)) { } echo implode(", ", array_slice(array_keys($ns), 0, 6));

Se isso não for 1 linha me avisa que eu dou uma arrumada. =]

Abraço

 
At 9:02 AM, Blogger RodrigoSol said...

Vinicius,

Se seguirmos a risca o que é lexicamente uma linha a maioria não das contribuições nao poderia ser considerada... Mas quer saber, o objetivo real era mostrar a expressividade de uma linguagem e seu exemplo mostra como PHP poder bem expressivo.

Daqui a pouco atualizo.

[]'s

 
At 10:03 AM, Anonymous Anônimo said...

Opa,

To aprendendo elisp e resolvi fazer uma versao para meu Emacs. Assim fica mais fácil escolher os números que vou apostar na mega-sena semana que vem :-)

Ficou gigante, espero poder reduzir esse código qdo tiver dominando mais Elisp:

(defun mega-sena ()
(interactive)
(let ((l ())
(n 100000)
i)
(dotimes (count 60)
(setq l (cons `(,(- 60 count) . 0) l)))
(while (> n 0)
(setq i (random 60))
(setcdr (car (nthcdr i l)) (1+ (cdr (car (nthcdr i l)))))
(setq n (1- n)))
(setq l (sort l (lambda (a b) (> (cdr a) (cdr b)))))
(setq n 0)
(while (< n 6)
(insert (format "%d " (car (car l))))
(setq n (1+ n))
(setq l (cdr l)))
(insert "\n")))

 
At 1:53 PM, Anonymous Anônimo said...

essa linha em Perl vale?

print join(' ',(sort{$t{$b}<=>$t{$a}}grep(!$t{$_}++,map{(int rand 60)+1}1..1000))[0..5])."\n"

 
At 12:41 AM, Anonymous Anônimo said...

Outro code em PHP..

-
$i=0;while(1){$r=rand(1,60);$t[$r]++;if(++$i==100000)die(arsort($t).join(',',array_splice(array_keys($t),1,6)));}
-

[]s

 
At 11:16 AM, Anonymous Anônimo said...

Opa! uma pequena modificação..

$i=0;while(1){$t[rand(1,60)]++;if(++$i==100000)die(arsort($t).join(',',array_splice(array_keys($t),1,6)));}

[]s :D

 
At 10:25 PM, Blogger Walker said...

PHP, 2 linhas(primeira tentativa)

Desculpem a cadeia de chamadas de array. mas para o resultado ficar organizado soh assim mesmo ;).

for($x = 0; $x < 100000; $x++, $i = mt_rand(1,60) ) $ar[$i] = (!isset($ar[$i]))?array(1,$ i):array($ar[$i][0]+1,$i);
echo ( (rsort($ar) and ($ar=array_slice($ar,0,6)) )?"":"" )."{$ar[0][1]}: {$ar[0][0]} vez es - {$ar[1][1]}: {$ar[1][0]} vezes - {$ar[2][1]}: {$ar[2][0]} vezes - {$ar[3][1]}: {$ar[3][0]} vezes - {$ar[4][1]}: {$ar[4][0]} vezes - {$ar[5][1]}: {$ar[5][0]} vezes";

 
At 3:15 PM, Anonymous Anônimo said...

solução em python:
from random import randint
l , ct = [] , {}
while len(l) <= 100000: l += [ randint(1,60) ]
for x in l: ct[x] = l.count(x)
count = ct.values()
count.sort()
for n in ct.keys():
if ct[n] == count[len(count)-1] or ct[n] == count[len(count)-2] or ct[n] == count[len(count)-3] or ct[n] == count[len(count)-4] or ct[n] == count[len(count)-5] or ct[n] == count[len(count)-6] : print n

 
At 6:12 PM, Anonymous Anônimo said...

o que eu estava procurando, obrigado

 
At 11:17 AM, Anonymous Anônimo said...

Fiz em io language, em três linhas também: http://joseoliveira.com/2007/08/26/code-contest-em-tempos-de-mega-sena-acumulada/

 
At 11:17 AM, Anonymous Anônimo said...

Realmente a linguagem é expressiva, em detrimento da legibilidade do código. Em Perl deve ser possível fazer com o mesmo número de linhas de código ou menos...

 
At 11:21 AM, Anonymous Anônimo said...

Por outro lado, o que eu queria destar é flexibilidade dessa nova geração de linguagens dinâmicas que eu simplesmente acho fantástico!

 
At 10:09 PM, Anonymous Locutor Antonio Cezar said...

Acho que consegui diminuir alguma coisa, depois de usar um dos pequenos códigos daqui por algum tempo:


OBS: Não sou programador.

 
At 10:48 PM, Anonymous Locutor Antonio Cezar said...

Como o meu código não saiu aqui, coloquei ele em:
http://olocutor.com/m

 
At 5:19 AM, Anonymous Anônimo said...

Look At This buy tramadol with cod delivery - buy tramadol online australia no prescription

 
At 10:48 PM, Blogger Unknown said...

ray ban sunglasses uk
michael kors outlet
rolex watches
fitflop shoes
coach outlet online
louboutin shoes
ugg boots outlet
scarpe hogan
nike air max pas cher
nike roshe run
201612.19wengdongdong

 
At 12:37 AM, Blogger raybanoutlet001 said...

ed hardy
michael kors handbags sale
michael kors outlet
michael kors handbags outlet
birkenstock sandals
cheap michael kors handbags
arizona cardinals jerseys
michael kors handbags
patriots jerseys

 
At 3:16 AM, Blogger raybanoutlet001 said...

nike roshe
polo ralph lauren
arizona cardinals jerseys
chiefs jersey
ed hardy
coach factory outlet
polo ralph lauren
ugg outlet
ralph lauren polo
ed hardy

 
At 10:19 PM, Blogger Unknown said...

pandora jewelry
nike running shoes
christian louboutin uk
hermes bags
ugg boots
ugg outlet
true religion outlet
coach factory outlet
uggs
canada goose canada
201710.7wengdongdong

 
At 12:59 AM, Blogger Unknown said...

zzzzz2018.7.4
valentino shoes
polo ralph lauren
nhl jerseys
ralph lauren uk
longchamp outlet
supreme shirt
reebok shoes
nike soldes femme
jordans
true religion outlet store

 
At 12:28 AM, Blogger 5689 said...

moncler jackets
off-white clothing
pandora
louboutin shoes
ralph lauren outlet
issey miyake perfume
off white jordan 1
nhl jerseys wholesale
pandora jewelry
adidas outlet online
zzzzz2018.8.8

 
At 10:51 PM, Blogger jeje said...

Habiller votre corps pour améliorer chacune des pièces appropriées est juste asics femme chaussure une récréation de proportion. Les automobilistes et les bois d'allées sont dotés de l'ingénierie réglable STR8-FIT TOUR et d'un canal de compression réglable qui renforce le volume des surfaces douces du club. Les fers 2, 3 et 4 sont généralement des fers de golf à cavité pleine poche. Les feuilles séchées, à l'inverse, sont trempées dans l'eau et transformées en cataplasme, puis appliquées sur les ulcères indolents. Cela pourrait vous aider à vous déplacer beaucoup plus facilement lorsque vous avez ce problème. Les maisons régénératrices innées du sérum limitent la blessure due à la formation de cicatrice et de blessure en reconstituant air jordan 11 aqua une matrice saine et en réglant des poursuites de métalloprotéinase.

 
At 9:30 AM, Blogger Unknown said...


Packing and unpacking is part and parcel of moving goods. Through our vendors you could get professional packing for the wide range of items for your home and office.
شركة نقل اثاث من جدة الى عمان
شركة نقل عفش من جدة الى دبي
شركة نقل عفش من الدمام الى القطيف

معلم دهانات بالرياض رخيص

شركة مكافحة الحمام بالرياض

 

Postar um comentário

<< Home