La mia Parola può battere la tua Parola


26

PROBLEMA

Con due parole, trova il vincitore in una battaglia di root digitale .

Definisci la radice digitale di una parola in questo modo:

  1. A ogni lettera dell'alfabeto viene assegnato un numero: A = 1, B = 2, C = 3, ..., Z = 26
  2. Aggiungi i valori per ogni lettera per sommare la parola. Prendi "CAT", per esempio. C + A + T = 3 + 1 + 20 = 24
  3. Aggiungi tutte le singole cifre che compongono quel risultato: 24 => 2 + 4 = 6
  4. Ripeti il ​​passaggio 3 fino a raggiungere una singola cifra. Quella singola cifra è la radice digitale della parola.

Regole:

  1. Un vincitore viene dichiarato se la sua radice digitale è più grande dell'altra.
  2. Se i valori della radice digitale sono uguali, abbreviare le parole rimuovendo ogni istanza della lettera del valore più alto da entrambe le parole e ricalcolando.
  3. Ripeti i passaggi 1 e 2 fino a quando non c'è un vincitore o una delle parole ha solo una sola lettera (o nessuna lettera) rimanente.
  4. Se i valori della radice digitale sono uguali dopo aver attraversato il processo di accorciamento, la parola più lunga viene dichiarata vincente.
  5. Se le parole hanno la stessa lunghezza e non viene trovato alcun vincitore dopo aver attraversato il processo di accorciamento, nessun vincitore viene dichiarato.

Regole speciali:

  1. Non è consentito l'uso del modulo nel calcolo della radice digitale stessa. Può essere usato altrove.
  2. Supponiamo che le parole siano composte solo da lettere maiuscole - nessuna punteggiatura, nessuno spazio, ecc.

INGRESSO

Inserisci le parole in uno stdin (separato da virgola). parametri del metodo, o nel modo desiderato. Rendi chiaro nella tua soluzione o nel codice come vengono analizzate o preparate le parole.

PRODUZIONE

Mostra la parola vincente. Se non è presente alcun vincitore, visualizzare "STALEMATE".

Esempi:

intput: CAN, BAT

CAN = 18 = 9
BAT = 23 = 5 

uscita: CAN

intput: ZOO, NO

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

OO = 30 = 3
N = 14 = 5

uscita: NO

AGGIORNAMENTO : L'input deve essere letto usando stdin con le parole come una stringa separata da virgola.

AGGIORNAMENTO : aggiunti un paio di esempi da testare.

AGGIORNAMENTO : chiarita la rimozione della lettera con il valore più alto in caso di pareggio - anche questa modifica leggermente la condizione di arresto - se una parola è lunga una lettera o zero, il processo di accorciamento viene interrotto


Dovresti decidere l'input, non lasciarlo a scelta, poiché fa una differenza enorme nei programmi. Scegliendo un metodo di input e specificandolo, si rimuovono le "interpretazioni creative" e si pone una sfida uguale per tutti.
— MtnViewMark,

@MtnViewMark - Capito, ma in effetti sto cercando di rimuovere la lettura dell'input dal conteggio dei caratteri. Non mi interessa il modo più intelligente o più breve di leggere le due parole. Richiedere un metodo specifico ostacola anche alcune lingue - immagino che sto solo cercando di capire il problema.
— Steve,

1
@Steve - Quindi non dovresti nemmeno specificare l'output come "display", sì? Tuttavia, penso che forse stai eliminando troppo dal problema. Un golf intelligente e corto spesso deriva dalla combinazione di diversi aspetti del problema in modi difficili, ad esempio piegando parte dell'elaborazione nell'input o output. Per quanto riguarda le lingue per disabili - praticamente tutti possono leggere stdin e scrivere stdout.
— MtnViewMark,

@MtnViewMark - Fair point. Farò un semplice aggiornamento e lo chiarirò. La mia lingua preferita ha solo un lungo modo di leggere dallo stdin, quindi mi viene di parte. :)
— Steve,

Prendere l'input come argomento principale conta come proveniente da stdin? Oh, e in generale, se vuoi mantenere bassi i requisiti su cose vaganti come leggere da stdin e dover importare o includere altri moduli o file, rendere il puzzle richiede una funzione piuttosto che un intero programma sarebbe il modo migliore per andare .
— Jonathan M Davis,

Risposte:


9

J, 100

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

funziona così:

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

non accetta ancora input esattamente come richiesto.


9

APL (Dyalog) ( 91 86)

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

Spiegazione (in ordine di esecuzione):

  • ⎕ML←3: imposta ML su 3 (questo rende la ⊂partizione media, tra le altre cose).
  • G←Z⊂⍨','≠Z←⍞: legge l'input, separa le virgole, memorizza in G e passa alla funzione.
  • +/¨⎕A∘⍳¨⍵: calcola il punteggio per ogni parola. ( ⎕Aè un elenco contenente l'alfabeto.)
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨: calcola la radice digitale per ogni punteggio (sommando tutte le cifre purché ci sia ancora più di una cifra) e memorizzale in Z.
  • Z≡∪Z: se tutti i punteggi sono unici ...
  • :G[↑⍒Z]: ... quindi emette la parola con il punteggio più alto (dall'elenco originale).
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE': altrimenti (se c'è un pareggio), se una delle parole ha lunghezza 1, genera STALEMATE.
  • ⋄∇1∘↓¨⍵: altrimenti, togli la prima lettera da ogni parola ed esegui di nuovo la funzione.

5

Rubino - 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]]

test:

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

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

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

La prima riga può essere abbreviata in d,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}.
— Ventero,

Perché non abbreviarlo ulteriormente usando un'altra parola per indicare un pareggio? vale a dire "TIE" vs. "STALEMATE"
— Gaffi,

@Gaffi perché le specifiche richiedono l'uso della parola "STALEMATE".
— Paul Prestidge,

@chron Vergognati, ho smesso di leggere a"If the words are of equal length and no winner is found after going through the shortening process, no winner is declared."
— Gaffi il

5

Haskell, 205 caratteri

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(/=',')

Esecuzioni campione:

> 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

  • Modifica: (227 -> 219) migliore selezione del vincitore, corrispondenza del modello abbreviata w, modulo importato più vecchio, più corto
  • Modifica: (219 -> 208) Incorporare i suggerimenti di JB
  • Modifica: (208 -> 205) gestiscono i numeri negativi, sfruttando le regole dispari in Haskell sul trattino

1
L'uso del confronto tra liste semplici è un bel tocco. Alcuni miglioramenti "a colpo d'occhio" suggeriti: ',':b→ _:b(-2), se non sei troppo attaccato all'elaborazione multilinea interact$unlines.map([...]).lines→ putStr.[...]=<<getLine(-11), se ti permetti di rallentare l'output putStr→ print(-1). Odio quell'operazione di negazione che prende così tanti caratteri, ma non riesco a trovare un modo per aggirarlo.
— JB,

Grazie JB! Ho incorporato la maggior parte dei suggerimenti. Ho pensato che l'output dovesse seguire le specifiche, in particolare terminare con una nuova riga. Ma sarei disposto a salvare quei due personaggi se si avvicinasse! :-)
— MtnViewMark

Ottimo lavoro con le sottrazioni!
— JB,

3

Perl, 224 225 229

Golf di base (ancora niente di intelligente):

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 e versioni successive, esegui con perl -M5.010 <file>operl -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]

Utilizza la gestione delle eccezioni per rilevare errori dello stack, che si traducono in casi di stallo.


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

Si scopre che il codice seguente non corrisponde alle specifiche, quindi ho dovuto rielaborare, aggiungendo molta lunghezza (vedi sopra). : - / Potrebbe essere possibile giocare a golf ulteriormente, ma è già abbastanza compatto e dubito che sarò in grado di riportarlo a un punteggio competitivo.

L'originale (sotto) non rimuoveva la lettera più apprezzata dalle parole quando c'era un pareggio.

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

Questo ha davvero preso la mia fantasia ed è il mio primo post. Anche se è vecchio, ho notato che nessuno aveva fatto una versione php, quindi ecco la mia.

<?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 personaggi.

Ora non sono sicuro delle regole per iniziare, quindi ho iniziato con $ f = 'CAN, CBN' come input. Spero fosse giusto. Ho eseguito tutti i test e li supera tutti anche se non è particolarmente elegante. Adesso devo davvero dormire un po ', ma mi sono divertito molto a risolverlo, grazie per un fantastico puzzle.

Codificato su http://codepad.org/ZSDuCdin


Puoi usare $f=trim(fgets(fopen('php://stdin')));per prendere l'input.
— Élektra,

Grattalo, $w=fgetcsv(STDIN);funziona meglio.
— Élektra,

1

D: 326 personaggi

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)]);}

Più leggibilmente:

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

matematica

Mancano ancora alcuni dettagli

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

Dopo aver scritto questo, ho notato che questo segue lo stesso ragionamento usato da Belisario,

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]] 

uso

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

risultati

Poiché la risposta non è competitiva (essendo così prolissa), ho deciso di utilizzare un formato di input più congeniale a 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

Non sono contento di questo come avrei potuto essere, ma lo metterò comunque. Il punteggio effettivo è molto conciso ( yfunzione), ma le ifs per confrontare i risultati (in z) diventano piuttosto lunghe.

Per usarlo chiama zcon le tue due parole (es z 'FOO','BAR'.). Segnerà entrambe le parole e restituirà la parola con punteggio più alto. Se è un pareggio, si richiamerà con le parole modificate (mantenendo gli originali per tornare alla fine, quindi i due parametri extra) che ottiene dalla xfunzione.

Il javascript equivalente (espanso) per gli interessati:

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

Racchetta 479 byte

(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))])))

Ungolfed:

(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)
                     )]
        ))))

test:

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

Produzione:

"CAN"
"NO"

1

PHP, 339 (non specificare), 410 382 359 339 337 byte

$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]);}

EDIT 1 : +71 byte. Utilizzando STDINinvece di fopen('php://stdin','r');e tag brevi. Inoltre, piena conformità alle specifiche.

EDIT 2 : -28 byte. Uso fgetcsv(STDIN)invece di explode(',',trim(fgets(STDIN)))e usato forloop anziché whileloop.

EDIT 3 : -23 byte. Funzioni unite ae b, unite per i loop.

MODIFICA 4 : -20 byte. Trasformato cda un ricorsivo in un ciclo. Quindi, rimuovere la funzione ce inserire il suo codice nello spazio dei nomi globale.

MODIFICA 5 : -2 byte. Grazie a @Titus per la -rbandiera.


1
non c'è bisogno di un tag PHP con -rbandiera
— Titus

0

GIAVA

    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");
        }

Il codice sopra sostituisce tutto il carattere massimo in caso di pareggio .. è necessario?
— Aman ZeeK Verma,

0

C ++, 473 (sto prendendo in prestito un ferro da stiro)

#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;}

Sono sicuro che potrei accorciarlo in qualche modo, ma sono stanco.

Modifica: inizialmente ha preso l'argomento della riga di comando, modificato per usare cin. Probabilmente ci vorranno ancora alcuni personaggi, ma sono troppo stanco per raccontarlo.


0

Python: 383 caratteri

eseguire la funzione 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 byte

Non ancora competitivo. Sono sicuro che c può essere abbreviato così come le ultime righe. Anche non avere un accesso più facile agli argomenti della riga di comando fa male qui.

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

Provalo online!

  • Ho salvato 3 byte vincolando s a stringa confrontandolo con stringa

Versione Ungolfed

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 byte

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;

esegui -no provalo online (TiO include la suddivisione).

Nel febbraio 2011, l'attuale versione di PHP era la 5.3.5; quindi non ho potuto

  • utilizzare l'assegnazione dell'elenco abbreviato ( [$a,$b]=fgetcsv(...)e simili)
  • alias in count_charslinea
  • la funzione di indice risulta direttamente
  • usa indici di stringa negativi invece di substr

Ma nessuno dei due avrebbe risparmiato molto; quindi non importa molto.

Le cose più costose erano i loop (ovviamente) e la regola # 4 ( 40 36 byte).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.