Problem54 - ProjectEuler(未解決)
30分プログラム、その330。id:mzp:20080701:eulerを動くようにした。でも答えは違っているので、続きはまた明日。
コード量があるから、ちょっとした修正をするだけですぐ30分たってしまう。
使い方
$ perl problem54.pl ... 702
ソースコード
#! /usr/bin/perl # -*- mode:perl; coding:utf-8 -*- # # problem54.pl - # # Copyright(C) 2008 by mzp # Author: MIZUNO Hiroki / mzpppp at gmail dot com # http://howdyworld.org # # Timestamp: 2008/07/01 22:35:35 # # This program is free software; you can redistribute it and/or # modify it under MIT Lincence. # use strict; use warnings; use Data::Dumper; package Card; use Class::Struct; struct Card =>{ suit => '$',val=>'$' }; sub make($$){ my ($self,$s,$v) = @_; my $card = Card->new(); $card->suit($s); $card->val($v); return $card; } sub parse($){ my ($self,$s) = @_; my %special = ('T'=>10,'J'=>11,'Q'=>12,'K'=>13,'A'=>1); if($s =~ /\A(..?)(.)\Z/){ my $v = $1; my $s = $2; if(defined $special{$v}){ $v = $special{$v}; } $self->make($s,$v); } } package main; use List::Util qw(reduce max); sub card_cmp($$){ my ($a,$b) = @_; my $r = $a->val <=> $b->val; unless($r==0){ $r; }else{ $a->suit cmp $b->suit; } } sub same_value(@){ my ($x) = @_; reduce {$a && $b} map { $_ == $x} @_; } sub flash(@){ my ($x) = @_; if(reduce {$a && $b} map { $_->suit eq $x->suit} @_){ (5,max map {$_->val()} @_); }else{ (); } } sub straight(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if($b = $a+1 && $c == $b+1 && $d == $c+1 && $e == $d+1){ (4,$e); }else{ (); } } sub royal_flash(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(flash(@_) && $a == 1 && $b == 10 && $c == 11 && $d == 12 && $e == 13){ (9,0); }else{ (); } } sub straight_flash(@){ my @val = map {$_->val()} @_; if(flash(@_) && straight(@_)){ (8,max @val); }else{ (); } } sub four(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(same_value($a,$b,$c,$d)){ (7,$a) }elsif(same_value($b,$c,$d,$e)){ (7,$b); }else{ (); }; } sub full_house(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(same_value($a,$b) && same_value($c,$d,$e)){ (6,$a > $c ? $a : $c); }elsif(same_value($a,$b,$c) && same_value($d,$e)){ (6,$a > $c ? $a : $d); }else{ (); } } sub three(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(same_value($a,$b,$c)){ (3,$a); }elsif(same_value($b,$c,$d)){ (3,$b); }elsif(same_value($c,$d,$e)){ (3,$c); }else{ (); } } sub two(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(same_value($a,$b) && same_value($c,$d)){ (2,$a > $c ? $a : $c); }elsif(same_value($a,$b) && same_value($d,$e)){ (2,$a > $d ? $a : $d); }elsif(same_value($b,$c) && same_value($d,$e)){ (2,$b > $d ? $b : $d); }else{ (); } } sub one(@){ my ($a,$b,$c,$d,$e) = map {$_->val()} @_; if(same_value($a,$b)){ (1,$a); }elsif(same_value($b,$c)){ (1,$b); }elsif(same_value($c,$d)){ (1,$c); }elsif(same_value($d,$e)){ (1,$d); }else{ (); } } sub none(@){ my @x = (0,max map {$_->val()} @_); @x; } sub check(@){ my @cards = @_; my @cmd = (\&royal_flash,\&straight_flash,\&four,\&full_house,\&flash,,\&straight,\&three,\&two,\&one,\&none); my $i=0; for(@cmd){ $i++; my @res = $_->(@cards); if(scalar @res != 0){ return @res; } } die "must not happen"; } sub cmp_line($){ my ($line) = @_; my @cards = split /\s+/,$line; my @player1 = sort { card_cmp($a,$b) } map { Card->parse($_) } @cards[0..4]; my @player2 = sort { card_cmp($a,$b) } map { Card->parse($_) } @cards[5..9]; my ($x1,$y1) = check(@player1); my ($x2,$y2) = check(@player2); if(($x1 > $x2) || ($y1 > $y2)){ 1; }else{ 0; } } #my @cards = sort { card_cmp($a,$b) } map { Card->parse($_) } qw(AH 2H 3H 4H 5H); open(FILE,'poker.txt'); my $i=0; while(<FILE>){ print $_; if(cmp_line($_)){ print "win\n"; $i++; }else{ print "lose\n"; } } print $i,"\n";