Mi palabra puede golpear tu palabra

26

PROBLEMA

Dadas dos palabras, encuentra al ganador en una batalla de raíz digital .

Defina la raíz digital de una palabra de esta manera:

  1. A cada letra del alfabeto se le asigna un número: A = 1, B = 2, C = 3, ..., Z = 26
  2. Agregue los valores para cada letra para totalizar la palabra. Tome "CAT", por ejemplo. C + A + T = 3 + 1 + 20 = 24
  3. Agregue todos los dígitos individuales que conforman ese resultado: 24 => 2 + 4 = 6
  4. Repita el paso 3 hasta llegar a un solo dígito. Ese solo dígito es la raíz digital de la palabra.

Reglas:

  1. Se declara un ganador si su raíz digital es más grande que la otra.
  2. Si los valores raíz digitales son iguales, acorte las palabras eliminando cada instancia de la letra del valor más alto de ambas palabras y recalculando.
  3. Repita los pasos 1 y 2 hasta que haya un ganador o una de las palabras tenga solo una letra (o ninguna letra) restante.
  4. Si los valores raíz digitales son iguales después de pasar por el proceso de acortamiento, la palabra más larga se declara ganadora.
  5. Si las palabras tienen la misma longitud y no se encuentra ningún ganador después de pasar por el proceso de acortamiento, no se declara ningún ganador.

Reglas especiales:

  1. No se permite el uso del módulo en el cálculo de la raíz digital en sí. Se puede usar en cualquier otro lugar.
  2. Suponga que las palabras consistirán solo en letras mayúsculas: sin puntuación, sin espacios, etc.

ENTRADA

Tire de las palabras a través de stdin (separadas por comas). parámetros del método, o como quieras. Deje claro en su solución o en el código cómo se analizan o preparan las palabras.

SALIDA

Muestra la palabra ganadora. Si no hay ganador, muestra "STALEMATE".

Ejemplos:

entrada: CAN, BAT

CAN = 18 = 9
BAT = 23 = 5 

salida: CAN

entrada: ZOO, NO

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

OO = 30 = 3
N = 14 = 5

salida: NO

ACTUALIZACIÓN : La entrada debe leerse usando stdin con las palabras como una cadena separada por comas.

ACTUALIZACIÓN : se agregaron un par de ejemplos para probar.

ACTUALIZACIÓN : aclaró la eliminación de la letra de mayor valor en el caso de un empate, esto también altera ligeramente la condición de detención, si una palabra tiene una letra o cero letras, el proceso de acortamiento se detiene

Steve
fuente
Debe decidir sobre la entrada, no dejarla a elección, ya que hace una gran diferencia en los programas. Al elegir un método de entrada y especificarlo, elimina las "interpretaciones creativas" y hace un desafío que es igual para todos.
MtnViewMark
@MtnViewMark - Entendido, pero efectivamente estoy tratando de eliminar la lectura de la entrada del recuento de caracteres. No estoy interesado en la forma más inteligente o más corta de leer las dos palabras. Requerir un método específico también perjudica ciertos idiomas; creo que solo estoy tratando de entender el problema.
Steve
1
@Steve - Entonces tampoco deberías especificar la salida como "display", ¿sí? Sin embargo, creo que tal vez estás eliminando demasiado el problema. Un golf inteligente y corto a menudo se debe a la combinación de diferentes aspectos del problema de maneras complicadas, por ejemplo, plegando parte del procesamiento en la entrada o salida. En cuanto a los idiomas para discapacitados, casi todos pueden leer stdin y escribir stdout.
MtnViewMark
@MtnViewMark - Punto justo. Haré una actualización simple y la aclararé. Mi idioma de elección solo tiene una larga forma de leer de stdin, por lo que soy parcial. :)
Steve
¿Tomando la entrada un argumento para main cuenta como de stdin? Ah, y en general, si desea mantener los requisitos bajos en cosas extraviadas como leer de stdin y tener que importar o incluir otros módulos o archivos, hacer que el rompecabezas requiera una función en lugar de un programa completo probablemente sería la mejor manera de hacerlo .
Jonathan M Davis

Respuestas:

9

J, 100

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

funciona así:

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

no tiene todavía acepta la entrada exactamente como se le pide.

Eelvex
fuente
9

APL (Dyalog) ( 91 86)

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

Explicación (en orden de ejecución):

  • ⎕ML←3: establece ML en 3 (esto hace una partición media, entre otras cosas).
  • G←Z⊂⍨','≠Z←⍞: lee la entrada, se separa por comas, se almacena en G y se pasa a la función.
  • +/¨⎕A∘⍳¨⍵: calcula la puntuación de cada palabra. ( ⎕Aes una lista que contiene el alfabeto).
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨: calcule la raíz digital para cada puntaje (sumando todos los dígitos siempre que haya más de un dígito) y guárdelos en Z.
  • Z≡∪Z: si todas las puntuaciones son únicas ...
  • :G[↑⍒Z]: ... luego muestra la palabra con la puntuación más alta (de la lista original).
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE': de lo contrario (si hay un empate), si una de las palabras es de longitud 1, salida STALEMATE.
  • ⋄∇1∘↓¨⍵: de lo contrario, quite la primera letra de cada palabra y vuelva a ejecutar la función.
marinus
fuente
5

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

Pruebas:

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

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

$ ruby1.9 1128.rb <<< ZOO,ZOO
STALEMATE
Arnaud Le Blanc
fuente
La primera línea se puede acortar a d,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}.
Ventero
¿Por qué no acortar esto aún más usando otra palabra para denotar un empate? es decir, "TIE" vs. "STALEMATE"
Gaffi el
@Gaffi porque la especificación requiere que se use la palabra "STALEMATE".
Paul Prestidge
@chron Vergüenza sobre mí, dejé de leer en"If the words are of equal length and no winner is found after going through the shortening process, no winner is declared."
Gaffi el
5

Haskell, 205 caracteres

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

Ejecuciones de muestra:

> 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

  • Editar: (227 -> 219) mejor selección del ganador, coincidencia de patrón acortado w, importado más antiguo, módulo más corto
  • Editar: (219 -> 208) Incorporar las sugerencias de JB
  • Editar: (208 -> 205) maneja números negativos, explotando reglas impares en Haskell sobre guiones
MtnViewMark
fuente
1
Usar una comparación de lista directa es un toque muy agradable. Algunas sugerencias de mejoras "de un vistazo": ',':b_:b(-2), si no está demasiado apegado al procesamiento multilínea interact$unlines.map([...]).linesputStr.[...]=<<getLine(-11), si se permite una salida laxa putStrprint(-1). Odio que la operación de negación tome tantos caracteres, pero no puedo encontrar una forma de evitarlo.
JB
Gracias JB! Incorporé la mayoría de las sugerencias. Sentí que la salida debería seguir las especificaciones, en particular terminar con una nueva línea. ¡Pero estaría dispuesto a salvar esos dos personajes si se acercara! :-)
MtnViewMark
Buen trabajo con las restas!
JB
3

Perl, 224 225 229

Golf básico (nada inteligente todavía):

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 y superior, corre 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
JB
fuente
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]

Utiliza el manejo de excepciones para detectar errores de pila, que resultan en casos de estancamiento.

tmartin
fuente
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

Resulta que el código a continuación no coincide con la especificación, por lo que tuve que volver a trabajar, agregando mucha longitud (ver arriba). : - / Es posible que esto pueda jugarse más, pero ya es bastante compacto y dudo que pueda volver a reducirlo a un puntaje competitivo.

El original (abajo) no eliminó la letra de mayor valor de las palabras cuando había un empate.

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
Gaffi
fuente
2

Esto realmente me gustó y es mi primer post. Aunque es viejo, noté que nadie había hecho una versión de PHP, así que aquí está la mía.

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

Ahora no estoy seguro de las reglas para comenzar, así que comencé con $ f = 'CAN, CBN' como mi entrada. Espero que haya sido correcto. He realizado todas las pruebas y las supera todas, aunque no es particularmente elegante. Realmente debo dormir un poco ahora, pero me divertí mucho resolviendo esto, gracias por un gran rompecabezas.

Codificado en http://codepad.org/ZSDuCdin

Paul Drewett
fuente
Puede usar $f=trim(fgets(fopen('php://stdin')));para tomar la entrada.
Élektra
Rasca eso, $w=fgetcsv(STDIN);funciona mejor.
Élektra
1

D: 326 caracteres

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

Más legible:

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)]);
}
Jonathan M Davis
fuente
1

Mathematica

Todavía faltan algunos detalles

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"}
Dr. belisario
fuente
1

Mathematica 220 207

Después de escribir esto, noté que esto sigue el mismo razonamiento que Belisario usó,

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

resultados

Debido a que la respuesta no es competitiva (por ser tan larga), decidí usar un formato de entrada más compatible con Mathematica.

DavidC
fuente
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

No estoy tan contento con este como podría haber estado, pero lo pondré de todos modos. La puntuación real es muy concisa ( yfunción), pero la ifs para comparar resultados (enz ) son bastante largos.

Para usarlo llame zcon sus dos palabras (por ejemplo z 'FOO','BAR'). Anotará ambas palabras y devolverá la palabra de mayor puntuación. Si es un empate, se repetirá con las palabras modificadas (manteniendo que los originales vuelvan eventualmente, de ahí los dos parámetros adicionales) que obtiene de la xfunción.

El javascript equivalente (expandido) para los interesados:

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, "");
    }
  }
};
Johno
fuente
1

Raqueta 479 bytes

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

Sin golf:

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

Pruebas:

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

Salida:

"CAN"
"NO"
rnso
fuente
1

PHP, 339 (no a las especificaciones), 410 382 359 339 337 Bytes

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

EDITAR 1 : +71 bytes. Usando en STDINlugar de fopen('php://stdin','r');y etiquetas cortas. Además, la plena conformidad con la especificación.

EDITAR 2 : -28 bytes. Usando en fgetcsv(STDIN)lugar de explode(',',trim(fgets(STDIN)))y forbucle usado en lugar de whilebucle.

EDITAR 3 : -23 bytes. Funciones fusionadas ay b, fusionadas para bucles.

EDITAR 4 : -20 bytes. Se convirtió cde un recursivo en un bucle. Luego, eliminó la función cy colocó su código en el espacio de nombres global.

EDITAR 5 : -2 bytes. Gracias a @Titus por la -rbandera.

Élektra
fuente
1
no hay necesidad de una etiqueta PHP con -rbandera
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");
        }
Aman ZeeK Verma
fuente
El código anterior reemplaza todos los caracteres máximos en caso de empate ... ¿es necesario?
Aman ZeeK Verma
0

C ++, 473 (estoy tomando prestado un curso de hierro)

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

Estoy seguro de que podría acortarlo de alguna manera, pero estoy cansado.

Editar: originalmente tomó el argumento de la línea de comando, modificado para usar cin. Probablemente sean algunos caracteres más largos ahora, pero estoy demasiado cansado para contarlo.

Wug
fuente
0

Python: 383 caracteres

ejecuta la función 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))
Ashwini Chaudhary
fuente
0

F #, 559 533 530 bytes

No competitivo hasta el momento. Estoy seguro de que c se puede acortar, así como las últimas líneas. No tener un acceso más fácil a los argumentos de la línea de comandos también está sufriendo aquí.

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

Pruébalo en línea!

  • Ahorró 3 bytes al restringir s a una cadena al compararlo con una cadena

Versión sin golf

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
Brunner
fuente
0

PHP, 296 281 267 bytes

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;

ejecutar -no probarlo en línea (TiO incluye desglose).

En febrero de 2011, la versión actual de PHP era 5.3.5; así que no pude

  • usar la asignación de lista abreviada ( [$a,$b]=fgetcsv(...)y tal
  • alias count_chars línea
  • resultados de la función de índice directamente
  • usar índices de cadena negativos en lugar de substr

Pero ninguno de los dos habría ahorrado mucho; así que no importa mucho.

Las cosas más costosas fueron los bucles (por supuesto) y la regla # 4 ( 40 36 bytes).

Titus
fuente