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

任意の置換を互換の積で表すプログラムを作りたいと思い以下のように考えたのですが、動作がおかしいです。
 恒等置換τに対し互換の積を施したものを改めてτとし、それを繰り返してσに到達する方法です。

【例】
(1 2 3 4 5 6 7 8 9) =σ
(5 3 9 8 7 2 1 4 6)

(1 2 3 4 5 6 7 8 9)=τ
(1 2 3 4 5 6 7 8 9)

(1 2 3 4 5 6 7 8 9)(1 5) = (5 2 3 4 1 6 7 8 9)
(5 2 3 4 1 6 7 8 9)(2 3) = (5 3 2 4 1 6 7 8 9)
(5 3 2 4 1 6 7 8 9)(2 9) = (5 3 9 4 1 6 7 8 2)
(5 3 9 4 1 6 7 8 2)(4 8) = (5 3 9 8 1 6 7 4 2)
(5 3 9 8 1 6 7 4 2)(1 7) = (5 3 9 8 7 6 1 4 2)
(5 3 9 8 7 6 1 4 2)(6 2) = (5 3 9 8 7 2 1 4 6)

[1] i = 1, k = σ(i) = 5, j =τ(i) = 1, τ=τ(j k) = τ(1 5)
[2] i = 2, k = σ(i) = 3, j =τ(i) = 2, τ=τ(j k) = τ(2 3)
[3] i = 3, k = σ(i) = 9, j =τ(i) = 2, τ=τ(j k) = τ(2 9)
[4] i = 4, k = σ(i) = 8, j =τ(i) = 4, τ=τ(j k) = τ(4 8)
[5] i = 5, k = σ(i) = 7, j =τ(i) = 1, τ=τ(j k) = τ(1 7)
[6] i = 6, k = σ(i) = 2, j =τ(i) = 6, τ=τ(j k) = τ(6 2)
[7] i = 7, k = σ(i) = 1, j =τ(i) = 1, σ(i) =τ(i) none

10BASICのコード

DIM s(1 TO 9)
DIM t(1 TO 9)

LET s(1) = 5
LET s(2) = 3
LET s(3) = 9
LET s(4) = 8
LET s(5) = 7
LET s(6) = 2
LET s(7) = 1
LET s(8) = 4
LET s(9) = 6

LET t(1) = 1
LET t(2) = 2
LET t(3) = 3
LET t(4) = 4
LET t(5) = 5
LET t(6) = 6
LET t(7) = 7
LET t(8) = 8
LET t(9) = 9

FOR i = 1 TO 9
  LET k = s(i)
  LET j = t(i)
  IF k <> j THEN
   LET dmy = t(j)
   LET t(j) = k
   LET t(k) = dmy
  END IF
  PRINT " i = ";i;
  PRINT " j = ";j;
  PRINT " k = ";k;
  PRINT "  (";
  FOR n = 1 TO 9
   PRINT t(n);
  NEXT n
  PRINT ")"
NEXT i

END

結果
i = 1 j = 1 k = 5 ( 5 2 3 4 1 6 7 8 9 )
i = 2 j = 2 k = 3 ( 5 3 2 4 1 6 7 8 9 )
i = 3 j = 2 k = 9 ( 5 9 2 4 1 6 7 8 3 ) ここからおかしい
i = 4 j = 4 k = 8 ( 5 9 2 8 1 6 7 4 3 )
i = 5 j = 1 k = 7 ( 7 9 2 8 1 6 5 4 3 )
i = 6 j = 6 k = 2 ( 7 6 2 8 1 2 5 4 3 )
i = 7 j = 5 k = 1 ( 1 6 2 8 1 2 5 4 3 )
i = 8 j = 4 k = 4 ( 1 6 2 8 1 2 5 4 3 )
i = 9 j = 3 k = 6 ( 1 6 6 8 1 2 5 4 3 )

i=6まで互換の組み合わせは合っているので、あとは t() の入れ替えがおかしいと思うのですが、原因がわかりません。

A 回答 (4件)

配列の内容は書き換えられているので、


目的の値が配列内のどこにあるのかを探してから置換しましょう。

例)
if 配列(i) <> 目的の値 then
_ let h = 1
_ do while 配列(h) <> 目的の値
_ _ let h = h+1
_ loop
_ let 配列(h) = 配列(i)
_ let 配列(i) = 目的の値
end if
    • good
    • 0
この回答へのお礼

> 目的の値が配列内のどこにあるのかを探してから置換しましょう。
そうするしかないですね。明日やってみます。ありがとうございました。

お礼日時:2022/11/14 00:23

ちょっと考えた.



s をぶっ壊していいなら話は簡単で
FOR i=1 TO 9
DO UNTIL i=s(i)
s(i) と s(s(i)) を交換
LOOP
NEXT
でいけると思う.

あるいは現状 (書き換えたやつ) でも, ループ不変条件を意識して IF の条件をいじればいけるんじゃないかなぁ. k<>j じゃなくって k>j とか.
    • good
    • 0

「ムダな表示」というのはどの「表示」のこと? 「i=6の動作がおかしい」というのは, 具体的には「どうであるべき」ところが「どうなっている」ことを「おかしい」と評価している?



あとここから「偶奇の判断」をどのようにするつもり?
    • good
    • 0
この回答へのお礼

こんな感じです

FOR i = 1 TO 9
  LET k = s(i)
  LET j = t(i)
  IF k <> j THEN
   LET dmy = t(i)
   LET t(i) = k
   LET t(k) = dmy
  END IF
  PRINT " i = ";i;
  PRINT " j = ";j;
  PRINT " k = ";k;
  PRINT "  (";
  FOR n = 1 TO 9
   PRINT t(n);
  NEXT n
  PRINT ")"
NEXT i

 i = 1 j = 1 k = 5 (5 2 3 4 1 6 7 8 9)
 i = 2 j = 2 k = 3 (5 3 2 4 1 6 7 8 9)
 i = 3 j = 2 k = 9 (5 3 9 4 1 6 7 8 2)
 i = 4 j = 4 k = 8 (5 3 9 8 1 6 7 4 2)
 i = 5 j = 1 k = 7 (5 3 9 8 7 6 1 4 2)
 i = 6 j = 6 k = 2 (5 6 9 8 7 2 1 4 2) ※ここからおかしい
 i = 7 j = 1 k = 1 (5 6 9 8 7 2 1 4 2)
 i = 8 j = 4 k = 4 (5 6 9 8 7 2 1 4 2)
 i = 9 j = 2 k = 6 (5 6 9 8 7 2 1 4 6)

> あとここから「偶奇の判断」をどのようにするつもり?
 本来ならi = 6でループ終了となるはずなのでループ回数で判断してよさそうな気がしますが・・・・・

お礼日時:2022/11/13 21:58

たとえばその「ここからおかしい」のその瞬間は


i=3, j=2, k=9
だよね. で, プログラム見ると s(i) と t(j) を入れ替えてる.

本当にそこを入れ替えていいの?
    • good
    • 0
この回答へのお礼

回答まことにありがとうございました。

  IF k <> j THEN
   LET dmy = t(i)
   LET t(i) = k
   LET t(k) = dmy
  END IF

とりあえずこれで最終的には正しい値になりましたが、ムダな表示が発生して偶奇の判断には使えません。i=6の動作がおかしいのです。

お礼日時:2022/11/13 21:29

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