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([...]).linesputStr.[...]=<<getLine(-11), se ti permetti di rallentare l'output putStrprint(-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.