アプリ版:「スタンプのみでお礼する」機能のリリースについて

クリスマスパーティーのプレゼント交換のためにプログラムを書いているのですがなかなか上手くいきません。下に実装したい機能(僕の考えた解決策)と僕の書いたコードを載せておくのでアドバイスをお願いします。よろしくお願いします。

実装したい機能(僕の考えた解決策)
1.自分の持ってきたプレゼントが自分に当たらないようにする
(プレゼントの番号と配列に格納する順番を一致させれば解決できると 思うのですが…)
2.全員の手にプレゼントが渡るようにする
(全ての数字(例えば参加者が5人なら0~4)が割り振られたことを確認し満たしていなければやり直しにすれば解決できると思ったのですが…)

---コードここから---
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){
char line[100]; /* キーボード入力用汎用変数 */
int participant; /* 参加者数 */
int flag = 0;
int i, j;
srand(time(NULL));

/* 参加者数を入力する */
printf("参加者数: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &participant);

int number[participant]; /* プレゼントの番号 */
char name[participant]; /* 参加者の名前 */
int check[participant]; /* チェック用配列 */

/* */
for(i = 0; i < participant; i++){
printf("参加者 %d 人目の名前: ", i + 1);
fgets(line, sizeof(line), stdin);
sscanf(line, "%s", &name[i]);
}

/* */
do{
for(i = 0; i < participant; i++){
number[i] = rand() % participant;
check[i] = number[i];
}
for(j = 0; j < participant; j++){
for(i = 0; i < participant; i++){
if(check[i] == j){
flag += 1;
}
}
}
}while(flag != participant);

/* */
for(i = 0; i < participant; i++){
printf(" %s ―\―\>プレゼント %d\n", name[i], number[i] + 1);
}
return 0;
}
---コードここまで---

A 回答 (2件)

7人居たら、number配列を


number[0]=0
number[1]=1
number[2]=2
number[3]=3
number[4]=4
number[5]=5
number[6]=6
と、初期化します。

次に
number[0]と、number[1]~number[6]のどれかと入れ替え(乱数で選ぶ)
number[1]と、number[2]~number[6]のどれかと入れ替え(乱数で選ぶ)
number[2]と、number[3]~number[6]のどれかと入れ替え(乱数で選ぶ)
number[3]と、number[4]~number[6]のどれかと入れ替え(乱数で選ぶ)
number[4]と、number[5]~number[6]のどれかと入れ替え(乱数で選ぶ)
number[5]と、number[6]と入れ替え
を実行してみましょう。

あと
char name[participant]; /* 参加者の名前 */
では、7人たったら「charが7バイトあるだけ」で、7人分の名前を保持する事は出来ません。

上記の不具合を修正すると、以下のようになります。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){
char line[100]; /* キーボード入力用汎用変数 */
int participant; /* 参加者数 */
int i, j, k;
srand(time(NULL));

/* 参加者数を入力する */
printf("参加者数: ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &participant);

int *number = new int[participant]; /* プレゼントの番号 */
char **name = new char *[participant]; /* 参加者の名前 */

for(i = 0; i < participant; i++){
name[i] = new char[100]; /* 人数分、100バイトづつの名前用バッファ確保 */
}

/* */
for(i = 0; i < participant; i++){
printf("参加者 %d 人目の名前: ", i + 1);
fgets(line, sizeof(line), stdin);
sscanf(line, "%s", name[i]); /* &name[i]ではない事に注意 */
}

/* */
for(i = 0; i < participant; i++){
number[i] = i; /* 通し番号で初期化。重複しない事が保証される */
}

/* */
for(i = 0; i < participant - 1; i++){
j=(rand() % (participant - 1 - i)) + 1 + i;
/* 入れ替えを行う */
k = number[i];
number[i] = number[j];
number[j] = k;
}

/* */
for(i = 0; i < participant; i++){
printf(" %s ――>プレゼント %d\n", name[i], number[i] + 1);
}

/* */
for(i = 0; i < participant; i++){
delete name[i]; /* 確保したら解放する */
}
delete name; /* 確保したら解放する */
delete number; /* 確保したら解放する */
return 0;
}
    • good
    • 0

あれ・・・どこかで聞いた事が有る話だね・・・


そのお話だと・・・

・全員のプレゼントに番号を振る(皆が固定位置なら振らなくても良い)
・「1」「+」「+1」などとかかれた要するに+1の紙を自分以外の人数分用意する
・「0」とかかれた紙を+1の紙より1少ない数用意する
・箱に入れてかき回す
・自分以外の全員に1枚引かせる
・総計分だけ箱の番号をずらす

とやると、全員が攪拌の権利を有し、かつ自分のプレゼントを自分で受け取る事は無くなるという方法。
(引く人数より0が1枚少ないので必ず1が1枚出て必ず1ずれ、自分は引かないので全員が1を引いても完全1周しない)
何番の質問だったかな・・・見つからないけどそんなやりかた。
原理が簡単だからプログラム化は 難しくないと思う。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!