Мое Слово может разбить твое Слово


26

ПРОБЛЕМА

Учитывая два слова, найдите победителя в битве цифровых корней .

Определите цифровой корень слова следующим образом:

  1. Каждой букве алфавита присваивается номер: A = 1, B = 2, C = 3, ..., Z = 26
  2. Добавьте значения для каждой буквы, чтобы суммировать слово. Возьмите "CAT", например. C + A + T = 3 + 1 + 20 = 24
  3. Добавьте все одиночные цифры, которые составляют этот результат: 24 => 2 + 4 = 6
  4. Повторяйте шаг № 3, пока не достигнете одной цифры. Эта единственная цифра является цифровым корнем слова.

Правила:

  1. Победитель объявляется, если его цифровой корень больше другого.
  2. Если значения цифрового корня равны, сократите слова, удалив каждый экземпляр буквы с самым высоким значением из обоих слов и произведя пересчет.
  3. Повторяйте шаги № 1 и № 2 до тех пор, пока не останется победитель или в одном из слов не останется только одна буква (или нет букв).
  4. Если значения цифрового корня равны после прохождения процесса сокращения, более длинное слово объявляется победителем.
  5. Если слова имеют одинаковую длину и победитель не найден после прохождения процесса сокращения, победитель не объявляется.

Особые правила:

  1. Не допускается использование модуля при расчете самого цифрового корня . Это может быть использовано где-либо еще.
  2. Предположим, что слова будут состоять только из заглавных букв - без знаков препинания, без пробелов и т. Д.

ВХОД

Потяните слова через стандартный ввод (через запятую). Параметры метода, или как вы хотите. Укажите в своем решении или коде, как слова анализируются или готовятся.

ВЫХОД

Показать победное слово. Если победителя нет, выведите «STALEMATE».

Примеры:

Intput: CAN, BAT

CAN = 18 = 9
BAT = 23 = 5 

выход: CAN

вход: зоопарк, нет

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

OO = 30 = 3
N = 14 = 5

выход: НЕТ

ОБНОВЛЕНИЕ : входные данные должны быть прочитаны с использованием стандартного ввода со словами в виде строки через запятую.

ОБНОВЛЕНИЕ : Добавлена ​​пара примеров для проверки.

ОБНОВЛЕНИЕ : разъяснено удаление буквы с самым высоким значением в случае связи - это также немного меняет условие остановки - если слово состоит из одной буквы или нуля букв, процесс сокращения останавливается


Вы должны принять решение о вводе, а не оставлять его на усмотрение, поскольку это имеет огромное значение в программах. Выбрав метод ввода и указав его, вы удаляете «творческие интерпретации» и решаете задачу, равную для всех.
MtnViewMark

@MtnViewMark - Понятно, но эффективно я пытаюсь удалить чтение ввода из числа символов. Меня не интересует самый умный или кратчайший способ чтения двух слов. Требование определенного метода также препятствует определенным языкам - я думаю, я просто пытаюсь понять суть проблемы.
Стив

1
@Steve - Тогда вы не должны указывать вывод как «дисплей», да? Тем не менее, я думаю, что вы, возможно, слишком много снимаете с этой проблемы. Умный и короткий гольф часто возникает из-за сложного сочетания различных аспектов проблемы, например, из-за того, что часть обработки складывается во ввод или вывод. Что касается языков гандикапов - почти все они могут читать stdin и писать stdout.
MtnViewMark

@MtnViewMark - Справедливая точка. Я сделаю простое обновление и проясню это. У моего любимого языка длинный путь чтения со стандартного ввода, поэтому я предвзят. :)
Стив

Принимает ли вход аргумент в main count как из stdin? Да, и вообще, если вы хотите снизить требования к случайным вещам, таким как чтение из stdin и необходимость импортировать или включать другие модули или файлы, создание головоломки требует функции, а не целой программы, вероятно, будет лучшим способом решения этой проблемы. ,
Джонатан М Дэвис

Ответы:


9

J, 100

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

работает так:

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

не все же принимают входные данные точно так , как просили.


9

APL (Дьялог) ( 91 86)

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

Пояснение (в порядке исполнения):

  • ⎕ML←3: установите ML в 3 (это делает среднее разделение, между прочим).
  • G←Z⊂⍨','≠Z←⍞: чтение ввода, разделение запятыми, сохранение в G и переход к функции.
  • +/¨⎕A∘⍳¨⍵: рассчитать оценку для каждого слова. ( ⎕Aэто список, содержащий алфавит.)
  • Z←{2>⍴⍕⍵:⍵⋄∇+/⍎¨⍕⍵}¨: вычислить цифровой корень для каждой оценки (суммируя все цифры до тех пор, пока есть еще одна цифра) и сохраняя их в Z.
  • Z≡∪Z: если все оценки уникальны ...
  • :G[↑⍒Z]: ... затем выведите слово с наибольшим количеством очков (из исходного списка).
  • ⋄1∊↑¨⍴¨⍵:'STALEMATE': в противном случае (если есть связь), если одно из слов имеет длину 1, выведите STALEMATE.
  • ⋄∇1∘↓¨⍵: в противном случае уберите первую букву из каждого слова и снова запустите функцию.

5

Рубин - 210

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

тесты:

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

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

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

Первая строка может быть сокращена до d,e=(a,b=gets.split ?,).map{|w|w.bytes.sort}.
Вентеро

Почему бы не сократить это далее, используя какое-то другое слово для обозначения связи? то есть "TIE" против "STALEMATE"
Гаффи

@Gaffi, потому что спецификация требует использования слова "STALEMATE".
Пол Престиж

@chron Позор мне, я перестал читать в"If the words are of equal length and no winner is found after going through the shortening process, no winner is declared."
Gaffi

5

Haskell, 205 символов

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

Образцы прогонов:

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

> ./WordVsWord <<< CAN,BAT
CAN

> ./WordVsWord <<< ZOO,NO
NO

> ./WordVsWord <<< FAT,BANANA
FAT

> ./WordVsWord <<< ONE,ONE
STALEMATE

  • Изменить: (227 -> 219) лучший выбор победителя, сопоставление с сокращенным рисунком w, импортированный более старый, более короткий модуль
  • Изменить: (219 -> 208) Включить предложения JB
  • Редактировать: (208 -> 205) обрабатывать отрицательные числа, используя странные правила в Хаскеле о дефисе

1
Использование прямого сравнения списков - очень приятное прикосновение. Несколько предложенных «быстрых» улучшений: ',':b_:b(-2), если вы не слишком привязаны к многострочной обработке interact$unlines.map([...]).linesputStr.[...]=<<getLine(-11), если вы позволяете себе ослаблять вывод putStrprint(-1). Я ненавижу эту операцию отрицания, принимающую так много символов, но не могу найти обходной путь.
JB

Спасибо, JB! Я включил большинство предложений. Я чувствовал, что результат должен соответствовать спецификации, в частности, завершиться переводом строки. Но я бы хотел сохранить этих двух персонажей, если они приблизятся! :-)
MtnViewMark

Хорошая работа с вычитаниями!
JB

3

Perl, 224 225 229

Базовый гольф (пока ничего умного):

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

Perl 5.10 и выше, запустить с perl -M5.010 <file>илиperl -E '<code here>'

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

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

2

К, 106

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

Использует обработку исключений, чтобы перехватить ошибки стека, которые приводят к тупиковой ситуации.


2

VBA ( 242 462)

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

Оказывается, приведенный ниже код не соответствует спецификации, поэтому мне пришлось переделать, добавив много длины (см. Выше). : / / Это может быть возможно в дальнейшем играть в гольф, но это уже довольно компактно, и я сомневаюсь, что смогу вернуть его к соревновательному счету.

Оригинал (ниже) не удалял наиболее ценные буквы из слов, когда был галстук.

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

2

Это действительно пришло мне в голову, и это мой первый пост. Хотя он старый, я заметил, что никто не сделал версию php, так что вот моя.

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

534 персонажа.

Теперь я не уверен относительно правил запуска, поэтому я начал с $ f = 'CAN, CBN' в качестве ввода. Я надеюсь, что это было правильно. Я выполнил все тесты, и он прошел все из них, хотя это не особенно элегантно. Я действительно должен немного поспать сейчас, но мне было очень приятно работать над этим - спасибо за отличную головоломку.

Кодировано на http://codepad.org/ZSDuCdin


Вы можете использовать $f=trim(fgets(fopen('php://stdin')));для ввода данных.
Электра

Поцарапайте это, $w=fgetcsv(STDIN);работает лучше.
Élektra

1

D: 326 символов

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

Более разборчиво:

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

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

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

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

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

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

1

Mathematica

Некоторые детали по-прежнему отсутствуют

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

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

{"NO"}

1

Mathematica 220 207

Написав это, я заметил, что это следует тем же рассуждениям, которые использовал Велисарий,

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

использование

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

полученные результаты

Поскольку ответ не является конкурентным (будучи таким многословным), я решил использовать формат ввода, более близкий к Mathematica.


1

CoffeeScript - 335

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

Не так доволен этим, как мог бы, но я все равно с этим справлюсь. Фактическая оценка очень краткая ( yфункция), но ifсравнивать результаты (в z) довольно долго.

Чтобы использовать это, позвоните zс двумя словами (например z 'FOO','BAR'). Он забьет оба слова и вернет слово с более высоким баллом. Если это галстук, он будет повторяться с измененными словами (сохраняя оригиналы, чтобы в конечном итоге вернуть, следовательно, дополнительные два параметра), которые он получает из xфункции.

Эквивалентный (расширенный) javascript для интересующихся:

var x, y, z;

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

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

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

1

Ракетка 479 байт

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

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

Тестирование:

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

Выход:

"CAN"
"NO"

1

PHP, 339 (без спецификации), 410 382 359 339 337 байт

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

РЕДАКТИРОВАТЬ 1 : +71 байт. Использование STDINвместо fopen('php://stdin','r');и коротких тегов. Также полное соответствие спец.

РЕДАКТИРОВАТЬ 2 : -28 байт. Используя fgetcsv(STDIN)вместо explode(',',trim(fgets(STDIN))), и использовал forцикл вместо whileцикла.

РЕДАКТИРОВАТЬ 3 : -23 байта. Объединенные функции aи bобъединенные для циклов.

РЕДАКТИРОВАТЬ 4 : -20 байт. Превратился cиз рекурсивного в петлю. Затем удалили функцию cи поместили ее код в глобальное пространство имен.

РЕДАКТИРОВАТЬ 5 : -2 байта. Спасибо @Titus за -rфлаг.


1
нет необходимости в теге PHP с -rфлагом
Titus

0

ДЖАВА

    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

0

C ++, 473 (я заимствую курс железа)

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

Я уверен, что мог бы как-то сократить его, но я устал.

Редактировать: первоначально принял аргумент командной строки, модифицированный для использования cin. Вероятно, теперь это на несколько символов длиннее, но я слишком устал, чтобы пересказывать это.


0

Python: 383 символа

запустите функцию c('CAN','BAT'):

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

0

F #, 559 533 530 байт

Пока не конкурентоспособен. Я уверен , что с может быть короче, а также последние несколько строк. Отсутствие более легкого доступа к аргументам командной строки также вредит.

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

Попробуйте онлайн!

  • Сохранено 3 байта путем ограничения строки s путем сравнения ее со строкой

Неуправляемая версия

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

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

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

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

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

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

0

PHP, 296 281 267 байт

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

запустить -nили попробовать онлайн (TiO включает разбивку).

В феврале 2011 года текущая версия PHP была 5.3.5; так что я не мог

  • использовать сокращенное назначение списка ( [$a,$b]=fgetcsv(...)и такое)
  • count_charsвстроенный псевдоним
  • индексная функция приводит непосредственно
  • использовать отрицательные строковые индексы вместо substr

Но ни один не спас бы много; так что это не имеет большого значения.

Самыми дорогостоящими вещами были циклы (конечно) и правило № 4 ( 40 36 байт).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.