Ma Parole peut battre ta Parole


26

PROBLÈME

Étant donné deux mots, trouvez le gagnant dans une bataille racine numérique .

Définissez la racine numérique d'un mot de cette façon:

  1. Chaque lettre de l'alphabet se voit attribuer un numéro: A = 1, B = 2, C = 3, ..., Z = 26
  2. Ajoutez les valeurs de chaque lettre pour additionner le mot. Prenez "CAT", par exemple. C + A + T = 3 + 1 + 20 = 24
  3. Ajoutez tous les chiffres uniques qui composent ce résultat: 24 => 2 + 4 = 6
  4. Répétez l'étape 3 jusqu'à ce que vous atteigniez un seul chiffre. Ce chiffre unique est la racine numérique du mot.

Règles:

  1. Un gagnant est déclaré si sa racine numérique est plus grande que l'autre.
  2. Si les valeurs de racine numériques sont égales, raccourcissez les mots en supprimant chaque instance de la lettre de valeur la plus élevée des deux mots et en recalculant.
  3. Répétez les étapes 1 et 2 jusqu'à ce qu'il y ait un gagnant ou qu'un des mots ne contienne qu'une seule lettre (ou aucune lettre).
  4. Si les valeurs de racine numérique sont égales après avoir suivi le processus de raccourcissement, le mot le plus long est déclaré vainqueur.
  5. Si les mots sont de longueur égale et qu'aucun gagnant n'est trouvé après avoir suivi le processus de raccourcissement, aucun gagnant n'est déclaré.

Règles spéciales:

  1. Aucune utilisation du module n'est autorisée dans le calcul de la racine numérique elle-même. Il peut être utilisé partout ailleurs.
  2. Supposons que les mots se composent uniquement de lettres majuscules - pas de ponctuation, pas d'espaces, etc.

CONTRIBUTION

Tirez les mots dans stdin (séparés par des virgules). paramètres de méthode, ou comme vous le souhaitez. Expliquez clairement dans votre solution ou dans le code comment les mots sont analysés ou préparés.

SORTIE

Affichez le mot gagnant. S'il n'y a pas de gagnant, affichez "STALEMATE".

Exemples:

entrée: CAN, BAT

CAN = 18 = 9
BAT = 23 = 5 

sortie: CAN

entrée: ZOO, NON

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

OO = 30 = 3
N = 14 = 5

sortie: NON

MISE À JOUR : L'entrée doit être lue en utilisant stdin avec les mots comme une chaîne séparée par des virgules.

MISE À JOUR : Ajout de quelques exemples pour tester.

MISE À JOUR : clarifié la suppression de la lettre la plus valorisée dans le cas d'une égalité - cela modifie également légèrement la condition d'arrêt également - si un mot a une lettre ou zéro lettre, le processus de raccourcissement est arrêté


Vous devez décider de l'entrée, ne pas la laisser au choix, car cela fait une énorme différence dans les programmes. En choisissant une méthode de saisie et en la spécifiant, vous supprimez les «interprétations créatives» et lancez un défi qui est égal pour tous.
MtnViewMark

@MtnViewMark - Compris, mais en fait j'essaye de supprimer la lecture de l'entrée du nombre de caractères. Je ne suis pas intéressé par la façon la plus intelligente ou la plus courte de lire les deux mots. Exiger une méthode spécifique handicape également certaines langues - je suppose que j'essaie simplement de comprendre le problème.
Steve

1
@Steve - Alors vous ne devriez pas non plus spécifier la sortie comme "affichage", oui? Cependant, je pense que vous éliminez peut-être trop le problème. Un golf intelligent et court découle souvent de la combinaison de différents aspects du problème de manière délicate, par exemple en repliant une partie du traitement en entrée ou en sortie. En ce qui concerne les langues handicapées, presque toutes peuvent lire stdin et écrire stdout.
MtnViewMark

@MtnViewMark - Juste point. Je vais faire une simple mise à jour et la clarifier. Ma langue de choix a juste une longue façon de lire à partir de stdin, donc je suis biaisé. :)
Steve

Est-ce que le fait de prendre en entrée un argument pour principal compte comme provenant de stdin? Oh, et généralement, si vous voulez limiter les exigences sur les choses errantes comme la lecture depuis stdin et devoir importer ou inclure d'autres modules ou fichiers, rendre le puzzle nécessitant une fonction plutôt qu'un programme entier serait probablement la meilleure façon de procéder .
Jonathan M Davis

Réponses:


9

J, 100

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

fonctionne comme ceci:

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

il n'accepte pas encore la saisie exactement comme demandé.


9

APL (Dyalog) ( 91 86)

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

Explication (par ordre d'exécution):

  • ⎕ML←3: définissez ML sur 3 (cela rend la partition moyenne, entre autres).
  • G←Z⊂⍨','≠Z←⍞: lire l'entrée, séparée par des virgules, stocker dans G et passer à la fonction.
  • +/¨⎕A∘⍳¨⍵: calcule le score de chaque mot. ( ⎕Aest une liste contenant l'alphabet.)
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨: calculez la racine numérique de chaque partition (en additionnant tous les chiffres tant qu'il y a encore plus d'un chiffre) et stockez-les dans Z.
  • Z≡∪Z: si tous les scores sont uniques ...
  • :G[↑⍒Z]: ... puis sortir le mot avec le score le plus élevé (de la liste d'origine).
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE': sinon (s'il y a égalité), si l'un des mots est de longueur 1, sortir STALEMATE.
  • ⋄∇1∘↓¨⍵: sinon, retirez la première lettre de chaque mot et exécutez à nouveau la fonction.

5

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

Tests:

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

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

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

La première ligne peut être raccourcie d,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}.
Ventero

Pourquoi ne pas raccourcir davantage en utilisant un autre mot pour désigner une cravate? ie "TIE" vs. "STALEMATE"
Gaffi

@Gaffi, car la spécification requiert que le mot "STALEMATE" soit utilisé.
Paul Prestidge

@chron Honte à moi, j'ai arrêté de lire à"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 caractères

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

Exemples de cycles:

> 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

  • Edit: (227 -> 219) meilleure sélection du gagnant, correspondance de modèle raccourcie w, module plus ancien importé, plus court
  • Modifier: (219 -> 208) Incorporer les suggestions de JB
  • Edit: (208 -> 205) gérer les nombres négatifs, en exploitant les règles étranges dans Haskell sur le trait d'union

1
L'utilisation d'une comparaison de liste simple est une très bonne touche. Quelques améliorations suggérées "en un coup d'œil": ',':b_:b(-2), si vous n'êtes pas trop attaché au traitement multiligne interact$unlines.map([...]).linesputStr.[...]=<<getLine(-11), si vous vous autorisez à une sortie laxiste putStrprint(-1). Je déteste ces opérations de négation prenant autant de caractères, mais je ne trouve pas de moyen de les contourner.
JB

Merci, JB! J'ai incorporé la plupart des suggestions. Je pensais que la sortie devrait suivre les spécifications, en particulier se terminer par une nouvelle ligne. Mais je serais prêt à sauver ces deux personnages si ça se rapprochait! :-)
MtnViewMark

Bon travail avec les soustractions!
JB

3

Perl, 224 225 229

Golf de base (rien d'intelligent pour l'instant):

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 et supérieur, exécuté avec perl -M5.010 <file>ouperl -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]

Utilise la gestion des exceptions pour détecter les erreurs de pile, ce qui entraîne des cas de blocage.


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

Il s'avère que le code ci-dessous ne correspondait pas aux spécifications, j'ai donc dû retravailler, en ajoutant beaucoup de longueur (voir ci-dessus). : - / Cela peut peut-être être joué plus loin, mais il est déjà assez compact et je doute que je puisse le ramener à un score compétitif.

L'original (ci-dessous) n'a pas supprimé la lettre la plus valorisée des mots en cas d'égalité.

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

Cela m'a vraiment pris de fantaisie et c'est mon premier post. Bien qu'il soit vieux, j'ai remarqué que personne n'avait fait de version php alors voici la mienne.

<?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 caractères.

Maintenant, je ne suis pas sûr des règles de démarrage, j'ai donc commencé avec $ f = 'CAN, CBN' comme entrée. J'espère que c'était vrai. J'ai exécuté tous les tests et il les réussit tous bien qu'il ne soit pas particulièrement élégant. Je dois vraiment dormir un peu maintenant, mais j'ai eu beaucoup de plaisir à travailler cela - merci pour un grand puzzle.

Codé sur http://codepad.org/ZSDuCdin


Vous pouvez utiliser $f=trim(fgets(fopen('php://stdin')));pour prendre l'entrée.
Élektra

Grattez ça, ça $w=fgetcsv(STDIN);fonctionne mieux.
Élektra

1

D: 326 caractères

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

Plus lisiblement:

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

Certains détails manquent encore

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

Après avoir écrit ceci, j'ai remarqué que cela suit le même raisonnement que celui utilisé par Bélisaire,

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

Usage

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

résultats

Parce que la réponse n'est pas compétitive (étant si longue), j'ai décidé d'utiliser un format d'entrée plus convivial pour 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

Pas aussi content de celui-ci que j'aurais pu l'être, mais je le mettrai quand même. Le score réel est très concis ( yfonction), mais le ifs pour comparer les résultats (enz ) deviennent assez longs.

Pour l'utiliser, appelez zavec vos deux mots (par exemple z 'FOO','BAR'). Il marquera les deux mots et renverra le mot ayant le score le plus élevé. S'il s'agit d'une égalité, il récurrera avec les mots modifiés (en conservant les originaux pour revenir éventuellement, d'où les deux paramètres supplémentaires) qu'il obtient de la xfonction.

Le javascript équivalent (étendu) pour les personnes intéressées:

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

Raquette 479 octets

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

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

Essai:

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

Sortie:

"CAN"
"NO"

1

PHP, 339 (pas SPEC), 410 382 359 339 337 octets

$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 octets. Utilisation STDINde fopen('php://stdin','r');balises au lieu de et courtes. En outre, pleine conformité à la spécification.

EDIT 2 : -28 octets. Utilisation fgetcsv(STDIN)au lieu de explode(',',trim(fgets(STDIN))), et forboucle utilisée au lieu de la whileboucle.

EDIT 3 : -23 octets. Fonctions fusionnées aet b, fusionnées pour les boucles.

EDIT 4 : -20 octets. Passé cd'un récursif en boucle. Ensuite, supprimez la fonction cet placez son code dans l'espace de noms global.

EDIT 5 : -2 octets. Merci à @Titus pour le -rdrapeau.


1
pas besoin d'une balise PHP avec -rindicateur
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");
        }

Le code ci-dessus remplace tous les caractères max en cas d'égalité .. est-ce nécessaire?
Aman ZeeK Verma

0

C ++, 473 (j'emprunte un cours de fer)

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

Je suis sûr que je pourrais le raccourcir d'une manière ou d'une autre, mais je suis fatigué.

Edit: initialement pris l'argument de la ligne de commande, modifié pour utiliser cin. C'est probablement quelques caractères de plus maintenant mais je suis trop fatigué pour le raconter.


0

Python: 383 caractères

exécutez la fonction 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 octets

Pas encore compétitif. Je suis sûr que c peut être raccourci ainsi que les dernières lignes. Ne pas avoir un accès plus facile aux arguments de la ligne de commande est également un problème ici.

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

Essayez-le en ligne!

  • Enregistré 3 octets en contraignant s à la chaîne en le comparant avec la chaîne

Version non golfée

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 octets

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;

courir avec -nou essayer en ligne (TiO inclut la panne).

En février 2011, la version PHP actuelle était la 5.3.5; donc je ne pouvais pas

  • utiliser l'affectation de liste abrégée ([$a,$b]=fgetcsv(...) et autres)
  • alias count_chars ligne
  • indexer directement les résultats de la fonction
  • utiliser des index de chaîne négatifs au lieu de substr

Mais ni l'un ni l'autre n'aurait économisé beaucoup; donc peu importe.

Les choses les plus coûteuses étaient les boucles (bien sûr) et la règle # 4 ( 40 36 octets).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.