私の言葉はあなたの言葉を打ち負かすことができます


26

問題

2つの単語が与えられたら、デジタルルートバトルで勝者を見つけます。

この方法で単語のデジタルルートを定義します。

  1. アルファベットの各文字には番号が割り当てられます: A = 1、B = 2、C = 3、...、Z = 26
  2. 各文字の値を追加して、単語を合計します。たとえば、「CAT」を使用します。C + A + T = 3 + 1 + 20 = 24
  3. その結果を構成するすべての1桁を追加します。24=> 2 + 4 = 6
  4. 1桁に達するまで手順3を繰り返します。その1桁が単語のデジタルルートです。

ルール:

  1. デジタルルートが他のルートよりも大きい場合、勝者が宣言されます。
  2. 場合デジタルルート値が等しい、単語および再計算の両方から最高値の文字のすべてのインスタンスを除去することにより、単語を短縮します。
  3. 勝者が現れるまで、または単語の1つに文字が1つしか残っていない(または文字が残っていない)まで、手順1と2を繰り返します。
  4. 短縮プロセスを経た後、デジタルルート値が等しい場合、長い単語が勝者として宣言されます。
  5. 単語が同じ長さで、短縮プロセスを行った後に勝者が見つからない場合、勝者は宣言されません。

特別なルール:

  1. デジタルルート自体の計算では、モジュラスの使用は許可されません。他のどこでも使用できます。
  2. 単語は大文字のみで構成されていると仮定します-句読点やスペースなどは使用できません

入力

標準入力(コンマ区切り)を使用して単語を取り込みます。メソッドパラメータ、または必要に応じて。ソリューションまたはコードで、単語の解析または準備方法を明確にします。

出力

勝った言葉を表示します。勝者がいない場合は、「STALEMATE」と表示します。

例:

入力:CAN、BAT

CAN = 18 = 9
BAT = 23 = 5 

出力:CAN

入力:ZOO、NO

ZOO = 56 = 11 = 2
NO = 29 = 11 = 2

OO = 30 = 3
N = 14 = 5

出力:NO

UPDATE:入力は、カンマ区切りの文字列としての単語を使用して、stdinを使用して読み取る必要があります。

更新:テスト対象のいくつかの例を追加しました。

更新:同点の場合に最高値の文字を削除することを明確にしました-これは停止条件もわずかに変更します-単語が1文字または0文字の場合、短縮プロセスは停止します


プログラムに大きな違いをもたらすため、入力を選択するのではなく、入力を決定する必要があります。インプットメソッドを選択して指定することで、「創造的な解釈」を取り除き、すべてに平等な挑戦をします。
MtnViewMark

@MtnViewMark-理解されましたが、事実上、文字カウントから入力の読み取りを削除しようとしています。2つの単語を読む最も賢い方法や最短の方法には興味がありません。特定の方法を必要とすると、特定の言語にも障害が発生します。問題の本質にたどり着こうとしています。
スティーブ

1
@Steve-出力を「表示」として指定するべきではありませんか?ただし、おそらく問題からあまりにも多くを排除していると思います。巧妙で短いゴルフは、問題のさまざまな側面を巧妙な方法で組み合わせることから生じることがよくあります。たとえば、処理の一部を入力または出力に折り畳むことです。ハンディキャップ言語については、ほとんどすべてが標準入力を読み、標準出力を書くことができます。
MtnViewMark

@MtnViewMark-フェアポイント。簡単な更新を行い、クリアします。私の選択言語は標準入力からの読み取り方法が長いため、偏見があります。:)
スティーブ

入力をメイン入力への引数にすると、stdinからのものとしてカウントされますか?ああ、一般的に、stdinからの読み取りや他のモジュールやファイルのインポートやインクルードなど、不要なものの要件を抑えたい場合、プログラム全体ではなく機能をパズルに組み込むのが最善の方法です。 。
ジョナサンMデイビス

回答:


9

J、100

z=:"."0@":@(+/)^:9@(64-~a.i.])@(#~' '&i.)"1
f=:*@-/"2@(z@((]#~]i.~{.@\:~)"1^:([:=/z))){'STALEMATE'&,

次のように実行されます。

f 'NO',:'ZOO'
NO       
f 'CAN',:'BAT'
CAN      
f 'FAT',:'BANANA'
FAT      
f 'ONE',:'ONE'
STALEMATE

求められたとおりの入力をまだ受け付けていませ


9

APL(ダイアログ)(91 86)

⎕ML←3⋄{Z≡∪Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨+/¨⎕A∘⍳¨⍵:G[↑⍒Z]⋄1∊↑¨⍴¨⍵:'STALEMATE'⋄∇1∘↓¨⍵}G←Z⊂⍨','≠Z←⍞

説明(実行順):

  • ⎕ML←3:MLを3に設定します(これにより、平均パーティションが作成されます)。
  • G←Z⊂⍨','≠Z←⍞:コンマで区切って入力を読み取り、Gに保存して関数に渡します。
  • +/¨⎕A∘⍳¨⍵:各単語のスコアを計算します。(⎕Aアルファベットを含むリストです。)
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨:各スコアのデジタルルートを計算し(まだ複数の数字がある限りすべての数字を合計することにより)、Zに保存します。
  • Z≡∪Z:すべてのスコアが一意の場合...
  • :G[↑⍒Z]:...次に、(元のリストから)最高スコアの単語を出力します。
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE':それ以外の場合(同点の場合)、単語の1つの長さが1の場合、STALEMATEを出力します。
  • ⋄∇1∘↓¨⍵:それ以外の場合、各単語の最初の文字を取り、関数を再度実行します。

5

ルビー-210

d,e=(a,b=$<.read.chop.split(/,/)).map{|w|w.bytes.sort}
r=->w,o=65{n=0;w.map{|c|n+=c-o};n>9?r[n.to_s.bytes,48]:n}
d.pop&e.pop while r[d]==r[e]&&d[1]&&e[1]
$><<[[:STALEMATE,a,b][a.size<=>b.size],a,b][r[d]<=>r[e]]

テスト:

$ ruby1.9 1128.rb <<< CAN,BAT
CAN

$ ruby1.9 1128.rb <<< ZOO,NO
NO

$ ruby1.9 1128.rb <<< ZOO,ZOO
STALEMATE

最初の行はに短縮できますd,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}
ヴェンテロ

ネクタイを示す他の単語を使用して、これをさらに短縮してみませんか?すなわち「TIE」対「STALEMATE」
-Gaffi

@Gaffi。仕様では「STALEMATE」という単語を使用する必要があるためです。
ポール・プレスティッジ

私に恥@chron、私が読んで停止"If the words are of equal length and no winner is found after going through the shortening process, no winner is declared."
Gaffi

5

Haskell、205文字

import List
s b=d.sum.map((-b+).fromEnum)
d q|q<10=q|1<3=s 48$show q
f=map(s 64.concat).tails.group.reverse.sort
w(a,_:b)=f a#f b where x#y|x<y=b|x>y=a|1<3="STALEMATE"
main=getLine>>=putStrLn.w.span(/=',')

サンプルの実行:

> ghc --make WordVsWord.hs 
[1 of 1] Compiling Main             ( WordVsWord.hs, WordVsWord.o )
Linking WordVsWord ...

> ./WordVsWord <<< CAN,BAT
CAN

> ./WordVsWord <<< ZOO,NO
NO

> ./WordVsWord <<< FAT,BANANA
FAT

> ./WordVsWord <<< ONE,ONE
STALEMATE

  • 編集:(227-> 219)勝者の選択の改善、パターンマッチの短縮w、インポートされた古い、短いモジュール
  • 編集:(219-> 208)JBの提案を組み込む
  • 編集:(208-> 205)負の数を処理し、Haskellのハイフンに関する奇妙なルールを活用する

1
ストレートリスト比較を使用すると、非常に便利です。いくつかの「一目でわかる」改善の提案:',':b_:b(-2)、マルチライン処理にあまり慣れていない場合interact$unlines.map([...]).linesputStr.[...]=<<getLine(-11)、出力を緩くすることができる場合putStrprint(-1)。私は非常に多くの文字を使用するこれらの否定操作が嫌いですが、その方法を見つけることができません。
JB

ありがとう、JB!ほとんどの提案を取り入れました。出力は仕様に従って、特に改行で終わるべきだと感じました。しかし、もしそれが近くなったら、私はそれらの2人のキャラクターを保存したいと思います!:-)
MtnViewMark

減算で良い仕事!
JB

3

Perlの、224 225 229

基本的なゴルフ(まだスマートなものはありません):

split",",<>;$_=[sort map-64+ord,/./g]for@a=@_;{for(@b=@a
){while($#$_){$s=0;$s+=$_ for@$_;$_=[$s=~/./g]}}($a,$b)=
map$$_[0],@b;if($a==$b){pop@$_ for@a;@{$a[1]}*@{$a[0]}&&
redo}}say+("STALEMATE",@_)[$a<=>$b||@{$a[0]}<=>@{$a[1]}]

Perl 5.10以降、perl -M5.010 <file>またはで実行perl -E '<code here>'

$ perl -M5.010 word.pl <<<CAN,BAT
CAN
$ perl -M5.010 word.pl <<<ZOO,NO
NO

$ perl -M5.010 word.pl <<<NO,ON
STALEMATE

2

K、106

{a::x;@[{$[(>). m:{+/"I"$'$+/@[;x].Q.A!1+!26}'x;a 0;(<). m;a 1;.z.s 1_'x@'>:'x]};x;"STALEMATE"]}[","\:0:0]

例外処理を使用して、スタックエラーをキャッチします。


2

VBA(242 462)

Function s(q,Optional l=0)
s=-1:t=Split(q,","):r=t:m=t
For j=0 To 1
m(j)=0:w=t(j)
While Len(w)>1 Or Not IsNumeric(w)
b=0
For i=1 To Len(w)
a=Mid(w,i,1):a=IIf(IsNumeric(a),a,Asc(a)-64):b=b+a
If m(j)+0<a+0 Then m(j)=a
Next
w=b
Wend
r(j)=b
Next
s=IIf(r(0)>r(1),0,IIf(r(0)<r(1),1,s))
For j=0 To 1
r(j)=Replace(t(j),Chr(m(j)+64),"",,1)
Next
If s<0 And Len(t(0))+Len(t(1))>2 Then s=s(r(0) & "," & r(1),1)
If l=0 Then If s>=0 Then s=t(s) Else s="STALEMATE"
End Function

以下のコードは仕様と一致しなかったため、多くの長さを追加して作業し直さなければなりませんでした(上記参照):-/これはさらにゴルフができるかもしれませんが、すでにかなりコンパクトであり、競争力のあるスコアに戻すことができるとは思えません。

オリジナル(下)は、同点があったときに単語から最高値の文字を削除しませんでした。

Sub s(q)
t=Split(q,",")
r=t
For j=0 To 1
w=t(j):b=0
For i=1 To Len(w)
b=b+Asc(Mid(w,i,1))-64
Next
While Len(b)>1
d=0
For i=1 To Len(b)
d=d+Mid(b,i,1)
Next
b=d
Wend
r(j)=b
Next
MsgBox IIf(r(0)>r(1),t(0),IIf(r(0)<r(1),t(1),"STALEMATE"))
End Sub

2

これは本当に私の空想を取り、私の最初の投稿です。それは古いですが、誰もPHPバージョンを実行していないことに気づいたので、ここに私のものがあります。

<?php $f='CAN,CBN';$w=explode(',',$f);$a=$ao=$w[0];$b=$bo=$w[1];$c='';
function splice($a,$t){$s=$h=0;$y=array();$x=str_split($a);
foreach($x as $k=>$v){$s=$s+ord($v)-64;if($v>$h){$h=$k;}}
$y[0]=$s;if($t==1){unset($x[$h1]);$y[1]=$x;}return $y;}
while($c==''){$y1=splice($a,0);$y2=splice($b,0);$y3=splice($y1[0],1);
$y4=splice($y2[0],1);if($y3[0]>$y4[0]){$c=$ao;}else if($y3[0]<$y4[0]){$c=$bo;
}else if((strlen($a)<1)OR(strlen($b)<1)){if(strlen($a)<strlen($b)){$c=$ao;}
else if(strlen($b)<strlen($a)){$c=$bo;}else{$c='STALEMATE';}}}
echo $c;
?>

534文字。

今、私は開始するためのルールがわからないので、入力として$ f = 'CAN、CBN'から始めました。それが正しかったことを願っています。私はすべてのテストを実行しましたが、特にエレガントではありませんが、すべてのテストに合格しました。今は本当に眠らなければなりませんが、これを解決するのはとても楽しかったです。すばらしいパズルをありがとう。

http://codepad.org/ZSDuCdinにコーディング


$f=trim(fgets(fopen('php://stdin')));入力を取得するために使用できます。
エレクトラ

スクラッチ、$w=fgetcsv(STDIN);より良く機能します。
エレクトラ

1

D:326文字

import std.algorithm,std.array,std.conv,std.stdio;void main(string[]a){alias reduce r;auto b=array(splitter(a[1],","));auto s=map!((a){int n=r!"a+b"(map!"cast(int)(a-'A')+1"(a));while(n>9)n=r!"a+b"(map!"cast(int)(a-'0')"(to!string(n)));return n;})(b);int v=r!"a>b?a:b"(s);writeln(count(s,v)>1?"STALEMATE":b[countUntil(s,v)]);}

より読みやすく:

import std.algorithm, std.array, std.conv, std.stdio;

void main(string[] a)
{
    alias reduce r;

    auto b = array(splitter(a[1], ","));
    auto s = map!((a){int n = r!"a + b"(map!"cast(int)(a - 'A') + 1"(a));

                      while(n > 9)
                          n = r!"a+b"(map!"cast(int)(a - '0')"(to!string(n)));

                      return n;
                     })(b);
    int v = r!"a > b ? a : b"(s);

    writeln(count(s, v) > 1 ? "STALEMATE" : b[countUntil(s, v)]);
}

1

Mathematica

一部の詳細がまだ欠落しています

a = {"ZOO"}; b = {"NO"}
f = FixedPoint[IntegerDigits@Total@# &, #] &

If[(s = f /@ 
        NestWhile[(# /. Max@# -> 0 &) /@ # &, (ToCharacterCode @@ # - 64) & /@ #, 
        f[#[[1]]] == f[#[[2]]] &, 1, 5] &@{a, b})[[1, 1]] > s[[2, 1]], 
   a, b, "STALMATE"]  

{"NO"}

1

Mathematica 220 207

これを書いた後、私はこれがベリサリウスが使用したのと同じ推論に従うことに気付きました

h@u_ := ToCharacterCode@u - 64;
m@w_ := FromCharacterCode[Most@Sort@h@w + 64];
f@v_ := FixedPoint[Tr@IntegerDigits@# &, Tr@h@v];
x_~g~y_ := If[f@x == f@y, g[m@x, m@y], If[f@x > f@y, 1, 2]];
x_~z~x_ := "STALEMATE";
x_~z~y_ := {x, y}[[x~g~y]] 

使用法

z["ZOO", "NO"]
z["CAN", "BAT"]
z["FAT", "BANANA"]
z["ONE", "ONE"]

結果

応答は競合的ではないため(非常に時間がかかります)、Mathematicaにより適した入力形式を使用することにしました。


1

CoffeeScript-335

z=(a,b,g=a,h=b)->c=y a;d=y b;e=a.length;f=b.length;return g if(c>d);return h if(d>c);return g if(e<2&&f>1);return h if(f<2&&e>1);return "STALEMATE" if(f==e&&f<2);z(x(a),x(b),a,b)
y=(a)->t=0;t+=c.charCodeAt(0)-1 for c in a;t-=9 while 9<t;t
x=(a)->for i in[90..65]
 b=new RegExp(String.fromCharCode(i));return a.replace b, "" if b.test a

私はこれに満足していないかもしれませんが、とにかくそれを我慢します。実際のスコアリングは非常に簡潔(y関数)ですが、if結果を比較するs(z)はかなり長くなります。

使用するにzは、2つの単語(たとえば、z 'FOO','BAR')で呼び出します。両方の単語にスコアを付け、より高いスコアの単語を返します。同点の場合、x関数から取得する変更された単語(最終的に元の単語を返すため、余分な2つのパラメータを保持)で再帰します。

興味がある人のための同等の(拡張された)javascript:

var x, y, z;

z = function(a, b, g, h) {
  var c, d, e, f;
  if (g == null) {
    g = a;
  }
  if (h == null) {
    h = b;
  }
  c = y(a);
  d = y(b);
  e = a.length;
  f = b.length;
  if (c > d) {
    return g;
  }
  if (d > c) {
    return h;
  }
  if (e < 2 && f > 1) {
    return g;
  }
  if (f < 2 && e > 1) {
    return h;
  }
  if (f === e && f < 2) {
    return "STALEMATE";
  }
  return z(x(a), x(b), a, b);
};

y = function(a) {
  var c, t, _i, _len;
  t = 0;
  for (_i = 0, _len = a.length; _i < _len; _i++) {
    c = a[_i];
    t += c.charCodeAt(0) - 1;
  }
  while (9 < t) {
    t -= 9;
  }
  return t;
};

x = function(a) {
  var b, i, _i;
  for (i = _i = 90; _i >= 65; i = --_i) {
    b = new RegExp(String.fromCharCode(i));
    if (b.test(a)) {
      return a.replace(b, "");
    }
  }
};

1

ラケット479バイト

(define(dl n)(let p((ol '())(n n))(let-values(((q r)(quotient/remainder n 10)))(if(= q 0)(cons r ol)(p(cons r ol)q)))))
(define(dr N)(let p2((n N))(define s(apply +(dl n)))(if(< s 10)s(p2 s))))
(let p3((l(for/list((i(string->list s)))(-(char->integer i)64)))(k(for/list((i(string->list t)))(-(char->integer i)64))))
(let((a(dr(apply + l)))(b(dr(apply + k))))(cond[(> a b)s][(< a b)t][(equal? l k)"STALEMATE"][else(p3(remove*(list(apply max l))l)(remove*(list(apply max k))k))])))

ゴルフをしていない:

(define (f s t)

  (define (getDigitList n)                     ; sub-fn  to get digit list
    (let loop ((ol '())
               (n n))
      (let-values (((q r) (quotient/remainder n 10)))
        (if (= q 0) (cons r ol)
            (loop (cons r ol) q)))))

  (define (digit_root N)                       ; sub-fn to get digital root of a number
    (let loop2 ((n N))                        
      (define s (apply + (getDigitList n)))    
      (if (< s 10)
          s
          (loop2 s))))

  (let loop3 ((l (for/list ((i (string->list s)))  ; actual fn to compare 2 strings
                   (- (char->integer i) 64)))
              (k (for/list ((i (string->list t)))
                   (- (char->integer i) 64))))
    (let ((a (digit_root (apply + l)))
          (b (digit_root (apply + k))))
      (cond
        [(> a b) s]
        [(< a b) t]
        [(equal? l k) "STALEMATE"]
        [else (loop3 (remove* (list (apply max l)) l)
                     (remove* (list (apply max k)) k)
                     )]
        ))))

テスト:

(f "CAN" "BAT")
(f "ZOO" "NO")

出力:

"CAN"
"NO"

1

PHP、339(仕様外)、410 382 359 339 337バイト

$b=$w=fgetcsv(STDIN);function a($c){for(;a&$g=$c[$p++];)$f+=ord($g)-64;$f=trim($f);for(;$f[1]&a;$f=$h)for($h=0;a&$r=$f[$q++];$h=bcadd($h,$r));return$f;}function d($f){return strtr($f,[max(str_split($f))=>'']);}for(;$c==$d;$b=[$e,$f]){$x=$z++?d:trim;$e=$x($b[0]);$f=$x($b[1]);$c=a($e);$d=a($f);$e||die(STALEMATE);$c!=$d&&die($w[$c<=$d]);}

編集1:+71バイト。を使用してSTDINfopen('php://stdin','r');短いタグの代わりにます。また、仕様に完全に準拠しています。

編集2:-28バイト。のfgetcsv(STDIN)代わりに使用し、代わりにループexplode(',',trim(fgets(STDIN)))を使用しましたforwhileループ。

編集3:-23バイト。統合された機能ab結合された、forループが結合されました。

編集4:-20バイト。投入cループに再帰から。次に、削除された機能cをし、そのコードをグローバル名前空間に配置しました。

編集5:-2バイト。-rフラグをくれた@Titusに感謝します。



0

JAVA

    public static void main(String args[]) throws Exception{
        String input=(new BufferedReader(new InputStreamReader(System.in)).readLine());
        StringTokenizer st = new StringTokenizer(input, ",");
        String w1 = st.nextToken();String w2 = st.nextToken();int s1=0;int s2=0;
        String flag="";
        do{ Integer sum1=0;Integer sum2=0;
        for (int i=0;i<w1.length();i++)
            sum1+=((int)w1.charAt(i) - 64);
        for (int i=0;i<w2.length();i++)
            sum2+=((int)w2.charAt(i) - 64);
        while (sum1.toString().length()>1){
            s1=0;
            for (int i=0;i<sum1.toString().length();i++)
                s1+=((int)sum1.toString().charAt(i)-48);
            sum1=s1;
        }
        while (sum2.toString().length()>1){
            s2=0;
            for (int i=0;i<sum2.toString().length();i++)
                s2+=((int)sum2.toString().charAt(i)-48);
            sum2 =s2;
        }
        flag=(s1>s2)?w1:(s1!=s2)?w2:"";
        if (flag!="")
            {st = new StringTokenizer(input,",");
                if (s1>s2)
                    System.out.println(st.nextToken());  
                else{
                    st.nextToken();
                    System.out.println(st.nextToken());
                }
            }
        int max=0;
        for (int i=0;i<w1.length();i++){
            max=((int)w1.charAt(i)>max)?(int)w1.charAt(i):max;
        }
        w1 = w1.replace((char)max, (char)64);
        max=0;
        for (int i=0;i<w2.length();i++){
            max=((int)w2.charAt(i)>max)?(int)w2.charAt(i):max;
        }
        w2 = w2.replace((char)max, (char)64);
            }while(flag=="" && !w1.equals(w2)); 
    if (flag.length()<1)
        System.out.println("STALEMATE");
        }

上記のコードは、同点の場合にすべての最大文字を置き換えます。それは必須ですか?
アマンZeeKヴァーマ

0

C ++、473(コースアイロンを借りています)

#include<iostream>
#define $ string
#define _ return
using namespace std;$ S($&s){int i=-1,m=i,x=0;while(++i<s.length())if(s[i]-'@'>x)m=i,x=s[i];s.erase(m,1);_ s;}int M($ w){int i,v=0;for(i=0;i<w.length();++i)v+=w[i]-'@';while(v>9){i=0;while(v)i+=v-v/10*10,v/=10;v=i;}_ v;}$ B($ x, $ y){while(!(M(x)-M(y)))S(x),S(y);if(M(x)>M(y))_ x;if(M(x)<M(y))_ y;_"STALEMATE";}int main(int c,char**v){$ s;cin>>s;$ x=s.substr(0,s.find(',')),y=s.substr(s.find(',')+1);cout<<B(x,y)<<endl;_ 0;}

どうにかして短縮できると確信していますが、疲れています。

編集:元々コマンドライン引数を取りましたが、cinを使用するように変更しました。おそらく今は数文字長くなっていますが、説明するのに疲れています。


0

Python:383文字

関数を実行しますc('CAN','BAT')

def k(j):
 l=list(j);l.remove(max(j));return''.join(l)
def f(x):
 x=str(x)
 if len(x)==1 and x.isdigit():return int(x)
 return f(sum('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.index(y)+1 for y in x)) if x.isalpha() else f(sum(map(int,x)))
def c(a,b):
 v=f(a);u=f(b);
 if v>u:return a
 if v<u:return b
 return'STALEMATE' if v==u and (len(a)==1 or len(b)==1)else c(k(a),k(b))

0

F#、559 533 530バイト

まだ競争力がありません。最後の数行だけでなくcも短くできると確信しています。コマンドライン引数に簡単にアクセスできないことも、ここで痛いです。

open System
let m=Seq.map
let a s=s="";s.ToUpper()|>m(fun c->int c-64)
let rec c i=if i>9 then string i|>m(int>>(-))|>m(fun x->x 48)|>Seq.sum|>c else i
let b i=Seq.fold(fun(r,a)j->(Seq.sum i-a)::r,a+j)([],0)(Seq.sortBy(~-)i)|>fst|>m c
[<EntryPoint>]
let x z=
 let y=z.[0].Split(',')
 let u,v=y.[0].Length,y.[1].Length
 printf"%s"(Seq.fold2(fun s l r->if l=r then 3::s else if l>r then 0::s else 1::s)[](b<|a y.[0])(b<|a y.[1])|>Seq.tryFind((>)3)|>function|None when u>v->y.[0]|None when u<v->y.[1]|Some x->y.[x]|_->"STALEMATE")
 0

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

  • sを文字列と比較して文字列に制限することで3バイトを節約しました

ゴルフされていないバージョン

open System
let m=Seq.map // this is just to save some characters and I'll use Seq.map for this version

let toIntList s =
    s = "" // constrain s to type string
    s.ToUpper()
    |>Seq.map (fun c -> int c - 64) // converts char value to int and offsets it so that A=1

let rec digitSumUntilSingle i =
    if i > 9 then
        string i                // convert number to string
        |>Seq.map ( int>>(-) )  // convert individual char to int and partially apply substraction
                                // this returns a function
        |>Seq.map (fun x -> x 48) // provide last parameter for substraction, this is equivalent to
                                  // charValue - 48
        |>Seq.sum                 // sum over all digits
        |>digitSumUntilSingle     // recursively call this function again in case we are >9
    else
        i

let calculateDigitalRoot input =
    Seq.fold(fun (result, acc) current ->       // calculate digital root for all possible iterations
                (Seq.sum input - acc)::result,  // basically, this calculates Rule 3 until the end for a given word
                acc + current
            ) ([], 0) (Seq.sortBy (~-) input) // sort input by value descending
    |>fst   // only interested in the lits, not the final accumulator
    |>Seq.map digitSumUntilSingle

[<EntryPoint>]
let main (args) =
    let y = args.[0].Split(',')
    let leftLength = y.[0].Length
    let rightLength = y.[1].Length

    Seq.fold2 (fun state left right ->
                if left = right then
                    3::state
                else if left > right then
                    0::state                // 0 is chosen because this represents y[0] index
                else
                    1::state
               ) [] (calculateDigitalRoot (toIntList y.[0])) (calculateDigitalRoot (toIntList y.[1]))
    |> Seq.tryFind ((>) 3)                  // try to find first variation where left and right digital root isn't equal
    |> function
        | None when leftLength > rightLength -> y.[0]
        | None when leftLength < rightLength -> y.[1]
        | Some x -> y.[x]
        | _ ->"STALEMATE"
    |>printf "%s" 
    0

0

PHP、296 281 267バイト

function f(&$s){for(;$c=$s[$i++];$m>$c||$m=$c)$p+=ord($c)&31;for($s=str_replace($m,'',$s);9<$p=array_sum(str_split($p)););return$p;}for(list($a,$b)=$x=fgetcsv(STDIN);$s==$t&&$a&$b;$t=f($b))$s=f($a);echo($s-=$t)||($s=strlen($x[0])-strlen($x[1]))?$x[+($s<0)]:STALEMATE;

で実行する-n、オンラインで試してください(TiOには故障が含まれます)。

2011年2月に戻って、現在のPHPバージョンは5.3.5でした。できなかった

  • 短縮リストの割り当てを使用する([$a,$b]=fgetcsv(...)など)
  • エイリアス count_charsインライン
  • インデックス関数の結果を直接
  • 代わりに負の文字列インデックスを使用します substr

しかし、どちらも大きな節約にはなりませんでした。それほど重要ではありません。

最も高価なものは、ループ(もちろん)とルール#4(40 36バイト)でした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.