質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

1548閲覧

JavaでBASE+BALL=GAMESの覆面算を縦型探索で解くプログラムを完成させたい

mt0503xx

総合スコア7

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2022/06/19 05:22

Nodeクラスのexpandの部分がなにを書いていいのか全くわかりません。。。
他の部分はかけたので、expandの部分をなにを書けばいいのかコードを教えていただきたいです。
下にコードを添付するので、//の部分を教えていただきたいです。

import java.util.*;

class Node {
int [] s = new int [7];
int p;

Node(int p) { this.p = p; } boolean goalp () { if ((s[0] == 0) || (s[5] == 0)) return false; int base = 1000 * s[0] + 100 * s[1] + 10 * s[2] + s[3]; int ball = 1000 * s[0] + 100 * s[1] + 10 * s[4] + s[4]; int games = 10000 * s[5] + 1000 * s[1] + 100 * s[6] + 10 * s[3] + s[2]; if (games == base + ball) return true; return false; } ArrayList<Node> expand() { ArrayList<Node> al = new ArrayList<Node>(); // ここがわからない return al; } void show() { System.out.println("B = " + s[0] + ", A = " + s[1] + ", S = " + s[2] + ", E = " + s[3] + ", L = " + s[4] + ", G = " + s[5] + ", M = " + s[6]); }

}

class Fukumen {
public static void main(String [] args) {
Stack<Node> st = new Stack<Node>();
st.push(new Node(0));
while(! st.isEmpty()) {
Node a = st.pop();
ArrayList<Node> en = a.expand();
for(int i = 0;i < en.size();i++) {
Node b = en.get(i);
if (b.p == b.s.length) {
if (b.goalp()) {
b.show(); // return;
}
} else {
st.push(b);
}
}
}
}
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xebme

2022/06/19 07:23

プログラムを組まずに解いていませんが、B≠0,G≠0は制約としますか。
xebme

2022/06/19 11:43 編集

しつれいしました。B≠0,G≠0はコードに含まれていますね。 (やることは順列10P7を作ることですが、b.p == b.s.lengthを調べる必要があるのかと思います。) Stackを使い、expand()でsに含まれない数字を末尾に追加してArrayListの要素を増やすやりかたですね。
guest

回答1

0

ベストアンサー

ヒント

ArrayListに追加される(複数の)Nodeは次のコンストラクターを使って生成します。Nodeの中身をコピーして、 sの末尾にsで使われていない数字を1つだけ追加します。

Java

1 Node(Node that, int x) { 2 s = that.s.clone(); 3 p = that.p; 4 s[p++]=x; 5 }

expand()のなかで配列sで使われていない数字を調べなければなりません。

解説

覆面算に使用する数字は7種類。expand()を使って0から9までの10個の数字から7個をとり並べる。
expand()1回分のルールは

  • 配列sに含まれない数字を1つだけ末尾に追加したNodeを作成する
  • 配列sに含まれない数字はもれなく使 って複数のNodeを作成する
  • 作成したNodeはArrayListに追加する

配列sの初期値は空[]。expand()を実行すると0-9までの数字を末尾に追加した10個のNodeが作られる。

[0],[1],...,[9]

これらのNodeのれぞれにexpand()が適用される。例えばsが[0]のときexpand()するとNodeは9個に増える。

[01],[02],[03],[04],...,[09]

[1]-[9]もそれぞれ9個に増える。以下同様。Nodeの数が増えてゆきます。expand()を7回実行すると求める順列が完成します。

Javaコード(追記)

Java

1import java.util.ArrayList; 2import java.util.Set; 3import java.util.stream.Collectors; 4import java.util.stream.IntStream; 5class Node { 6 int[] s = new int[7]; 7 int p; 8 Node(int p) { 9 this.p = p; 10 } 11 protected Node(Node that, int x) { 12 this.s = that.s.clone(); 13 this.p = that.p; 14 this.s[p++] = x; 15 } 16 boolean goalp() { 17 // if ((s[0] == 0) || (s[5] == 0)) return false; 18 int base = 1000 * s[0] + 100 * s[1] + 10 * s[2] + s[3]; 19 int ball = 1000 * s[0] + 100 * s[1] + 10 * s[4] + s[4]; 20 int games = 10000 * s[5] + 1000 * s[1] + 100 * s[6] + 10 * s[3] + s[2]; 21 return (games == base + ball); 22 } 23 ArrayList<Node> expand() { 24 ArrayList<Node> al = new ArrayList<>(); 25 // ここがわからない 26 boolean[] b = new boolean[10]; // 数字: 0 - 9 の除外対象 27 for (int i=0; i < p; ++i) { 28 b[s[i]] = true; // 既に数字s[i]が存在する。 29 } 30 if (p == 0 || p == 5) b[0] = true; // B != 0, G != 0 31 for (int i=0; i < b.length; ++i) { // 残りの数字を全て使う 32 if (!b[i]) al.add(new Node(this,i)); 33 } 34 return al; 35 } 36 //B = 7, A = 4, S = 8, E = 3, L = 5, G = 1, M = 9 37 void show() { 38 System.out.println("B = " + s[0] + ", A = " + s[1] + ", S = " + s[2] + ", E = " + s[3] + ", L = " + s[4] + ", G = " 39 + s[5] + ", M = " + s[6]); 40 } 41// ArrayList<Node> expand() { 42// Set<Integer> set = IntStream.of(s).limit(p).mapToObj(Integer::valueOf).collect(Collectors.toSet()); 43// return IntStream.range((p == 0 || p == 5) ? 1 : 0, 10).filter(x -> !set.contains(x)).mapToObj(x -> new Node(this, x)).collect(Collectors.toCollection(ArrayList::new)); 44// } 45}

投稿2022/06/19 13:45

編集2022/06/25 00:11
xebme

総合スコア1081

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

xebme

2022/06/20 11:07

なぜStackを使うのかがわかりませんでした ArrayListは幅優先ですが、Stackを使って深さ優先にするため( タイトルは縦型探索と言っています) 幅優先ならStackの代わりにQueueを使うと思います また、深さ優先ならまず再帰を試すでしょうね
xebme

2022/06/21 11:02

expand()で、B≠0,G≠0制約をかければ、順列の生成を節約できます。
mt0503xx

2022/06/25 03:50

めちゃめちゃ参考になって助かりました!! 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問