他者の回答の中に
『現実世界のシミュレーション』
という言葉があるので,現実世界の話で考えてみました.
10人の中で一番の者を決める にはどうするだろうか…?
↓
【トーナメント戦で決めたら良いのではないだろうか】と.
…というわけで,10人で争うためのトーナメント表をてきとーに定めました.
絵には 0~18 の数値が書かれていますが,これは,
1の場所の人と2の場所の人とが戦い,勝った方が10の場所に進む
みたいな,トーナメント表での場所を示すindex値で,この値はそのまま下記コードでの配列 P[]
のindexに対応しています.
で,「戦いは年齢が上の側が勝つ」ということにして,ひたすら試合を消化していく→最後に P[18]
の場所に到達した者こそが年長者であるということになります.
C
1 //aとb年齢を比較し,年齢が大きい側を返す(同年齢の場合はa側を返す)
2 const Students * Older ( const Students * a , const Students * b )
3 { return ( ( a -> age >= b -> age ) ? a : b ) ; }
4
5 int main ( void )
6 {
7 //※入力部は省略
8 const Students data [ 10 ] = {
9 { "A" , 5 } , { "B" , 38 } , { "C" , 8 } , { "D" , 6 } , { "E" , 1 } ,
10 { "F" , 16 } , { "G" , 4 } , { "H" , 7 } , { "I" , 0 } , { "J" , 3 }
11 } ;
12
13 //初期状態:0~9の場所に10人を配置する
14 const Students * P [ 19 ] = { 0 } ;
15 for ( int i = 0 ; i < 10 ; ++ i ) { P [ i ] = data + i ; }
16
17 //1回戦
18 P [ 10 ] = Older ( P [ 1 ] , P [ 2 ] ) ; //1の場所の人と2の場所の人とが戦い,勝った方が10の場所に進む
19 P [ 11 ] = Older ( P [ 3 ] , P [ 4 ] ) ;
20 P [ 12 ] = Older ( P [ 6 ] , P [ 7 ] ) ;
21 P [ 13 ] = Older ( P [ 8 ] , P [ 9 ] ) ;
22 //2回戦
23 P [ 14 ] = Older ( P [ 10 ] , P [ 11 ] ) ;
24 P [ 15 ] = Older ( P [ 12 ] , P [ 13 ] ) ;
25 //3回戦
26 P [ 16 ] = Older ( P [ 0 ] , P [ 14 ] ) ;
27 P [ 17 ] = Older ( P [ 5 ] , P [ 15 ] ) ;
28 //決勝戦(4回戦)
29 P [ 18 ] = Older ( P [ 16 ] , P [ 17 ] ) ;
30
31 //結果表示
32 printf ( "%s : %d\n" , P [ 18 ] -> name , P [ 18 ] -> age ) ;
33 return 0 ;
34 }
[追記]
あるいは,こんなのでも良いかもしれない.
各々が,自身よりも若い者のいずれか1人を指し示す(対象がいない場合は何もしない)
最も指し示された人は退場する(全員の指し示された数が0回だろうが,とにかく誰かを退場させる)
というのを,最後の1人になるまで繰り返す.
C
1 int main ( void )
2 {
3 //※入力部は省略
4 const Students data [ 10 ] = {
5 { "A" , 5 } , { "B" , 38 } , { "C" , 8 } , { "D" , 6 } , { "E" , 1 } ,
6 { "F" , 16 } , { "G" , 4 } , { "H" , 7 } , { "I" , 0 } , { "J" , 3 }
7 } ;
8
9 //初期状態:最初は10人全員
10 int nSurvivors = 10 ;
11 const Students * Survivors [ 10 ] = { 0 } ;
12 for ( int i = 0 ; i < 10 ; ++ i ) { Survivors [ i ] = data + i ; }
13
14 //残り1人になるまで追放審議会を繰り返す.
15 while ( nSurvivors > 1 )
16 {
17 //各々が追放したい1人に投票する(ただし,自身より若い奴にしか投票しない)
18 int VotingSpace [ 10 ] = { 0 } ;
19 for ( int i = 0 ; i < nSurvivors ; ++ i )
20 {
21 //てきとーに自分りも若い奴を1人見つけて,そいつに投票する
22 for ( int j = 0 ; j < nSurvivors ; ++ j )
23 {
24 if ( Survivors [ i ] -> age > Survivors [ j ] -> age )
25 {
26 VotingSpace [ j ] ++ ;
27 break ;
28 }
29 }
30 }
31 //最も票が多かった人は追放です
32 int iMaxVote = 0 ;
33 int MaxVote = VotingSpace [ 0 ] ;
34 for ( int i = 1 ; i < nSurvivors ; ++ i )
35 {
36 if ( MaxVote < VotingSpace [ i ] )
37 {
38 iMaxVote = i ;
39 MaxVote = VotingSpace [ i ] ;
40 }
41 }
42 Survivors [ iMaxVote ] = Survivors [ nSurvivors - 1 ] ;
43 -- nSurvivors ;
44 }
45
46 //結果表示
47 printf ( "%s : %d\n" , Survivors [ 0 ] -> name , Survivors [ 0 ] -> age ) ;
48 return 0 ;
49 }
[さらに追記]
老人が若い奴を蹴落としていくやり方をするなら,
「平均年齢より低い人はお帰り下さい」みたいなルールで一度にごっそりと脱落者を出していく方が話が早いな.
↑のwhile以降の部分を以下のように変えればいいかな.
C
1 while ( 1 )
2 {
3 int Sum = 0 ;
4 for ( int i = 0 ; i < nSurvivors ; ++ i ) { Sum += Survivors [ i ] -> age ; }
5
6 int n = nSurvivors ;
7 for ( int i = 0 ; i < n ; /*NOP*/ )
8 {
9 if ( nSurvivors * Survivors [ i ] -> age < Sum )
10 {
11 Survivors [ i ] = Survivors [ n - 1 ] ;
12 -- n ;
13 }
14 else
15 { ++ i ; }
16 }
17 if ( n == nSurvivors ) break ;
18 nSurvivors = n ;
19 }
20
21 //結果表示
22 for ( int i = 0 ; i < nSurvivors ; ++ i )
23 { printf ( "%s : %d\n" , Survivors [ i ] -> name , Survivors [ i ] -> age ) ; }