Thread Zahlenkombinationen suchen (16 answers)
Opened by hugenyn at 2010-10-22 00:55

topeg
 2010-10-22 05:34
#142110 #142110
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Ich habe die Bedingungen ein wenig geändert, damit das Programm auch zu einem Ende kommt:
1. Der Suchwert ist >= dem größten wert im Blatt
2. wenn man keine Karten ablegen konnte muß man eine ziehen
Und hier die Rekursive Lösung:
Code (perl): (dl )
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/perl
use strict;
use warnings;

my $val=45;

my @peg=(1..45);

#Karten mischen
for(@peg)
{
  my $p=int(rand(scalar @peg));
  my $k=$_;
  $_=$peg[$p];
  $peg[$p]=$k;
}

# erste Hand abheben
my @hand=splice(@peg,0,4);

# sicherheitshalber einen Counter
# damit das Script nach 1000 Durchläufen terminiert
my $cnt=0;
while(@hand && $cnt++<1000)
{
  # Alle Kombinationen in der Hand Testen
  my @result=test_values($val,@hand);
  # etwas gefunden?
  if(@result)
  {
    # Sortieren und doppelte Einträge entfernen
    my %found=();
    @result=sort{@$b <=> @$a}map{$found{join(',', sort @$_)}++?():$_}@result;

    for my $card (@{$result[0]})
    {
      # Karte ablegen
      @hand=map{$card==$_?():$_}@hand;

      # und in den Stapel
      push(@peg,$card);
    }

    print "Eine Kombination gefunden!(".join('+',sort(@{$result[0]})).")\n";
  }
  else
  {
    # eine Karte aus dem Stapel ziehen
    # habe ich gemacht, damit das Programm auch mal ein Ende findet.
    push(@hand,shift(@peg));
    print "Keine Kombination gefunden!\n";
  }

  print "Die Hand ist: ".join(', ',sort @hand)."\n\n";
  print "Nächste Runde!\n\n";
}

if(@hand)
{ print "Verloren!\n"; }
else
{ print "Gewonnen! ($cnt Rounds)\n"; }

########################################################################

sub test_values
{
  # der gesuchte wert
  my $val=shift;
  # die Karten
  my @cards=@_;

  # wenn alle Karten größer als der Suchwert,
  # dann Abbruch.
  return () unless(grep{$_<=$val}@cards);

  # wenn nur noch eine Karte
  # und diese nicht gleich dem gesuchten Wert,
  # dann Abbruch!
  return () if(@cards==1 && $cards[0] != $val);

  # summe aller Karten
  my $sum=0;
  map{$sum+=$_}@cards;
  # wenn die summe kleiner als der Suchwert abbrechen!
  return () if($sum<$val);
  # wenn die Summe der Suchwert ist,
  # dann diese Liste zurück
  return \@cards if($sum==$val);

  my @ret=();

  # wenn eine Karte dem Suchwert entspricht
  if(grep{$val==$_}@cards)
  {
    push(@ret,[$val]);
    push(@ret,test_values($val,map{$_==$val?():$_}@cards));
  }
  else
  {
    # alle Karten durch gehen
    for my $card (@cards)
    {
      # mit einer Karte weniger
      # und kleinerem Suchwert in die nächste Rekursion
      my @r=test_values($val-$card,map{$_==$card?():$_}@cards);
      if(@r)
      {
        push(@$_,$card) for(@r);
        push(@ret,@r);
      }
    }
  }

  return @ret;
}

View full thread Zahlenkombinationen suchen