# アレックスは時々正しいです

50

この挑戦は、私たちのmod アレックスA.の精神を持ち上げることです、彼は通常間違っています。

たとえば、次の方程式リストでは、たった1つの結論命題`A = C`がたまたま真です。

``````A = B
B = C
therefore
A = C
``````

``````Alex is right
``````

すべての結論が前提から論理的に続く場合、およびそうでなければ出力

``````Alex is wrong
``````

バイト単位の最短コードが優先されます。

これらのケースに注意してください：

• 変数は常に自分自身に等しくなります。例えば

``````B = A
therefore
A = A
X = X
``````

結果はになり`Alex is right`ます。

• 未知の関係を持つ変数は等しいと仮定することはできません。例えば

``````P = Q
therefore
E = R
``````

結果はになり`Alex is wrong`ます。

• `therefore`その後に方程式がない場合、結論は空虚に真実です。例えば

``````D = C
therefore``````

そして

``therefore``

両方ともになり`Alex is right`ます。

• その前に方程式が存在しない場合、`therefore`自己平等のみが推測されます。例えば

``````therefore
R = R
``````

結果は`Alex is right`ですが、

``````therefore
R = W
``````

結果はになり`Alex is wrong`ます。

## その他の例

アレックスは間違ったケースです：（空行で区切られています）

``````A = B
C = D
therefore
A = C

A = L
E = X
A = I
S = W
R = O
N = G
therefore
G = N
L = I
R = O
S = A
X = X
X = E

D = K
D = Q
L = P
O = L
M = O
therefore
K = L

A = B
therefore
B = C

Z = A
S = S
therefore
A = Z
A = A
S = A
A = S
Z = A
Z = A

K = L
K = X
therefore
X = P
L = X
L = P

therefore
A = B
B = C
A = C

therefore
A = A
B = B
C = C
D = D
E = E
F = F
G = G
H = H
I = I
J = J
K = K
T = I
L = L
M = M
N = N
O = O
P = P
Q = Q
R = R
S = S
T = T
U = U
V = V
W = W
X = X
Y = Y
Z = Z

A = B
B = C
C = D
D = E
E = F
F = G
G = H
H = I
I = J
J = K
K = L
L = M
M = N
N = O
O = P
P = O
Q = R
R = S
S = T
T = U
U = V
V = W
W = X
X = Y
Y = Z
therefore
A = Z

therefore
C = D
T = Y
A = Z

P = Q
therefore
E = R

therefore
R = W``````

アレックスは正しいケースです：

``````H = J
therefore
J = H

K = L
K = X
therefore
L = X

C = B
B = A
therefore
A = B

K = L
K = X
K = P
therefore
L = X
L = P
X = P

A = Y
Y = Q
Q = O
therefore
O = Y
O = A

C = C
therefore
C = C

A = B
B = A
therefore
A = B
B = A

A = B
B = C
C = D
therefore
A = A
A = B
A = C
A = D
B = A
B = B
B = C
B = D
C = A
C = B
C = C
C = D
D = A
D = B
D = C
D = D

therefore
A = A
B = B
C = C
D = D
E = E
F = F
G = G
H = H
I = I
J = J
K = K
L = L
M = M
N = N
O = O
P = P
Q = Q
R = R
S = S
T = T
U = U
V = V
W = W
X = X
Y = Y
Z = Z

D = I
F = H
J = M
therefore
M = J
D = I
H = F

A = B
B = C
C = D
D = E
E = F
F = G
G = H
H = I
I = J
J = K
K = L
L = M
M = N
N = O
O = P
P = Q
Q = R
R = S
S = T
T = U
U = V
V = W
W = X
X = Y
Y = Z
therefore
Z = A
F = R
G = I
W = L

A = B
B = C
therefore
A = C

B = A
therefore
A = A
X = X

P = P
C = G
M = C
therefore

D = C
therefore

therefore

therefore
R = R``````

42
PHP、13バイト`Alex is wrong`すべてのテストケースを検証します。
デニス

19
ねえ、時には決してより良いです。¯\ _（ツ）_ /¯
アレックスA.

7
`therefore\nTABS < SPACES`->`Alex is right`
ドアノブ

7
プロローグで解決策を見るのが大好き。
azz

18

# CJam、49

``````"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?
``````

histocratのRubyソリューションに触発されました。オンラインそれを試してみてください
jimmy23013に感謝を抹消3つのバイトを:)

``````"Alex is "    first push the part we know
qN%           read the input and split into lines
S             push a space (initial no-op replacement string, see below)
{…}h          do-while
f{…}        for each line and the replacement string
)         take out the last character
er        replace the remaining character(s) with that character
(           afterwards, take out the first line
_el         duplicate and convert to lowercase
-           remove all the resulting characters from the line
this removes all lowercase letters and non-letters
"X = Y" becomes "XY" (new replacement string)
and "therefore" becomes "" (ending the loop)
this is the loop condition and is left on the stack every time
;             after the loop, pop the empty string (from "therefore")
{…},          filter the remaining (conclusion) lines using the condition block
)           take out the last character
#           find its index in the remaining string
this is 0 (false) iff the first character is the same as the last
afterwards, we have an array of lines with non-equal variables
"wrong"       push "wrong"
"right"       push "right"
?             choose "wrong" if the array was not empty, else choose "right"
``````

``````"Alex is "26,:A;{:i{{_A=_@-}g}%\$~}:F;0q"= "-'t/Nf%~\{A\Ft:A;}/1>{F=}%-"right""wrong"?
``````

これは、ユニオン検索アルゴリズムを使用します。オンラインで試す

1
`"Alex is "qN%S{f{)er}(_el-}h;{)#},"wrong""right"?`
jimmy23013

1

1

`Alex is * wrong * right * ?`
チャーリー

32

# ルビー、80 76 + 2 = 78

コマンドラインフラグを使用して`p0`、実行

``````gsub\$1,\$2%p=\$`[/e/]while~/(.) = (?!\1)(.)/
\$_="Alex is #{p ?:wrong: :right}"
``````

これは、純粋な文字列操作を使用します。`p0`完全な入力を単一の文字列として変数に読み込みます`\$_`。次に、その文字列を正規表現と繰り返し照合します。正規表現は`/(.) = (?!\1)(.)/`、XとYが同じ文字ではない「X = Y」という形式のすべての文字列を見つけ、Xを\$ 1に、Yを\$ 2に割り当てます。そのような一致が見つかると`gsub\$1,\$2`、文字列内のXのすべてのインスタンスをYに置き換えます。また、この一致が「therefore」の前または後に発生したかどうかをチェックします

``````\$`[/e/]
``````

それが後に発生した場合、それは不当な主張であり、アレックスは間違っています。を使用して、そのような発生が発生したかどうかを追跡し`p=`ます。`p`追跡変数として使用することで、ループが一度もヒットしない場合でも、`p`割り当てられていない場合はnilを返すため、破損を防ぎます。

この投稿の時点で、CJamソリューションはより長くなっています。誇らしげな、間違いなくつかの間の瞬間。

15

アレックスA.

`String#format`gsub呼び出しと代入の両方を1つの式にまとめるという悪用は、かなりきちんとした考えです。+ 1！
ヴェンテロ

12

# CJam、83 75 68 67 64バイト

1バイトを節約してくれたDennisに感謝します。

``````"Alex is "q_elN--N/:\$La/~{)-},\{__m*{:&},::^|}5*-"wrong""right"?
``````

テストスイート。テストケースはパーマリンクには長すぎるため、質問からコピーしてください。これはかなり遅いことに注意してください-オンライン通訳では1〜2分かかります。あなたは、変更することにより、はるかに速くそれを作ることが可能`5*``2*`その場合には、それがほぼ瞬時に終了し、すべてが、1つのテストケースを解決します。

## 説明

（少し古い。）

``````"Alex is " e# Push the string.
_elN-      e# Make a copy, convert to lower case, remove linefeeds. This gives us a string
e# with all the characters we don't want from the input.
-          e# Remove them from the input. This leaves two upper-case letters on each line
e# and an empty line between premises and conclusions.
N/         e# Split into lines.
La/        e# Split around the empty line.
~          e# Dump both halves on the stack.
{)-},      e# Remove any "A = A"-type equalities from the conclusions.
\          e# Swap with the premises.
{          e# Extend the premises 5 times...
_Wf%     e#   Duplicate the premises and reverse each one, because = is symmetric.
|        e#   Set union with the original premises.
__m*     e#   Make two copies and get an array of every possible pair of premises.
{:&},    e#   Select those which have at least one character in common.
::^      e#   For each such pair, take the mutual set difference, i.e. those characters
e#   that are in only one of the strings.
|        e#   Set union with the original premises.
}5*
-          e# Remove all the equalities we've obtained from the conclusions. If all
e# conclusions were valid, the result will now be a empty array, which is falsy.
!          e# Logical not.
"wrong""right"?
e# Select "wrong" or "right", respectively.
``````

user2357112

@ user2357112最初のステップで入力のすべての反転が追加されるため、両方向で生成されるべきだと思います（または、さらにゴルフを行ったバージョンでは、すべての前提と結論の平等をソートします）。
マーティンエンダー

しかし、対称的な違いをとると、両方向にエッジができますか？（または、さらにゴルフされたバージョンでは、対称的な違いが必要な方向のエッジを生成しますか？）
user2357112

@ user2357112私はデカルト積全体を処理しているため、両方の順序で等値の各ペアを取得し、描画された結論の両方の順序になります（明示的に逆にする、または初期入力を並べ替える必要があるのは、元の前提は必ずしもこのプロセスで生成されるわけではないため、デカルト積のセットの差を取得しても元に戻されることはありません）。
マーティンエンダー

6

## R、183 192バイト

user2357112によって指摘された制限に対処するために、回答を修正しました。アレックスが実際に正しい場合にアレックスを呼び出す可能性はまだ非常に小さいです（チャレンジのコンテキストを理解している場合、それ自体はあまり頻繁に発生しないようです:-)。彼が気にしないことを願っています。

``````i=grep("t",z<-scan(,"",,,"\n"))
``````

これを少しデゴルフする必要があります。

``````lines = scan(, what = "", sep = "\n")
therefore_idx = grep("therefore", lines)
setup = paste(LETTERS, "=", 1:26)
premises = sample(rep(head(lines, therefore_idx - 1), 1000))
propositions = paste(c(TRUE, sub("=", "==", tail(lines, -therefore_idx))), collapse = "&")
things_to_evaluate = c(setup, premises, propositions)
boolean_result = eval(parse(text = things_to_evaluate))
cat("Alex is", if (boolean_result) "right" else "wrong")
``````

たとえば、入力が

``````A = B
B = C
therefore
A = C
B = C
``````

``````A = 1
B = 2
...
Z = 26
``````

そうして `premises`

``````A = B
B = C
``````

ランダムな順序でそれぞれ1,000回実行されます。これは、すべての等式が伝播されることを確認する（「ほぼ確実に」）ためです。最後に、それは評価し`propositions`ます：

``````TRUE & A == B & B == C
``````

3

user2357112

flodel

flodel

5

``````import Data.Equivalence.Persistent
c l=equate(l!!0)\$last l
r=foldr(c)\$emptyEquivalence('A','Z')
l#r=equiv r(l!!0)\$last l
f x|(h,_:t)<-span((<'t').head)\$lines x="Alex is "++if all(#r h)t then"right"else"wrong"
``````

`Data.Equivalence.Persistent`等価クラスを操作するための機能を提供するモジュールに作業をオフロードしています。あとは、入力を解析して、適切なゴルフには名前が長すぎる場合がある関数を呼び出すだけです。

``````*Main> f "A = B\nB = C\ntherefore\nA = C"
"Alex is right"

*Main> f "A = B\nB = D\ntherefore\nA = C"
"Alex is wrong"
``````

3

# Mathematica、182

``````f[s_]:="Alex is "<>If[True===And@@Simplify[#2,#1]&@@(StringSplit[s,"\n"]/.{a___,"therefore",b___}:>StringSplit/@{{a},{b}}/.{x_,_,y_}:>Symbol[x<>"\$"]==Symbol[y<>"\$"]),"right","wrong"]
``````

チャレンジごとに、文字列入力で動作します。

``````In[]:= f["A = B
B = C
therefore
A = C"]
Out[]= Alex is right

In[]:= f["D = K
D = Q
L = P
O = L
M = O
therefore
K = L"]
Out[]= Alex is wrong
``````

`f`純粋な関数として宣言し、で置換`Simplify[#2,#1]``#2~Simplify~#`、で置換`StringSplit[s,"\n"]`すると、8バイトを失う可能性があります`#~StringSplit~"<actual newline>"`
LegionMammal978

また、`a___`そして`b___`おそらくに変更することができ`a__`、および`b__`、と`s=Symbol;`
LegionMammal978

`a__`そして、`b__`施設、提案または両方がある場合は動作しません空けれども

3

# 網膜、90バイト

``````s+`^(.) = (.)(.*)\1
\$1 = \$2\$3\$2
)`^. .+\n
<empty>
^.+|(.) = \1
<empty>
^\n*\$
right
^[^r]+
wrong
^
Alex is
``````

2番目の置換では、最初の前提が入力から削除されます。これで完了です。その後、`)`モディファイアは最初の置換にループバックし、ループ全体のパスに変更がなくなるまで繰り返します。これは、すべての施設が置換および削除され、入力がで始まる場合に発生し`therefore`ます。

3番目の置換は、入力の最初の行（`therefore`）またはフォームの`A = A`任意の行と一致し、それを削除します。すべての命題が施設によってサポートされている場合、それらはすべてこの形式に一致するため、残りは改行のみで構成される必要があります。4番目の置換はこれをに変更し`right`ます。そうでない場合、5番目の置換は残りのすべて（削除されて`r`から含まれない`therefore`）をに変更し`wrong`ます。最後に、最後の交換が`Alex is `最初に追加されます。

3

# Python 2、264バイト

すでにありますmbomb007によって顕著Pythonの3答えが。この答えは、その答えからひどく盗みます（特に「Alex is wrriognhgt」トリック）。

そして、この答えはそれよりもかなり長いです...

とにかく、この答えのアイデアは、キーと値のペアの辞書を維持することです。キーは26個の大文字で、各キーの対応する値はキーに相当する文字のセットです。（26文字すべてが同等である場合、各キーには対応する値の26文字のセットがあります。）

``````def a(s):
d={C:set(C)for C in map(chr,range(65,91))};p,c=s.split('t');c,p=[x.split('\n')for x in[c[9:],p]]
for u in p[:-1]:
g,h=u[::4];y=d[g]|d[h]
for v in y:
for w in y:d[v]|=d[w];d[w]|=d[v]
print'Alex is','wrriognhgt'[all(u[0]in d[u[4]]for u in c if u)::2]``````

（バイトを節約するために、この回答ではスペースとタブを組み合わせています。これはPython 2で有効です。）

このコードは、辞書が最大入力サイズ（上記の26 x 26）に制限されており、入力の行数に依存しないため、非常に効率的です。

``d={C:set(C)for C in map(``

``d={C:C for C in map(``

もちろん、あなたはまた`|`、文字列連結`+`で集合和演算の3つのインスタンスを置き換える必要があります（注：これをしないでください）が、それはコード長を変えません。結果は、セットの場合のように重複を排除しないことを除いて、すべて同じように機能するはずです（文字列の最後に追加し続けるだけです）。サウンドは問題ありません。確かに少し効率は落ちますが、264ではなく260バイトです。

まあ、260バイトのバージョンは非常に効率が悪いので`MemoryError`テストしたときに

``````A = B
A = B
therefore
B = A``````

これは私にとって驚くべきことでした。 260バイトの「文字列連結」バージョンを調べてみましょう！

もちろん、キーと値のペア`A:A`から始めます`B:B`（さらに、関係のない他の24個）。`d[A]`キー`A`に対応する辞書値を意味するように書くので、最初に持ってい`d[A] = A`たでしょう。さて、前提を考えると`A = B`、値`d[A]=A`を連結し`d[B]=B`て取得することから始まります`y = AB`。次に、この文字列を2回ループします：`for v in AB: for w in AB:`...

したがって、ループを初めて通過するときは、とが`v=A`あり`w=A`ます。次の辞書シーケンスを適用し`d[v] += d[w]``d[w] += d[v]`結果します。

``````{A:A, B:B}      (start)
{A:AA, B:B}     (d[A] += d[A])
{A:AAAA, B:B}     (d[A] += d[A])``````

``````{A:AAAA, B:B}     (start)
{A:AAAAB, B:B}    (d[A] += d[B])
{A:AAAAB, B:BAAAAB}   (d[B] += d[A])``````

``````{A:AAAAB, B:BAAAAB}   (start)
{A:AAAAB, B:BAAAABAAAAB}     (d[B] += d[A])
{A:AAAABBAAAABAAAAB, B:BAAAABAAAAB}     (d[A] += d[B])``````

そして`v=B, w=B`

``````{A:AAAABBAAAABAAAAB, B:BAAAABAAAAB}     (start)
{A:AAAABBAAAABAAAAB, B:BAAAABAAAABBAAAABAAAAB}     (d[B] += d[B])
{A:AAAABBAAAABAAAAB, B:BAAAABAAAABBAAAABAAAABBAAAABAAAABBAAAABAAAAB}     (d[B] += d[B])``````

うん。たぶんそれは非常に効率的な実装ではないでしょう。

mbomb007

1
@ mbomb007ええ、それを聞いてすみません。（クールなアプローチがあったと思います！）「素晴らしい」という言葉に反対したので、「驚くべき」に置き換えました。:)
mathmandan

2

# ES6、128バイト

``````r=s=>(m=/^[^e]*(.) = (?!\1)(.)/.exec(s))?r(s.replace(RegExp(m[1],'g'),m[2])):'Alex is '+(/(.) = (?!\1)/.test(s)?'wrong':'right')
``````

「したがって」の前に自己不等式を探し、毎回文字列全体で変数を再帰的に置換します（これにより、whileループでバイトが節約されます）。

1

# C、240バイト

``````#define V[v-65]
v[26];char*r[]={"wrong","right"};i=65;j;g(a){return a V^a?g(a V):a;}main(){char b[16];for(;i<91;++i)i V=i;while(gets(b)&&*b<99)b[0]V=b[4]V=b[0]V<b[4]V?b[0]V:b[4]V;while(gets(b))j|=g(*b)^g(b[4]);printf("Alex is %s\n",r[!j]);}``````

これは、値をセットツリーに結合することで機能するため、同等の値は同じセットルートになります。暗黙の型を明示的にした、ゴルフを解かれた。

``````// Anything before `V` becomes an index into `v`, offset by -'A'.
#define V [v-65]
int v[26];
char* r[] = {"wrong", "right"};
int i=65;
int j;
// Finds a set identifier for a by recursing until some index points to itself.
int g(int a) {
return a V ^ a
? g(a V)
: a;
}
int main() {
char b[16];
// Initialize all entries to point to themselves.
for(; i < 91; ++i)
i V = i;
// For each premise "A = B", set the entries for A and B to point to the
// smaller of their current values. This exits after reading "therefore"
// as 't' > 99.
while (gets(b) && *b < 99)
b[0]V = b[4]V = b[0]V < b[4]V
? b[0]V
: b[4]V;
// For each conclusion "A = B", OR j with non-zero if the set identifiers
// for A and B are different.
while (gets(b))
j |= g(*b) ^ g(b[4]);
printf("Alex is %s\n", r[!j]);
}``````

# 180バイト

この短いバージョンはOPのすべてのケースで機能しますが、他のいくつかの入力では、Alexが間違っていると誤って主張しています。同様のアプローチを使用しますが、前提ごとに、2番目のエントリを最初のエントリの現在の値に設定するだけです。比較するとき、ツリーを検索するのではなく、正確な値のみを調べます。

``v[26];*V=v-65;char*r[]={"wrong","right"};i;j;main(){char b[16];for(;i<26;++i)v[i]=i;while(gets(b)&&*b<99)V[b[4]]=V[*b];while(gets(b))j|=V[*b]^V[b[4]];printf("Alex is %s\n",r[!j]);}``

これが失敗する入力の例：

A = B
C = B
したがって
A = C

1

# 05AB1E、32 バイト

``````…±º€ˆ „–Ñƒ©#|€á[ćD.l#`:}\€ËPè«.ª
``````

``````…±º€ˆ      # Push dictionary string "alex is "
„–Ñƒ©      # Push dictionary string "wrong right"
#     # Split by spaces: ["wrong","right"]
|          # Push all input-lines as list
€à        # Only leave the letters of each line
[       # Start an infinite loop:
ć      #  Extract the head of the list; pop and push remainder-list and head separately
.l   #  If it's a lowercase string:
#  #   Stop the infinite loop
`      #  Push both letters in the string to the stack
:     #  Replace all these letters in the remainder-list
}\        # After the infinite loop: discard the duplicated "therefore"
€       # For each letter-pair in the remainder list of condition-lines:
Ë      #  Check if both letters are equal (1 if truhy; 0 if falsey)
P       # Check if everything was truthy by taking the product
è      # Use this to index into the earlier ["wrong","right"]-list
«     # Append it to the "alex is " string
.ª   # Sentence capitalize it
# (after which the result is output implicitly)``````

（セクション鉱山のこの05AB1Eチップを参照してください。辞書を使用する方法？理由を理解すること`…±º€ˆ`である`"alex is "``„–Ñƒ©`されます`"wrong right"`

0

# bash + awk + SWI-Prolog、167バイト

``head -n1 <(awk '/therefore/{s=1;next};{if(s)print"?=("\$1","\$3")";else print};END{print"write(\"Alex is right\");write(\"Alex is wrong\"). halt."}' -|paste -sd ,|swipl)``

オンラインでお試しください！

もともとこれはPrologの答えにすぎませんでしたが、実際に入力形式を使用可能なものに変換するために見つけることができるツールは十分に限られており、経験のほとんどないにもかかわらずその部分をbashで行うことにしましたbashで何かをしていて、awkに触れることさえなかった。167バイトになり、すべてのモンスターにかろうじてゴルフをした後でも、投稿するのに十分な時間を費やしました。